/*
- * "$Id: template.c 5548 2006-05-19 19:38:31Z mike $"
+ * CGI template function.
*
- * CGI template function.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
*
- * Copyright 1997-2006 by Easy Software Products.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
- * "LICENSE.txt" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
- *
- * Contents:
- *
- * cgiCopyTemplateFile() - Copy a template file and replace all the
- * '{variable}' strings with the variable value.
- * cgiCopyTemplateLang() - Copy a template file using a language...
- * cgiGetTemplateDir() - Get the templates directory...
- * cgiSetServerVersion() - Set the server name and CUPS version...
- * cgi_copy() - Copy the template file, substituting as needed...
- * cgi_puts() - Put a string to the output file, quoting as
- * needed...
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
#include "cgi-private.h"
#include <errno.h>
+#include <regex.h>
/*
FILE *in; /* Input file */
- fprintf(stderr, "DEBUG: cgiCopyTemplateFile(out=%p, tmpl=\"%s\")\n", out,
+ fprintf(stderr, "DEBUG2: cgiCopyTemplateFile(out=%p, tmpl=\"%s\")\n", out,
tmpl ? tmpl : "(null)");
+ /*
+ * Range check input...
+ */
+
+ if (!tmpl || !out)
+ return;
+
/*
* Open the template file...
*/
void
cgiCopyTemplateLang(const char *tmpl) /* I - Base filename */
{
- int i; /* Looping var */
char filename[1024], /* Filename */
- locale[16]; /* Locale name */
+ locale[16], /* Locale name */
+ *locptr; /* Pointer into locale name */
const char *directory, /* Directory for templates */
*lang; /* Language */
FILE *in; /* Input file */
- fprintf(stderr, "DEBUG: cgiCopyTemplateLang(tmpl=\"%s\")\n",
+ fprintf(stderr, "DEBUG2: cgiCopyTemplateLang(tmpl=\"%s\")\n",
tmpl ? tmpl : "(null)");
/*
* Convert the language to a locale name...
*/
+ locale[0] = '\0';
+
if ((lang = getenv("LANG")) != NULL)
{
- for (i = 0; lang[i] && i < 15; i ++)
- if (isalnum(lang[i] & 255) || lang[i] == '_')
- locale[i] = tolower(lang[i]);
- else if (lang[i] == '-')
- locale[i] = '_';
- else
- break;
+ locale[0] = '/';
+ strlcpy(locale + 1, lang, sizeof(locale) - 1);
- locale[i] = '\0';
+ if ((locptr = strchr(locale, '.')) != NULL)
+ *locptr = '\0'; /* Strip charset */
}
- else
- locale[0] = '\0';
- fprintf(stderr, "DEBUG: locale=\"%s\"...\n", locale);
+ fprintf(stderr, "DEBUG2: lang=\"%s\", locale=\"%s\"...\n",
+ lang ? lang : "(null)", locale);
/*
* See if we have a template file for this language...
directory = cgiGetTemplateDir();
- snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
- if (access(filename, 0))
+ snprintf(filename, sizeof(filename), "%s%s/%s", directory, locale, tmpl);
+ if ((in = fopen(filename, "r")) == NULL)
{
- locale[2] = '\0';
+ locale[3] = '\0';
- snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
- if (access(filename, 0))
+ snprintf(filename, sizeof(filename), "%s%s/%s", directory, locale, tmpl);
+ if ((in = fopen(filename, "r")) == NULL)
+ {
snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl);
+ in = fopen(filename, "r");
+ }
}
- fprintf(stderr, "DEBUG: Template file is \"%s\"...\n", filename);
+ fprintf(stderr, "DEBUG2: Template file is \"%s\"...\n", filename);
/*
* Open the template file...
*/
- if ((in = fopen(filename, "r")) == NULL)
+ if (!in)
{
fprintf(stderr, "ERROR: Unable to open template file \"%s\" - %s\n",
filename, strerror(errno));
compare[1024]; /* Comparison string */
int result; /* Result of comparison */
int uriencode; /* Encode as URI */
+ regex_t re; /* Regular expression to match */
- fprintf(stderr, "DEBUG: %*sStarting at file position %ld...\n", indent, "",
+ fprintf(stderr, "DEBUG2: %*sStarting at file position %ld...\n", indent, "",
ftell(in));
/*
uriencode = 0;
for (s = name; (ch = getc(in)) != EOF;)
- if (strchr("}]<>=! \t\n", ch))
+ if (strchr("}]<>=!~ \t\n", ch))
break;
else if (s == name && ch == '%')
uriencode = 1;
else if (s > name && ch == '?')
break;
else if (s < (name + sizeof(name) - 1))
- *s++ = ch;
+ *s++ = (char)ch;
*s = '\0';
if (s == name && isspace(ch & 255))
{
- fprintf(stderr, "DEBUG: %*sLone { at %ld...\n", indent, "", ftell(in));
+ fprintf(stderr, "DEBUG2: %*sLone { at %ld...\n", indent, "", ftell(in));
if (out)
{
}
if (ch == '}')
- fprintf(stderr, "DEBUG: %*s\"{%s}\" at %ld...\n", indent, "", name,
+ fprintf(stderr, "DEBUG2: %*s\"{%s}\" at %ld...\n", indent, "", name,
ftell(in));
/*
pos = ftell(in);
- fprintf(stderr, "DEBUG: %*sLooping on \"%s\" at %ld, count=%d...\n",
+ fprintf(stderr, "DEBUG2: %*sLooping on \"%s\" at %ld, count=%d...\n",
indent, "", name + 1, pos, count);
if (count > 0)
else
cgi_copy(NULL, in, 0, '}', indent + 2);
- fprintf(stderr, "DEBUG: %*sFinished looping on \"%s\"...\n", indent,
+ fprintf(stderr, "DEBUG2: %*sFinished looping on \"%s\"...\n", indent,
"", name + 1);
continue;
}
+ else if (name[0] == '$')
+ {
+ /*
+ * Insert cookie value or nothing if not defined.
+ */
+
+ if ((value = cgiGetCookie(name + 1)) != NULL)
+ outptr = value;
+ else
+ {
+ outval[0] = '\0';
+ outptr = outval;
+ }
+ }
else
{
/*
{
if (uriencode)
cgi_puturi(outptr, out);
+ else if (!_cups_strcasecmp(name, "?cupsdconf_default"))
+ fputs(outptr, stdout);
else
cgi_puts(outptr, out);
}
* {name<value?true:false} Less than
* {name>value?true:false} Greater than
* {name!value?true:false} Not equal
+ * {name~refex?true:false} Regex match
*/
- op = ch;
+ op = (char)ch;
if (ch == '?')
{
* Test for existance...
*/
- result = cgiGetArray(name, element) != NULL && outptr[0];
+ if (name[0] == '?')
+ result = cgiGetArray(name + 1, element) != NULL;
+ else if (name[0] == '#')
+ result = cgiGetVariable(name + 1) != NULL;
+ else
+ result = cgiGetArray(name, element) != NULL;
+
+ result = result && outptr[0];
compare[0] = '\0';
}
else
innerptr = innername;
while ((ch = getc(in)) != EOF && ch != '}')
if (innerptr < (innername + sizeof(innername) - 1))
- *innerptr++ = ch;
+ *innerptr++ = (char)ch;
*innerptr = '\0';
if (innername[0] == '#')
if ((innerval = cgiGetArray(innername, atoi(innerptr) - 1)) == NULL)
*s = '\0';
else
- strlcpy(s, innerval, sizeof(compare) - (s - compare));
+ strlcpy(s, innerval, sizeof(compare) - (size_t)(s - compare));
}
else if (innername[0] == '?')
{
if ((innerval = cgiGetArray(innername + 1, element)) == NULL)
*s = '\0';
else
- strlcpy(s, innerval, sizeof(compare) - (s - compare));
+ strlcpy(s, innerval, sizeof(compare) - (size_t)(s - compare));
}
else if ((innerval = cgiGetArray(innername, element)) == NULL)
- snprintf(s, sizeof(compare) - (s - compare), "{%s}", innername);
+ snprintf(s, sizeof(compare) - (size_t)(s - compare), "{%s}", innername);
else
- strlcpy(s, innerval, sizeof(compare) - (s - compare));
+ strlcpy(s, innerval, sizeof(compare) - (size_t)(s - compare));
s += strlen(s);
}
else if (ch == '\\')
- *s++ = getc(in);
+ *s++ = (char)getc(in);
else
- *s++ = ch;
+ *s++ = (char)ch;
*s = '\0';
if (ch != '?')
{
fprintf(stderr,
- "DEBUG: %*sBad terminator '%c' at file position %ld...\n",
+ "DEBUG2: %*sBad terminator '%c' at file position %ld...\n",
indent, "", ch, ftell(in));
return;
}
switch (op)
{
case '<' :
- result = strcasecmp(outptr, compare) < 0;
+ result = _cups_strcasecmp(outptr, compare) < 0;
break;
case '>' :
- result = strcasecmp(outptr, compare) > 0;
+ result = _cups_strcasecmp(outptr, compare) > 0;
break;
case '=' :
- result = strcasecmp(outptr, compare) == 0;
+ result = _cups_strcasecmp(outptr, compare) == 0;
break;
case '!' :
- result = strcasecmp(outptr, compare) != 0;
+ result = _cups_strcasecmp(outptr, compare) != 0;
+ break;
+ case '~' :
+ fprintf(stderr, "DEBUG: Regular expression \"%s\"\n", compare);
+
+ if (regcomp(&re, compare, REG_EXTENDED | REG_ICASE))
+ {
+ fprintf(stderr,
+ "ERROR: Unable to compile regular expression \"%s\"!\n",
+ compare);
+ result = 0;
+ }
+ else
+ {
+ regmatch_t matches[10];
+
+ result = 0;
+
+ if (!regexec(&re, outptr, 10, matches, 0))
+ {
+ int i;
+ for (i = 0; i < 10; i ++)
+ {
+ fprintf(stderr, "DEBUG: matches[%d].rm_so=%d\n", i,
+ (int)matches[i].rm_so);
+ if (matches[i].rm_so < 0)
+ break;
+
+ result ++;
+ }
+ }
+
+ regfree(&re);
+ }
break;
default :
result = 1;
}
fprintf(stderr,
- "DEBUG: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n",
+ "DEBUG2: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n",
indent, "", name, op, compare, ftell(in), result);
if (result)
* Comparison true; output first part and ignore second...
*/
- fprintf(stderr, "DEBUG: %*sOutput first part...\n", indent, "");
+ fprintf(stderr, "DEBUG2: %*sOutput first part...\n", indent, "");
cgi_copy(out, in, element, ':', indent + 2);
- fprintf(stderr, "DEBUG: %*sSkip second part...\n", indent, "");
+ fprintf(stderr, "DEBUG2: %*sSkip second part...\n", indent, "");
cgi_copy(NULL, in, element, '}', indent + 2);
}
else
* Comparison false; ignore first part and output second...
*/
- fprintf(stderr, "DEBUG: %*sSkip first part...\n", indent, "");
+ fprintf(stderr, "DEBUG2: %*sSkip first part...\n", indent, "");
cgi_copy(NULL, in, element, ':', indent + 2);
- fprintf(stderr, "DEBUG: %*sOutput second part...\n", indent, "");
+ fprintf(stderr, "DEBUG2: %*sOutput second part...\n", indent, "");
cgi_copy(out, in, element, '}', indent + 2);
}
- fprintf(stderr, "DEBUG: %*sFinished \"{%s%c%s\", out=%p...\n", indent, "",
+ fprintf(stderr, "DEBUG2: %*sFinished \"{%s%c%s\", out=%p...\n", indent, "",
name, op, compare, out);
}
else if (ch == '\\') /* Quoted char */
putc(ch, out);
if (ch == EOF)
- fprintf(stderr, "DEBUG: %*sReturning at file position %ld on EOF...\n",
+ fprintf(stderr, "DEBUG2: %*sReturning at file position %ld on EOF...\n",
indent, "", ftell(in));
else
fprintf(stderr,
- "DEBUG: %*sReturning at file position %ld on character '%c'...\n",
+ "DEBUG2: %*sReturning at file position %ld on character '%c'...\n",
indent, "", ftell(in), ch);
if (ch == EOF && term)
while (*s)
{
if (*s == '<')
- {
- /*
- * Pass <A HREF="url"> and </A>, otherwise quote it...
- */
-
- if (!strncasecmp(s, "<A HREF=\"", 9))
- {
- fputs("<A HREF=\"", out);
- s += 9;
-
- while (*s && *s != '\"')
- {
- if (*s == '&')
- fputs("&", out);
- else
- putc(*s, out);
-
- s ++;
- }
-
- if (*s)
- s ++;
-
- fputs("\">", out);
- }
- else if (!strncasecmp(s, "</A>", 4))
- {
- fputs("</A>", out);
- s += 3;
- }
- else
- fputs("<", out);
- }
+ fputs("<", out);
else if (*s == '>')
fputs(">", out);
else if (*s == '\"')
fputs(""", out);
+ else if (*s == '\'')
+ fputs("'", out);
else if (*s == '&')
fputs("&", out);
else
{
while (*s)
{
- if (strchr("%&+ <>#=", *s) || *s & 128)
+ if (strchr("%@&+ <>#=", *s) || *s < ' ' || *s & 128)
fprintf(out, "%%%02X", *s & 255);
else
putc(*s, out);
s ++;
}
}
-
-
-/*
- * End of "$Id: template.c 5548 2006-05-19 19:38:31Z mike $".
- */