]>
git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/template.c
2 * "$Id: template.c 6986 2007-09-25 15:34:52Z mike $"
4 * CGI template function.
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
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/".
17 * cgiCopyTemplateFile() - Copy a template file and replace all the
18 * '{variable}' strings with the variable value.
19 * cgiCopyTemplateLang() - Copy a template file using a language...
20 * cgiGetTemplateDir() - Get the templates directory...
21 * cgiSetServerVersion() - Set the server name and CUPS version...
22 * cgi_copy() - Copy the template file, substituting as needed...
23 * cgi_puts() - Put a string to the output file, quoting as
27 #include "cgi-private.h"
36 static void cgi_copy(FILE *out
, FILE *in
, int element
, char term
,
38 static void cgi_puts(const char *s
, FILE *out
);
39 static void cgi_puturi(const char *s
, FILE *out
);
43 * 'cgiCopyTemplateFile()' - Copy a template file and replace all the
44 * '{variable}' strings with the variable value.
48 cgiCopyTemplateFile(FILE *out
, /* I - Output file */
49 const char *tmpl
) /* I - Template file to read */
51 FILE *in
; /* Input file */
54 fprintf(stderr
, "DEBUG2: cgiCopyTemplateFile(out=%p, tmpl=\"%s\")\n", out
,
55 tmpl
? tmpl
: "(null)");
58 * Open the template file...
61 if ((in
= fopen(tmpl
, "r")) == NULL
)
63 fprintf(stderr
, "ERROR: Unable to open template file \"%s\" - %s\n",
64 tmpl
? tmpl
: "(null)", strerror(errno
));
69 * Parse the file to the end...
72 cgi_copy(out
, in
, 0, 0, 0);
75 * Close the template file and return...
83 * 'cgiCopyTemplateLang()' - Copy a template file using a language...
87 cgiCopyTemplateLang(const char *tmpl
) /* I - Base filename */
89 char filename
[1024], /* Filename */
90 locale
[16], /* Locale name */
91 *locptr
; /* Pointer into locale name */
92 const char *directory
, /* Directory for templates */
94 FILE *in
; /* Input file */
97 fprintf(stderr
, "DEBUG2: cgiCopyTemplateLang(tmpl=\"%s\")\n",
98 tmpl
? tmpl
: "(null)");
101 * Convert the language to a locale name...
106 if ((lang
= getenv("LANG")) != NULL
)
109 strlcpy(locale
+ 1, lang
, sizeof(locale
) - 1);
111 if ((locptr
= strchr(locale
, '.')) != NULL
)
112 *locptr
= '\0'; /* Strip charset */
115 fprintf(stderr
, "DEBUG: lang=\"%s\", locale=\"%s\"...\n",
116 lang
? lang
: "(null)", locale
);
119 * See if we have a template file for this language...
122 directory
= cgiGetTemplateDir();
124 snprintf(filename
, sizeof(filename
), "%s%s/%s", directory
, locale
, tmpl
);
125 if ((in
= fopen(filename
, "r")) == NULL
)
129 snprintf(filename
, sizeof(filename
), "%s%s/%s", directory
, locale
, tmpl
);
130 if ((in
= fopen(filename
, "r")) == NULL
)
132 snprintf(filename
, sizeof(filename
), "%s/%s", directory
, tmpl
);
133 in
= fopen(filename
, "r");
137 fprintf(stderr
, "DEBUG2: Template file is \"%s\"...\n", filename
);
140 * Open the template file...
145 fprintf(stderr
, "ERROR: Unable to open template file \"%s\" - %s\n",
146 filename
, strerror(errno
));
151 * Parse the file to the end...
154 cgi_copy(stdout
, in
, 0, 0, 0);
157 * Close the template file and return...
165 * 'cgiGetTemplateDir()' - Get the templates directory...
168 char * /* O - Template directory */
169 cgiGetTemplateDir(void)
171 const char *datadir
; /* CUPS_DATADIR env var */
172 static char templates
[1024] = ""; /* Template directory */
178 * Build the template directory pathname...
181 if ((datadir
= getenv("CUPS_DATADIR")) == NULL
)
182 datadir
= CUPS_DATADIR
;
184 snprintf(templates
, sizeof(templates
), "%s/templates", datadir
);
192 * 'cgiSetServerVersion()' - Set the server name and CUPS version...
196 cgiSetServerVersion(void)
198 cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME"));
199 cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER"));
200 cgiSetVariable("CUPS_VERSION", CUPS_SVERSION
);
203 setlocale(LC_TIME
, "");
209 * 'cgi_copy()' - Copy the template file, substituting as needed...
213 cgi_copy(FILE *out
, /* I - Output file */
214 FILE *in
, /* I - Input file */
215 int element
, /* I - Element number (0 to N) */
216 char term
, /* I - Terminating character */
217 int indent
) /* I - Debug info indentation */
219 int ch
; /* Character from file */
220 char op
; /* Operation */
221 char name
[255], /* Name of variable */
222 *nameptr
, /* Pointer into name */
223 innername
[255], /* Inner comparison name */
224 *innerptr
, /* Pointer into inner name */
225 *s
; /* String pointer */
226 const char *value
; /* Value of variable */
227 const char *innerval
; /* Inner value */
228 const char *outptr
; /* Output string pointer */
229 char outval
[1024], /* Formatted output string */
230 compare
[1024]; /* Comparison string */
231 int result
; /* Result of comparison */
232 int uriencode
; /* Encode as URI */
233 regex_t re
; /* Regular expression to match */
236 fprintf(stderr
, "DEBUG2: %*sStarting at file position %ld...\n", indent
, "",
240 * Parse the file to the end...
243 while ((ch
= getc(in
)) != EOF
)
249 * Get a variable name...
254 for (s
= name
; (ch
= getc(in
)) != EOF
;)
255 if (strchr("}]<>=!~ \t\n", ch
))
257 else if (s
== name
&& ch
== '%')
259 else if (s
> name
&& ch
== '?')
261 else if (s
< (name
+ sizeof(name
) - 1))
266 if (s
== name
&& isspace(ch
& 255))
268 fprintf(stderr
, "DEBUG2: %*sLone { at %ld...\n", indent
, "", ftell(in
));
280 fprintf(stderr
, "DEBUG2: %*s\"{%s}\" at %ld...\n", indent
, "", name
,
284 * See if it has a value...
290 * Insert value only if it exists...
293 if ((nameptr
= strrchr(name
, '-')) != NULL
&& isdigit(nameptr
[1] & 255))
297 if ((value
= cgiGetArray(name
+ 1, atoi(nameptr
) - 1)) != NULL
)
305 else if ((value
= cgiGetArray(name
+ 1, element
)) != NULL
)
313 else if (name
[0] == '#')
320 sprintf(outval
, "%d", cgiGetSize(name
+ 1));
322 sprintf(outval
, "%d", element
+ 1);
326 else if (name
[0] == '[')
329 * Loop for # of elements...
332 int i
; /* Looping var */
333 long pos
; /* File position */
334 int count
; /* Number of elements */
337 if (isdigit(name
[1] & 255))
338 count
= atoi(name
+ 1);
340 count
= cgiGetSize(name
+ 1);
344 fprintf(stderr
, "DEBUG2: %*sLooping on \"%s\" at %ld, count=%d...\n",
345 indent
, "", name
+ 1, pos
, count
);
349 for (i
= 0; i
< count
; i
++)
352 fseek(in
, pos
, SEEK_SET
);
354 cgi_copy(out
, in
, i
, '}', indent
+ 2);
358 cgi_copy(NULL
, in
, 0, '}', indent
+ 2);
360 fprintf(stderr
, "DEBUG2: %*sFinished looping on \"%s\"...\n", indent
,
368 * Insert variable or variable name (if element is NULL)...
371 if ((nameptr
= strrchr(name
, '-')) != NULL
&& isdigit(nameptr
[1] & 255))
374 if ((value
= cgiGetArray(name
, atoi(nameptr
) - 1)) == NULL
)
376 snprintf(outval
, sizeof(outval
), "{%s}", name
);
382 else if ((value
= cgiGetArray(name
, element
)) == NULL
)
384 snprintf(outval
, sizeof(outval
), "{%s}", name
);
392 * See if the terminating character requires another test...
398 * End of substitution...
404 cgi_puturi(outptr
, out
);
405 else if (!strcasecmp(name
, "?cupsdconf_default"))
406 fputs(outptr
, stdout
);
408 cgi_puts(outptr
, out
);
415 * OK, process one of the following checks:
417 * {name?exist:not-exist} Exists?
418 * {name=value?true:false} Equal
419 * {name<value?true:false} Less than
420 * {name>value?true:false} Greater than
421 * {name!value?true:false} Not equal
422 * {name~refex?true:false} Regex match
430 * Test for existance...
433 result
= cgiGetArray(name
, element
) != NULL
&& outptr
[0];
439 * Compare to a string...
442 for (s
= compare
; (ch
= getc(in
)) != EOF
;)
445 else if (s
>= (compare
+ sizeof(compare
) - 1))
449 sprintf(s
, "%d", element
+ 1);
455 * Grab the value of a variable...
458 innerptr
= innername
;
459 while ((ch
= getc(in
)) != EOF
&& ch
!= '}')
460 if (innerptr
< (innername
+ sizeof(innername
) - 1))
464 if (innername
[0] == '#')
465 sprintf(s
, "%d", cgiGetSize(innername
+ 1));
466 else if ((innerptr
= strrchr(innername
, '-')) != NULL
&&
467 isdigit(innerptr
[1] & 255))
470 if ((innerval
= cgiGetArray(innername
, atoi(innerptr
) - 1)) == NULL
)
473 strlcpy(s
, innerval
, sizeof(compare
) - (s
- compare
));
475 else if (innername
[0] == '?')
477 if ((innerval
= cgiGetArray(innername
+ 1, element
)) == NULL
)
480 strlcpy(s
, innerval
, sizeof(compare
) - (s
- compare
));
482 else if ((innerval
= cgiGetArray(innername
, element
)) == NULL
)
483 snprintf(s
, sizeof(compare
) - (s
- compare
), "{%s}", innername
);
485 strlcpy(s
, innerval
, sizeof(compare
) - (s
- compare
));
499 "DEBUG2: %*sBad terminator '%c' at file position %ld...\n",
500 indent
, "", ch
, ftell(in
));
505 * Do the comparison...
511 result
= strcasecmp(outptr
, compare
) < 0;
514 result
= strcasecmp(outptr
, compare
) > 0;
517 result
= strcasecmp(outptr
, compare
) == 0;
520 result
= strcasecmp(outptr
, compare
) != 0;
523 fprintf(stderr
, "DEBUG: Regular expression \"%s\"\n", compare
);
525 if (regcomp(&re
, compare
, REG_EXTENDED
| REG_ICASE
))
528 "ERROR: Unable to compile regular expresion \"%s\"!\n",
534 regmatch_t matches
[10];
538 if (!regexec(&re
, outptr
, 10, matches
, 0))
541 for (i
= 0; i
< 10; i
++)
543 fprintf(stderr
, "DEBUG: matches[%d].rm_so=%d\n", i
,
544 (int)matches
[i
].rm_so
);
545 if (matches
[i
].rm_so
< 0)
562 "DEBUG2: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n",
563 indent
, "", name
, op
, compare
, ftell(in
), result
);
568 * Comparison true; output first part and ignore second...
571 fprintf(stderr
, "DEBUG2: %*sOutput first part...\n", indent
, "");
572 cgi_copy(out
, in
, element
, ':', indent
+ 2);
574 fprintf(stderr
, "DEBUG2: %*sSkip second part...\n", indent
, "");
575 cgi_copy(NULL
, in
, element
, '}', indent
+ 2);
580 * Comparison false; ignore first part and output second...
583 fprintf(stderr
, "DEBUG2: %*sSkip first part...\n", indent
, "");
584 cgi_copy(NULL
, in
, element
, ':', indent
+ 2);
586 fprintf(stderr
, "DEBUG2: %*sOutput second part...\n", indent
, "");
587 cgi_copy(out
, in
, element
, '}', indent
+ 2);
590 fprintf(stderr
, "DEBUG2: %*sFinished \"{%s%c%s\", out=%p...\n", indent
, "",
591 name
, op
, compare
, out
);
593 else if (ch
== '\\') /* Quoted char */
604 fprintf(stderr
, "DEBUG2: %*sReturning at file position %ld on EOF...\n",
605 indent
, "", ftell(in
));
608 "DEBUG2: %*sReturning at file position %ld on character '%c'...\n",
609 indent
, "", ftell(in
), ch
);
611 if (ch
== EOF
&& term
)
612 fprintf(stderr
, "ERROR: %*sSaw EOF, expected '%c'!\n", indent
, "", term
);
615 * Flush any pending output...
624 * 'cgi_puts()' - Put a string to the output file, quoting as needed...
628 cgi_puts(const char *s
, /* I - String to output */
629 FILE *out
) /* I - Output file */
636 * Pass <A HREF="url"> and </A>, otherwise quote it...
639 if (!strncasecmp(s
, "<A HREF=\"", 9))
641 fputs("<A HREF=\"", out
);
644 while (*s
&& *s
!= '\"')
659 else if (!strncasecmp(s
, "</A>", 4))
670 fputs(""", out
);
682 * 'cgi_puturi()' - Put a URI string to the output file, quoting as needed...
686 cgi_puturi(const char *s
, /* I - String to output */
687 FILE *out
) /* I - Output file */
691 if (strchr("%&+ <>#=", *s
) || *s
& 128)
692 fprintf(out
, "%%%02X", *s
& 255);
702 * End of "$Id: template.c 6986 2007-09-25 15:34:52Z mike $".