]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/var.c
Fixed a bug in the cgi_initialize_string() code - was not sorting vars!
[thirdparty/cups.git] / cgi-bin / var.c
1 /*
2 * "$Id: var.c,v 1.5 1997/05/13 16:38:07 mike Exp $"
3 *
4 * CGI form variable functions.
5 *
6 * Copyright 1997 by Easy Software Products, All Rights Reserved.
7 *
8 * Contents:
9 *
10 * cgiInitialize() - Initialize the CGI variable "database"...
11 * cgiCheckVariables() - Check for the presence of "required" variables.
12 * cgiGetVariable() - Get a CGI variable from the database...
13 * cgiSetVariable() - Set a CGI variable in the database...
14 * cgi_sort_variables() - Sort all form variables for faster lookup.
15 * cgi_compare_variables() - Compare two variables.
16 * cgi_add_variable() - Add a form variable.
17 * cgi_initialize_string() - Initialize form variables from a string.
18 * cgi_initialize_get() - Initialize form variables using the GET method.
19 * cgi_initialize_post() - Initialize variables using the POST method.
20 *
21 * Revision History:
22 *
23 * $Log: var.c,v $
24 * Revision 1.5 1997/05/13 16:38:07 mike
25 * Fixed a bug in the cgi_initialize_string() code - was not sorting vars!
26 *
27 * Revision 1.4 1997/05/13 15:16:30 mike
28 * Updated cgiCheckVariables() to see if the variable is blank.
29 *
30 * Revision 1.3 1997/05/13 14:56:37 mike
31 * Added cgiCheckVariables() function to check for required variables.
32 *
33 * Revision 1.2 1997/05/08 20:14:19 mike
34 * Renamed CGI_Name functions to cgiName functions.
35 * Updated documentation.
36 *
37 * Revision 1.1 1997/05/08 19:55:53 mike
38 * Initial revision
39 */
40
41 /*#define DEBUG*/
42 #include "cgi.h"
43
44
45 /*
46 * Data structure to hold all the CGI form variables...
47 */
48
49 typedef struct
50 {
51 char *name, /* Name of variable */
52 *value; /* Value of variable */
53 } var_t;
54
55
56 /*
57 * Local globals...
58 */
59
60 static int form_count = 0; /* Form variable count */
61 static var_t *form_vars = NULL; /* Form variables */
62
63
64 /*
65 * Local functions...
66 */
67
68 static void cgi_sort_variables(void);
69 static int cgi_compare_variables(var_t *v1, var_t *v2);
70 static void cgi_add_variable(char *name, char *value);
71 static void cgi_initialize_string(char *data);
72 static int cgi_initialize_get(int need_content);
73 static int cgi_initialize_post(int need_content);
74
75
76 /*
77 * 'cgiInitialize()' - Initialize the CGI variable "database"...
78 */
79
80 int
81 cgiInitialize(int need_content) /* I - True if input is required */
82 {
83 char *method; /* Form posting method */
84
85
86 #ifdef DEBUG
87 setbuf(stdout, NULL);
88 puts("Content-type: text/plain\n");
89 #endif /* DEBUG */
90
91 method = getenv("REQUEST_METHOD");
92
93 if (method == NULL)
94 return (!need_content);
95
96 if (strcasecmp(method, "GET") == 0)
97 return (cgi_initialize_get(need_content));
98 else if (strcasecmp(method, "POST") == 0)
99 return (cgi_initialize_post(need_content));
100 else
101 return (!need_content);
102 }
103
104
105 /*
106 * 'cgiCheckVariables()' - Check for the presence of "required" variables.
107 *
108 * Returns 1 if all variables are present, 0 otherwise. Name may be separated
109 * by spaces and/or commas.
110 */
111
112 int
113 cgiCheckVariables(char *names) /* I - Variables to look for */
114 {
115 char name[255], /* Current variable name */
116 *s, /* Pointer in string */
117 *val; /* Value of variable */
118
119
120 if (names == NULL)
121 return (1);
122
123 while (*names != '\0')
124 {
125 while (*names == ' ' || *names == ',')
126 names ++;
127
128 for (s = name; *names != '\0' && *names != ' ' && *names != ','; s ++, names ++)
129 *s = *names;
130
131 *s = 0;
132 if (name[0] == '\0')
133 break;
134
135 if ((val = cgiGetVariable(name)) == 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 * 'cgiGetVariable()' - Get a CGI variable from the database...
148 *
149 * Returns NULL if the variable doesn't exist...
150 */
151
152 char *
153 cgiGetVariable(char *name) /* I - Name of variable */
154 {
155 var_t key, /* Search key */
156 *var; /* Returned variable */
157
158
159 if (form_count < 1)
160 return (NULL);
161
162 key.name = name;
163
164 var = bsearch(&key, form_vars, form_count, sizeof(var_t),
165 (int (*)(const void *, const void *))cgi_compare_variables);
166
167 #ifdef DEBUG
168 if (var == NULL)
169 printf("cgiGetVariable(\"%s\") is returning NULL...\n", name);
170 else
171 printf("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name, var->value);
172 #endif /* DEBUG */
173
174 return ((var == NULL) ? NULL : var->value);
175 }
176
177
178 /*
179 * 'cgiSetVariable()' - Set a CGI variable in the database...
180 */
181
182 void
183 cgiSetVariable(char *name, /* I - Name of variable */
184 char *value) /* I - Value of variable */
185 {
186 var_t key, /* Search key */
187 *var; /* Returned variable */
188
189
190 if (form_count > 0)
191 {
192 key.name = name;
193
194 var = bsearch(&key, form_vars, form_count, sizeof(var_t),
195 (int (*)(const void *, const void *))cgi_compare_variables);
196 }
197 else
198 var = NULL;
199
200 if (var == NULL)
201 {
202 cgi_add_variable(name, value);
203 cgi_sort_variables();
204 }
205 else
206 {
207 free(var->value);
208 var->value = strdup(value);
209 };
210 }
211
212
213 /*
214 * 'cgi_sort_variables()' - Sort all form variables for faster lookup.
215 */
216
217 static void
218 cgi_sort_variables(void)
219 {
220 #ifdef DEBUG
221 int i;
222
223
224 puts("Sorting variables...");
225 #endif /* DEBUG */
226
227 if (form_count < 2)
228 return;
229
230 qsort(form_vars, form_count, sizeof(var_t),
231 (int (*)(const void *, const void *))cgi_compare_variables);
232
233 #ifdef DEBUG
234 puts("New variable list is:");
235 for (i = 0; i < form_count; i ++)
236 printf("%s = %s\n", form_vars[i].name, form_vars[i].value);
237 #endif /* DEBUG */
238 }
239
240
241 /*
242 * 'cgi_compare_variables()' - Compare two variables.
243 */
244
245 static int
246 cgi_compare_variables(var_t *v1, /* I - First variable */
247 var_t *v2) /* I - Second variable */
248 {
249 return (strcasecmp(v1->name, v2->name));
250 }
251
252
253 /*
254 * 'cgi_add_variable()' - Add a form variable.
255 */
256
257 static void
258 cgi_add_variable(char *name, /* I - Variable name */
259 char *value) /* I - Variable value */
260 {
261 var_t *var;
262
263
264 #ifdef DEBUG
265 printf("Adding variable \'%s\' with value \'%s\'...\n", name, value);
266 #endif /* DEBUG */
267
268 if (form_count == 0)
269 form_vars = malloc(sizeof(var_t));
270 else
271 form_vars = realloc(form_vars, (form_count + 1) * sizeof(var_t));
272
273 var = form_vars + form_count;
274 var->name = strdup(name);
275 var->value = strdup(value);
276 form_count ++;
277 }
278
279
280 /*
281 * 'cgi_initialize_string()' - Initialize form variables from a string.
282 */
283
284 static void
285 cgi_initialize_string(char *data) /* I - Form data string */
286 {
287 int done; /* True if we're done reading a form variable */
288 char *s, /* Pointer to current form string */
289 ch, /* Temporary character */
290 name[255], /* Name of form variable */
291 value[65536]; /* Variable value... */
292
293
294 /*
295 * Check input...
296 */
297
298 if (data == NULL)
299 return;
300
301 /*
302 * Loop until we've read all the form data...
303 */
304
305 while (*data != '\0')
306 {
307 /*
308 * Get the variable name...
309 */
310
311 for (s = name; *data != '\0'; data ++, s ++)
312 if (*data == '=')
313 break;
314 else
315 *s = *data;
316
317 *s = '\0';
318 if (*data == '=')
319 data ++;
320
321 /*
322 * Read the variable value...
323 */
324
325 for (s = value, done = 0; !done && *data != '\0'; data ++, s ++)
326 switch (*data)
327 {
328 case '&' : /* End of data... */
329 done = 1;
330 s --;
331 break;
332
333 case '+' : /* Escaped space character */
334 *s = ' ';
335 break;
336
337 case '%' : /* Escaped control character */
338 /*
339 * Read the hex code from stdin...
340 */
341
342 data ++;
343 ch = *data - '0';
344 if (ch > 9)
345 ch -= 7;
346 *s = ch << 4;
347
348 data ++;
349 ch = *data - '0';
350 if (ch > 9)
351 ch -= 7;
352 *s |= ch;
353 break;
354
355 default : /* Other characters come straight through */
356 *s = *data;
357 break;
358 };
359
360 *s = '\0'; /* nul terminate the string */
361
362 /*
363 * Add the string to the variable "database"...
364 */
365
366 cgi_add_variable(name, value);
367 };
368
369 cgi_sort_variables();
370 }
371
372
373 /*
374 * 'cgi_initialize_get()' - Initialize form variables using the GET method.
375 */
376
377 static int
378 cgi_initialize_get(int need_content) /* I - True if input is required */
379 {
380 char *data; /* Pointer to form data string */
381
382
383 #ifdef DEBUG
384 puts("Initializing variables using GET method...");
385 #endif /* DEBUG */
386
387 /*
388 * Check to see if there is anything for us to read...
389 */
390
391 data = getenv("QUERY_STRING");
392 if (data == NULL)
393 return (!need_content);
394
395 /*
396 * Parse it out...
397 */
398
399 cgi_initialize_string(data);
400
401 /*
402 * Return...
403 */
404
405 return (1);
406 }
407
408
409 /*
410 * 'cgi_initialize_post()' - Initialize variables using the POST method.
411 */
412
413 static int
414 cgi_initialize_post(int need_content) /* I - True if input is required */
415 {
416 char *content_length, /* Length of input data (string) */
417 *data; /* Pointer to form data string */
418 int length, /* Length of input data */
419 nbytes, /* Number of bytes read this read() */
420 tbytes; /* Total number of bytes read */
421
422
423 #ifdef DEBUG
424 puts("Initializing variables using POST method...");
425 #endif /* DEBUG */
426
427 /*
428 * Check to see if there is anything for us to read...
429 */
430
431 content_length = getenv("CONTENT_LENGTH");
432 if (content_length == NULL)
433 return (!need_content);
434
435 /*
436 * Get the length of the input stream and allocate a buffer for it...
437 */
438
439 length = atoi(content_length);
440 data = malloc(length + 1);
441
442 /*
443 * Read the data into the buffer...
444 */
445
446 for (tbytes = 0; tbytes < length; tbytes += nbytes)
447 if ((nbytes = read(0, data + tbytes, length - tbytes)) < 0)
448 {
449 free(data);
450 return (!need_content);
451 };
452
453 data[length] = '\0';
454
455 /*
456 * Parse it out...
457 */
458
459 cgi_initialize_string(data);
460
461 /*
462 * Free the data and return...
463 */
464
465 free(data);
466
467 return (1);
468 }
469
470
471 /*
472 * End of "$Id: var.c,v 1.5 1997/05/13 16:38:07 mike Exp $".
473 */