My Shell-CGI Samples / yinlei



1. html sample



Polls Admin tool




Polls Summary / User list


Get the User (IP-address) List for a poll ID.

Input the PollID:
Go To Today's Polls Summary

2. listuser.cgi sample

#!/bin/sh
eval `/home/yinlei/apache/cgi-bin/proccgi $*`


set -f
echo Content-type: text/html
echo

#echo argv is $FORM_id, argc is $#

if [ -z "$FORM_id" ]; then
  echo "Usage:  listuser pollId"
  echo
  exit 1
fi

id=$FORM_id



echo "--------------- All the users ip of $id of Today -----------------------
" echo "
" echo "number ip choice
" eval `/home/yinlei/apache/cgi-bin/listuser.sh $id` # add a link to user sort listuser.tmp | uniq -c | sort -r | awk '{print $1,"", $2,"", $3, $4,"
"}' echo echo "--------------------------------------------" echo "end"
3. listuser.sh sample
bash-2.04$ cat listuser.sh
#!/bin/sh
cd /home/yinlei/apache/cgi-bin

/usr/bin/grep $1  /home/apache/logs/poll1/error | grep "### User" | sed -e 's|-| |g' | awk '$4!="PollID:" {print $4, $9, $10}' | sort > ./listuser.tmp
/usr/bin/grep $1  /home/apache/logs/poll1/error |  grep "### User" |sed -e 's|-| |g' | awk '$4=="PollID:" {print $3, $8, $9}' | sort >> ./listuser.tmp
#/usr/bin/grep $1  /home/polls/logs/*.poll |  grep "### User" |sed -e 's|-| |g'| awk '$4!="PollID:" {print $4, $9, $10}' | sort >> ./listuser.tmp
#/usr/bin/grep $1  /home/polls/logs/*.poll |  grep "### User" |sed -e 's|-| |g'| awk '$4=="PollID:" {print $3, $8, $9}' | sort >> ./listuser.tmp

bash-2.04$
4. proccgi.c
/*
 * Proccgi
 *
 * Reads form variables and dumps them on standard output.
 * Distributed by the GNU General Public License. Use and be happy.
 *
 * Frank Pilhofer
 * fp@informatik.uni-frankfurt.de
 *
 * Last changed 11/06/1997
 */

#include 
#include 
#include 
#include 
#include 

/*
 * Duplicate string
 */

char *
FP_strdup (char *string)
{
  char *result;

  if (string == NULL)
    return NULL;

  if ((result = (char *) malloc (strlen (string) + 1)) == NULL) {
    fprintf (stderr, "proccgi -- out of memory dupping %d bytes\n",
	     (int) strlen (string));
    return NULL;
  }

  strcpy (result, string);
  return result;
}

/*
 * Read CGI input
 */

char *
LoadInput (void)
{
  char *result, *method, *p;
  int length, ts;

  if ((method = getenv ("REQUEST_METHOD")) == NULL) {
    return NULL;
  }

  if (strcmp (method, "GET") == 0) {
    if ((p = getenv ("QUERY_STRING")) == NULL)
      return NULL;
    else
      result = FP_strdup (p);
  }
  else if (strcmp (method, "POST") == 0) {
    if ((length = atoi (getenv ("CONTENT_LENGTH"))) == 0)
      return NULL;

    if ((result = malloc (length + 1)) == NULL) {
      fprintf (stderr, "proccgi -- out of memory allocating %d bytes\n",
	       length);
      return NULL;
    }

    if ((ts = fread (result, sizeof (char), length, stdin)) < length) {
      fprintf (stderr, "proccgi -- error reading post data, %d bytes read, %d expedted\n",
	       ts, length);
    }
    result[length] = '\0';
  }
  else {
    return NULL;
  }

  return result;
}

/*
 * Parse + and %XX in CGI data
 */

char *
ParseString (char *instring)
{
  char *ptr1=instring, *ptr2=instring;

  if (instring == NULL)
    return instring;

  while (isspace (*ptr1))
    ptr1++;

  while (*ptr1) {
    if (*ptr1 == '+') {
      ptr1++; *ptr2++=' ';
    }
    else if (*ptr1 == '%' && isxdigit (*(ptr1+1)) && isxdigit (*(ptr1+2))) {
      ptr1++;
      *ptr2    = ((*ptr1>='0'&&*ptr1<='9')?(*ptr1-'0'):((char)toupper(*ptr1)-'A'+10)) << 4;
      ptr1++;
      *ptr2++ |= ((*ptr1>='0'&&*ptr1<='9')?(*ptr1-'0'):((char)toupper(*ptr1)-'A'+10));
      ptr1++;
    }
    else 
      *ptr2++ = *ptr1++;
  }
  while (ptr2>instring && isspace(*(ptr2-1)))
    ptr2--;

  *ptr2 = '\0';

  return instring;
}

/*
 * break into attribute/value pair. Mustn't use strtok, which is
 * already used one level below. We assume that the attribute doesn't
 * have any special characters.
 */

void
HandleString (char *input)
{
  char *data, *ptr, *p2;

  if (input == NULL) {
    return;
  }

  data = FP_strdup   (input);
  ptr  = ParseString (data);

  /*
   * Security:
   *
   * only accept all-alphanumeric attributes, and don't accept empty
   * values
   */

  if (!isalpha(*ptr) && *ptr != '_') {free (data); return;}
  ptr++;
  while (isalnum(*ptr) || *ptr == '_') ptr++;
  if (*ptr != '=') {free (data); return;}

  *ptr = '\0';
  p2 = ptr+1;

  fprintf (stdout, "FORM_%s=\"", data);

  /*
   * escape value
   */

  while (*p2) {
    switch (*p2) {
    case '"': case '\\': case '`': case '$':
      putc ('\\', stdout);
    default:
      putc (*p2,  stdout);
      break;
    }
    p2++;
  }
  putc ('"',  stdout);
  putc ('\n', stdout);
  *ptr = '=';
  free (data);
}

int
main (int argc, char *argv[])
{
  char *ptr, *data = LoadInput();
  int i;

  /*
   * Handle CGI data
   */

  if (data) {
    ptr = strtok (data, "&");
    while (ptr) {
      HandleString (ptr);
      ptr = strtok (NULL, "&");
    }
    free (data);
  }

  /*
   * Add Path info
   */

  if (getenv ("PATH_INFO") != NULL) {
    data = FP_strdup (getenv ("PATH_INFO"));
    ptr = strtok (data, "/");
    while (ptr) {
      HandleString (ptr);
      ptr = strtok (NULL, "/");
    }
    free (data);
  }

  /*
   * Add args
   */

  for (i=1; i < argc; i++) {
    HandleString (argv[i]);
  }

  /*
   * done
   */

  return 0;
}