aboutsummaryrefslogtreecommitdiff
path: root/query.c
diff options
context:
space:
mode:
Diffstat (limited to 'query.c')
-rw-r--r--query.c91
1 files changed, 78 insertions, 13 deletions
diff --git a/query.c b/query.c
index 09e7578..bc96778 100644
--- a/query.c
+++ b/query.c
@@ -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