summaryrefslogtreecommitdiff
path: root/cgi-bin/var.c
diff options
context:
space:
mode:
authorjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>2006-01-13 01:51:53 +0000
committerjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>2006-01-13 01:51:53 +0000
commitef416fc25c4af449e930416117bedb12fc9924ba (patch)
tree11f8aa8c5d3565a17d4a6d5121d3edba22e2a21e /cgi-bin/var.c
parent9ec11526e139aeacf6a052799a6aa22cbbe6ebb2 (diff)
downloadcups-ef416fc25c4af449e930416117bedb12fc9924ba.tar.gz
Load cups into easysw/current.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@2 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'cgi-bin/var.c')
-rw-r--r--cgi-bin/var.c1024
1 files changed, 1024 insertions, 0 deletions
diff --git a/cgi-bin/var.c b/cgi-bin/var.c
new file mode 100644
index 000000000..4a1a214a7
--- /dev/null
+++ b/cgi-bin/var.c
@@ -0,0 +1,1024 @@
+/*
+ * "$Id: var.c 4869 2005-12-06 02:43:40Z mike $"
+ *
+ * CGI form variable and array functions.
+ *
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * cgiCheckVariables() - Check for the presence of "required" variables.
+ * cgiGetArray() - Get an element from a form array...
+ * cgiGetFile() - Get the file (if any) that was submitted in the form.
+ * cgiGetSize() - Get the size of a form array value.
+ * cgiGetVariable() - Get a CGI variable from the database...
+ * cgiInitialize() - Initialize the CGI variable "database"...
+ * cgiIsPOST() - Determine whether this page was POSTed.
+ * cgiSetArray() - Set array element N to the specified string.
+ * cgiSetSize() - Set the array size.
+ * cgiSetVariable() - Set a CGI variable in the database...
+ * cgi_add_variable() - Add a form variable.
+ * cgi_compare_variables() - Compare two variables.
+ * cgi_find_variable() - Find a variable...
+ * cgi_initialize_get() - Initialize form variables using the GET method.
+ * cgi_initialize_multipart() - Initialize variables and file using the POST method.
+ * cgi_initialize_post() - Initialize variables using the POST method.
+ * cgi_initialize_string() - Initialize form variables from a string.
+ * cgi_passwd() - Catch authentication requests and notify the server.
+ * cgi_sort_variables() - Sort all form variables for faster lookup.
+ * cgi_unlink_file() - Remove the uploaded form.
+ */
+
+/*#define DEBUG*/
+#include "cgi-private.h"
+#include <errno.h>
+
+
+/*
+ * Data structure to hold all the CGI form variables and arrays...
+ */
+
+typedef struct /**** Form variable structure ****/
+{
+ const char *name; /* Name of variable */
+ int nvalues, /* Number of values */
+ avalues; /* Number of values allocated */
+ const char **values; /* Value(s) of variable */
+} _cgi_var_t;
+
+
+/*
+ * Local globals...
+ */
+
+static int form_count = 0, /* Form variable count */
+ form_alloc = 0; /* Number of variables allocated */
+static _cgi_var_t *form_vars = NULL;
+ /* Form variables */
+static cgi_file_t *form_file = NULL;
+ /* Uploaded file */
+
+
+/*
+ * Local functions...
+ */
+
+static void cgi_add_variable(const char *name, int element,
+ const char *value);
+static int cgi_compare_variables(const _cgi_var_t *v1,
+ const _cgi_var_t *v2);
+static _cgi_var_t *cgi_find_variable(const char *name);
+static int cgi_initialize_get(void);
+static int cgi_initialize_multipart(const char *boundary);
+static int cgi_initialize_post(void);
+static int cgi_initialize_string(const char *data);
+static const char *cgi_passwd(const char *prompt);
+static void cgi_sort_variables(void);
+static void cgi_unlink_file(void);
+
+
+/*
+ * 'cgiCheckVariables()' - Check for the presence of "required" variables.
+ *
+ * Names may be separated by spaces and/or commas.
+ */
+
+int /* O - 1 if all variables present, 0 otherwise */
+cgiCheckVariables(const char *names) /* I - Variables to look for */
+{
+ char name[255], /* Current variable name */
+ *s; /* Pointer in string */
+ const char *val; /* Value of variable */
+ int element; /* Array element number */
+
+
+ if (names == NULL)
+ return (1);
+
+ while (*names != '\0')
+ {
+ while (*names == ' ' || *names == ',')
+ names ++;
+
+ for (s = name; *names != '\0' && *names != ' ' && *names != ','; s ++, names ++)
+ *s = *names;
+
+ *s = 0;
+ if (name[0] == '\0')
+ break;
+
+ if ((s = strrchr(name, '-')) != NULL)
+ {
+ *s = '\0';
+ element = atoi(s + 1) - 1;
+ val = cgiGetArray(name, element);
+ }
+ else
+ val = cgiGetVariable(name);
+
+ if (val == NULL)
+ return (0);
+
+ if (*val == '\0')
+ return (0); /* Can't be blank, either! */
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'cgiGetArray()' - Get an element from a form array...
+ */
+
+const char * /* O - Element value or NULL */
+cgiGetArray(const char *name, /* I - Name of array variable */
+ int element) /* I - Element number (0 to N) */
+{
+ _cgi_var_t *var; /* Pointer to variable */
+
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ return (NULL);
+
+ if (var->nvalues == 1)
+ return (var->values[0]);
+
+ if (element < 0 || element >= var->nvalues)
+ return (NULL);
+
+ return (var->values[element]);
+}
+
+
+/*
+ * 'cgiGetFile()' - Get the file (if any) that was submitted in the form.
+ */
+
+const cgi_file_t * /* O - Attached file or NULL */
+cgiGetFile(void)
+{
+ return (form_file);
+}
+
+
+/*
+ * 'cgiGetSize()' - Get the size of a form array value.
+ */
+
+int /* O - Number of elements */
+cgiGetSize(const char *name) /* I - Name of variable */
+{
+ _cgi_var_t *var; /* Pointer to variable */
+
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ return (0);
+
+ return (var->nvalues);
+}
+
+
+/*
+ * 'cgiGetVariable()' - Get a CGI variable from the database...
+ *
+ * Returns NULL if the variable doesn't exist. If the variable is an
+ * array of values, returns the last element...
+ */
+
+const char * /* O - Value of variable */
+cgiGetVariable(const char *name) /* I - Name of variable */
+{
+ const _cgi_var_t *var; /* Returned variable */
+
+
+ var = cgi_find_variable(name);
+
+#ifdef DEBUG
+ if (var == NULL)
+ printf("cgiGetVariable(\"%s\") is returning NULL...\n", name);
+ else
+ printf("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name,
+ var->values[var->nvalues - 1]);
+#endif /* DEBUG */
+
+ return ((var == NULL) ? NULL : var->values[var->nvalues - 1]);
+}
+
+
+/*
+ * 'cgiInitialize()' - Initialize the CGI variable "database"...
+ */
+
+int /* O - Non-zero if there was form data */
+cgiInitialize(void)
+{
+ const char *method; /* Form posting method */
+ const char *content_type; /* Content-Type of post data */
+
+
+ /*
+ * Setup a password callback for authentication...
+ */
+
+ cupsSetPasswordCB(cgi_passwd);
+
+#ifdef DEBUG
+ /*
+ * Disable output buffering to find bugs...
+ */
+
+ setbuf(stdout, NULL);
+ puts("Content-type: text/plain\n");
+#endif /* DEBUG */
+
+ /*
+ * Get the request method (GET or POST)...
+ */
+
+ method = getenv("REQUEST_METHOD");
+ content_type = getenv("CONTENT_TYPE");
+ if (!method)
+ return (0);
+
+ /*
+ * Grab form data from the corresponding location...
+ */
+
+ if (!strcasecmp(method, "GET"))
+ return (cgi_initialize_get());
+ else if (!strcasecmp(method, "POST") && content_type)
+ {
+ const char *boundary = strstr(content_type, "boundary=");
+
+ if (boundary)
+ boundary += 9;
+
+ if (content_type && !strncmp(content_type, "multipart/form-data; ", 21))
+ return (cgi_initialize_multipart(boundary));
+ else
+ return (cgi_initialize_post());
+ }
+ else
+ return (0);
+}
+
+
+/*
+ * 'cgiIsPOST()' - Determine whether this page was POSTed.
+ */
+
+int /* O - 1 if POST, 0 if GET */
+cgiIsPOST(void)
+{
+ const char *method; /* REQUEST_METHOD environment variable */
+
+
+ if ((method = getenv("REQUEST_METHOD")) == NULL)
+ return (0);
+ else
+ return (!strcmp(method, "POST"));
+}
+
+
+/*
+ * 'cgiSetArray()' - Set array element N to the specified string.
+ *
+ * If the variable array is smaller than (element + 1), the intervening
+ * elements are set to NULL.
+ */
+
+void
+cgiSetArray(const char *name, /* I - Name of variable */
+ int element, /* I - Element number (0 to N) */
+ const char *value) /* I - Value of variable */
+{
+ int i; /* Looping var */
+ _cgi_var_t *var; /* Returned variable */
+
+
+ if (name == NULL || value == NULL || element < 0 || element > 100000)
+ return;
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ {
+ cgi_add_variable(name, element, value);
+ cgi_sort_variables();
+ }
+ else
+ {
+ if (element >= var->avalues)
+ {
+ var->avalues = element + 16;
+ var->values = (const char **)realloc((void *)(var->values),
+ sizeof(char *) * var->avalues);
+ }
+
+ if (element >= var->nvalues)
+ {
+ for (i = var->nvalues; i < element; i ++)
+ var->values[i] = NULL;
+
+ var->nvalues = element + 1;
+ }
+ else if (var->values[element])
+ free((char *)var->values[element]);
+
+ var->values[element] = strdup(value);
+ }
+}
+
+
+/*
+ * 'cgiSetSize()' - Set the array size.
+ */
+
+void
+cgiSetSize(const char *name, /* I - Name of variable */
+ int size) /* I - Number of elements (0 to N) */
+{
+ int i; /* Looping var */
+ _cgi_var_t *var; /* Returned variable */
+
+
+ if (name == NULL || size < 0 || size > 100000)
+ return;
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ return;
+
+ if (size >= var->avalues)
+ {
+ var->avalues = size + 16;
+ var->values = (const char **)realloc((void *)(var->values),
+ sizeof(char *) * var->avalues);
+ }
+
+ if (size > var->nvalues)
+ {
+ for (i = var->nvalues; i < size; i ++)
+ var->values[i] = NULL;
+ }
+ else if (size < var->nvalues)
+ {
+ for (i = size; i < var->nvalues; i ++)
+ if (var->values[i])
+ free((void *)(var->values[i]));
+ }
+
+ var->nvalues = size;
+}
+
+
+/*
+ * 'cgiSetVariable()' - Set a CGI variable in the database...
+ *
+ * If the variable is an array, this truncates the array to a single element.
+ */
+
+void
+cgiSetVariable(const char *name, /* I - Name of variable */
+ const char *value) /* I - Value of variable */
+{
+ int i; /* Looping var */
+ _cgi_var_t *var; /* Returned variable */
+
+
+ if (name == NULL || value == NULL)
+ return;
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ {
+ cgi_add_variable(name, 0, value);
+ cgi_sort_variables();
+ }
+ else
+ {
+ for (i = 0; i < var->nvalues; i ++)
+ if (var->values[i])
+ free((char *)var->values[i]);
+
+ var->values[0] = strdup(value);
+ var->nvalues = 1;
+ }
+}
+
+
+/*
+ * 'cgi_add_variable()' - Add a form variable.
+ */
+
+static void
+cgi_add_variable(const char *name, /* I - Variable name */
+ int element, /* I - Array element number */
+ const char *value) /* I - Variable value */
+{
+ _cgi_var_t *var; /* New variable */
+
+
+ if (name == NULL || value == NULL || element < 0 || element > 100000)
+ return;
+
+#ifdef DEBUG
+ printf("Adding variable \'%s\' with value \'%s\'...\n", name, value);
+#endif /* DEBUG */
+
+ if (form_count >= form_alloc)
+ {
+ if (form_alloc == 0)
+ form_vars = malloc(sizeof(_cgi_var_t) * 16);
+ else
+ form_vars = realloc(form_vars, (form_alloc + 16) * sizeof(_cgi_var_t));
+
+ form_alloc += 16;
+ }
+
+ var = form_vars + form_count;
+ var->name = strdup(name);
+ var->nvalues = element + 1;
+ var->avalues = element + 1;
+ var->values = calloc(element + 1, sizeof(char *));
+ var->values[element] = strdup(value);
+
+ form_count ++;
+}
+
+
+/*
+ * 'cgi_compare_variables()' - Compare two variables.
+ */
+
+static int /* O - Result of comparison */
+cgi_compare_variables(
+ const _cgi_var_t *v1, /* I - First variable */
+ const _cgi_var_t *v2) /* I - Second variable */
+{
+ return (strcasecmp(v1->name, v2->name));
+}
+
+
+/*
+ * 'cgi_find_variable()' - Find a variable...
+ */
+
+static _cgi_var_t * /* O - Variable pointer or NULL */
+cgi_find_variable(const char *name) /* I - Name of variable */
+{
+ _cgi_var_t key; /* Search key */
+
+
+ if (form_count < 1 || name == NULL)
+ return (NULL);
+
+ key.name = name;
+
+ return ((_cgi_var_t *)bsearch(&key, form_vars, form_count, sizeof(_cgi_var_t),
+ (int (*)(const void *, const void *))cgi_compare_variables));
+}
+
+
+/*
+ * 'cgi_initialize_get()' - Initialize form variables using the GET method.
+ */
+
+static int /* O - 1 if form data read */
+cgi_initialize_get(void)
+{
+ char *data; /* Pointer to form data string */
+
+
+#ifdef DEBUG
+ puts("Initializing variables using GET method...");
+#endif /* DEBUG */
+
+ /*
+ * Check to see if there is anything for us to read...
+ */
+
+ data = getenv("QUERY_STRING");
+ if (data == NULL || strlen(data) == 0)
+ return (0);
+
+ /*
+ * Parse it out and return...
+ */
+
+ return (cgi_initialize_string(data));
+}
+
+
+/*
+ * 'cgi_initialize_multipart()' - Initialize variables and file using the POST method.
+ *
+ * TODO: Update to support files > 2GB.
+ */
+
+static int /* O - 1 if form data was read */
+cgi_initialize_multipart(
+ const char *boundary) /* I - Boundary string */
+{
+ char line[10240], /* MIME header line */
+ name[1024], /* Form variable name */
+ filename[1024], /* Form filename */
+ mimetype[1024], /* MIME media type */
+ bstring[256], /* Boundary string to look for */
+ *ptr, /* Pointer into name/filename */
+ *end; /* End of buffer */
+ int ch, /* Character from file */
+ fd, /* Temporary file descriptor */
+ blen; /* Length of boundary string */
+
+
+ DEBUG_printf(("cgi_initialize_multipart(boundary=\"%s\")\n", boundary));
+
+ /*
+ * Read multipart form data until we run out...
+ */
+
+ name[0] = '\0';
+ filename[0] = '\0';
+ mimetype[0] = '\0';
+
+ snprintf(bstring, sizeof(bstring), "\r\n--%s", boundary);
+ blen = strlen(bstring);
+
+ while (fgets(line, sizeof(line), stdin))
+ {
+ if (!strcmp(line, "\r\n"))
+ {
+ /*
+ * End of headers, grab value...
+ */
+
+ if (filename[0])
+ {
+ /*
+ * Read an embedded file...
+ */
+
+ if (form_file)
+ {
+ /*
+ * Remove previous file...
+ */
+
+ cgi_unlink_file();
+ }
+
+ /*
+ * Allocate memory for the new file...
+ */
+
+ if ((form_file = calloc(1, sizeof(cgi_file_t))) == NULL)
+ return (0);
+
+ form_file->name = strdup(name);
+ form_file->filename = strdup(filename);
+ form_file->mimetype = strdup(mimetype);
+
+ fd = cupsTempFd(form_file->tempfile, sizeof(form_file->tempfile));
+
+ if (fd < 0)
+ return (0);
+
+ atexit(cgi_unlink_file);
+
+ /*
+ * Copy file data to the temp file...
+ */
+
+ ptr = line;
+
+ while ((ch = getchar()) != EOF)
+ {
+ *ptr++ = ch;
+
+ if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen))
+ {
+ ptr -= blen;
+ break;
+ }
+
+ if ((ptr - line - blen) >= 8192)
+ {
+ /*
+ * Write out the first 8k of the buffer...
+ */
+
+ write(fd, line, 8192);
+ memmove(line, line + 8192, ptr - line - 8192);
+ ptr -= 8192;
+ }
+ }
+
+ /*
+ * Write the rest of the data and close the temp file...
+ */
+
+ if (ptr > line)
+ write(fd, line, ptr - line);
+
+ close(fd);
+ }
+ else
+ {
+ /*
+ * Just get a form variable; the current code only handles
+ * form values up to 10k in size...
+ */
+
+ ptr = line;
+ end = line + sizeof(line) - 1;
+
+ while ((ch = getchar()) != EOF)
+ {
+ if (ptr < end)
+ *ptr++ = ch;
+
+ if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen))
+ {
+ ptr -= blen;
+ break;
+ }
+ }
+
+ *ptr = '\0';
+
+ /*
+ * Set the form variable...
+ */
+
+ if ((ptr = strrchr(name, '-')) != NULL && isdigit(ptr[1] & 255))
+ {
+ /*
+ * Set a specific index in the array...
+ */
+
+ *ptr++ = '\0';
+ if (line[0])
+ cgiSetArray(name, atoi(ptr) - 1, line);
+ }
+ else if (cgiGetVariable(name))
+ {
+ /*
+ * Add another element in the array...
+ */
+
+ cgiSetArray(name, cgiGetSize(name), line);
+ }
+ else
+ {
+ /*
+ * Just set the line...
+ */
+
+ cgiSetVariable(name, line);
+ }
+ }
+
+ /*
+ * Read the rest of the current line...
+ */
+
+ fgets(line, sizeof(line), stdin);
+
+ /*
+ * Clear the state vars...
+ */
+
+ name[0] = '\0';
+ filename[0] = '\0';
+ mimetype[0] = '\0';
+ }
+ else if (!strncasecmp(line, "Content-Disposition:", 20))
+ {
+ if ((ptr = strstr(line + 20, " name=\"")) != NULL)
+ {
+ strlcpy(name, ptr + 7, sizeof(name));
+
+ if ((ptr = strchr(name, '\"')) != NULL)
+ *ptr = '\0';
+ }
+
+ if ((ptr = strstr(line + 20, " filename=\"")) != NULL)
+ {
+ strlcpy(filename, ptr + 11, sizeof(filename));
+
+ if ((ptr = strchr(filename, '\"')) != NULL)
+ *ptr = '\0';
+ }
+ }
+ else if (!strncasecmp(line, "Content-Type:", 13))
+ {
+ for (ptr = line + 13; isspace(*ptr & 255); ptr ++);
+
+ strlcpy(mimetype, ptr, sizeof(mimetype));
+
+ for (ptr = mimetype + strlen(mimetype) - 1;
+ ptr > mimetype && isspace(*ptr & 255);
+ *ptr-- = '\0');
+ }
+ }
+
+ /*
+ * Return 1 for "form data found"...
+ */
+
+ return (1);
+}
+
+
+/*
+ * 'cgi_initialize_post()' - Initialize variables using the POST method.
+ */
+
+static int /* O - 1 if form data was read */
+cgi_initialize_post(void)
+{
+ char *content_length, /* Length of input data (string) */
+ *data; /* Pointer to form data string */
+ int length, /* Length of input data */
+ nbytes, /* Number of bytes read this read() */
+ tbytes, /* Total number of bytes read */
+ status; /* Return status */
+
+
+#ifdef DEBUG
+ puts("Initializing variables using POST method...");
+#endif /* DEBUG */
+
+ /*
+ * Check to see if there is anything for us to read...
+ */
+
+ content_length = getenv("CONTENT_LENGTH");
+ if (content_length == NULL || atoi(content_length) <= 0)
+ return (0);
+
+ /*
+ * Get the length of the input stream and allocate a buffer for it...
+ */
+
+ length = atoi(content_length);
+ data = malloc(length + 1);
+
+ if (data == NULL)
+ return (0);
+
+ /*
+ * Read the data into the buffer...
+ */
+
+ for (tbytes = 0; tbytes < length; tbytes += nbytes)
+ if ((nbytes = read(0, data + tbytes, length - tbytes)) < 0)
+ if (errno != EAGAIN)
+ {
+ free(data);
+ return (0);
+ }
+
+ data[length] = '\0';
+
+ /*
+ * Parse it out...
+ */
+
+ status = cgi_initialize_string(data);
+
+ /*
+ * Free the data and return...
+ */
+
+ free(data);
+
+ return (status);
+}
+
+
+/*
+ * 'cgi_initialize_string()' - Initialize form variables from a string.
+ */
+
+static int /* O - 1 if form data was processed */
+cgi_initialize_string(const char *data) /* I - Form data string */
+{
+ int done; /* True if we're done reading a form variable */
+ char *s, /* Pointer to current form string */
+ ch, /* Temporary character */
+ name[255], /* Name of form variable */
+ value[65536]; /* Variable value... */
+
+
+ /*
+ * Check input...
+ */
+
+ if (data == NULL)
+ return (0);
+
+ /*
+ * Loop until we've read all the form data...
+ */
+
+ while (*data != '\0')
+ {
+ /*
+ * Get the variable name...
+ */
+
+ for (s = name; *data != '\0'; data ++)
+ if (*data == '=')
+ break;
+ else if (*data >= ' ' && s < (name + sizeof(name) - 1))
+ *s++ = *data;
+
+ *s = '\0';
+ if (*data == '=')
+ data ++;
+ else
+ return (0);
+
+ /*
+ * Read the variable value...
+ */
+
+ for (s = value, done = 0; !done && *data != '\0'; data ++)
+ switch (*data)
+ {
+ case '&' : /* End of data... */
+ done = 1;
+ break;
+
+ case '+' : /* Escaped space character */
+ if (s < (value + sizeof(value) - 1))
+ *s++ = ' ';
+ break;
+
+ case '%' : /* Escaped control character */
+ /*
+ * Read the hex code...
+ */
+
+ if (s < (value + sizeof(value) - 1))
+ {
+ data ++;
+ ch = *data - '0';
+ if (ch > 9)
+ ch -= 7;
+ *s = ch << 4;
+
+ data ++;
+ ch = *data - '0';
+ if (ch > 9)
+ ch -= 7;
+ *s++ |= ch;
+ }
+ else
+ data += 2;
+ break;
+
+ default : /* Other characters come straight through */
+ if (*data >= ' ' && s < (value + sizeof(value) - 1))
+ *s++ = *data;
+ break;
+ }
+
+ *s = '\0'; /* nul terminate the string */
+
+ /*
+ * Remove trailing whitespace...
+ */
+
+ if (s > value)
+ s --;
+
+ while (s >= value && *s == ' ')
+ *s-- = '\0';
+
+ /*
+ * Add the string to the variable "database"...
+ */
+
+ if ((s = strrchr(name, '-')) != NULL && isdigit(s[1] & 255))
+ {
+ *s++ = '\0';
+ if (value[0])
+ cgiSetArray(name, atoi(s) - 1, value);
+ }
+ else if (cgiGetVariable(name) != NULL)
+ cgiSetArray(name, cgiGetSize(name), value);
+ else
+ cgiSetVariable(name, value);
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'cgi_passwd()' - Catch authentication requests and notify the server.
+ *
+ * This function sends a Status header and exits, forcing authentication
+ * for this request.
+ */
+
+static const char * /* O - NULL (no return) */
+cgi_passwd(const char *prompt) /* I - Prompt (not used) */
+{
+ (void)prompt;
+
+ fprintf(stderr, "DEBUG: cgi_passwd(prompt=\"%s\") called!\n", prompt);
+
+ /*
+ * Send a 401 (unauthorized) status to the server, so it can notify
+ * the client that authentication is required.
+ */
+
+ puts("Status: 401\n");
+ exit(0);
+
+ /*
+ * This code is never executed, but is present to satisfy the compiler.
+ */
+
+ return (NULL);
+}
+
+
+/*
+ * 'cgi_sort_variables()' - Sort all form variables for faster lookup.
+ */
+
+static void
+cgi_sort_variables(void)
+{
+#ifdef DEBUG
+ int i;
+
+
+ puts("Sorting variables...");
+#endif /* DEBUG */
+
+ if (form_count < 2)
+ return;
+
+ qsort(form_vars, form_count, sizeof(_cgi_var_t),
+ (int (*)(const void *, const void *))cgi_compare_variables);
+
+#ifdef DEBUG
+ puts("Sorted variable list is:");
+ for (i = 0; i < form_count; i ++)
+ printf("%d: %s (%d) = \"%s\" ...\n", i, form_vars[i].name,
+ form_vars[i].nvalues, form_vars[i].values[0]);
+#endif /* DEBUG */
+}
+
+
+/*
+ * 'cgi_unlink_file()' - Remove the uploaded form.
+ */
+
+static void
+cgi_unlink_file(void)
+{
+ if (form_file)
+ {
+ /*
+ * Remove the temporary file...
+ */
+
+ unlink(form_file->tempfile);
+
+ /*
+ * Free memory used...
+ */
+
+ free(form_file->name);
+ free(form_file->filename);
+ free(form_file->mimetype);
+ free(form_file);
+
+ form_file = NULL;
+ }
+}
+
+
+/*
+ * End of "$Id: var.c 4869 2005-12-06 02:43:40Z mike $".
+ */