]>
Commit | Line | Data |
---|---|---|
9153c417 | 1 | /* |
c9d3f842 | 2 | * "$Id$" |
9153c417 | 3 | * |
4 | * CGI template function. | |
5 | * | |
4e8d321f | 6 | * Copyright 2007 by Apple Inc. |
8d72b7e6 | 7 | * Copyright 1997-2006 by Easy Software Products. |
4a409eae | 8 | * |
921a23f4 | 9 | * These coded instructions, statements, and computer programs are the |
4e8d321f | 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/". | |
a548a235 | 14 | * |
15 | * Contents: | |
16 | * | |
17 | * cgiCopyTemplateFile() - Copy a template file and replace all the | |
18 | * '{variable}' strings with the variable value. | |
a3e17a89 | 19 | * cgiCopyTemplateLang() - Copy a template file using a language... |
921a23f4 | 20 | * cgiGetTemplateDir() - Get the templates directory... |
21 | * cgiSetServerVersion() - Set the server name and CUPS version... | |
90beaed3 | 22 | * cgi_copy() - Copy the template file, substituting as needed... |
1d5c0d20 | 23 | * cgi_puts() - Put a string to the output file, quoting as |
24 | * needed... | |
9153c417 | 25 | */ |
26 | ||
921a23f4 | 27 | #include "cgi-private.h" |
a0932c5c | 28 | #include <errno.h> |
9153c417 | 29 | |
30 | ||
90beaed3 | 31 | /* |
32 | * Local functions... | |
33 | */ | |
34 | ||
a0932c5c | 35 | static void cgi_copy(FILE *out, FILE *in, int element, char term, |
36 | int indent); | |
1d5c0d20 | 37 | static void cgi_puts(const char *s, FILE *out); |
a2885801 | 38 | static void cgi_puturi(const char *s, FILE *out); |
90beaed3 | 39 | |
40 | ||
9153c417 | 41 | /* |
a548a235 | 42 | * 'cgiCopyTemplateFile()' - Copy a template file and replace all the |
43 | * '{variable}' strings with the variable value. | |
9153c417 | 44 | */ |
45 | ||
46 | void | |
a3e17a89 | 47 | cgiCopyTemplateFile(FILE *out, /* I - Output file */ |
48 | const char *tmpl) /* I - Template file to read */ | |
9153c417 | 49 | { |
a3e17a89 | 50 | FILE *in; /* Input file */ |
51 | ||
52 | ||
a0932c5c | 53 | fprintf(stderr, "DEBUG: cgiCopyTemplateFile(out=%p, tmpl=\"%s\")\n", out, |
48d2c418 | 54 | tmpl ? tmpl : "(null)"); |
a0932c5c | 55 | |
a3e17a89 | 56 | /* |
57 | * Open the template file... | |
58 | */ | |
59 | ||
60 | if ((in = fopen(tmpl, "r")) == NULL) | |
a0932c5c | 61 | { |
62 | fprintf(stderr, "ERROR: Unable to open template file \"%s\" - %s\n", | |
48d2c418 | 63 | tmpl ? tmpl : "(null)", strerror(errno)); |
a3e17a89 | 64 | return; |
a0932c5c | 65 | } |
a3e17a89 | 66 | |
67 | /* | |
68 | * Parse the file to the end... | |
69 | */ | |
70 | ||
a0932c5c | 71 | cgi_copy(out, in, 0, 0, 0); |
a3e17a89 | 72 | |
73 | /* | |
74 | * Close the template file and return... | |
75 | */ | |
76 | ||
77 | fclose(in); | |
78 | } | |
79 | ||
80 | ||
81 | /* | |
82 | * 'cgiCopyTemplateLang()' - Copy a template file using a language... | |
83 | */ | |
84 | ||
85 | void | |
8d72b7e6 | 86 | cgiCopyTemplateLang(const char *tmpl) /* I - Base filename */ |
a3e17a89 | 87 | { |
8d72b7e6 | 88 | int i; /* Looping var */ |
89 | char filename[1024], /* Filename */ | |
90 | locale[16]; /* Locale name */ | |
91 | const char *directory, /* Directory for templates */ | |
92 | *lang; /* Language */ | |
93 | FILE *in; /* Input file */ | |
9153c417 | 94 | |
95 | ||
48d2c418 | 96 | fprintf(stderr, "DEBUG: cgiCopyTemplateLang(tmpl=\"%s\")\n", |
97 | tmpl ? tmpl : "(null)"); | |
a0932c5c | 98 | |
a3e17a89 | 99 | /* |
100 | * Convert the language to a locale name... | |
101 | */ | |
102 | ||
8d72b7e6 | 103 | if ((lang = getenv("LANG")) != NULL) |
a3e17a89 | 104 | { |
105 | for (i = 0; lang[i] && i < 15; i ++) | |
6d3d0c4d | 106 | if (isalnum(lang[i] & 255) || lang[i] == '_') |
a3e17a89 | 107 | locale[i] = tolower(lang[i]); |
7225c653 | 108 | else if (lang[i] == '-') |
a3e17a89 | 109 | locale[i] = '_'; |
7225c653 | 110 | else |
111 | break; | |
a3e17a89 | 112 | |
113 | locale[i] = '\0'; | |
114 | } | |
115 | else | |
116 | locale[0] = '\0'; | |
117 | ||
a0932c5c | 118 | fprintf(stderr, "DEBUG: locale=\"%s\"...\n", locale); |
7225c653 | 119 | |
a3e17a89 | 120 | /* |
121 | * See if we have a template file for this language... | |
122 | */ | |
123 | ||
8d72b7e6 | 124 | directory = cgiGetTemplateDir(); |
125 | ||
a6988fb1 | 126 | snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl); |
a3e17a89 | 127 | if (access(filename, 0)) |
128 | { | |
129 | locale[2] = '\0'; | |
130 | ||
a6988fb1 | 131 | snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl); |
a3e17a89 | 132 | if (access(filename, 0)) |
a6988fb1 | 133 | snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl); |
a3e17a89 | 134 | } |
135 | ||
a0932c5c | 136 | fprintf(stderr, "DEBUG: Template file is \"%s\"...\n", filename); |
137 | ||
9153c417 | 138 | /* |
139 | * Open the template file... | |
140 | */ | |
141 | ||
a3e17a89 | 142 | if ((in = fopen(filename, "r")) == NULL) |
a0932c5c | 143 | { |
144 | fprintf(stderr, "ERROR: Unable to open template file \"%s\" - %s\n", | |
145 | filename, strerror(errno)); | |
9153c417 | 146 | return; |
a0932c5c | 147 | } |
9153c417 | 148 | |
90beaed3 | 149 | /* |
150 | * Parse the file to the end... | |
151 | */ | |
152 | ||
a0932c5c | 153 | cgi_copy(stdout, in, 0, 0, 0); |
90beaed3 | 154 | |
155 | /* | |
156 | * Close the template file and return... | |
157 | */ | |
158 | ||
159 | fclose(in); | |
160 | } | |
161 | ||
162 | ||
921a23f4 | 163 | /* |
164 | * 'cgiGetTemplateDir()' - Get the templates directory... | |
165 | */ | |
166 | ||
167 | char * /* O - Template directory */ | |
168 | cgiGetTemplateDir(void) | |
169 | { | |
170 | const char *datadir; /* CUPS_DATADIR env var */ | |
171 | static char templates[1024] = ""; /* Template directory */ | |
172 | ||
173 | ||
174 | if (!templates[0]) | |
175 | { | |
176 | /* | |
177 | * Build the template directory pathname... | |
178 | */ | |
179 | ||
180 | if ((datadir = getenv("CUPS_DATADIR")) == NULL) | |
181 | datadir = CUPS_DATADIR; | |
182 | ||
183 | snprintf(templates, sizeof(templates), "%s/templates", datadir); | |
184 | } | |
185 | ||
186 | return (templates); | |
187 | } | |
188 | ||
189 | ||
190 | /* | |
191 | * 'cgiSetServerVersion()' - Set the server name and CUPS version... | |
192 | */ | |
193 | ||
194 | void | |
195 | cgiSetServerVersion(void) | |
196 | { | |
197 | cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME")); | |
198 | cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER")); | |
199 | cgiSetVariable("CUPS_VERSION", CUPS_SVERSION); | |
200 | ||
201 | #ifdef LC_TIME | |
202 | setlocale(LC_TIME, ""); | |
203 | #endif /* LC_TIME */ | |
204 | } | |
205 | ||
206 | ||
90beaed3 | 207 | /* |
208 | * 'cgi_copy()' - Copy the template file, substituting as needed... | |
209 | */ | |
210 | ||
211 | static void | |
a0932c5c | 212 | cgi_copy(FILE *out, /* I - Output file */ |
213 | FILE *in, /* I - Input file */ | |
214 | int element, /* I - Element number (0 to N) */ | |
215 | char term, /* I - Terminating character */ | |
216 | int indent) /* I - Debug info indentation */ | |
90beaed3 | 217 | { |
a0932c5c | 218 | int ch; /* Character from file */ |
219 | char op; /* Operation */ | |
220 | char name[255], /* Name of variable */ | |
221 | *nameptr, /* Pointer into name */ | |
222 | innername[255], /* Inner comparison name */ | |
223 | *innerptr, /* Pointer into inner name */ | |
224 | *s; /* String pointer */ | |
225 | const char *value; /* Value of variable */ | |
226 | const char *innerval; /* Inner value */ | |
227 | const char *outptr; /* Output string pointer */ | |
228 | char outval[1024], /* Formatted output string */ | |
229 | compare[1024]; /* Comparison string */ | |
230 | int result; /* Result of comparison */ | |
a2885801 | 231 | int uriencode; /* Encode as URI */ |
a0932c5c | 232 | |
233 | ||
234 | fprintf(stderr, "DEBUG: %*sStarting at file position %ld...\n", indent, "", | |
235 | ftell(in)); | |
90beaed3 | 236 | |
9153c417 | 237 | /* |
238 | * Parse the file to the end... | |
239 | */ | |
240 | ||
241 | while ((ch = getc(in)) != EOF) | |
3f78f826 | 242 | if (ch == term) |
90beaed3 | 243 | break; |
244 | else if (ch == '{') | |
9153c417 | 245 | { |
246 | /* | |
247 | * Get a variable name... | |
248 | */ | |
249 | ||
a2885801 | 250 | uriencode = 0; |
251 | ||
3f78f826 | 252 | for (s = name; (ch = getc(in)) != EOF;) |
e0663562 | 253 | if (strchr("}]<>=! \t\n", ch)) |
9153c417 | 254 | break; |
a2885801 | 255 | else if (s == name && ch == '%') |
256 | uriencode = 1; | |
778c51c8 | 257 | else if (s > name && ch == '?') |
258 | break; | |
3225d87b | 259 | else if (s < (name + sizeof(name) - 1)) |
3f78f826 | 260 | *s++ = ch; |
261 | ||
9153c417 | 262 | *s = '\0'; |
263 | ||
da275f55 | 264 | if (s == name && isspace(ch & 255)) |
462bddea | 265 | { |
a0932c5c | 266 | fprintf(stderr, "DEBUG: %*sLone { at %ld...\n", indent, "", ftell(in)); |
267 | ||
4874fe20 | 268 | if (out) |
269 | { | |
270 | putc('{', out); | |
271 | putc(ch, out); | |
272 | } | |
273 | ||
462bddea | 274 | continue; |
275 | } | |
276 | ||
a0932c5c | 277 | if (ch == '}') |
278 | fprintf(stderr, "DEBUG: %*s\"{%s}\" at %ld...\n", indent, "", name, | |
279 | ftell(in)); | |
280 | ||
9153c417 | 281 | /* |
282 | * See if it has a value... | |
283 | */ | |
284 | ||
3d860279 | 285 | if (name[0] == '?') |
90beaed3 | 286 | { |
287 | /* | |
288 | * Insert value only if it exists... | |
289 | */ | |
290 | ||
da275f55 | 291 | if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1] & 255)) |
e9b903a7 | 292 | { |
293 | *nameptr++ = '\0'; | |
294 | ||
295 | if ((value = cgiGetArray(name + 1, atoi(nameptr) - 1)) != NULL) | |
4874fe20 | 296 | outptr = value; |
e9b903a7 | 297 | else |
4874fe20 | 298 | { |
e9b903a7 | 299 | outval[0] = '\0'; |
4874fe20 | 300 | outptr = outval; |
301 | } | |
e9b903a7 | 302 | } |
1f4b7b03 | 303 | else if ((value = cgiGetArray(name + 1, element)) != NULL) |
4874fe20 | 304 | outptr = value; |
3f78f826 | 305 | else |
4874fe20 | 306 | { |
3f78f826 | 307 | outval[0] = '\0'; |
4874fe20 | 308 | outptr = outval; |
309 | } | |
90beaed3 | 310 | } |
311 | else if (name[0] == '#') | |
312 | { | |
313 | /* | |
314 | * Insert count... | |
315 | */ | |
316 | ||
4a409eae | 317 | if (name[1]) |
318 | sprintf(outval, "%d", cgiGetSize(name + 1)); | |
319 | else | |
320 | sprintf(outval, "%d", element + 1); | |
4874fe20 | 321 | |
322 | outptr = outval; | |
90beaed3 | 323 | } |
324 | else if (name[0] == '[') | |
325 | { | |
326 | /* | |
327 | * Loop for # of elements... | |
328 | */ | |
329 | ||
330 | int i; /* Looping var */ | |
331 | long pos; /* File position */ | |
332 | int count; /* Number of elements */ | |
333 | ||
334 | ||
da275f55 | 335 | if (isdigit(name[1] & 255)) |
3f78f826 | 336 | count = atoi(name + 1); |
337 | else | |
338 | count = cgiGetSize(name + 1); | |
339 | ||
340 | pos = ftell(in); | |
90beaed3 | 341 | |
a0932c5c | 342 | fprintf(stderr, "DEBUG: %*sLooping on \"%s\" at %ld, count=%d...\n", |
343 | indent, "", name + 1, pos, count); | |
344 | ||
3f78f826 | 345 | if (count > 0) |
90beaed3 | 346 | { |
3f78f826 | 347 | for (i = 0; i < count; i ++) |
348 | { | |
a0932c5c | 349 | if (i) |
350 | fseek(in, pos, SEEK_SET); | |
351 | ||
352 | cgi_copy(out, in, i, '}', indent + 2); | |
3f78f826 | 353 | } |
354 | } | |
355 | else | |
a0932c5c | 356 | cgi_copy(NULL, in, 0, '}', indent + 2); |
357 | ||
358 | fprintf(stderr, "DEBUG: %*sFinished looping on \"%s\"...\n", indent, | |
359 | "", name + 1); | |
892b98d3 | 360 | |
361 | continue; | |
90beaed3 | 362 | } |
9153c417 | 363 | else |
3d860279 | 364 | { |
90beaed3 | 365 | /* |
366 | * Insert variable or variable name (if element is NULL)... | |
367 | */ | |
3d860279 | 368 | |
da275f55 | 369 | if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1] & 255)) |
e9b903a7 | 370 | { |
371 | *nameptr++ = '\0'; | |
372 | if ((value = cgiGetArray(name, atoi(nameptr) - 1)) == NULL) | |
4874fe20 | 373 | { |
a6988fb1 | 374 | snprintf(outval, sizeof(outval), "{%s}", name); |
4874fe20 | 375 | outptr = outval; |
376 | } | |
e9b903a7 | 377 | else |
4874fe20 | 378 | outptr = value; |
e9b903a7 | 379 | } |
380 | else if ((value = cgiGetArray(name, element)) == NULL) | |
4874fe20 | 381 | { |
a6988fb1 | 382 | snprintf(outval, sizeof(outval), "{%s}", name); |
4874fe20 | 383 | outptr = outval; |
384 | } | |
90beaed3 | 385 | else |
4874fe20 | 386 | outptr = value; |
3f78f826 | 387 | } |
388 | ||
389 | /* | |
390 | * See if the terminating character requires another test... | |
391 | */ | |
392 | ||
393 | if (ch == '}') | |
394 | { | |
395 | /* | |
396 | * End of substitution... | |
397 | */ | |
398 | ||
399 | if (out) | |
a2885801 | 400 | { |
401 | if (uriencode) | |
402 | cgi_puturi(outptr, out); | |
403 | else | |
404 | cgi_puts(outptr, out); | |
405 | } | |
3f78f826 | 406 | |
407 | continue; | |
408 | } | |
409 | ||
410 | /* | |
411 | * OK, process one of the following checks: | |
412 | * | |
413 | * {name?exist:not-exist} Exists? | |
414 | * {name=value?true:false} Equal | |
415 | * {name<value?true:false} Less than | |
416 | * {name>value?true:false} Greater than | |
417 | * {name!value?true:false} Not equal | |
418 | */ | |
419 | ||
a0932c5c | 420 | op = ch; |
421 | ||
3f78f826 | 422 | if (ch == '?') |
423 | { | |
424 | /* | |
425 | * Test for existance... | |
426 | */ | |
427 | ||
a0932c5c | 428 | result = cgiGetArray(name, element) != NULL && outptr[0]; |
429 | compare[0] = '\0'; | |
3f78f826 | 430 | } |
431 | else | |
432 | { | |
433 | /* | |
434 | * Compare to a string... | |
435 | */ | |
436 | ||
3f78f826 | 437 | for (s = compare; (ch = getc(in)) != EOF;) |
438 | if (ch == '?') | |
439 | break; | |
4874fe20 | 440 | else if (s >= (compare + sizeof(compare) - 1)) |
441 | continue; | |
4a409eae | 442 | else if (ch == '#') |
443 | { | |
444 | sprintf(s, "%d", element + 1); | |
445 | s += strlen(s); | |
446 | } | |
d4c438d4 | 447 | else if (ch == '{') |
448 | { | |
449 | /* | |
450 | * Grab the value of a variable... | |
451 | */ | |
452 | ||
453 | innerptr = innername; | |
454 | while ((ch = getc(in)) != EOF && ch != '}') | |
3225d87b | 455 | if (innerptr < (innername + sizeof(innername) - 1)) |
456 | *innerptr++ = ch; | |
d4c438d4 | 457 | *innerptr = '\0'; |
458 | ||
459 | if (innername[0] == '#') | |
460 | sprintf(s, "%d", cgiGetSize(innername + 1)); | |
461 | else if ((innerptr = strrchr(innername, '-')) != NULL && | |
da275f55 | 462 | isdigit(innerptr[1] & 255)) |
d4c438d4 | 463 | { |
464 | *innerptr++ = '\0'; | |
e9b903a7 | 465 | if ((innerval = cgiGetArray(innername, atoi(innerptr) - 1)) == NULL) |
d4c438d4 | 466 | *s = '\0'; |
467 | else | |
def978d5 | 468 | strlcpy(s, innerval, sizeof(compare) - (s - compare)); |
d4c438d4 | 469 | } |
470 | else if (innername[0] == '?') | |
471 | { | |
472 | if ((innerval = cgiGetArray(innername + 1, element)) == NULL) | |
473 | *s = '\0'; | |
474 | else | |
def978d5 | 475 | strlcpy(s, innerval, sizeof(compare) - (s - compare)); |
d4c438d4 | 476 | } |
477 | else if ((innerval = cgiGetArray(innername, element)) == NULL) | |
c79d1143 | 478 | snprintf(s, sizeof(compare) - (s - compare), "{%s}", innername); |
d4c438d4 | 479 | else |
def978d5 | 480 | strlcpy(s, innerval, sizeof(compare) - (s - compare)); |
d4c438d4 | 481 | |
482 | s += strlen(s); | |
483 | } | |
3f78f826 | 484 | else if (ch == '\\') |
485 | *s++ = getc(in); | |
486 | else | |
487 | *s++ = ch; | |
488 | ||
489 | *s = '\0'; | |
490 | ||
491 | if (ch != '?') | |
a0932c5c | 492 | { |
493 | fprintf(stderr, | |
494 | "DEBUG: %*sBad terminator '%c' at file position %ld...\n", | |
495 | indent, "", ch, ftell(in)); | |
3f78f826 | 496 | return; |
a0932c5c | 497 | } |
3f78f826 | 498 | |
499 | /* | |
500 | * Do the comparison... | |
501 | */ | |
502 | ||
503 | switch (op) | |
504 | { | |
505 | case '<' : | |
4874fe20 | 506 | result = strcasecmp(outptr, compare) < 0; |
3f78f826 | 507 | break; |
508 | case '>' : | |
4874fe20 | 509 | result = strcasecmp(outptr, compare) > 0; |
3f78f826 | 510 | break; |
511 | case '=' : | |
4874fe20 | 512 | result = strcasecmp(outptr, compare) == 0; |
3f78f826 | 513 | break; |
514 | case '!' : | |
4874fe20 | 515 | result = strcasecmp(outptr, compare) != 0; |
3f78f826 | 516 | break; |
d21a7597 | 517 | default : |
518 | result = 1; | |
519 | break; | |
3f78f826 | 520 | } |
521 | } | |
522 | ||
a0932c5c | 523 | fprintf(stderr, |
524 | "DEBUG: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n", | |
525 | indent, "", name, op, compare, ftell(in), result); | |
526 | ||
3f78f826 | 527 | if (result) |
528 | { | |
529 | /* | |
530 | * Comparison true; output first part and ignore second... | |
531 | */ | |
532 | ||
a0932c5c | 533 | fprintf(stderr, "DEBUG: %*sOutput first part...\n", indent, ""); |
534 | cgi_copy(out, in, element, ':', indent + 2); | |
535 | ||
536 | fprintf(stderr, "DEBUG: %*sSkip second part...\n", indent, ""); | |
537 | cgi_copy(NULL, in, element, '}', indent + 2); | |
3f78f826 | 538 | } |
539 | else | |
540 | { | |
541 | /* | |
542 | * Comparison false; ignore first part and output second... | |
543 | */ | |
544 | ||
a0932c5c | 545 | fprintf(stderr, "DEBUG: %*sSkip first part...\n", indent, ""); |
546 | cgi_copy(NULL, in, element, ':', indent + 2); | |
547 | ||
548 | fprintf(stderr, "DEBUG: %*sOutput second part...\n", indent, ""); | |
549 | cgi_copy(out, in, element, '}', indent + 2); | |
90beaed3 | 550 | } |
a0932c5c | 551 | |
552 | fprintf(stderr, "DEBUG: %*sFinished \"{%s%c%s\", out=%p...\n", indent, "", | |
553 | name, op, compare, out); | |
9153c417 | 554 | } |
555 | else if (ch == '\\') /* Quoted char */ | |
3f78f826 | 556 | { |
557 | if (out) | |
558 | putc(getc(in), out); | |
559 | else | |
560 | getc(in); | |
561 | } | |
562 | else if (out) | |
9153c417 | 563 | putc(ch, out); |
4874fe20 | 564 | |
a0932c5c | 565 | if (ch == EOF) |
566 | fprintf(stderr, "DEBUG: %*sReturning at file position %ld on EOF...\n", | |
46fd19e2 | 567 | indent, "", ftell(in)); |
a0932c5c | 568 | else |
569 | fprintf(stderr, | |
570 | "DEBUG: %*sReturning at file position %ld on character '%c'...\n", | |
571 | indent, "", ftell(in), ch); | |
572 | ||
573 | if (ch == EOF && term) | |
574 | fprintf(stderr, "ERROR: %*sSaw EOF, expected '%c'!\n", indent, "", term); | |
575 | ||
4874fe20 | 576 | /* |
577 | * Flush any pending output... | |
578 | */ | |
579 | ||
580 | if (out) | |
581 | fflush(out); | |
9153c417 | 582 | } |
583 | ||
584 | ||
585 | /* | |
1d5c0d20 | 586 | * 'cgi_puts()' - Put a string to the output file, quoting as needed... |
587 | */ | |
588 | ||
589 | static void | |
372d627e | 590 | cgi_puts(const char *s, /* I - String to output */ |
591 | FILE *out) /* I - Output file */ | |
1d5c0d20 | 592 | { |
593 | while (*s) | |
594 | { | |
372d627e | 595 | if (*s == '<') |
596 | { | |
597 | /* | |
598 | * Pass <A HREF="url"> and </A>, otherwise quote it... | |
599 | */ | |
600 | ||
601 | if (!strncasecmp(s, "<A HREF=\"", 9)) | |
602 | { | |
603 | fputs("<A HREF=\"", out); | |
604 | s += 9; | |
605 | ||
606 | while (*s && *s != '\"') | |
607 | { | |
608 | if (*s == '&') | |
609 | fputs("&", out); | |
610 | else | |
611 | putc(*s, out); | |
612 | ||
613 | s ++; | |
614 | } | |
615 | ||
616 | if (*s) | |
617 | s ++; | |
618 | ||
619 | fputs("\">", out); | |
620 | } | |
621 | else if (!strncasecmp(s, "</A>", 4)) | |
622 | { | |
623 | fputs("</A>", out); | |
624 | s += 3; | |
625 | } | |
626 | else | |
627 | fputs("<", out); | |
628 | } | |
629 | else if (*s == '>') | |
753453e4 | 630 | fputs(">", out); |
822daded | 631 | else if (*s == '\"') |
632 | fputs(""", out); | |
372d627e | 633 | else if (*s == '&') |
822daded | 634 | fputs("&", out); |
1d5c0d20 | 635 | else |
636 | putc(*s, out); | |
637 | ||
638 | s ++; | |
639 | } | |
640 | } | |
641 | ||
642 | ||
a2885801 | 643 | /* |
644 | * 'cgi_puturi()' - Put a URI string to the output file, quoting as needed... | |
645 | */ | |
646 | ||
647 | static void | |
648 | cgi_puturi(const char *s, /* I - String to output */ | |
649 | FILE *out) /* I - Output file */ | |
650 | { | |
651 | while (*s) | |
652 | { | |
653 | if (strchr("%&+ <>#=", *s) || *s & 128) | |
654 | fprintf(out, "%%%02X", *s & 255); | |
655 | else | |
656 | putc(*s, out); | |
657 | ||
658 | s ++; | |
659 | } | |
660 | } | |
661 | ||
662 | ||
1d5c0d20 | 663 | /* |
c9d3f842 | 664 | * End of "$Id$". |
9153c417 | 665 | */ |