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.