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