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