gcgi  0.9.5
About: GCGI implements NCSA's Common Gateway Interface along with the extensions to that interface defined in RFC2388.
  Fossies Dox: gcgi-0.9.5.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

gcgi.c
Go to the documentation of this file.
1 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
2 /*
3  * GCGI Library, implementing NCSA'a Common Gateway Interface and RFC2338.
4  * Copyright (C) 2001-2002 Julian Catchen, julian@catchen.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 #include "gcgi_private.h"
22 
23 static const char* const envVars[] =
24  {
25  "HTTP_COOKIE",
26  "HTTP_REFERER",
27  "AUTH_TYPE",
28  "CONTENT_LENGTH",
29  "CONTENT_TYPE",
30  "GATEWAY_INTERFACE",
31  "PATH_INFO",
32  "PATH_TRANSLATED",
33  "QUERY_STRING",
34  "REMOTE_ADDR",
35  "REMOTE_HOST",
36  "REMOTE_IDENT",
37  "REMOTE_USER",
38  "REQUEST_METHOD",
39  "SCRIPT_NAME",
40  "SERVER_NAME",
41  "SERVER_PORT",
42  "SERVER_PROTOCOL",
43  "SERVER_SOFTWARE"
44  };
45 
46 #define ENVCOUNT 19
47 
48 /*------ Global Variables ------*/
49 static CgiQuery *cgiQuery = NULL;
50 static int debug = 0;
51 static char *envVariablesFile = NULL;
52 static char *cgiQueryFile = NULL;
53 static size_t fieldLimit = 0;
54 static size_t queryLimit = 0;
55 
56 static const char gcgi_ident[] =
57  "$GCGI: GCGI " VERSION " Copyright (C) 2001-2002 Julian Catchen $\n"
58  "$Authors: Julian Catchen, topeka@catchen.org $";
59 
62 {
63  int numBytes, gcgifd;
64 
65  if (debug)
67 
68  /* Dup stdout to gcgiOut */
69  gcgifd = dup(fileno(stdout));
70  gcgiOut = fdopen(gcgifd, "w");
71 
72  /* Create the cgiQuery object. */
74 
75  if (cgiQuery->env[gcgiRequestMethod] == NULL )
76  return GCGIFATALERROR;
77 
78  if (! strncasecmp(cgiQuery->env[gcgiRequestMethod],"GET", 3) ) {
79  parseGetQueryString(&numBytes);
80  if (numBytes < 0)
81  return GCGIFATALERROR;
82  }
83  else if (! strncasecmp(cgiQuery->env[gcgiRequestMethod],"POST", 4) ) {
84  parsePostQueryString(&numBytes);
85  if (numBytes < 0)
86  return GCGIFATALERROR;
87  }
88  else
89  return GCGIFATALERROR;
90 
91  return GCGISUCCESS;
92 }
93 
94 
95 void
97 {
98  freeCgiQuery();
99 
101  if (cgiQueryFile != NULL) XFREE(cgiQueryFile);
102 
103 }
104 
105 
106 /* Limits specified in number of bytes. */
108 gcgiSetLimits(size_t flimit, size_t qlimit)
109 {
110  fieldLimit = flimit;
111  queryLimit = qlimit;
112 
113  return GCGISUCCESS;
114 }
115 
116 
118 parsePostQueryString(int *numBytes)
119 {
120  FILE *input;
121  char *querystring;
122  size_t clen;
123  int result;
124 
125  querystring = NULL;
126  result = 0;
127 
128  /* Return if we don't have the content length env variable. */
129  if (cgiQuery->env[gcgiContentLength] == NULL || cgiQuery->env[gcgiContentType] == NULL)
130  return GCGIFATALERROR;
131 
132  clen = strtol(cgiQuery->env[gcgiContentLength], NULL, 10);
133  /* Content Length was out of range */
134  if (errno == ERANGE)
135  return GCGIFATALERROR;
136 
137  if (debug) {
138  if ((input = fopen(cgiQueryFile, "r")) == NULL)
139  return GCGIFATALERROR;
140  }
141  else {
142  input = stdin;
143  }
144 
145  /* Standard URL Encoded POST string. */
146  if (strncasecmp(cgiQuery->env[gcgiContentType], "application/x-www-form-urlencoded", 33) == 0) {
147  querystring = readQueryFromStream(input, clen);
148  parseUrlEncoded(querystring, clen);
149 
150  *numBytes = clen;
151  }
152 
153  /* RFC2388 Encoding */
154  else if (strncasecmp(cgiQuery->env[gcgiContentType], "multipart/form-data", 19) == 0) {
155  /* Pass the file to the MIME library to parse. */
156  if ((result = parseFormData(input)) == GCGIFATALERROR)
157  return GCGIFATALERROR;
158 
159  *numBytes = clen;
160  }
161 
162  /* Unknown Encoding. */
163  else {
164  fprintf(stderr,"Unknown Encoding.\n");
165  return GCGIFATALERROR;
166  }
167 
168  if (debug) fclose(input);
169 
170  XFREE(querystring);
171 
172  if (result == GCGITRUNCATED)
173  return GCGITRUNCATED;
174  else
175  return GCGISUCCESS;
176 }
177 
178 
180 parseGetQueryString(int *numBytes)
181 {
182  size_t clen;
183 
184  if (cgiQuery->env[gcgiQueryString] == NULL)
185  return GCGIFATALERROR;
186 
187  clen = strlen(cgiQuery->env[gcgiQueryString]);
188 
189  if (clen <= 0)
190  return GCGIFATALERROR;
191 
192  *numBytes = parseUrlEncoded(cgiQuery->env[gcgiQueryString], clen);
193 
194  return GCGISUCCESS;
195 }
196 
197 
199 parseUrlEncoded(char *querystring, int clen)
200 {
201  QueryStringNode *qstring;
202  char *beg, *end, *qlen;
203  char *offset, *p;
204  int i;
205 
206  beg = end = qlen = NULL;
207 
208  offset = querystring + strlen(querystring);
209  /* Count the number of fileds in the Query String. */
210  for (p = querystring, i = 0; p < offset; p++)
211  if (*p == '&')
212  i++;
213  /* There is one more field than '&' characters. */
214  i++;
215  /* Create the QueryStringColl Array */
217 
218  qlen = querystring + clen;
219  for (beg = querystring; beg < qlen && end < qlen; beg = end+1) {
220  /* Malloc the queryString object and initialize it. */
221  createQueryStringNode(&qstring);
222 
223  /* Get Field Name */
224  for (end = beg; *end != '=' && end < qlen; end++);
225  qstring->field = XMALLOC(char, end - beg + 1);
226  strncpy(qstring->field, beg, end-beg);
227  qstring->field[end-beg] = '\0'; /* Zero out the string */
228 
229  /* Get Data */
230  for (beg = end+1; *end != '&' && end < qlen; end++);
231  qstring->data = XMALLOC(char, end - beg + 1);
232  strncpy(qstring->data, beg, end-beg);
233  qstring->data[end-beg] = '\0'; /* Zero out the string */
234  qstring->size = end - beg + 1;
235 
236  decodeUrl(qstring);
237 
238  /* Add struct to linked list. */
239  insertQueryStringNode(qstring);
240 
241  } /* for (beg = querystring; *beg < qlen && *end < qlen; beg++) */
242 
243  return GCGISUCCESS;
244 }
245 
246 
248 parseFormData(FILE *data)
249 {
250  MimePart *mime, *n;
251  QueryStringNode *node;
252  int len, i, trunc;
253 
254  if ((mime = mimeParseMimeMessage(data, queryLimit, fieldLimit)) == NULL)
255  return GCGIFATALERROR;
256 
257  /* Check if the MIME message was truncated. */
258  trunc = mime->truncated;
259 
260  /* Count the number of fileds in the Query String. */
261  for (n = mime->next, i = 0; n != NULL; n = n->next) i++;
263 
264  for (n = mime->next; n != NULL; n = n->next) {
265  createQueryStringNode(&node);
266  len = strlen(n->name);
267  node->field = XMALLOC(char, len + 1);
268  strncpy(node->field, n->name, len);
269  node->field[len] = '\0';
270 
271  node->type = n->type;
272  node->encoding = n->encoding;
273 
274  len = strlen(n->subtype);
275  node->subtype = XMALLOC(char, len + 1);
276  strncpy(node->subtype, n->subtype, len);
277  node->subtype[len] = '\0';
278 
279  if (n->filename != NULL) {
280  len = strlen(n->filename);
281  node->filename = XMALLOC(char, len + 1);
282  strncpy(node->filename, n->filename, len);
283  node->filename[len] = '\0';
284  }
285 
286  len = n->bodylen;
287  node->data = XMALLOC(char, len + 1);
288  /* Remove final "\r\n" that separated the boundary from the body. */
289  if (n->body[len-1] == '\n' && n->body[len-2] == '\r')
290  len -= 2;
291 
292  memcpy(node->data, n->body, len);
293  node->data[len] = '\0';
294  node->size = len;
295  node->truncated = n->truncated;
296 
297  if (debug)
298  fprintf(stderr,"N: Field: %s, Type: %d, Subtype: %s\n",n->name, n->type, n->subtype);
299  insertQueryStringNode(node);
300  node = NULL;
301  }
302 
303  /* Free the MIME structures. */
304  mimeFreeMimeMessage(mime);
305 
306  if (trunc)
307  return GCGITRUNCATED;
308  else
309  return GCGISUCCESS;
310 }
311 
312 
313 void
315 {
316  char *f, *d;
317  int flen, dlen;
318 
319  gcgiDecodeUrlEncodedString(qstring->field, &f, &flen);
320  strncpy(qstring->field, f, flen);
321  qstring->field[flen-1] = '\0';
322 
323  gcgiDecodeUrlEncodedString(qstring->data, &d, &dlen);
324  strncpy(qstring->data, d, dlen);
325  qstring->data[dlen-1] = '\0';
326 
327  XFREE(d);
328  XFREE(f);
329 }
330 
331 
333 gcgiSendContentType(char *mimeType, char *name, char *charset, HTTPHeader header)
334 {
335  fprintf(gcgiOut, "Content-Type: %s", mimeType);
336 
337  if ( (charset!= NULL) && (strlen(charset) > 0) )
338  fprintf(gcgiOut, "; charset=\"%s\"", charset);
339 
340  if ( (name!= NULL) && (strlen(name) > 0) )
341  fprintf(gcgiOut, "; name=\"%s\"", name);
342 
343  if (header == LAST)
344  fprintf(gcgiOut, "\r\n");
345 
346  fprintf(gcgiOut, "\r\n");
347 
348  return GCGISUCCESS;
349 }
350 
351 
353 gcgiSendContentDisp(MimeDisposition disp, char *filename, HTTPHeader header)
354 {
355  char *strDisp[] = { "inlined",
356  "attachment",
357  "formdata" };
358 
359  fprintf(gcgiOut, "Content-Disposition: %s", strDisp[disp]);
360 
361  if ( (filename!= NULL) && (strlen(filename) > 0) )
362  fprintf(gcgiOut, "; filename=\"%s\"", filename);
363 
364  if (header == LAST)
365  fprintf(gcgiOut, "\r\n");
366 
367  fprintf(gcgiOut, "\r\n");
368 
369  return GCGISUCCESS;
370 }
371 
372 
375 {
376  fprintf(gcgiOut, "Content-Length: %d", length);
377 
378  if (header == LAST)
379  fprintf(gcgiOut, "\r\n");
380 
381  fprintf(gcgiOut, "\r\n");
382 
383  return GCGISUCCESS;
384 }
385 
386 
388 gcgiSendLocation(char *redirectURL)
389 {
390  fprintf(gcgiOut, "Location: %s\r\n\r\n", redirectURL);
391 
392  return GCGISUCCESS;
393 }
394 
395 
397 gcgiSendStatus(int status, char *message)
398 {
399  fprintf(gcgiOut, "HTTP/1.1 %d %s\r\n\r\n", status, message);
400 
401  return GCGISUCCESS;
402 }
403 
404 
406 gcgiSendCacheControl(char *cache, HTTPHeader header)
407 {
408  fprintf(gcgiOut, "Cache-Control: %s", cache);
409 
410  if (header == LAST)
411  fprintf(gcgiOut, "\r\n");
412 
413  fprintf(gcgiOut, "\r\n");
414 
415  return GCGISUCCESS;
416 }
417 
418 
420 gcgiSendCookie(char *name, char *value, char *path, char *domain, char *expires, int secure, HTTPHeader header)
421 {
422  char *cookieEncoded;
423 
424  gcgiEncodeBaseSixtyFourString(value, strlen(value), &cookieEncoded);
425 
426  fprintf(gcgiOut,
427  "Set-Cookie: %s=%s; path=%s; domain=%s;",
428  name, cookieEncoded, path, domain);
429 
430  if (expires && strlen(expires) > 0)
431  fprintf(gcgiOut, " expires=%s;", expires);
432 
433  if (secure)
434  fprintf(gcgiOut, " secure");
435 
436  if (header == LAST)
437  fprintf(gcgiOut, "\r\n");
438 
439  fprintf(gcgiOut, "\r\n");
440 
441  XFREE(cookieEncoded);
442 
443  return GCGISUCCESS;
444 }
445 
446 
448 gcgiFetchCookies(char ***cookies)
449 {
451 
452  return GCGISUCCESS;
453 }
454 
455 
457 gcgiParseCookie(char *cookie, char **name, char **value)
458 {
459  char *encoded, *decoded;
460  int size;
461 
462  parseToken(cookie, name, &encoded);
463 
464  gcgiDecodeBaseSixtyFourString(encoded, &decoded, &size);
465 
466  size++;
467  decoded = XREALLOC(char, decoded, size);
468  decoded[size-1] = '\0';
469 
470  *value = decoded;
471  XFREE(encoded);
472 
473  return GCGISUCCESS;
474 }
475 
476 
478 gcgiFreeCookies(char **cookies)
479 {
480  freeStringArray(cookies);
481 
482  return GCGISUCCESS;
483 }
484 
485 
486 #ifdef USE_SSL
488 gcgiSendEncryptedCookie(char *name, char *value, char *path, char *domain, char *expires,
489  int secure, unsigned char *key, HTTPHeader header)
490 {
491  char *cookieEncoded;
492  char *ciphertext, *digestEncoded;
493  unsigned char *digest;
494  int ctlen, dlen;
495 
496  ciphertext = NULL;
497  digest = NULL;
498  digestEncoded = NULL;
499  ctlen = 0;
500  dlen = 0;
501 
502  encryptString(value, strlen(value), key, &ciphertext, &ctlen);
503  generateStringHMAC(ciphertext, ctlen, &digest, &dlen);
504  gcgiEncodeBaseSixtyFourString(ciphertext, ctlen, &cookieEncoded);
505  gcgiEncodeBaseSixtyFourString(digest, dlen, &digestEncoded);
506 
507  fprintf(gcgiOut,
508  "Set-Cookie: %s=%s&%s; path=%s; domain=%s;",
509  name, cookieEncoded, digestEncoded, path, domain);
510 
511  if (expires && strlen(expires) > 0)
512  fprintf(gcgiOut, " expires=%s;", expires);
513 
514  if (secure)
515  fprintf(gcgiOut, " secure");
516 
517  if (header == LAST)
518  fprintf(gcgiOut, "\r\n");
519 
520  fprintf(gcgiOut, "\r\n");
521 
522  XFREE(cookieEncoded);
523  XFREE(ciphertext);
524  XFREE(digest);
525  XFREE(digestEncoded);
526 
527  return GCGISUCCESS;
528 }
529 
530 
532 gcgiParseEncryptedCookie(char *cookie, unsigned char *key, char **name, char **value)
533 {
534  char **tokens;
535  int size;
536  char *ciphertext, *cdigest, *encoded, *decoded;
537  unsigned char *digest;
538  int ctlen, dlen, cdlen;
539 
540  ciphertext = NULL;
541  digest = NULL;
542  cdigest = NULL;
543  ctlen = 0;
544  dlen = 0;
545  cdlen = 0;
546 
547  parseToken(cookie, name, &encoded);
548 
549  tokenizeURLString(encoded, strlen(encoded), &tokens);
550  gcgiDecodeBaseSixtyFourString(tokens[0], &ciphertext, &ctlen);
551  decryptString(ciphertext, ctlen, key, &decoded, &size);
552  gcgiDecodeBaseSixtyFourString(tokens[1], &cdigest, &cdlen);
553  generateStringHMAC(ciphertext, ctlen, &digest, &dlen);
554 
555  if (dlen != cdlen && strncmp(digest, cdigest, dlen) != 0)
556  return GCGIBADDATA;
557 
558  size++;
559  decoded = XREALLOC(char, decoded, size);
560  decoded[size-1] = '\0';
561 
562  *value = decoded;
563 
564  freeStringArray(tokens);
565  XFREE(encoded);
566  XFREE(ciphertext);
567  XFREE(digest);
568  XFREE(cdigest);
569 
570  return GCGISUCCESS;
571 }
572 
573 
575 gcgiGenerateKey(unsigned char **key)
576 {
577  *key = generateKey();
578 
579  return GCGISUCCESS;
580 }
581 
582 
584 gcgiWriteKeyToFile(unsigned char *key, char *path)
585 {
586  if (writeKeyToFile(key, path) < 0)
587  return GCGIFATALERROR;
588 
589  return GCGISUCCESS;
590 }
591 
592 
594 gcgiReadKeyFromFile(char *path, unsigned char **key)
595 {
596  if (readKeyFromFile(path, key) < 0)
597  return GCGIFATALERROR;
598 
599  return GCGISUCCESS;
600 }
601 #endif
602 
603 
606 {
607  *ret = cgiQuery->queryCount;
608 
609  return GCGISUCCESS;
610 }
611 
612 
614 gcgiNumFields(char *field, int *ret)
615 {
616  int i;
617 
618  if (findQueryStringColl(field, &i) == GCGIFIELDNOTFOUND) {
619  *ret = 0;
620  return GCGIFIELDNOTFOUND;
621  }
622 
623  *ret = cgiQuery->query[i]->num;
624 
625  return GCGISUCCESS;
626 }
627 
628 
630 gcgiFetchInteger(char *field, int *ret, int defaultRet)
631 {
632  int i;
633  QueryStringNode *qs;
634 
635  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
636  *ret = defaultRet;
637  return GCGIFIELDNOTFOUND;
638  }
639 
640  if (qs->size <= 1 && qs->data[0] == '\0') {
641  *ret = defaultRet;
642  return GCGIFIELDEMPTY;
643  }
644 
645  i = strtol(qs->data,NULL,10);
646 
647  if (errno == ERANGE) {
648  *ret = defaultRet;
649  return GCGIBADDATA;
650  }
651  else
652  *ret = i;
653 
654  return GCGISUCCESS;
655 }
656 
657 
659 gcgiFetchIntegerNext(char *field, int *ret, int defaultRet)
660 {
661  int i;
662  QueryStringNode *qs;
663 
664  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND) {
665  *ret = defaultRet;
666  return GCGIFIELDNOTFOUND;
667  }
668 
669  if (qs->size <= 1 && qs->data[0] == '\0') {
670  *ret = defaultRet;
671  return GCGIFIELDEMPTY;
672  }
673 
674  i = strtol(qs->data,NULL,10);
675 
676  if (errno == ERANGE) {
677  *ret = defaultRet;
678  return GCGIBADDATA;
679  }
680  else
681  *ret = i;
682 
683  return GCGISUCCESS;
684 }
685 
686 
688 gcgiFetchDouble(char *field, double *ret, double defaultRet)
689 {
690  double i;
691  QueryStringNode *qs;
692 
693  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
694  *ret = defaultRet;
695  return GCGIFIELDNOTFOUND;
696  }
697 
698  if (qs->size <= 1 && qs->data[0] == '\0') {
699  *ret = defaultRet;
700  return GCGIFIELDEMPTY;
701  }
702 
703  i = strtod(qs->data, NULL);
704 
705  if (errno == ERANGE) {
706  *ret = defaultRet;
707  return GCGIBADDATA;
708  }
709  else
710  *ret = i;
711 
712  return GCGISUCCESS;
713 }
714 
715 
717 gcgiFetchDoubleNext(char *field, double *ret, double defaultRet)
718 {
719  double i;
720  QueryStringNode *qs;
721 
722  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND) {
723  *ret = defaultRet;
724  return GCGIFIELDNOTFOUND;
725  }
726 
727  if (qs->size <= 1 && qs->data[0] == '\0') {
728  *ret = defaultRet;
729  return GCGIFIELDEMPTY;
730  }
731 
732  i = strtod(qs->data, NULL);
733 
734  if (errno == ERANGE) {
735  *ret = defaultRet;
736  return GCGIBADDATA;
737  }
738  else
739  *ret = i;
740 
741  return GCGISUCCESS;
742 }
743 
744 
746 gcgiFieldLength(char *field, int *ret)
747 {
748  QueryStringNode *qs;
749 
750  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
751  *ret = 0;
752  return GCGIFIELDNOTFOUND;
753  }
754 
755  *ret = strlen(qs->data);
756 
757  if (*ret == 0)
758  return GCGIFIELDEMPTY;
759  else
760  return GCGISUCCESS;
761 }
762 
763 
765 gcgiFieldLengthCur(char *field, int *ret)
766 {
767  QueryStringNode *qs;
768 
769  if (findQueryStringNodeCur(field, &qs) == GCGIFIELDNOTFOUND) {
770  *ret = 0;
771  return GCGIFIELDNOTFOUND;
772  }
773 
774  *ret = strlen(qs->data);
775 
776  if (*ret == 0)
777  return GCGIFIELDEMPTY;
778  else
779  return GCGISUCCESS;
780 }
781 
782 
784 gcgiFieldLengthNext(char *field, int *ret)
785 {
786  QueryStringNode *qs;
787 
788  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND) {
789  *ret = 0;
790  return GCGIFIELDNOTFOUND;
791  }
792 
793  *ret = strlen(qs->data);
794 
795  if (*ret == 0)
796  return GCGIFIELDEMPTY;
797  else
798  return GCGISUCCESS;
799 }
800 
801 
803 gcgiFieldSize(char *field, int *ret)
804 {
805  QueryStringNode *qs;
806 
807  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
808  *ret = 0;
809  return GCGIFIELDNOTFOUND;
810  }
811 
812  *ret = qs->size;
813 
814  return GCGISUCCESS;
815 }
816 
817 
819 gcgiFieldSizeCur(char *field, int *ret)
820 {
821  QueryStringNode *qs;
822 
823  if (findQueryStringNodeCur(field, &qs) == GCGIFIELDNOTFOUND) {
824  *ret = 0;
825  return GCGIFIELDNOTFOUND;
826  }
827 
828  *ret = qs->size;
829 
830  return GCGISUCCESS;
831 }
832 
833 
835 gcgiFieldSizeNext(char *field, int *ret)
836 {
837  QueryStringNode *qs;
838 
839  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND) {
840  *ret = 0;
841  return GCGIFIELDNOTFOUND;
842  }
843 
844  *ret = qs->size;
845 
846  return GCGISUCCESS;
847 }
848 
849 
850 char *
852 {
853  return cgiQuery->env[env];
854 }
855 
856 
858 gcgiFetchString(char *field, char *ret, int max)
859 {
860  int i;
861  QueryStringNode *qs;
862 
863  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
864  ret[0] = '\0';
865  return GCGIFIELDNOTFOUND;
866  }
867 
868  i = strlen(qs->data);
869 
870  if (i >= max)
871  i = max-1;
872 
873  strncpy(ret, qs->data, i);
874  ret[i] = '\0';
875 
876  if (i == 0)
877  return GCGIFIELDEMPTY;
878  else
879  return GCGISUCCESS;
880 }
881 
882 
884 gcgiFetchStringNext(char *field, char *ret, int max)
885 {
886  int i;
887  QueryStringNode *qs;
888 
889  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND) {
890  ret[0] = '\0';
891  return GCGIFIELDNOTFOUND;
892  }
893 
894  i = strlen(qs->data);
895  if (i >= max)
896  i = max-1;
897 
898  strncpy(ret, qs->data, i);
899  ret[i] = '\0';
900 
901  if (i == 0)
902  return GCGIFIELDEMPTY;
903  else
904  return GCGISUCCESS;
905 }
906 
907 
909 gcgiFetchStringNoNewLines(char *field, char *ret, int max)
910 {
911  int len,i,j;
912  QueryStringNode *qs;
913 
914  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
915  ret[0] = '\0';
916  return GCGIFIELDNOTFOUND;
917  }
918 
919  len = strlen(qs->data);
920  if (len >= max)
921  len = max-1;
922 
923  for (j = 0, i = 0; i <= len && qs->data[j] != '\0'; j++, i++)
924  if (qs->data[j] == '\r' && qs->data[j+1] == '\n') {
925  ret[i] = ' ';
926  j++;
927  }
928  else if (qs->data[j] == '\n') {
929  ret[i] = ' ';
930  }
931  else
932  ret[i] = qs->data[j];
933 
934  if (i <= len)
935  ret[i] = '\0';
936  else
937  ret[len] = '\0';
938 
939  if (len == 0)
940  return GCGIFIELDEMPTY;
941  else
942  return GCGISUCCESS;
943 }
944 
945 
947 gcgiFetchStringNoNewLinesNext(char *field, char *ret, int max)
948 {
949  int len,i,j;
950  QueryStringNode *qs;
951 
952  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND) {
953  ret[0] = '\0';
954  return GCGIFIELDNOTFOUND;
955  }
956 
957  len = strlen(qs->data);
958  if (len >= max)
959  len = max-1;
960 
961  for (j = 0, i = 0; i <= len && qs->data[j] != '\0'; j++, i++)
962  if (qs->data[j] == '\r' && qs->data[j+1] == '\n') {
963  ret[i] = ' ';
964  i++;
965  j += 2;
966  }
967  else if (qs->data[j] == '\n') {
968  ret[i] = ' ';
969  j++;
970  }
971  else
972  ret[i] = qs->data[j];
973 
974  if (i <= len)
975  ret[i] = '\0';
976  else
977  ret[len] = '\0';
978 
979  if (i == 0)
980  return GCGIFIELDEMPTY;
981  else
982  return GCGISUCCESS;
983 }
984 
985 
987 gcgiFetchData(char *field, char *ret, int max, MimeType *type,
988  char **subtype, MimeEncoding *encoding, char **filename, int *truncated)
989 {
990  size_t i;
991  QueryStringNode *qs;
992 
993  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND)
994  return GCGIFIELDNOTFOUND;
995 
996  if (qs->truncated)
997  *truncated = 1;
998  else
999  *truncated = 0;
1000 
1001  i = qs->size;
1002  if (i >= max)
1003  i = max;
1004 
1005  if (i == 0)
1006  return GCGIFIELDNOTFOUND;
1007 
1008  memcpy(ret, qs->data, i);
1009 
1010  *type = qs->type;
1011  *encoding = qs->encoding;
1012 
1013  if (subtype != NULL) {
1014  *subtype = XMALLOC(char, strlen(qs->subtype)+1);
1015  strcpy(*subtype, qs->subtype);
1016  }
1017 
1018  if (filename != NULL) {
1019  *filename = XMALLOC(char, strlen(qs->filename)+1);
1020  strcpy(*filename, qs->filename);
1021  }
1022 
1023  return GCGISUCCESS;
1024 }
1025 
1026 
1028 gcgiFetchDataNext(char *field, char *ret, int max, MimeType *type,
1029  char **subtype, MimeEncoding *encoding, char **filename, int *truncated)
1030 {
1031  size_t i;
1032  QueryStringNode *qs;
1033 
1034  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND)
1035  return GCGIFIELDNOTFOUND;
1036 
1037  i = qs->size;
1038  if (i >= max)
1039  i = max;
1040 
1041  if (i == 0)
1042  return GCGIFIELDNOTFOUND;
1043 
1044  memcpy(ret, qs->data, i);
1045 
1046  *type = qs->type;
1047  *encoding = qs->encoding;
1048 
1049  return GCGISUCCESS;
1050 }
1051 
1052 
1054 gcgiFetchMultipleString(char *field, char ***data)
1055 {
1056  int i, j;
1057  QueryStringNode *qs;
1058  QueryStringColl *qsc;
1059 
1060  if (findQueryStringColl(field, &i) == GCGIFIELDNOTFOUND) {
1061  *data = NULL;
1062  return GCGIFIELDNOTFOUND;
1063  }
1064 
1065  qsc = cgiQuery->query[i];
1066 
1067  /* Malloc the array of char pointers. */
1068  *data = XMALLOC(char *, qsc->num + 1);
1069 
1070  (*data)[qsc->num] = '\0';
1071 
1072  for (qs = qsc->beg, j = 0; qs != NULL; qs = qs->next, j++) {
1073  (*data)[j] = XMALLOC(char, qs->size);
1074  strncpy((*data)[j], qs->data, qs->size - 1);
1075  (*data)[j][qs->size - 1] = '\0';
1076  }
1077 
1078  return GCGISUCCESS;
1079 }
1080 
1081 
1084 {
1085  int i;
1086 
1087  if (data == NULL)
1088  return GCGISUCCESS;
1089 
1090  for (i = 0; data[i] != NULL; i++)
1091  XFREE(data[i]);
1092 
1093  XFREE(data);
1094  return GCGISUCCESS;
1095 }
1096 
1097 
1100 {
1101  int i;
1102 
1103  if (findQueryStringColl(field, &i) == GCGIFIELDNOTFOUND)
1104  return GCGIFIELDNOTFOUND;
1105 
1106  cgiQuery->query[i]->cur = cgiQuery->query[i]->beg;
1107 
1108  return GCGISUCCESS;
1109 }
1110 
1111 
1113 gcgiFetchSelectIndex(char *field, char **data, int size, int *ret, int defaultVal)
1114 {
1115  QueryStringNode *qs;
1116  int i;
1117 
1118  *ret = -1;
1119 
1120  if (findQueryStringNode(field, &qs) == GCGIFIELDNOTFOUND)
1121  return GCGIFIELDNOTFOUND;
1122 
1123  for (i = 0; data[i] != NULL && i < size; i++)
1124  if (strncmp(data[i],qs->data,qs->size) == 0)
1125  *ret = i;
1126 
1127  if (*ret == -1) {
1128  *ret = defaultVal;
1129  return GCGIFIELDNOTFOUND;
1130  }
1131 
1132  return GCGISUCCESS;
1133 }
1134 
1135 
1137 gcgiFetchCheckbox(char *field, int *ret)
1138 {
1139  QueryStringNode *qs;
1140 
1141  if (findQueryStringNodeFirst(field, &qs) == GCGIFIELDNOTFOUND) {
1142  *ret = 0;
1143  return GCGIFIELDNOTFOUND;
1144  }
1145 
1146  *ret = 1;
1147 
1148  return GCGISUCCESS;
1149 }
1150 
1151 
1153 gcgiFetchMultipleCheckbox(char *field, char **data, int size, int **ret)
1154 {
1155  QueryStringNode *qs;
1156  int i;
1157 
1158  for (i = 0; data[i] != NULL && i < size; i++) {
1159  if (findQueryStringNodeByData(field, data[i], &qs) == GCGIFIELDNOTFOUND)
1160  (*ret)[i] = 0;
1161  else
1162  (*ret)[i] = 1;
1163  }
1164 
1165  return GCGISUCCESS;
1166 }
1167 
1168 
1171 {
1172  FILE *envfile;
1173  char line[256], *p;
1174  char *input;
1175  int ilen, len;
1176  int isize;
1177 
1178  input = NULL;
1179 
1180  if ((envfile = fopen(path,"r")) == NULL)
1181  return GCGIFATALERROR;
1182 
1183  while (!feof(envfile)) {
1184  /* Allocate a new string */
1185  ilen = 0;
1186  isize = 256;
1187  input = XMALLOC(char, isize);
1188  memset(input, 0, isize);
1189 
1190  do {
1191  fgets(line, 256, envfile);
1192  len = strlen(line);
1193  if (ilen + len <= isize - 1) {
1194  strcat(input, line);
1195  ilen += len;
1196  }
1197  else {
1198  isize = isize * 2;
1199  ilen += len;
1200  input = XREALLOC(char, input, isize);
1201  strcat(input, line);
1202  }
1203  } while (!feof(envfile) && input[ilen-1] != '\n');
1204 
1205  /* Remove the newline. */
1206  for (p = input; *p != '\n' && p < (input+ilen); p++);
1207  if (*(p-1) == '\r') *p = '\0';
1208  if (*p == '\n') *p = '\0';
1209 
1210  /* String becomes part of the environment */
1211  if (putenv(input) < 0) {
1212  fclose(envfile);
1213  XFREE(input);
1214  return GCGIFATALERROR;
1215  }
1216  }
1217 
1218  fclose(envfile);
1219  XFREE(input);
1220 
1221  return GCGISUCCESS;
1222 }
1223 
1224 
1227 {
1228  FILE *envfile;
1229  int i;
1230 
1231  if ((envfile = fopen(path,"w")) == NULL) {
1232  fprintf(stderr, "Unable to open file to save environment variables to: %s\n", path);
1233  return GCGIFATALERROR;
1234  }
1235 
1236  for (i = 0; i < ENVCOUNT; i++) {
1237  if (cgiQuery->env[i] != NULL)
1238  fprintf(envfile, "%s=%s\n", envVars[i], cgiQuery->env[i]);
1239  }
1240 
1241  fclose(envfile);
1242 
1243  return GCGISUCCESS;
1244 }
1245 
1246 
1248 gcgiDebug(char *envVarsPath, char *cgiQueryPath)
1249 {
1250  int evlen, cqlen;
1251 
1252  evlen = strlen(envVarsPath);
1253  cqlen = strlen(cgiQueryPath);
1254 
1255  debug++;
1256  envVariablesFile = XMALLOC(char, evlen + 1);
1257  strncpy(envVariablesFile, envVarsPath, evlen);
1258  envVariablesFile[evlen] = '\0';
1259 
1260  cgiQueryFile = XMALLOC(char, cqlen + 1);
1261  strncpy(cgiQueryFile, cgiQueryPath, cqlen);
1262  cgiQueryFile[cqlen] = '\0';
1263 
1264  return GCGISUCCESS;
1265 }
1266 
1267 
1270 {
1271  int i;
1272 
1273  cgiQuery = XMALLOC(CgiQuery, 1);
1274 
1275  if ((cgiQuery->env = (char **) malloc(ENVCOUNT * sizeof(char *))) == NULL)
1276  return GCGIFATALERROR;
1277 
1278  for (i = 0; i < ENVCOUNT; i++)
1279  cgiQuery->env[i] = NULL;
1280  cgiQuery->envCount = 0;
1281 
1282  /* Populate the env array. */
1283  getEnvVariables();
1284  //gcgiSaveEnvVariables();
1285 
1286  /* Set the queryStringColl pointer to NULL for now. */
1287  cgiQuery->query = NULL;
1288 
1289  return GCGISUCCESS;
1290 }
1291 
1292 
1295 {
1296  int i;
1297 
1298  if (cgiQuery == NULL)
1299  return GCGISUCCESS;
1300 
1301  /* Free the env variables array */
1302  for (i = 0; i < cgiQuery->envCount; i++)
1303  if (cgiQuery->env[i] != NULL) XFREE(cgiQuery->env[i]);
1304 
1305  /* Free the QueryNodeColl array */
1306  for (i = 0; i < cgiQuery->queryCount; i++)
1308 
1309  XFREE(cgiQuery->env);
1310  XFREE(cgiQuery->query);
1311  XFREE(cgiQuery);
1312 
1313  return GCGISUCCESS;
1314 }
1315 
1316 
1319 {
1320  int i, len;
1321  char *e;
1322 
1323  for (i = 0; i < ENVCOUNT; i++) {
1324  if ((e = getenv(envVars[i])) != NULL) {
1325  len = strlen(e);
1326  cgiQuery->env[i] = XMALLOC(char, len + 1);
1327  strncpy(cgiQuery->env[i], e, len);
1328  cgiQuery->env[i][len] = '\0';
1329  cgiQuery->envCount++;
1330  }
1331  else
1332  cgiQuery->env[i] = NULL;
1333  }
1334 
1335  return GCGISUCCESS;
1336 }
1337 
1338 
1341 {
1342  int i, res;
1343  QueryStringColl *qsc;
1344 
1345  res = findQueryStringColl(q->field, &i);
1346 
1347  /* A collection for this field doen not exist. */
1348  if (res == GCGIFIELDNOTFOUND) {
1349  //qsc = cgiQuery->query[cgiQuery->queryCount];
1350  createQueryStringColl(&qsc);
1351  cgiQuery->query[cgiQuery->queryCount] = qsc;
1352  i = cgiQuery->queryCount;
1353  cgiQuery->queryCount++;
1354  }
1355  else {
1356  qsc = cgiQuery->query[i];
1357  }
1358 
1359  /* Insert the node at the end of the collection's node list. */
1360  if (qsc->end == NULL) {
1361  qsc->end = q;
1362  qsc->beg = q;
1363  qsc->cur = q;
1364  }
1365  else {
1366  qsc->end->next = q;
1367  qsc->end = q;
1368  }
1369  q->next = NULL;
1370  qsc->num++;
1371 
1372  return GCGISUCCESS;
1373 }
1374 
1375 
1377 findQueryStringColl(char *field, int *index)
1378 {
1379  int flen, qlen, len;
1380  QueryStringColl **qsc;
1381 
1382  flen = strlen(field);
1383  if (cgiQuery == NULL) {
1384  *index = -1;
1385  return GCGIFIELDNOTFOUND;
1386  }
1387 
1388  qsc = cgiQuery->query;
1389 
1390  for (*index = 0; *index < cgiQuery->queryCount; (*index)++) {
1391  qlen = strlen(qsc[*index]->beg->field);
1392  (qlen >= flen) ? (len = qlen) : (len = flen);
1393 
1394  if (! strncmp(field, qsc[*index]->beg->field, len))
1395  return GCGISUCCESS;
1396  }
1397 
1398  return GCGIFIELDNOTFOUND;
1399 }
1400 
1401 
1404 {
1405  int flen, i, res;
1406 
1407  flen = strlen(field);
1408  if (cgiQuery == NULL || cgiQuery->queryCount == 0) {
1409  *q = NULL;
1410  return GCGIFIELDNOTFOUND;
1411  }
1412 
1413  res = findQueryStringColl(field, &i);
1414 
1415  if (res == GCGIFIELDNOTFOUND) {
1416  *q = NULL;
1417  return GCGIFIELDNOTFOUND;
1418  }
1419 
1420  if (cgiQuery->query[i]->beg != NULL)
1421  *q = cgiQuery->query[i]->beg;
1422  else {
1423  *q = NULL;
1424  return GCGIFIELDNOTFOUND;
1425  }
1426 
1427  return GCGISUCCESS;
1428 }
1429 
1430 
1433 {
1434  int flen, i, res;
1435 
1436  flen = strlen(field);
1437  if (cgiQuery == NULL || cgiQuery->queryCount == 0) {
1438  *q = NULL;
1439  return GCGIFIELDNOTFOUND;
1440  }
1441 
1442  res = findQueryStringColl(field, &i);
1443 
1444  if (res == GCGIFIELDNOTFOUND) {
1445  *q = NULL;
1446  return GCGIFIELDNOTFOUND;
1447  }
1448 
1449  if (cgiQuery->query[i]->cur != NULL)
1450  *q = cgiQuery->query[i]->cur;
1451  else {
1452  *q = NULL;
1453  return GCGIFIELDNOTFOUND;
1454  }
1455 
1456  /* Return the current item in the list and then increment it. */
1457  if (cgiQuery->query[i]->cur->next != NULL)
1458  cgiQuery->query[i]->cur = cgiQuery->query[i]->cur->next;
1459  else
1460  cgiQuery->query[i]->cur = NULL;
1461 
1462  return GCGISUCCESS;
1463 }
1464 
1465 
1468 {
1469  int flen, i, res;
1470 
1471  flen = strlen(field);
1472  if (cgiQuery == NULL || cgiQuery->queryCount == 0) {
1473  *q = NULL;
1474  return GCGIFIELDNOTFOUND;
1475  }
1476 
1477  res = findQueryStringColl(field, &i);
1478 
1479  if (res == GCGIFIELDNOTFOUND) {
1480  *q = NULL;
1481  return GCGIFIELDNOTFOUND;
1482  }
1483 
1484  /* Return the current item in the list but don't increment it. */
1485  if (cgiQuery->query[i]->cur != NULL)
1486  *q = cgiQuery->query[i]->cur;
1487  else {
1488  *q = NULL;
1489  return GCGIFIELDNOTFOUND;
1490  }
1491 
1492  return GCGISUCCESS;
1493 }
1494 
1495 
1497 findQueryStringNodeByData(char *field, char *data, QueryStringNode **q)
1498 {
1499  QueryStringNode *qs;
1500  int i;
1501 
1502  if (findQueryStringColl(field, &i) == GCGIFIELDNOTFOUND)
1503  return GCGIFIELDNOTFOUND;
1504 
1505  for (qs = cgiQuery->query[i]->beg;
1506  qs != NULL && strncmp(qs->data, data, qs->size) != 0;
1507  qs = qs->next);
1508 
1509  if (qs != NULL) {
1510  *q = qs;
1511  return GCGISUCCESS;
1512  }
1513  else
1514  return GCGIFIELDNOTFOUND;
1515 }
1516 
1517 
1520 {
1521  *q = XMALLOC(QueryStringNode, 1);
1522  (*q)->next = NULL;
1523  (*q)->field = NULL;
1524  (*q)->data = NULL;
1525  (*q)->subtype = NULL;
1526  (*q)->filename = NULL;
1527  (*q)->size = 0;
1528  (*q)->encoding = sevenbit;
1529  (*q)->type = text;
1530 
1531  return GCGISUCCESS;
1532 }
1533 
1534 
1537 {
1538  if (q->data != NULL) XFREE(q->data);
1539  if (q->field != NULL) XFREE(q->field);
1540  if (q->subtype != NULL) XFREE(q->subtype);
1541  if (q->subtype != NULL) XFREE(q->filename);
1542  q->next = NULL;
1543 
1544  XFREE(q);
1545 
1546  return 0;
1547 }
1548 
1549 
1552 {
1553  *q = XMALLOC(QueryStringColl, 1);
1554 
1555  (*q)->num = 0;
1556  (*q)->beg = NULL;
1557  (*q)->end = NULL;
1558  (*q)->cur = NULL;
1559 
1560  return GCGISUCCESS;
1561 }
1562 
1563 
1566 {
1567  int i;
1568 
1569  /* Malloc the query[] array and clear it. */
1570  if ((cgiQuery->query = (QueryStringColl **) malloc(numColls * sizeof(QueryStringColl *))) == NULL)
1571  return GCGIFATALERROR;
1572 
1573  for (i = 0; i < numColls; i++)
1574  cgiQuery->query[i] = NULL;
1575 
1576  cgiQuery->queryCount = 0;
1577 
1578  return GCGISUCCESS;
1579 }
1580 
1581 
1584 {
1585  QueryStringNode *m, *n;
1586 
1587  for (m = n = q->beg; n != NULL; m = n) {
1588  n = n->next;
1590  }
1591 
1592  q->beg = NULL;
1593  q->end = NULL;
1594  q->cur = NULL;
1595 
1596  XFREE(q);
1597 
1598  return GCGISUCCESS;
1599 }
1600 
1601 
1604 {
1605  QueryStringNode *node;
1606 
1607  for (node = q->beg; node != NULL; node = node->next) {
1608  printQueryStringNode(node, stream);
1609  }
1610 
1611  return GCGISUCCESS;
1612 }
1613 
1614 
1616 printQuery(FILE *stream)
1617 {
1618  int i;
1619 
1620  for (i = 0; i < cgiQuery->queryCount; i++) {
1621  fprintf(stream, "QueryString Collection #%d:\n", i);
1622  printQueryStringColl(cgiQuery->query[i], stream);
1623  }
1624 
1625  return GCGISUCCESS;
1626 }
1627 
1628 
1631 {
1632  fprintf(stream, " %s: %s\n", q->field, q->data);
1633 
1634  return GCGISUCCESS;
1635 }
gcgiContentLength
Definition: gcgi.h:35
gcgiFetchMultipleString
gcgiReturnType gcgiFetchMultipleString(char *field, char ***data)
Definition: gcgi.c:1054
freeCgi
void freeCgi()
Definition: gcgi.c:96
gcgiFetchIntegerNext
gcgiReturnType gcgiFetchIntegerNext(char *field, int *ret, int defaultRet)
Definition: gcgi.c:659
GCGITRUNCATED
Definition: gcgi.h:59
querystringcoll::beg
QueryStringNode * beg
Definition: gcgi_private.h:51
gcgiFetchStringNoNewLines
gcgiReturnType gcgiFetchStringNoNewLines(char *field, char *ret, int max)
Definition: gcgi.c:909
readQueryFromStream
char * readQueryFromStream(FILE *input, int clen)
Definition: common.c:64
gcgiFetchInteger
gcgiReturnType gcgiFetchInteger(char *field, int *ret, int defaultRet)
Definition: gcgi.c:630
tokenizeURLString
int tokenizeURLString(char *string, int size, char ***output)
Definition: parse.c:308
gcgi_private.h
parseFormData
gcgiReturnType parseFormData(FILE *data)
Definition: gcgi.c:248
querystringcoll::num
size_t num
Definition: gcgi_private.h:50
gcgiSendCookie
gcgiReturnType gcgiSendCookie(char *name, char *value, char *path, char *domain, char *expires, int secure, HTTPHeader header)
Definition: gcgi.c:420
gcgiDecodeBaseSixtyFourString
gcgiReturnType gcgiDecodeBaseSixtyFourString(char *text, char **decodedText, int *numBytes)
Definition: code.c:41
gcgiFieldSizeCur
gcgiReturnType gcgiFieldSizeCur(char *field, int *ret)
Definition: gcgi.c:819
errno
int errno
gcgiFieldLength
gcgiReturnType gcgiFieldLength(char *field, int *ret)
Definition: gcgi.c:746
findQueryStringColl
gcgiReturnType findQueryStringColl(char *field, int *index)
Definition: gcgi.c:1377
mimepart::body
char * body
Definition: mime.h:45
mimeParseMimeMessage
MimePart * mimeParseMimeMessage(FILE *mimeIn, size_t mimeLimit, size_t mimePartLimit)
Definition: mime.c:84
XFREE
#define XFREE(stale)
Definition: common.h:70
gcgiSendContentType
gcgiReturnType gcgiSendContentType(char *mimeType, char *name, char *charset, HTTPHeader header)
Definition: gcgi.c:333
gcgiFreeMultipleString
gcgiReturnType gcgiFreeMultipleString(char **data)
Definition: gcgi.c:1083
mimepart::name
char * name
Definition: mime.h:39
gcgiFetchStringNext
gcgiReturnType gcgiFetchStringNext(char *field, char *ret, int max)
Definition: gcgi.c:884
printQuery
gcgiReturnType printQuery(FILE *stream)
Definition: gcgi.c:1616
printQueryStringNode
gcgiReturnType printQueryStringNode(QueryStringNode *q, FILE *stream)
Definition: gcgi.c:1630
querystringnode::data
char * data
Definition: gcgi_private.h:38
querystringnode::encoding
MimeEncoding encoding
Definition: gcgi_private.h:42
gcgiFetchMultipleCheckbox
gcgiReturnType gcgiFetchMultipleCheckbox(char *field, char **data, int size, int **ret)
Definition: gcgi.c:1153
gcgiFetchCookies
gcgiReturnType gcgiFetchCookies(char ***cookies)
Definition: gcgi.c:448
gcgiLoadEnvVariables
gcgiReturnType gcgiLoadEnvVariables(char *path)
Definition: gcgi.c:1170
gcgiSendContentLength
gcgiReturnType gcgiSendContentLength(int length, HTTPHeader header)
Definition: gcgi.c:374
querystringnode::subtype
char * subtype
Definition: gcgi_private.h:41
gcgiFetchSelectIndex
gcgiReturnType gcgiFetchSelectIndex(char *field, char **data, int size, int *ret, int defaultVal)
Definition: gcgi.c:1113
readKeyFromFile
int readKeyFromFile(char *path, unsigned char **key)
querystringcoll::cur
QueryStringNode * cur
Definition: gcgi_private.h:53
gcgiFetchCheckbox
gcgiReturnType gcgiFetchCheckbox(char *field, int *ret)
Definition: gcgi.c:1137
mimepart::bodylen
size_t bodylen
Definition: mime.h:46
cgiquery
Definition: gcgi_private.h:57
text
Definition: gcgi.h:66
gcgiQueryString
Definition: gcgi.h:40
gcgiFetchStringNoNewLinesNext
gcgiReturnType gcgiFetchStringNoNewLinesNext(char *field, char *ret, int max)
Definition: gcgi.c:947
decodeUrl
void decodeUrl(QueryStringNode *qstring)
Definition: gcgi.c:314
gcgiSetLimits
gcgiReturnType gcgiSetLimits(size_t flimit, size_t qlimit)
Definition: gcgi.c:108
XMALLOC
#define XMALLOC(type, num)
Definition: common.h:66
createCgiQuery
gcgiReturnType createCgiQuery()
Definition: gcgi.c:1269
querystringnode
Definition: gcgi_private.h:36
sevenbit
Definition: gcgi.h:77
GCGIFATALERROR
Definition: gcgi.h:55
cgiquery::envCount
size_t envCount
Definition: gcgi_private.h:59
gcgiNumFormFields
gcgiReturnType gcgiNumFormFields(int *ret)
Definition: gcgi.c:605
parsePostQueryString
gcgiReturnType parsePostQueryString(int *numBytes)
Definition: gcgi.c:118
gcgiSendStatus
gcgiReturnType gcgiSendStatus(int status, char *message)
Definition: gcgi.c:397
generateKey
unsigned char * generateKey()
tokenizeString
int tokenizeString(char *string, int size, char ***output)
Definition: parse.c:241
gcgiRequestMethod
Definition: gcgi.h:45
XREALLOC
#define XREALLOC(type, p, num)
Definition: common.h:68
gcgiContentType
Definition: gcgi.h:36
GCGIBADDATA
Definition: gcgi.h:60
gcgiEncodeBaseSixtyFourString
gcgiReturnType gcgiEncodeBaseSixtyFourString(char *text, int numBytes, char **encodedText)
Definition: code.c:96
gcgiFetchEnvVar
char * gcgiFetchEnvVar(int env)
Definition: gcgi.c:851
querystringnode::size
size_t size
Definition: gcgi_private.h:39
mimepart::truncated
size_t truncated
Definition: mime.h:48
gcgiDebug
gcgiReturnType gcgiDebug(char *envVarsPath, char *cgiQueryPath)
Definition: gcgi.c:1248
gcgiReadKeyFromFile
gcgiReturnType gcgiReadKeyFromFile(char *path, unsigned char **key)
gcgiSaveEnvVariables
gcgiReturnType gcgiSaveEnvVariables(char *path)
Definition: gcgi.c:1226
gcgi_ident
static const char gcgi_ident[]
Definition: gcgi.c:56
querystringnode::truncated
size_t truncated
Definition: gcgi_private.h:44
gcgiWriteKeyToFile
gcgiReturnType gcgiWriteKeyToFile(unsigned char *key, char *path)
findQueryStringNodeByData
gcgiReturnType findQueryStringNodeByData(char *field, char *data, QueryStringNode **q)
Definition: gcgi.c:1497
parseGetQueryString
gcgiReturnType parseGetQueryString(int *numBytes)
Definition: gcgi.c:180
gcgiSendCacheControl
gcgiReturnType gcgiSendCacheControl(char *cache, HTTPHeader header)
Definition: gcgi.c:406
freeQueryStringColl
gcgiReturnType freeQueryStringColl(QueryStringColl *q)
Definition: gcgi.c:1583
mimepart::encoding
MimeEncoding encoding
Definition: mime.h:37
gcgiSendContentDisp
gcgiReturnType gcgiSendContentDisp(MimeDisposition disp, char *filename, HTTPHeader header)
Definition: gcgi.c:353
gcgiOut
FILE * gcgiOut
Definition: gcgi.h:188
cgiQueryFile
static char * cgiQueryFile
Definition: gcgi.c:52
GCGIFIELDNOTFOUND
Definition: gcgi.h:57
MimeDisposition
MimeDisposition
Definition: gcgi.h:89
parseUrlEncoded
gcgiReturnType parseUrlEncoded(char *querystring, int clen)
Definition: gcgi.c:199
gcgiParseCookie
gcgiReturnType gcgiParseCookie(char *cookie, char **name, char **value)
Definition: gcgi.c:457
encryptString
void encryptString(char *text, int size, unsigned char *key, char **ciphertext, int *ctlen)
gcgiFetchDataNext
gcgiReturnType gcgiFetchDataNext(char *field, char *ret, int max, MimeType *type, char **subtype, MimeEncoding *encoding, char **filename, int *truncated)
Definition: gcgi.c:1028
gcgiGenerateKey
gcgiReturnType gcgiGenerateKey(unsigned char **key)
writeKeyToFile
int writeKeyToFile(unsigned char *key, char *path)
ENVCOUNT
#define ENVCOUNT
Definition: gcgi.c:46
fieldLimit
static size_t fieldLimit
Definition: gcgi.c:53
createQueryStringNode
gcgiReturnType createQueryStringNode(QueryStringNode **q)
Definition: gcgi.c:1519
freeStringArray
int freeStringArray(char **string)
Definition: parse.c:364
gcgiFetchDoubleNext
gcgiReturnType gcgiFetchDoubleNext(char *field, double *ret, double defaultRet)
Definition: gcgi.c:717
printQueryStringColl
gcgiReturnType printQueryStringColl(QueryStringColl *q, FILE *stream)
Definition: gcgi.c:1603
mimepart::filename
char * filename
Definition: mime.h:40
cgiquery::queryCount
size_t queryCount
Definition: gcgi_private.h:60
parseToken
int parseToken(char *token, char **property, char **value)
Definition: parse.c:385
gcgiFetchDouble
gcgiReturnType gcgiFetchDouble(char *field, double *ret, double defaultRet)
Definition: gcgi.c:688
gcgiFieldLengthCur
gcgiReturnType gcgiFieldLengthCur(char *field, int *ret)
Definition: gcgi.c:765
cgiquery::query
QueryStringColl ** query
Definition: gcgi_private.h:61
gcgiFetchData
gcgiReturnType gcgiFetchData(char *field, char *ret, int max, MimeType *type, char **subtype, MimeEncoding *encoding, char **filename, int *truncated)
Definition: gcgi.c:987
gcgiDecodeUrlEncodedString
gcgiReturnType gcgiDecodeUrlEncodedString(char *text, char **decodedText, int *size)
Definition: code.c:290
envVariablesFile
static char * envVariablesFile
Definition: gcgi.c:51
GCGIFIELDEMPTY
Definition: gcgi.h:58
gcgiResetMultipleField
gcgiReturnType gcgiResetMultipleField(char *field)
Definition: gcgi.c:1099
cgiquery::env
char ** env
Definition: gcgi_private.h:58
gcgiHttpCookie
Definition: gcgi.h:32
gcgiNumFields
gcgiReturnType gcgiNumFields(char *field, int *ret)
Definition: gcgi.c:614
message
Definition: gcgi.h:72
MimeType
MimeType
Definition: gcgi.h:65
HTTPHeader
HTTPHeader
Definition: gcgi.h:104
gcgiFieldLengthNext
gcgiReturnType gcgiFieldLengthNext(char *field, int *ret)
Definition: gcgi.c:784
querystringnode::field
char * field
Definition: gcgi_private.h:37
gcgiFetchString
gcgiReturnType gcgiFetchString(char *field, char *ret, int max)
Definition: gcgi.c:858
gcgiSendEncryptedCookie
gcgiReturnType gcgiSendEncryptedCookie(char *name, char *value, char *path, char *domain, char *expires, int secure, unsigned char *key, HTTPHeader header)
gcgiReturnType
gcgiReturnType
Definition: gcgi.h:54
gcgiFreeCookies
gcgiReturnType gcgiFreeCookies(char **cookies)
Definition: gcgi.c:478
cgiQuery
static CgiQuery * cgiQuery
Definition: gcgi.c:49
mimepart
Definition: mime.h:33
MimeEncoding
MimeEncoding
Definition: gcgi.h:76
findQueryStringNode
gcgiReturnType findQueryStringNode(char *field, QueryStringNode **q)
Definition: gcgi.c:1432
gcgiFieldSize
gcgiReturnType gcgiFieldSize(char *field, int *ret)
Definition: gcgi.c:803
mimepart::subtype
char * subtype
Definition: mime.h:36
findQueryStringNodeCur
gcgiReturnType findQueryStringNodeCur(char *field, QueryStringNode **q)
Definition: gcgi.c:1467
mimepart::type
MimeType type
Definition: mime.h:35
querystringcoll::end
QueryStringNode * end
Definition: gcgi_private.h:52
querystringnode::filename
char * filename
Definition: gcgi_private.h:43
createQueryStringColl
gcgiReturnType createQueryStringColl(QueryStringColl **q)
Definition: gcgi.c:1551
querystringnode::next
struct querystringnode * next
Definition: gcgi_private.h:45
freeQueryStringNode
gcgiReturnType freeQueryStringNode(QueryStringNode *q)
Definition: gcgi.c:1536
querystringcoll
Definition: gcgi_private.h:49
getEnvVariables
gcgiReturnType getEnvVariables(void)
Definition: gcgi.c:1318
queryLimit
static size_t queryLimit
Definition: gcgi.c:54
decryptString
void decryptString(char *ciphertext, int ctlen, unsigned char *key, char **text, int *size)
envVars
static const char *const envVars[]
Definition: gcgi.c:23
mimeFreeMimeMessage
void mimeFreeMimeMessage(MimePart *mime)
Definition: mime.c:140
LAST
Definition: gcgi.h:109
createQueryStringCollArray
gcgiReturnType createQueryStringCollArray(int numColls)
Definition: gcgi.c:1565
mimepart::next
struct mimepart * next
Definition: mime.h:49
insertQueryStringNode
gcgiReturnType insertQueryStringNode(QueryStringNode *q)
Definition: gcgi.c:1340
querystringnode::type
MimeType type
Definition: gcgi_private.h:40
gcgiFieldSizeNext
gcgiReturnType gcgiFieldSizeNext(char *field, int *ret)
Definition: gcgi.c:835
freeCgiQuery
gcgiReturnType freeCgiQuery()
Definition: gcgi.c:1294
gcgiSendLocation
gcgiReturnType gcgiSendLocation(char *redirectURL)
Definition: gcgi.c:388
generateStringHMAC
void generateStringHMAC(char *text, int size, unsigned char **hmac, int *hlen)
gcgiParseEncryptedCookie
gcgiReturnType gcgiParseEncryptedCookie(char *cookie, unsigned char *key, char **name, char **value)
findQueryStringNodeFirst
gcgiReturnType findQueryStringNodeFirst(char *field, QueryStringNode **q)
Definition: gcgi.c:1403
debug
static int debug
Definition: gcgi.c:50
GCGISUCCESS
Definition: gcgi.h:56
initCgi
gcgiReturnType initCgi()
Definition: gcgi.c:61