]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/var.c
Load cups into easysw/current.
[thirdparty/cups.git] / cgi-bin / var.c
1 /*
2 * "$Id: var.c 6649 2007-07-11 21:46:42Z mike $"
3 *
4 * CGI form variable and array functions.
5 *
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2005 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * Contents:
16 *
17 * cgiCheckVariables() - Check for the presence of "required" variables.
18 * cgiGetArray() - Get an element from a form array...
19 * cgiGetFile() - Get the file (if any) that was submitted in the form.
20 * cgiGetSize() - Get the size of a form array value.
21 * cgiGetVariable() - Get a CGI variable from the database...
22 * cgiInitialize() - Initialize the CGI variable "database"...
23 * cgiIsPOST() - Determine whether this page was POSTed.
24 * cgiSetArray() - Set array element N to the specified string.
25 * cgiSetSize() - Set the array size.
26 * cgiSetVariable() - Set a CGI variable in the database...
27 * cgi_add_variable() - Add a form variable.
28 * cgi_compare_variables() - Compare two variables.
29 * cgi_find_variable() - Find a variable...
30 * cgi_initialize_get() - Initialize form variables using the GET method.
31 * cgi_initialize_multipart() - Initialize variables and file using the POST method.
32 * cgi_initialize_post() - Initialize variables using the POST method.
33 * cgi_initialize_string() - Initialize form variables from a string.
34 * cgi_passwd() - Catch authentication requests and notify the server.
35 * cgi_sort_variables() - Sort all form variables for faster lookup.
36 * cgi_unlink_file() - Remove the uploaded form.
37 */
38
39 /*#define DEBUG*/
40 #include "cgi-private.h"
41 #include <errno.h>
42
43
44 /*
45 * Data structure to hold all the CGI form variables and arrays...
46 */
47
48 typedef struct /**** Form variable structure ****/
49 {
50 const char *name; /* Name of variable */
51 int nvalues, /* Number of values */
52 avalues; /* Number of values allocated */
53 const char **values; /* Value(s) of variable */
54 } _cgi_var_t;
55
56
57 /*
58 * Local globals...
59 */
60
61 static int form_count = 0, /* Form variable count */
62 form_alloc = 0; /* Number of variables allocated */
63 static _cgi_var_t *form_vars = NULL;
64 /* Form variables */
65 static cgi_file_t *form_file = NULL;
66 /* Uploaded file */
67
68
69 /*
70 * Local functions...
71 */
72
73 static void cgi_add_variable(const char *name, int element,
74 const char *value);
75 static int cgi_compare_variables(const _cgi_var_t *v1,
76 const _cgi_var_t *v2);
77 static _cgi_var_t *cgi_find_variable(const char *name);
78 static int cgi_initialize_get(void);
79 static int cgi_initialize_multipart(const char *boundary);
80 static int cgi_initialize_post(void);
81 static int cgi_initialize_string(const char *data);
82 static const char *cgi_passwd(const char *prompt);
83 static void cgi_sort_variables(void);
84 static void cgi_unlink_file(void);
85
86
87 /*
88 * 'cgiCheckVariables()' - Check for the presence of "required" variables.
89 *
90 * Names may be separated by spaces and/or commas.
91 */
92
93 int /* O - 1 if all variables present, 0 otherwise */
94 cgiCheckVariables(const char *names) /* I - Variables to look for */
95 {
96 char name[255], /* Current variable name */
97 *s; /* Pointer in string */
98 const char *val; /* Value of variable */
99 int element; /* Array element number */
100
101
102 if (names == NULL)
103 return (1);
104
105 while (*names != '\0')
106 {
107 while (*names == ' ' || *names == ',')
108 names ++;
109
110 for (s = name; *names != '\0' && *names != ' ' && *names != ','; s ++, names ++)
111 *s = *names;
112
113 *s = 0;
114 if (name[0] == '\0')
115 break;
116
117 if ((s = strrchr(name, '-')) != NULL)
118 {
119 *s = '\0';
120 element = atoi(s + 1) - 1;
121 val = cgiGetArray(name, element);
122 }
123 else
124 val = cgiGetVariable(name);
125
126 if (val == NULL)
127 return (0);
128
129 if (*val == '\0')
130 return (0); /* Can't be blank, either! */
131 }
132
133 return (1);
134 }
135
136
137 /*
138 * 'cgiGetArray()' - Get an element from a form array...
139 */
140
141 const char * /* O - Element value or NULL */
142 cgiGetArray(const char *name, /* I - Name of array variable */
143 int element) /* I - Element number (0 to N) */
144 {
145 _cgi_var_t *var; /* Pointer to variable */
146
147
148 if ((var = cgi_find_variable(name)) == NULL)
149 return (NULL);
150
151 if (var->nvalues == 1)
152 return (var->values[0]);
153
154 if (element < 0 || element >= var->nvalues)
155 return (NULL);
156
157 return (var->values[element]);
158 }
159
160
161 /*
162 * 'cgiGetFile()' - Get the file (if any) that was submitted in the form.
163 */
164
165 const cgi_file_t * /* O - Attached file or NULL */
166 cgiGetFile(void)
167 {
168 return (form_file);
169 }
170
171
172 /*
173 * 'cgiGetSize()' - Get the size of a form array value.
174 */
175
176 int /* O - Number of elements */
177 cgiGetSize(const char *name) /* I - Name of variable */
178 {
179 _cgi_var_t *var; /* Pointer to variable */
180
181
182 if ((var = cgi_find_variable(name)) == NULL)
183 return (0);
184
185 return (var->nvalues);
186 }
187
188
189 /*
190 * 'cgiGetVariable()' - Get a CGI variable from the database...
191 *
192 * Returns NULL if the variable doesn't exist. If the variable is an
193 * array of values, returns the last element...
194 */
195
196 const char * /* O - Value of variable */
197 cgiGetVariable(const char *name) /* I - Name of variable */
198 {
199 const _cgi_var_t *var; /* Returned variable */
200
201
202 var = cgi_find_variable(name);
203
204 #ifdef DEBUG
205 if (var == NULL)
206 printf("cgiGetVariable(\"%s\") is returning NULL...\n", name);
207 else
208 printf("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name,
209 var->values[var->nvalues - 1]);
210 #endif /* DEBUG */
211
212 return ((var == NULL) ? NULL : var->values[var->nvalues - 1]);
213 }
214
215
216 /*
217 * 'cgiInitialize()' - Initialize the CGI variable "database"...
218 */
219
220 int /* O - Non-zero if there was form data */
221 cgiInitialize(void)
222 {
223 const char *method; /* Form posting method */
224 const char *content_type; /* Content-Type of post data */
225
226
227 /*
228 * Setup a password callback for authentication...
229 */
230
231 cupsSetPasswordCB(cgi_passwd);
232
233 /*
234 * Set the locale so that times, etc. are formatted properly...
235 */
236
237 setlocale(LC_ALL, "");
238
239 #ifdef DEBUG
240 /*
241 * Disable output buffering to find bugs...
242 */
243
244 setbuf(stdout, NULL);
245 puts("Content-type: text/plain\n");
246 #endif /* DEBUG */
247
248 /*
249 * Get the request method (GET or POST)...
250 */
251
252 method = getenv("REQUEST_METHOD");
253 content_type = getenv("CONTENT_TYPE");
254 if (!method)
255 return (0);
256
257 /*
258 * Grab form data from the corresponding location...
259 */
260
261 if (!strcasecmp(method, "GET"))
262 return (cgi_initialize_get());
263 else if (!strcasecmp(method, "POST") && content_type)
264 {
265 const char *boundary = strstr(content_type, "boundary=");
266
267 if (boundary)
268 boundary += 9;
269
270 if (content_type && !strncmp(content_type, "multipart/form-data; ", 21))
271 return (cgi_initialize_multipart(boundary));
272 else
273 return (cgi_initialize_post());
274 }
275 else
276 return (0);
277 }
278
279
280 /*
281 * 'cgiIsPOST()' - Determine whether this page was POSTed.
282 */
283
284 int /* O - 1 if POST, 0 if GET */
285 cgiIsPOST(void)
286 {
287 const char *method; /* REQUEST_METHOD environment variable */
288
289
290 if ((method = getenv("REQUEST_METHOD")) == NULL)
291 return (0);
292 else
293 return (!strcmp(method, "POST"));
294 }
295
296
297 /*
298 * 'cgiSetArray()' - Set array element N to the specified string.
299 *
300 * If the variable array is smaller than (element + 1), the intervening
301 * elements are set to NULL.
302 */
303
304 void
305 cgiSetArray(const char *name, /* I - Name of variable */
306 int element, /* I - Element number (0 to N) */
307 const char *value) /* I - Value of variable */
308 {
309 int i; /* Looping var */
310 _cgi_var_t *var; /* Returned variable */
311
312
313 if (name == NULL || value == NULL || element < 0 || element > 100000)
314 return;
315
316 if ((var = cgi_find_variable(name)) == NULL)
317 {
318 cgi_add_variable(name, element, value);
319 cgi_sort_variables();
320 }
321 else
322 {
323 if (element >= var->avalues)
324 {
325 var->avalues = element + 16;
326 var->values = (const char **)realloc((void *)(var->values),
327 sizeof(char *) * var->avalues);
328 }
329
330 if (element >= var->nvalues)
331 {
332 for (i = var->nvalues; i < element; i ++)
333 var->values[i] = NULL;
334
335 var->nvalues = element + 1;
336 }
337 else if (var->values[element])
338 free((char *)var->values[element]);
339
340 var->values[element] = strdup(value);
341 }
342 }
343
344
345 /*
346 * 'cgiSetSize()' - Set the array size.
347 */
348
349 void
350 cgiSetSize(const char *name, /* I - Name of variable */
351 int size) /* I - Number of elements (0 to N) */
352 {
353 int i; /* Looping var */
354 _cgi_var_t *var; /* Returned variable */
355
356
357 if (name == NULL || size < 0 || size > 100000)
358 return;
359
360 if ((var = cgi_find_variable(name)) == NULL)
361 return;
362
363 if (size >= var->avalues)
364 {
365 var->avalues = size + 16;
366 var->values = (const char **)realloc((void *)(var->values),
367 sizeof(char *) * var->avalues);
368 }
369
370 if (size > var->nvalues)
371 {
372 for (i = var->nvalues; i < size; i ++)
373 var->values[i] = NULL;
374 }
375 else if (size < var->nvalues)
376 {
377 for (i = size; i < var->nvalues; i ++)
378 if (var->values[i])
379 free((void *)(var->values[i]));
380 }
381
382 var->nvalues = size;
383 }
384
385
386 /*
387 * 'cgiSetVariable()' - Set a CGI variable in the database...
388 *
389 * If the variable is an array, this truncates the array to a single element.
390 */
391
392 void
393 cgiSetVariable(const char *name, /* I - Name of variable */
394 const char *value) /* I - Value of variable */
395 {
396 int i; /* Looping var */
397 _cgi_var_t *var; /* Returned variable */
398
399
400 if (name == NULL || value == NULL)
401 return;
402
403 if ((var = cgi_find_variable(name)) == NULL)
404 {
405 cgi_add_variable(name, 0, value);
406 cgi_sort_variables();
407 }
408 else
409 {
410 for (i = 0; i < var->nvalues; i ++)
411 if (var->values[i])
412 free((char *)var->values[i]);
413
414 var->values[0] = strdup(value);
415 var->nvalues = 1;
416 }
417 }
418
419
420 /*
421 * 'cgi_add_variable()' - Add a form variable.
422 */
423
424 static void
425 cgi_add_variable(const char *name, /* I - Variable name */
426 int element, /* I - Array element number */
427 const char *value) /* I - Variable value */
428 {
429 _cgi_var_t *var; /* New variable */
430
431
432 if (name == NULL || value == NULL || element < 0 || element > 100000)
433 return;
434
435 #ifdef DEBUG
436 printf("Adding variable \'%s\' with value \'%s\'...\n", name, value);
437 #endif /* DEBUG */
438
439 if (form_count >= form_alloc)
440 {
441 if (form_alloc == 0)
442 form_vars = malloc(sizeof(_cgi_var_t) * 16);
443 else
444 form_vars = realloc(form_vars, (form_alloc + 16) * sizeof(_cgi_var_t));
445
446 form_alloc += 16;
447 }
448
449 var = form_vars + form_count;
450 var->name = strdup(name);
451 var->nvalues = element + 1;
452 var->avalues = element + 1;
453 var->values = calloc(element + 1, sizeof(char *));
454 var->values[element] = strdup(value);
455
456 form_count ++;
457 }
458
459
460 /*
461 * 'cgi_compare_variables()' - Compare two variables.
462 */
463
464 static int /* O - Result of comparison */
465 cgi_compare_variables(
466 const _cgi_var_t *v1, /* I - First variable */
467 const _cgi_var_t *v2) /* I - Second variable */
468 {
469 return (strcasecmp(v1->name, v2->name));
470 }
471
472
473 /*
474 * 'cgi_find_variable()' - Find a variable...
475 */
476
477 static _cgi_var_t * /* O - Variable pointer or NULL */
478 cgi_find_variable(const char *name) /* I - Name of variable */
479 {
480 _cgi_var_t key; /* Search key */
481
482
483 if (form_count < 1 || name == NULL)
484 return (NULL);
485
486 key.name = name;
487
488 return ((_cgi_var_t *)bsearch(&key, form_vars, form_count, sizeof(_cgi_var_t),
489 (int (*)(const void *, const void *))cgi_compare_variables));
490 }
491
492
493 /*
494 * 'cgi_initialize_get()' - Initialize form variables using the GET method.
495 */
496
497 static int /* O - 1 if form data read */
498 cgi_initialize_get(void)
499 {
500 char *data; /* Pointer to form data string */
501
502
503 #ifdef DEBUG
504 puts("Initializing variables using GET method...");
505 #endif /* DEBUG */
506
507 /*
508 * Check to see if there is anything for us to read...
509 */
510
511 data = getenv("QUERY_STRING");
512 if (data == NULL || strlen(data) == 0)
513 return (0);
514
515 /*
516 * Parse it out and return...
517 */
518
519 return (cgi_initialize_string(data));
520 }
521
522
523 /*
524 * 'cgi_initialize_multipart()' - Initialize variables and file using the POST method.
525 *
526 * TODO: Update to support files > 2GB.
527 */
528
529 static int /* O - 1 if form data was read */
530 cgi_initialize_multipart(
531 const char *boundary) /* I - Boundary string */
532 {
533 char line[10240], /* MIME header line */
534 name[1024], /* Form variable name */
535 filename[1024], /* Form filename */
536 mimetype[1024], /* MIME media type */
537 bstring[256], /* Boundary string to look for */
538 *ptr, /* Pointer into name/filename */
539 *end; /* End of buffer */
540 int ch, /* Character from file */
541 fd, /* Temporary file descriptor */
542 blen; /* Length of boundary string */
543
544
545 DEBUG_printf(("cgi_initialize_multipart(boundary=\"%s\")\n", boundary));
546
547 /*
548 * Read multipart form data until we run out...
549 */
550
551 name[0] = '\0';
552 filename[0] = '\0';
553 mimetype[0] = '\0';
554
555 snprintf(bstring, sizeof(bstring), "\r\n--%s", boundary);
556 blen = strlen(bstring);
557
558 while (fgets(line, sizeof(line), stdin))
559 {
560 if (!strcmp(line, "\r\n"))
561 {
562 /*
563 * End of headers, grab value...
564 */
565
566 if (filename[0])
567 {
568 /*
569 * Read an embedded file...
570 */
571
572 if (form_file)
573 {
574 /*
575 * Remove previous file...
576 */
577
578 cgi_unlink_file();
579 }
580
581 /*
582 * Allocate memory for the new file...
583 */
584
585 if ((form_file = calloc(1, sizeof(cgi_file_t))) == NULL)
586 return (0);
587
588 form_file->name = strdup(name);
589 form_file->filename = strdup(filename);
590 form_file->mimetype = strdup(mimetype);
591
592 fd = cupsTempFd(form_file->tempfile, sizeof(form_file->tempfile));
593
594 if (fd < 0)
595 return (0);
596
597 atexit(cgi_unlink_file);
598
599 /*
600 * Copy file data to the temp file...
601 */
602
603 ptr = line;
604
605 while ((ch = getchar()) != EOF)
606 {
607 *ptr++ = ch;
608
609 if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen))
610 {
611 ptr -= blen;
612 break;
613 }
614
615 if ((ptr - line - blen) >= 8192)
616 {
617 /*
618 * Write out the first 8k of the buffer...
619 */
620
621 write(fd, line, 8192);
622 memmove(line, line + 8192, ptr - line - 8192);
623 ptr -= 8192;
624 }
625 }
626
627 /*
628 * Write the rest of the data and close the temp file...
629 */
630
631 if (ptr > line)
632 write(fd, line, ptr - line);
633
634 close(fd);
635 }
636 else
637 {
638 /*
639 * Just get a form variable; the current code only handles
640 * form values up to 10k in size...
641 */
642
643 ptr = line;
644 end = line + sizeof(line) - 1;
645
646 while ((ch = getchar()) != EOF)
647 {
648 if (ptr < end)
649 *ptr++ = ch;
650
651 if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen))
652 {
653 ptr -= blen;
654 break;
655 }
656 }
657
658 *ptr = '\0';
659
660 /*
661 * Set the form variable...
662 */
663
664 if ((ptr = strrchr(name, '-')) != NULL && isdigit(ptr[1] & 255))
665 {
666 /*
667 * Set a specific index in the array...
668 */
669
670 *ptr++ = '\0';
671 if (line[0])
672 cgiSetArray(name, atoi(ptr) - 1, line);
673 }
674 else if (cgiGetVariable(name))
675 {
676 /*
677 * Add another element in the array...
678 */
679
680 cgiSetArray(name, cgiGetSize(name), line);
681 }
682 else
683 {
684 /*
685 * Just set the line...
686 */
687
688 cgiSetVariable(name, line);
689 }
690 }
691
692 /*
693 * Read the rest of the current line...
694 */
695
696 fgets(line, sizeof(line), stdin);
697
698 /*
699 * Clear the state vars...
700 */
701
702 name[0] = '\0';
703 filename[0] = '\0';
704 mimetype[0] = '\0';
705 }
706 else if (!strncasecmp(line, "Content-Disposition:", 20))
707 {
708 if ((ptr = strstr(line + 20, " name=\"")) != NULL)
709 {
710 strlcpy(name, ptr + 7, sizeof(name));
711
712 if ((ptr = strchr(name, '\"')) != NULL)
713 *ptr = '\0';
714 }
715
716 if ((ptr = strstr(line + 20, " filename=\"")) != NULL)
717 {
718 strlcpy(filename, ptr + 11, sizeof(filename));
719
720 if ((ptr = strchr(filename, '\"')) != NULL)
721 *ptr = '\0';
722 }
723 }
724 else if (!strncasecmp(line, "Content-Type:", 13))
725 {
726 for (ptr = line + 13; isspace(*ptr & 255); ptr ++);
727
728 strlcpy(mimetype, ptr, sizeof(mimetype));
729
730 for (ptr = mimetype + strlen(mimetype) - 1;
731 ptr > mimetype && isspace(*ptr & 255);
732 *ptr-- = '\0');
733 }
734 }
735
736 /*
737 * Return 1 for "form data found"...
738 */
739
740 return (1);
741 }
742
743
744 /*
745 * 'cgi_initialize_post()' - Initialize variables using the POST method.
746 */
747
748 static int /* O - 1 if form data was read */
749 cgi_initialize_post(void)
750 {
751 char *content_length, /* Length of input data (string) */
752 *data; /* Pointer to form data string */
753 int length, /* Length of input data */
754 nbytes, /* Number of bytes read this read() */
755 tbytes, /* Total number of bytes read */
756 status; /* Return status */
757
758
759 #ifdef DEBUG
760 puts("Initializing variables using POST method...");
761 #endif /* DEBUG */
762
763 /*
764 * Check to see if there is anything for us to read...
765 */
766
767 content_length = getenv("CONTENT_LENGTH");
768 if (content_length == NULL || atoi(content_length) <= 0)
769 return (0);
770
771 /*
772 * Get the length of the input stream and allocate a buffer for it...
773 */
774
775 length = atoi(content_length);
776 data = malloc(length + 1);
777
778 if (data == NULL)
779 return (0);
780
781 /*
782 * Read the data into the buffer...
783 */
784
785 for (tbytes = 0; tbytes < length; tbytes += nbytes)
786 if ((nbytes = read(0, data + tbytes, length - tbytes)) < 0)
787 if (errno != EAGAIN)
788 {
789 free(data);
790 return (0);
791 }
792
793 data[length] = '\0';
794
795 /*
796 * Parse it out...
797 */
798
799 status = cgi_initialize_string(data);
800
801 /*
802 * Free the data and return...
803 */
804
805 free(data);
806
807 return (status);
808 }
809
810
811 /*
812 * 'cgi_initialize_string()' - Initialize form variables from a string.
813 */
814
815 static int /* O - 1 if form data was processed */
816 cgi_initialize_string(const char *data) /* I - Form data string */
817 {
818 int done; /* True if we're done reading a form variable */
819 char *s, /* Pointer to current form string */
820 ch, /* Temporary character */
821 name[255], /* Name of form variable */
822 value[65536]; /* Variable value... */
823
824
825 /*
826 * Check input...
827 */
828
829 if (data == NULL)
830 return (0);
831
832 /*
833 * Loop until we've read all the form data...
834 */
835
836 while (*data != '\0')
837 {
838 /*
839 * Get the variable name...
840 */
841
842 for (s = name; *data != '\0'; data ++)
843 if (*data == '=')
844 break;
845 else if (*data >= ' ' && s < (name + sizeof(name) - 1))
846 *s++ = *data;
847
848 *s = '\0';
849 if (*data == '=')
850 data ++;
851 else
852 return (0);
853
854 /*
855 * Read the variable value...
856 */
857
858 for (s = value, done = 0; !done && *data != '\0'; data ++)
859 switch (*data)
860 {
861 case '&' : /* End of data... */
862 done = 1;
863 break;
864
865 case '+' : /* Escaped space character */
866 if (s < (value + sizeof(value) - 1))
867 *s++ = ' ';
868 break;
869
870 case '%' : /* Escaped control character */
871 /*
872 * Read the hex code...
873 */
874
875 if (s < (value + sizeof(value) - 1))
876 {
877 data ++;
878 ch = *data - '0';
879 if (ch > 9)
880 ch -= 7;
881 *s = ch << 4;
882
883 data ++;
884 ch = *data - '0';
885 if (ch > 9)
886 ch -= 7;
887 *s++ |= ch;
888 }
889 else
890 data += 2;
891 break;
892
893 default : /* Other characters come straight through */
894 if (*data >= ' ' && s < (value + sizeof(value) - 1))
895 *s++ = *data;
896 break;
897 }
898
899 *s = '\0'; /* nul terminate the string */
900
901 /*
902 * Remove trailing whitespace...
903 */
904
905 if (s > value)
906 s --;
907
908 while (s >= value && *s == ' ')
909 *s-- = '\0';
910
911 /*
912 * Add the string to the variable "database"...
913 */
914
915 if ((s = strrchr(name, '-')) != NULL && isdigit(s[1] & 255))
916 {
917 *s++ = '\0';
918 if (value[0])
919 cgiSetArray(name, atoi(s) - 1, value);
920 }
921 else if (cgiGetVariable(name) != NULL)
922 cgiSetArray(name, cgiGetSize(name), value);
923 else
924 cgiSetVariable(name, value);
925 }
926
927 return (1);
928 }
929
930
931 /*
932 * 'cgi_passwd()' - Catch authentication requests and notify the server.
933 *
934 * This function sends a Status header and exits, forcing authentication
935 * for this request.
936 */
937
938 static const char * /* O - NULL (no return) */
939 cgi_passwd(const char *prompt) /* I - Prompt (not used) */
940 {
941 (void)prompt;
942
943 fprintf(stderr, "DEBUG: cgi_passwd(prompt=\"%s\") called!\n",
944 prompt ? prompt : "(null)");
945
946 /*
947 * Send a 401 (unauthorized) status to the server, so it can notify
948 * the client that authentication is required.
949 */
950
951 puts("Status: 401\n");
952 exit(0);
953
954 /*
955 * This code is never executed, but is present to satisfy the compiler.
956 */
957
958 return (NULL);
959 }
960
961
962 /*
963 * 'cgi_sort_variables()' - Sort all form variables for faster lookup.
964 */
965
966 static void
967 cgi_sort_variables(void)
968 {
969 #ifdef DEBUG
970 int i;
971
972
973 puts("Sorting variables...");
974 #endif /* DEBUG */
975
976 if (form_count < 2)
977 return;
978
979 qsort(form_vars, form_count, sizeof(_cgi_var_t),
980 (int (*)(const void *, const void *))cgi_compare_variables);
981
982 #ifdef DEBUG
983 puts("Sorted variable list is:");
984 for (i = 0; i < form_count; i ++)
985 printf("%d: %s (%d) = \"%s\" ...\n", i, form_vars[i].name,
986 form_vars[i].nvalues, form_vars[i].values[0]);
987 #endif /* DEBUG */
988 }
989
990
991 /*
992 * 'cgi_unlink_file()' - Remove the uploaded form.
993 */
994
995 static void
996 cgi_unlink_file(void)
997 {
998 if (form_file)
999 {
1000 /*
1001 * Remove the temporary file...
1002 */
1003
1004 unlink(form_file->tempfile);
1005
1006 /*
1007 * Free memory used...
1008 */
1009
1010 free(form_file->name);
1011 free(form_file->filename);
1012 free(form_file->mimetype);
1013 free(form_file);
1014
1015 form_file = NULL;
1016 }
1017 }
1018
1019
1020 /*
1021 * End of "$Id: var.c 6649 2007-07-11 21:46:42Z mike $".
1022 */