diff options
Diffstat (limited to 'query.c')
-rw-r--r-- | query.c | 91 |
1 files changed, 78 insertions, 13 deletions
@@ -1,29 +1,94 @@ +#include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #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 -setqs() +setquery() { - qs = getenv("QUERY_STRING"); - if(!qs){ + 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 * -query(char *key) +split(char *param) { - char *w; int n; - - for(w = strtok(qs, "&"); w; w = strtok(NULL, "&")){ - n = strcspn(w, "="); - if(strncmp(w, key, n) == 0) - return w + n + (w[n] == '='); - } - - return NULL; + + n = strcspn(param, "="); + if(!param[n]) + return NULL; + param[n] = 0; + return param+n+1; }
\ No newline at end of file |