This is analform.c in view mode; [Download] [Up]
/* analform.c 1.9beta -- parse the output of the analog form interface */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* You must change the next line to indicate where the analog program lives */
#define COMMAND "/http/cgi-bin/analog"
#define MAXARGLENGTH (2048) /* should be plenty */
#define OK (0)
#define ERR (-1)
#define STRLENGTH (64)
typedef int flag;
void unhttp(char *url) /* converts back all http special characters */
{
char *tempp;
char tempstr[MAXARGLENGTH];
int i;
/* firstly, change +'s into spaces */
for (i = strlen(url) - 1; i >= 0; i--) {
if (url[i] == '+')
url[i] = ' ';
}
/* secondly change %7E to ~, etc. */
tempp = url;
while ((tempp = strchr(tempp, '%')) != NULL) {
sscanf(tempp + 1, "%2x", &i);
if (i >= 0x20 && i < 0x7F) {
*tempp = i;
strcpy(tempstr, tempp + 3);
strcpy(tempp + 1, tempstr);
/* strcpy(tempp + 1, tempp + 3) may not be safe on all machines
(overlapping arguments) */
}
tempp++;
}
}
void genopts(FILE *thepipe, char name[9], int sortby, char *astr, char *cstr)
{
fprintf(thepipe, "%sSORTBY ", name);
if (sortby == 3)
fprintf(thepipe, "RANDOM\n");
else if (sortby == 2)
fprintf(thepipe, "ALPHABETICAL\n");
else if (sortby == 1)
fprintf(thepipe, "BYTES\n");
else
fprintf(thepipe, "REQUESTS\n");
if (sortby == 1) {
if (cstr[0] != '\0')
fprintf(thepipe, "%sMINBYTES %s\n", name, cstr);
}
else {
if (astr[0] != '\0')
fprintf(thepipe, "%sMINREQS %s\n", name, astr);
}
}
int main()
{
extern void exit();
/* the input */
char *argstring;
char *nextarg;
char *nextval;
/* the variables that can be read in */
int xq = 0, mq = 0, Wq = 0, dq = 0, Dq = 0, hq = 0, oq = 0, Sq = 0;
int iq = 0, rq = 0, fq = 0, bq = 0, Bq = 0, cq = 0, eq = 0, Hq = 0;
char mg = '\0', Wg = '\0', dg = '\0', Dg = '\0', hg = '\0', Hg = '\0';
int os, Ss, is, rs, fs, Bs, bs;
int ou = 0;
char oa[STRLENGTH], Sa[STRLENGTH], ia[STRLENGTH], ra[STRLENGTH];
char fa[STRLENGTH], Ba[STRLENGTH], ba[STRLENGTH];
char oc[STRLENGTH], Sc[STRLENGTH], ic[STRLENGTH], rc[STRLENGTH];
char fc[STRLENGTH], Bc[STRLENGTH], bc[STRLENGTH];
int dirlevel;
char reqtype, reqlinks;
char *from = NULL, *to = NULL;
char *fonly = NULL, *fign = NULL;
char *honly = NULL, *hign = NULL;
char *org = NULL, *home = NULL;
char *logfile, *reflog, *browlog, *errlog, *cachefile;
char *TZ = NULL;
char TZenv[STRLENGTH];
FILE *thepipe;
int ret;
oa[0] = '\0';
Sa[0] = '\0';
ia[0] = '\0';
ra[0] = '\0';
fa[0] = '\0';
ba[0] = '\0';
Ba[0] = '\0';
oc[0] = '\0';
Sc[0] = '\0';
ic[0] = '\0';
rc[0] = '\0';
fc[0] = '\0';
bc[0] = '\0';
Bc[0] = '\0';
if ((argstring = getenv("QUERY_STRING")) == NULL) {
printf("Content-type: text/plain\n\n");
printf("Error: cannot find environment variable QUERY_STRING\n");
exit(ERR);
}
unhttp(argstring);
nextarg = strtok(argstring, "&");
while (nextarg != NULL) {
nextval = strchr(nextarg, '=') + 1;
if (nextval[0] != '\0') {
switch(nextarg[0]) {
case 'b':
switch(nextarg[1]) {
case 'a':
strcpy(ba, nextval);
break;
case 'b':
strcpy(ba, "-");
strcat(ba, nextval);
break;
case 'c':
strcpy(bc, nextval);
break;
case 'd':
strcpy(bc, "-");
strcat(bc, nextval);
break;
case 'q':
bq = atoi(nextval);
break;
case 's':
bs = atoi(nextval);
break;
}
break;
case 'B':
switch(nextarg[1]) {
case 'a':
strcpy(Ba, nextval);
break;
case 'b':
strcpy(ba, "-");
strcat(ba, nextval);
break;
case 'c':
strcpy(Bc, nextval);
break;
case 'd':
strcpy(Bc, "-");
strcat(Bc, nextval);
break;
case 'q':
Bq = atoi(nextval);
break;
case 's':
Bs = atoi(nextval);
break;
}
break;
case 'c':
cq = atoi(nextval);
break;
case 'd':
switch(nextarg[1]) {
case 'g':
dg = nextval[0];
break;
case 'q':
dq = 1;
break;
}
break;
case 'D':
switch(nextarg[1]) {
case 'g':
Dg = nextval[0];
break;
case 'q':
Dq = 1;
break;
}
break;
case 'e':
eq = atoi(nextval);
break;
case 'f':
switch(nextarg[1]) {
case 'a':
strcpy(fa, nextval);
break;
case 'b':
strcpy(fa, "-");
strcat(fa, nextval);
break;
case 'c':
strcpy(fc, nextval);
break;
case 'd':
strcpy(fc, "-");
strcat(fc, nextval);
break;
case 'i':
fign = nextval;
break;
case 'q':
fq = atoi(nextval);
break;
case 'r':
from = nextval;
break;
case 's':
fs = atoi(nextval);
break;
case 'y':
fonly = nextval;
break;
}
break;
case 'h':
switch(nextarg[1]) {
case 'g':
hg = nextval[0];
break;
case 'i':
hign = nextval;
break;
case 'o':
home = nextval;
break;
case 'q':
hq = 1;
break;
case 'y':
honly = nextval;
break;
}
break;
case 'H':
switch(nextarg[1]) {
case 'g':
Hg = nextval[0];
break;
case 'q':
Hq = atoi(nextval);
break;
}
break;
case 'i':
switch(nextarg[1]) {
case 'a':
strcpy(ia, nextval);
break;
case 'b':
strcpy(ia, "-");
strcat(ia, nextval);
break;
case 'c':
strcpy(ic, nextval);
break;
case 'd':
strcpy(ic, "-");
strcat(ic, nextval);
break;
case 'e':
dirlevel = atoi(nextval);
break;
case 'q':
iq = atoi(nextval);
break;
case 's':
is = atoi(nextval);
break;
}
break;
case 'l':
switch(nextarg[1]) {
case 'b':
browlog = nextval;
break;
case 'c':
cachefile = nextval;
break;
case 'e':
errlog = nextval;
break;
case 'f':
reflog = nextval;
break;
case 'o':
logfile = nextval;
break;
}
break;
case 'm':
switch(nextarg[1]) {
case 'g':
mg = nextval[0];
break;
case 'q':
mq = 1;
break;
}
break;
case 'o':
switch(nextarg[1]) {
case 'a':
strcpy(oa, nextval);
break;
case 'b':
strcpy(oa, "-");
strcat(oa, nextval);
break;
case 'c':
strcpy(oc, nextval);
break;
case 'd':
strcpy(oc, "-");
strcat(oc, nextval);
break;
case 'q':
oq = atoi(nextval);
break;
case 'r':
org = nextval;
break;
case 's':
os = atoi(nextval);
break;
case 'u':
ou = atoi(nextval);
break;
}
break;
case 'r':
switch(nextarg[1]) {
case 'a':
strcpy(ra, nextval);
break;
case 'b':
strcpy(ra, "-");
strcat(ra, nextval);
break;
case 'c':
strcpy(rc, nextval);
break;
case 'd':
strcpy(rc, "-");
strcat(rc, nextval);
break;
case 'l':
reqlinks = nextval[0];
break;
case 'q':
rq = atoi(nextval);
break;
case 's':
rs = atoi(nextval);
break;
case 't':
reqtype = nextval[0];
break;
}
break;
case 'S':
switch(nextarg[1]) {
case 'a':
strcpy(Sa, nextval);
break;
case 'b':
strcpy(Sa, "-");
strcat(Sa, nextval);
break;
case 'c':
strcpy(Sc, nextval);
break;
case 'd':
strcpy(Sc, "-");
strcat(Sc, nextval);
break;
case 'q':
Sq = atoi(nextval);
break;
case 's':
Ss = atoi(nextval);
break;
}
break;
case 't':
to = nextval;
break;
case 'T':
TZ = nextval;
break;
case 'W':
switch(nextarg[1]) {
case 'g':
Wg = nextval[0];
break;
case 'q':
Wq = 1;
break;
}
break;
case 'x':
xq = 1;
break;
}
}
nextarg = strtok((char *)NULL, "&");
}
/* OK, so we've read everything in, now send it to the program */
if (TZ != NULL) {
strcpy(TZenv, "TZ=");
strcat(TZenv, TZ);
putenv(TZenv);
}
if ((thepipe = popen(COMMAND " +g-", "w")) == NULL) {
printf("Content-type: text/plain\n\n");
printf("Error: cannot start analog program at %s\n", COMMAND);
}
else {
printf("Content-type: text/html\n\n");
fflush(stdout);
fprintf(thepipe, "OUTFILE stdout\n");
if (xq < 2)
fprintf(thepipe, "GENERAL %s\n", xq?"ON":"OFF");
if (mq < 2)
fprintf(thepipe, "MONTHLY %s\n", mq?"ON":"OFF");
if (Wq < 2)
fprintf(thepipe, "WEEKLY %s\n", Wq?"ON":"OFF");
if (dq < 2)
fprintf(thepipe, "DAILY %s\n", dq?"ON":"OFF");
if (Dq < 2)
fprintf(thepipe, "FULLDAILY %s\n", Dq?"ON":"OFF");
if (hq < 2)
fprintf(thepipe, "HOURLY %s\n", hq?"ON":"OFF");
if (Hq < 2)
fprintf(thepipe, "FULLHOURLY %s\n", Hq?"ON":"OFF");
if (oq < 2)
fprintf(thepipe, "DOMAIN %s\n", oq?"ON":"OFF");
if (Sq < 2)
fprintf(thepipe, "FULLHOSTS %s\n", Sq?"ON":"OFF");
if (iq < 2)
fprintf(thepipe, "DIRECTORY %s\n", iq?"ON":"OFF");
if (rq < 2)
fprintf(thepipe, "REQUEST %s\n", rq?"ON":"OFF");
if (bq < 2)
fprintf(thepipe, "BROWSER %s\n", bq?"ON":"OFF");
if (Bq < 2)
fprintf(thepipe, "FULLBROWSER %s\n", Bq?"ON":"OFF");
if (cq < 2)
fprintf(thepipe, "STATUS %s\n", bq?"ON":"OFF");
if (eq < 2)
fprintf(thepipe, "ERROR %s\n", bq?"ON":"OFF");
if (fq < 2)
fprintf(thepipe, "REFERER %s\n", bq?"ON":"OFF");
if (mq && mg != '\0')
fprintf(thepipe, "MONTHGRAPH %c", mg);
if (Wq && Wg != '\0')
fprintf(thepipe, "WEEKGRAPH %c", Wg);
if (hq && hg != '\0')
fprintf(thepipe, "HOURGRAPH %c", hg);
if (Hq && Hg != '\0')
fprintf(thepipe, "FULLHOURGRAPH %c", Hg);
if (dq && dg != '\0')
fprintf(thepipe, "DAYGRAPH %c", dg);
if (Dq && Dg != '\0')
fprintf(thepipe, "FULLDAYGRAPH %c", Dg);
if (oq)
genopts(thepipe, "DOM", os, oa, oc);
if (Sq)
genopts(thepipe, "HOST", Ss, Sa, Sc);
if (iq) {
genopts(thepipe, "DIR", is, ia, ic);
fprintf(thepipe, "DIRLEVEL %d\n", dirlevel);
}
if (rq) {
genopts(thepipe, "REQ", rs, ra, rc);
fprintf(thepipe, "REQTYPE %s\n", reqtype=='f'?"ALL":"PAGES");
fprintf(thepipe, "PAGELINKS %s\n", reqlinks=='f'?"ALL":(reqlinks=='p'?"ON":"OFF"));
}
if (bq)
genopts(thepipe, "BROW", bs, ba, bc);
if (Bq)
genopts(thepipe, "FULLBROW", Bs, Ba, Bc);
if (fq)
genopts(thepipe, "REF", fs, fa, fc);
fprintf(thepipe, "OUTPUT %s\n", ou?"ASCII":"HTML");
if (from != NULL)
fprintf(thepipe, "FROM %s\n", from);
if (to != NULL)
fprintf(thepipe, "TO %s\n", to);
if (org != NULL)
fprintf(thepipe, "HOSTNAME \"%s\"\n", org);
if (home != NULL)
fprintf(thepipe, "HOSTURL %s\n", home);
else
fprintf(thepipe, "HOSTURL -\n");
/* That just leaves the only's and ignore's and logfiles, which are a bit
more complicated as we have to parse them still. Recycle 'nextarg'. */
nextarg = strtok(fonly, " ,"); /* split at spaces and commas */
while (nextarg != NULL) {
fprintf(thepipe, "FILEINCLUDE %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(fign, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "FILEEXCLUDE %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(honly, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "HOSTINCLUDE %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(hign, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "HOSTEXCLUDE %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(browlog, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "BROWLOG %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(errlog, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "ERRLOG %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(reflog, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "REFLOG %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(logfile, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "LOGFILE %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
nextarg = strtok(cachefile, " ,");
while (nextarg != NULL) {
fprintf(thepipe, "CACHEFILE %s\n", nextarg);
nextarg = strtok((char *)NULL, " ,");
}
}
fflush(thepipe);
ret = pclose(thepipe);
if (ret != 0) {
printf("Analog failed to run or returned an error code.\n");
printf("Maybe your server's error log will give a clue why.\n");
}
fflush(stdout);
exit(ret);
}
extern int putenv(char *newval)
{
extern char **environ;
static int firstTime = 1;
char **ep;
char *cp;
int esiz;
char *np;
if (!(np = strchr(newval, '=')))
return 1;
*np = '\0';
/* look it up */
for (ep=environ ; *ep ; ep++)
{
/* this should always be true... */
if (cp = strchr(*ep, '='))
{
*cp = '\0';
if (!strcmp(*ep, newval))
{
/* got it! */
*cp = '=';
break;
}
*cp = '=';
}
else
{
*np = '=';
return 1;
}
}
*np = '=';
if (*ep)
{
/* the string was already there: just replace it with the new one */
*ep = newval;
return 0;
}
/* expand environ by one */
for (esiz=2, ep=environ ; *ep ; ep++)
esiz++;
if (firstTime)
{
char **epp;
char **newenv;
if (!(newenv = malloc(esiz * sizeof(char *))))
return 1;
for (ep=environ, epp=newenv ; *ep ;)
*epp++ = *ep++;
*epp++ = newval;
*epp = (char *) 0;
environ = newenv;
}
else
{
if (!(environ = realloc(environ, esiz * sizeof(char *))))
return 1;
environ[esiz - 2] = newval;
environ[esiz - 1] = (char *) 0;
firstTime = 0;
}
return 0;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.