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