#include #include #include #include #include "query.h" /* * Return allocated string containing next query string parameter * ("key=value"). The string is truncated to max characters. If * truncation occurred, the -1th character of the string is set to 1. */ char * nextparam(int max) { char *buf; int i, sz; static int j = 0; if(!query.post && !query.string[j-1]) return NULL; #define STEP 256 sz = STEP; if(!(buf = malloc(1+sz))) /* Leave space for -1th character. */ err(1, "malloc"); /* * buf's -1th character is set to 1 if the string * has been truncated (i.e. if input exceeded max). */ buf++; TRUNCATED(buf) = 0; #define READ(b) (query.post? fread(b, 1, 1, stdin): (*(b) = query.string[j++])) /* Return NULL if first character cannot be read. */ if(!READ(buf)) return NULL; i = 0; goto loop; for(; READ(buf+i); i++){ loop: if(buf[i] == '&'){ buf[i] = 0; break; } if(i+1 > max){ TRUNCATED(buf) = 1; /* Skip ahead to next parameter. */ while(READ(buf+i+1) && buf[i+1] != '&') ; break; } if(i+1 >= sz){ sz += STEP; /* Remember to adjust for -1th character. */ if(buf--, buf = realloc(buf, 1+sz), !buf++) err(1, "realloc"); } } buf[i] = 0; return buf; } /* Fill global query structure from CGI environment variables. */ void setquery() { query.string = getenv("QUERY_STRING"); if(!query.string){ fprintf(stderr, "no QUERY_STRING\n"); exit(1); } query.post = strcmp(getenv("REQUEST_METHOD"), "POST") == 0; } /* * Split parameter string on equals sign and return value portion; * return NULL if none found. */ char * split(char *param) { int n; n = strcspn(param, "="); if(!param[n]) return NULL; param[n] = 0; return param+n+1; }