]>
git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/template.c
f6f213fef547bb74f5b3c038f2eb97d37aec820e
2 * "$Id: template.c 5461 2006-04-25 17:15:45Z mike $"
4 * CGI template function.
6 * Copyright 1997-2006 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * cgiCopyTemplateFile() - Copy a template file and replace all the
27 * '{variable}' strings with the variable value.
28 * cgiCopyTemplateLang() - Copy a template file using a language...
29 * cgiGetTemplateDir() - Get the templates directory...
30 * cgiSetServerVersion() - Set the server name and CUPS version...
31 * cgi_copy() - Copy the template file, substituting as needed...
32 * cgi_puts() - Put a string to the output file, quoting as
36 #include "cgi-private.h"
44 static void cgi_copy(FILE *out
, FILE *in
, int element
, char term
,
46 static void cgi_puts(const char *s
, FILE *out
);
47 static void cgi_puturi(const char *s
, FILE *out
);
51 * 'cgiCopyTemplateFile()' - Copy a template file and replace all the
52 * '{variable}' strings with the variable value.
56 cgiCopyTemplateFile(FILE *out
, /* I - Output file */
57 const char *tmpl
) /* I - Template file to read */
59 FILE *in
; /* Input file */
62 fprintf(stderr
, "DEBUG: cgiCopyTemplateFile(out=%p, tmpl=\"%s\")\n", out
,
66 * Open the template file...
69 if ((in
= fopen(tmpl
, "r")) == NULL
)
71 fprintf(stderr
, "ERROR: Unable to open template file \"%s\" - %s\n",
72 tmpl
, strerror(errno
));
77 * Parse the file to the end...
80 cgi_copy(out
, in
, 0, 0, 0);
83 * Close the template file and return...
91 * 'cgiCopyTemplateLang()' - Copy a template file using a language...
95 cgiCopyTemplateLang(const char *tmpl
) /* I - Base filename */
97 int i
; /* Looping var */
98 char filename
[1024], /* Filename */
99 locale
[16]; /* Locale name */
100 const char *directory
, /* Directory for templates */
101 *lang
; /* Language */
102 FILE *in
; /* Input file */
105 fprintf(stderr
, "DEBUG: cgiCopyTemplateLang(tmpl=\"%s\")\n", tmpl
);
108 * Convert the language to a locale name...
111 if ((lang
= getenv("LANG")) != NULL
)
113 for (i
= 0; lang
[i
] && i
< 15; i
++)
114 if (isalnum(lang
[i
] & 255) || lang
[i
] == '_')
115 locale
[i
] = tolower(lang
[i
]);
116 else if (lang
[i
] == '-')
126 fprintf(stderr
, "DEBUG: locale=\"%s\"...\n", locale
);
129 * See if we have a template file for this language...
132 directory
= cgiGetTemplateDir();
134 snprintf(filename
, sizeof(filename
), "%s/%s/%s", directory
, locale
, tmpl
);
135 if (access(filename
, 0))
139 snprintf(filename
, sizeof(filename
), "%s/%s/%s", directory
, locale
, tmpl
);
140 if (access(filename
, 0))
141 snprintf(filename
, sizeof(filename
), "%s/%s", directory
, tmpl
);
144 fprintf(stderr
, "DEBUG: Template file is \"%s\"...\n", filename
);
147 * Open the template file...
150 if ((in
= fopen(filename
, "r")) == NULL
)
152 fprintf(stderr
, "ERROR: Unable to open template file \"%s\" - %s\n",
153 filename
, strerror(errno
));
158 * Parse the file to the end...
161 cgi_copy(stdout
, in
, 0, 0, 0);
164 * Close the template file and return...
172 * 'cgiGetTemplateDir()' - Get the templates directory...
175 char * /* O - Template directory */
176 cgiGetTemplateDir(void)
178 const char *datadir
; /* CUPS_DATADIR env var */
179 static char templates
[1024] = ""; /* Template directory */
185 * Build the template directory pathname...
188 if ((datadir
= getenv("CUPS_DATADIR")) == NULL
)
189 datadir
= CUPS_DATADIR
;
191 snprintf(templates
, sizeof(templates
), "%s/templates", datadir
);
199 * 'cgiSetServerVersion()' - Set the server name and CUPS version...
203 cgiSetServerVersion(void)
205 cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME"));
206 cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER"));
207 cgiSetVariable("CUPS_VERSION", CUPS_SVERSION
);
210 setlocale(LC_TIME
, "");
216 * 'cgi_copy()' - Copy the template file, substituting as needed...
220 cgi_copy(FILE *out
, /* I - Output file */
221 FILE *in
, /* I - Input file */
222 int element
, /* I - Element number (0 to N) */
223 char term
, /* I - Terminating character */
224 int indent
) /* I - Debug info indentation */
226 int ch
; /* Character from file */
227 char op
; /* Operation */
228 char name
[255], /* Name of variable */
229 *nameptr
, /* Pointer into name */
230 innername
[255], /* Inner comparison name */
231 *innerptr
, /* Pointer into inner name */
232 *s
; /* String pointer */
233 const char *value
; /* Value of variable */
234 const char *innerval
; /* Inner value */
235 const char *outptr
; /* Output string pointer */
236 char outval
[1024], /* Formatted output string */
237 compare
[1024]; /* Comparison string */
238 int result
; /* Result of comparison */
239 int uriencode
; /* Encode as URI */
242 fprintf(stderr
, "DEBUG: %*sStarting at file position %ld...\n", indent
, "",
246 * Parse the file to the end...
249 while ((ch
= getc(in
)) != EOF
)
255 * Get a variable name...
260 for (s
= name
; (ch
= getc(in
)) != EOF
;)
261 if (strchr("}]<>=! \t\n", ch
))
263 else if (s
== name
&& ch
== '%')
265 else if (s
> name
&& ch
== '?')
267 else if (s
< (name
+ sizeof(name
) - 1))
272 if (s
== name
&& isspace(ch
& 255))
274 fprintf(stderr
, "DEBUG: %*sLone { at %ld...\n", indent
, "", ftell(in
));
286 fprintf(stderr
, "DEBUG: %*s\"{%s}\" at %ld...\n", indent
, "", name
,
290 * See if it has a value...
296 * Insert value only if it exists...
299 if ((nameptr
= strrchr(name
, '-')) != NULL
&& isdigit(nameptr
[1] & 255))
303 if ((value
= cgiGetArray(name
+ 1, atoi(nameptr
) - 1)) != NULL
)
311 else if ((value
= cgiGetArray(name
+ 1, element
)) != NULL
)
319 else if (name
[0] == '#')
326 sprintf(outval
, "%d", cgiGetSize(name
+ 1));
328 sprintf(outval
, "%d", element
+ 1);
332 else if (name
[0] == '[')
335 * Loop for # of elements...
338 int i
; /* Looping var */
339 long pos
; /* File position */
340 int count
; /* Number of elements */
343 if (isdigit(name
[1] & 255))
344 count
= atoi(name
+ 1);
346 count
= cgiGetSize(name
+ 1);
350 fprintf(stderr
, "DEBUG: %*sLooping on \"%s\" at %ld, count=%d...\n",
351 indent
, "", name
+ 1, pos
, count
);
355 for (i
= 0; i
< count
; i
++)
358 fseek(in
, pos
, SEEK_SET
);
360 cgi_copy(out
, in
, i
, '}', indent
+ 2);
364 cgi_copy(NULL
, in
, 0, '}', indent
+ 2);
366 fprintf(stderr
, "DEBUG: %*sFinished looping on \"%s\"...\n", indent
,
374 * Insert variable or variable name (if element is NULL)...
377 if ((nameptr
= strrchr(name
, '-')) != NULL
&& isdigit(nameptr
[1] & 255))
380 if ((value
= cgiGetArray(name
, atoi(nameptr
) - 1)) == NULL
)
382 snprintf(outval
, sizeof(outval
), "{%s}", name
);
388 else if ((value
= cgiGetArray(name
, element
)) == NULL
)
390 snprintf(outval
, sizeof(outval
), "{%s}", name
);
398 * See if the terminating character requires another test...
404 * End of substitution...
410 cgi_puturi(outptr
, out
);
412 cgi_puts(outptr
, out
);
419 * OK, process one of the following checks:
421 * {name?exist:not-exist} Exists?
422 * {name=value?true:false} Equal
423 * {name<value?true:false} Less than
424 * {name>value?true:false} Greater than
425 * {name!value?true:false} Not equal
433 * Test for existance...
436 result
= cgiGetArray(name
, element
) != NULL
&& outptr
[0];
442 * Compare to a string...
445 for (s
= compare
; (ch
= getc(in
)) != EOF
;)
448 else if (s
>= (compare
+ sizeof(compare
) - 1))
452 sprintf(s
, "%d", element
+ 1);
458 * Grab the value of a variable...
461 innerptr
= innername
;
462 while ((ch
= getc(in
)) != EOF
&& ch
!= '}')
463 if (innerptr
< (innername
+ sizeof(innername
) - 1))
467 if (innername
[0] == '#')
468 sprintf(s
, "%d", cgiGetSize(innername
+ 1));
469 else if ((innerptr
= strrchr(innername
, '-')) != NULL
&&
470 isdigit(innerptr
[1] & 255))
473 if ((innerval
= cgiGetArray(innername
, atoi(innerptr
) - 1)) == NULL
)
476 strlcpy(s
, innerval
, sizeof(compare
) - (s
- compare
));
478 else if (innername
[0] == '?')
480 if ((innerval
= cgiGetArray(innername
+ 1, element
)) == NULL
)
483 strlcpy(s
, innerval
, sizeof(compare
) - (s
- compare
));
485 else if ((innerval
= cgiGetArray(innername
, element
)) == NULL
)
486 snprintf(s
, sizeof(compare
) - (s
- compare
), "{%s}", innername
);
488 strlcpy(s
, innerval
, sizeof(compare
) - (s
- compare
));
502 "DEBUG: %*sBad terminator '%c' at file position %ld...\n",
503 indent
, "", ch
, ftell(in
));
508 * Do the comparison...
514 result
= strcasecmp(outptr
, compare
) < 0;
517 result
= strcasecmp(outptr
, compare
) > 0;
520 result
= strcasecmp(outptr
, compare
) == 0;
523 result
= strcasecmp(outptr
, compare
) != 0;
532 "DEBUG: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n",
533 indent
, "", name
, op
, compare
, ftell(in
), result
);
538 * Comparison true; output first part and ignore second...
541 fprintf(stderr
, "DEBUG: %*sOutput first part...\n", indent
, "");
542 cgi_copy(out
, in
, element
, ':', indent
+ 2);
544 fprintf(stderr
, "DEBUG: %*sSkip second part...\n", indent
, "");
545 cgi_copy(NULL
, in
, element
, '}', indent
+ 2);
550 * Comparison false; ignore first part and output second...
553 fprintf(stderr
, "DEBUG: %*sSkip first part...\n", indent
, "");
554 cgi_copy(NULL
, in
, element
, ':', indent
+ 2);
556 fprintf(stderr
, "DEBUG: %*sOutput second part...\n", indent
, "");
557 cgi_copy(out
, in
, element
, '}', indent
+ 2);
560 fprintf(stderr
, "DEBUG: %*sFinished \"{%s%c%s\", out=%p...\n", indent
, "",
561 name
, op
, compare
, out
);
563 else if (ch
== '\\') /* Quoted char */
574 fprintf(stderr
, "DEBUG: %*sReturning at file position %ld on EOF...\n",
575 indent
, "", ftell(in
));
578 "DEBUG: %*sReturning at file position %ld on character '%c'...\n",
579 indent
, "", ftell(in
), ch
);
581 if (ch
== EOF
&& term
)
582 fprintf(stderr
, "ERROR: %*sSaw EOF, expected '%c'!\n", indent
, "", term
);
585 * Flush any pending output...
594 * 'cgi_puts()' - Put a string to the output file, quoting as needed...
598 cgi_puts(const char *s
, /* I - String to output */
599 FILE *out
) /* I - Output file */
606 * Pass <A HREF="url"> and </A>, otherwise quote it...
609 if (!strncasecmp(s
, "<A HREF=\"", 9))
611 fputs("<A HREF=\"", out
);
614 while (*s
&& *s
!= '\"')
629 else if (!strncasecmp(s
, "</A>", 4))
640 fputs(""", out
);
652 * 'cgi_puturi()' - Put a URI string to the output file, quoting as needed...
656 cgi_puturi(const char *s
, /* I - String to output */
657 FILE *out
) /* I - Output file */
661 if (strchr("%&+ <>#=", *s
) || *s
& 128)
662 fprintf(out
, "%%%02X", *s
& 255);
672 * End of "$Id: template.c 5461 2006-04-25 17:15:45Z mike $".