]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/var.c
Import CUPS 1.4svn-r7226.
[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-2008 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 const char **temp; /* Temporary pointer */
326
327 temp = (const char **)realloc((void *)(var->values),
328 sizeof(char *) * (element + 16));
329 if (!temp)
330 return;
331
332 var->avalues = element + 16;
333 var->values = temp;
334 }
335
336 if (element >= var->nvalues)
337 {
338 for (i = var->nvalues; i < element; i ++)
339 var->values[i] = NULL;
340
341 var->nvalues = element + 1;
342 }
343 else if (var->values[element])
344 free((char *)var->values[element]);
345
346 var->values[element] = strdup(value);
347 }
348 }
349
350
351 /*
352 * 'cgiSetSize()' - Set the array size.
353 */
354
355 void
356 cgiSetSize(const char *name, /* I - Name of variable */
357 int size) /* I - Number of elements (0 to N) */
358 {
359 int i; /* Looping var */
360 _cgi_var_t *var; /* Returned variable */
361
362
363 if (name == NULL || size < 0 || size > 100000)
364 return;
365
366 if ((var = cgi_find_variable(name)) == NULL)
367 return;
368
369 if (size >= var->avalues)
370 {
371 const char **temp; /* Temporary pointer */
372
373 temp = (const char **)realloc((void *)(var->values),
374 sizeof(char *) * (size + 16));
375 if (!temp)
376 return;
377
378 var->avalues = size + 16;
379 var->values = temp;
380 }
381
382 if (size > var->nvalues)
383 {
384 for (i = var->nvalues; i < size; i ++)
385 var->values[i] = NULL;
386 }
387 else if (size < var->nvalues)
388 {
389 for (i = size; i < var->nvalues; i ++)
390 if (var->values[i])
391 free((void *)(var->values[i]));
392 }
393
394 var->nvalues = size;
395 }
396
397
398 /*
399 * 'cgiSetVariable()' - Set a CGI variable in the database...
400 *
401 * If the variable is an array, this truncates the array to a single element.
402 */
403
404 void
405 cgiSetVariable(const char *name, /* I - Name of variable */
406 const char *value) /* I - Value of variable */
407 {
408 int i; /* Looping var */
409 _cgi_var_t *var; /* Returned variable */
410
411
412 if (name == NULL || value == NULL)
413 return;
414
415 if ((var = cgi_find_variable(name)) == NULL)
416 {
417 cgi_add_variable(name, 0, value);
418 cgi_sort_variables();
419 }
420 else
421 {
422 for (i = 0; i < var->nvalues; i ++)
423 if (var->values[i])
424 free((char *)var->values[i]);
425
426 var->values[0] = strdup(value);
427 var->nvalues = 1;
428 }
429 }
430
431
432 /*
433 * 'cgi_add_variable()' - Add a form variable.
434 */
435
436 static void
437 cgi_add_variable(const char *name, /* I - Variable name */
438 int element, /* I - Array element number */
439 const char *value) /* I - Variable value */
440 {
441 _cgi_var_t *var; /* New variable */
442
443
444 if (name == NULL || value == NULL || element < 0 || element > 100000)
445 return;
446
447 #ifdef DEBUG
448 printf("Adding variable \'%s\' with value \'%s\'...\n", name, value);
449 #endif /* DEBUG */
450
451 if (form_count >= form_alloc)
452 {
453 _cgi_var_t *temp_vars; /* Temporary form pointer */
454
455
456 if (form_alloc == 0)
457 temp_vars = malloc(sizeof(_cgi_var_t) * 16);
458 else
459 temp_vars = realloc(form_vars, (form_alloc + 16) * sizeof(_cgi_var_t));
460
461 if (!temp_vars)
462 return;
463
464 form_vars = temp_vars;
465 form_alloc += 16;
466 }
467
468 var = form_vars + form_count;
469
470 if ((var->values = calloc(element + 1, sizeof(char *))) == NULL)
471 return;
472
473 var->name = strdup(name);
474 var->nvalues = element + 1;
475 var->avalues = element + 1;
476 var->values[element] = strdup(value);
477
478 form_count ++;
479 }
480
481
482 /*
483 * 'cgi_compare_variables()' - Compare two variables.
484 */
485
486 static int /* O - Result of comparison */
487 cgi_compare_variables(
488 const _cgi_var_t *v1, /* I - First variable */
489 const _cgi_var_t *v2) /* I - Second variable */
490 {
491 return (strcasecmp(v1->name, v2->name));
492 }
493
494
495 /*
496 * 'cgi_find_variable()' - Find a variable...
497 */
498
499 static _cgi_var_t * /* O - Variable pointer or NULL */
500 cgi_find_variable(const char *name) /* I - Name of variable */
501 {
502 _cgi_var_t key; /* Search key */
503
504
505 if (form_count < 1 || name == NULL)
506 return (NULL);
507
508 key.name = name;
509
510 return ((_cgi_var_t *)bsearch(&key, form_vars, form_count, sizeof(_cgi_var_t),
511 (int (*)(const void *, const void *))cgi_compare_variables));
512 }
513
514
515 /*
516 * 'cgi_initialize_get()' - Initialize form variables using the GET method.
517 */
518
519 static int /* O - 1 if form data read */
520 cgi_initialize_get(void)
521 {
522 char *data; /* Pointer to form data string */
523
524
525 #ifdef DEBUG
526 puts("Initializing variables using GET method...");
527 #endif /* DEBUG */
528
529 /*
530 * Check to see if there is anything for us to read...
531 */
532
533 data = getenv("QUERY_STRING");
534 if (data == NULL || strlen(data) == 0)
535 return (0);
536
537 /*
538 * Parse it out and return...
539 */
540
541 return (cgi_initialize_string(data));
542 }
543
544
545 /*
546 * 'cgi_initialize_multipart()' - Initialize variables and file using the POST method.
547 *
548 * TODO: Update to support files > 2GB.
549 */
550
551 static int /* O - 1 if form data was read */
552 cgi_initialize_multipart(
553 const char *boundary) /* I - Boundary string */
554 {
555 char line[10240], /* MIME header line */
556 name[1024], /* Form variable name */
557 filename[1024], /* Form filename */
558 mimetype[1024], /* MIME media type */
559 bstring[256], /* Boundary string to look for */
560 *ptr, /* Pointer into name/filename */
561 *end; /* End of buffer */
562 int ch, /* Character from file */
563 fd, /* Temporary file descriptor */
564 blen; /* Length of boundary string */
565
566
567 DEBUG_printf(("cgi_initialize_multipart(boundary=\"%s\")\n", boundary));
568
569 /*
570 * Read multipart form data until we run out...
571 */
572
573 name[0] = '\0';
574 filename[0] = '\0';
575 mimetype[0] = '\0';
576
577 snprintf(bstring, sizeof(bstring), "\r\n--%s", boundary);
578 blen = strlen(bstring);
579
580 while (fgets(line, sizeof(line), stdin))
581 {
582 if (!strcmp(line, "\r\n"))
583 {
584 /*
585 * End of headers, grab value...
586 */
587
588 if (filename[0])
589 {
590 /*
591 * Read an embedded file...
592 */
593
594 if (form_file)
595 {
596 /*
597 * Remove previous file...
598 */
599
600 cgi_unlink_file();
601 }
602
603 /*
604 * Allocate memory for the new file...
605 */
606
607 if ((form_file = calloc(1, sizeof(cgi_file_t))) == NULL)
608 return (0);
609
610 form_file->name = strdup(name);
611 form_file->filename = strdup(filename);
612 form_file->mimetype = strdup(mimetype);
613
614 fd = cupsTempFd(form_file->tempfile, sizeof(form_file->tempfile));
615
616 if (fd < 0)
617 return (0);
618
619 atexit(cgi_unlink_file);
620
621 /*
622 * Copy file data to the temp file...
623 */
624
625 ptr = line;
626
627 while ((ch = getchar()) != EOF)
628 {
629 *ptr++ = ch;
630
631 if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen))
632 {
633 ptr -= blen;
634 break;
635 }
636
637 if ((ptr - line - blen) >= 8192)
638 {
639 /*
640 * Write out the first 8k of the buffer...
641 */
642
643 write(fd, line, 8192);
644 memmove(line, line + 8192, ptr - line - 8192);
645 ptr -= 8192;
646 }
647 }
648
649 /*
650 * Write the rest of the data and close the temp file...
651 */
652
653 if (ptr > line)
654 write(fd, line, ptr - line);
655
656 close(fd);
657 }
658 else
659 {
660 /*
661 * Just get a form variable; the current code only handles
662 * form values up to 10k in size...
663 */
664
665 ptr = line;
666 end = line + sizeof(line) - 1;
667
668 while ((ch = getchar()) != EOF)
669 {
670 if (ptr < end)
671 *ptr++ = ch;
672
673 if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen))
674 {
675 ptr -= blen;
676 break;
677 }
678 }
679
680 *ptr = '\0';
681
682 /*
683 * Set the form variable...
684 */
685
686 if ((ptr = strrchr(name, '-')) != NULL && isdigit(ptr[1] & 255))
687 {
688 /*
689 * Set a specific index in the array...
690 */
691
692 *ptr++ = '\0';
693 if (line[0])
694 cgiSetArray(name, atoi(ptr) - 1, line);
695 }
696 else if (cgiGetVariable(name))
697 {
698 /*
699 * Add another element in the array...
700 */
701
702 cgiSetArray(name, cgiGetSize(name), line);
703 }
704 else
705 {
706 /*
707 * Just set the line...
708 */
709
710 cgiSetVariable(name, line);
711 }
712 }
713
714 /*
715 * Read the rest of the current line...
716 */
717
718 fgets(line, sizeof(line), stdin);
719
720 /*
721 * Clear the state vars...
722 */
723
724 name[0] = '\0';
725 filename[0] = '\0';
726 mimetype[0] = '\0';
727 }
728 else if (!strncasecmp(line, "Content-Disposition:", 20))
729 {
730 if ((ptr = strstr(line + 20, " name=\"")) != NULL)
731 {
732 strlcpy(name, ptr + 7, sizeof(name));
733
734 if ((ptr = strchr(name, '\"')) != NULL)
735 *ptr = '\0';
736 }
737
738 if ((ptr = strstr(line + 20, " filename=\"")) != NULL)
739 {
740 strlcpy(filename, ptr + 11, sizeof(filename));
741
742 if ((ptr = strchr(filename, '\"')) != NULL)
743 *ptr = '\0';
744 }
745 }
746 else if (!strncasecmp(line, "Content-Type:", 13))
747 {
748 for (ptr = line + 13; isspace(*ptr & 255); ptr ++);
749
750 strlcpy(mimetype, ptr, sizeof(mimetype));
751
752 for (ptr = mimetype + strlen(mimetype) - 1;
753 ptr > mimetype && isspace(*ptr & 255);
754 *ptr-- = '\0');
755 }
756 }
757
758 /*
759 * Return 1 for "form data found"...
760 */
761
762 return (1);
763 }
764
765
766 /*
767 * 'cgi_initialize_post()' - Initialize variables using the POST method.
768 */
769
770 static int /* O - 1 if form data was read */
771 cgi_initialize_post(void)
772 {
773 char *content_length, /* Length of input data (string) */
774 *data; /* Pointer to form data string */
775 int length, /* Length of input data */
776 nbytes, /* Number of bytes read this read() */
777 tbytes, /* Total number of bytes read */
778 status; /* Return status */
779
780
781 #ifdef DEBUG
782 puts("Initializing variables using POST method...");
783 #endif /* DEBUG */
784
785 /*
786 * Check to see if there is anything for us to read...
787 */
788
789 content_length = getenv("CONTENT_LENGTH");
790 if (content_length == NULL || atoi(content_length) <= 0)
791 return (0);
792
793 /*
794 * Get the length of the input stream and allocate a buffer for it...
795 */
796
797 length = atoi(content_length);
798 data = malloc(length + 1);
799
800 if (data == NULL)
801 return (0);
802
803 /*
804 * Read the data into the buffer...
805 */
806
807 for (tbytes = 0; tbytes < length; tbytes += nbytes)
808 if ((nbytes = read(0, data + tbytes, length - tbytes)) < 0)
809 {
810 if (errno != EAGAIN)
811 {
812 free(data);
813 return (0);
814 }
815 else
816 nbytes = 0;
817 }
818
819 data[length] = '\0';
820
821 /*
822 * Parse it out...
823 */
824
825 status = cgi_initialize_string(data);
826
827 /*
828 * Free the data and return...
829 */
830
831 free(data);
832
833 return (status);
834 }
835
836
837 /*
838 * 'cgi_initialize_string()' - Initialize form variables from a string.
839 */
840
841 static int /* O - 1 if form data was processed */
842 cgi_initialize_string(const char *data) /* I - Form data string */
843 {
844 int done; /* True if we're done reading a form variable */
845 char *s, /* Pointer to current form string */
846 ch, /* Temporary character */
847 name[255], /* Name of form variable */
848 value[65536]; /* Variable value... */
849
850
851 /*
852 * Check input...
853 */
854
855 if (data == NULL)
856 return (0);
857
858 /*
859 * Loop until we've read all the form data...
860 */
861
862 while (*data != '\0')
863 {
864 /*
865 * Get the variable name...
866 */
867
868 for (s = name; *data != '\0'; data ++)
869 if (*data == '=')
870 break;
871 else if (*data >= ' ' && s < (name + sizeof(name) - 1))
872 *s++ = *data;
873
874 *s = '\0';
875 if (*data == '=')
876 data ++;
877 else
878 return (0);
879
880 /*
881 * Read the variable value...
882 */
883
884 for (s = value, done = 0; !done && *data != '\0'; data ++)
885 switch (*data)
886 {
887 case '&' : /* End of data... */
888 done = 1;
889 break;
890
891 case '+' : /* Escaped space character */
892 if (s < (value + sizeof(value) - 1))
893 *s++ = ' ';
894 break;
895
896 case '%' : /* Escaped control character */
897 /*
898 * Read the hex code...
899 */
900
901 if (s < (value + sizeof(value) - 1))
902 {
903 data ++;
904 ch = *data - '0';
905 if (ch > 9)
906 ch -= 7;
907 *s = ch << 4;
908
909 data ++;
910 ch = *data - '0';
911 if (ch > 9)
912 ch -= 7;
913 *s++ |= ch;
914 }
915 else
916 data += 2;
917 break;
918
919 default : /* Other characters come straight through */
920 if (*data >= ' ' && s < (value + sizeof(value) - 1))
921 *s++ = *data;
922 break;
923 }
924
925 *s = '\0'; /* nul terminate the string */
926
927 /*
928 * Remove trailing whitespace...
929 */
930
931 if (s > value)
932 s --;
933
934 while (s >= value && *s == ' ')
935 *s-- = '\0';
936
937 /*
938 * Add the string to the variable "database"...
939 */
940
941 if ((s = strrchr(name, '-')) != NULL && isdigit(s[1] & 255))
942 {
943 *s++ = '\0';
944 if (value[0])
945 cgiSetArray(name, atoi(s) - 1, value);
946 }
947 else if (cgiGetVariable(name) != NULL)
948 cgiSetArray(name, cgiGetSize(name), value);
949 else
950 cgiSetVariable(name, value);
951 }
952
953 return (1);
954 }
955
956
957 /*
958 * 'cgi_passwd()' - Catch authentication requests and notify the server.
959 *
960 * This function sends a Status header and exits, forcing authentication
961 * for this request.
962 */
963
964 static const char * /* O - NULL (no return) */
965 cgi_passwd(const char *prompt) /* I - Prompt (not used) */
966 {
967 (void)prompt;
968
969 fprintf(stderr, "DEBUG: cgi_passwd(prompt=\"%s\") called!\n",
970 prompt ? prompt : "(null)");
971
972 /*
973 * Send a 401 (unauthorized) status to the server, so it can notify
974 * the client that authentication is required.
975 */
976
977 puts("Status: 401\n");
978 exit(0);
979
980 /*
981 * This code is never executed, but is present to satisfy the compiler.
982 */
983
984 return (NULL);
985 }
986
987
988 /*
989 * 'cgi_sort_variables()' - Sort all form variables for faster lookup.
990 */
991
992 static void
993 cgi_sort_variables(void)
994 {
995 #ifdef DEBUG
996 int i;
997
998
999 puts("Sorting variables...");
1000 #endif /* DEBUG */
1001
1002 if (form_count < 2)
1003 return;
1004
1005 qsort(form_vars, form_count, sizeof(_cgi_var_t),
1006 (int (*)(const void *, const void *))cgi_compare_variables);
1007
1008 #ifdef DEBUG
1009 puts("Sorted variable list is:");
1010 for (i = 0; i < form_count; i ++)
1011 printf("%d: %s (%d) = \"%s\" ...\n", i, form_vars[i].name,
1012 form_vars[i].nvalues, form_vars[i].values[0]);
1013 #endif /* DEBUG */
1014 }
1015
1016
1017 /*
1018 * 'cgi_unlink_file()' - Remove the uploaded form.
1019 */
1020
1021 static void
1022 cgi_unlink_file(void)
1023 {
1024 if (form_file)
1025 {
1026 /*
1027 * Remove the temporary file...
1028 */
1029
1030 unlink(form_file->tempfile);
1031
1032 /*
1033 * Free memory used...
1034 */
1035
1036 free(form_file->name);
1037 free(form_file->filename);
1038 free(form_file->mimetype);
1039 free(form_file);
1040
1041 form_file = NULL;
1042 }
1043 }
1044
1045
1046 /*
1047 * End of "$Id: var.c 6649 2007-07-11 21:46:42Z mike $".
1048 */