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