]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cgi-bin/template.c
Remove all of the Subversion keywords from various source files.
[thirdparty/cups.git] / cgi-bin / template.c
index d2fd9b8e3c09de431b237dabedd789a86c61965d..c7d2144f8cfb6603e2a5d8705d9578f5d3766ce8 100644 (file)
@@ -1,40 +1,19 @@
 /*
- * "$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>
 
 
 /*
@@ -59,9 +38,16 @@ cgiCopyTemplateFile(FILE       *out, /* I - Output file */
   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...
   */
@@ -94,37 +80,34 @@ cgiCopyTemplateFile(FILE       *out,        /* I - Output 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...
@@ -132,23 +115,26 @@ cgiCopyTemplateLang(const char *tmpl)     /* I - Base filename */
 
   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));
@@ -238,9 +224,10 @@ cgi_copy(FILE *out,                        /* I - Output file */
                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));
 
  /*
@@ -259,20 +246,20 @@ cgi_copy(FILE *out,                       /* I - Output file */
       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)
        {
@@ -284,7 +271,7 @@ cgi_copy(FILE *out,                 /* I - Output file */
       }
 
       if (ch == '}')
-       fprintf(stderr, "DEBUG: %*s\"{%s}\" at %ld...\n", indent, "", name,
+       fprintf(stderr, "DEBUG2: %*s\"{%s}\" at %ld...\n", indent, "", name,
                ftell(in));
 
      /*
@@ -348,7 +335,7 @@ cgi_copy(FILE *out,                 /* I - Output file */
 
        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)
@@ -364,11 +351,25 @@ cgi_copy(FILE *out,                       /* I - Output file */
        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
       {
        /*
@@ -409,6 +410,8 @@ cgi_copy(FILE *out,                 /* I - Output file */
        {
          if (uriencode)
            cgi_puturi(outptr, out);
+         else if (!_cups_strcasecmp(name, "?cupsdconf_default"))
+           fputs(outptr, stdout);
          else
            cgi_puts(outptr, out);
         }
@@ -424,9 +427,10 @@ cgi_copy(FILE *out,                        /* I - Output file */
       *   {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 == '?')
       {
@@ -434,7 +438,14 @@ cgi_copy(FILE *out,                        /* I - Output file */
         * 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
@@ -462,7 +473,7 @@ cgi_copy(FILE *out,                 /* I - Output file */
            innerptr = innername;
            while ((ch = getc(in)) != EOF && ch != '}')
              if (innerptr < (innername + sizeof(innername) - 1))
-               *innerptr++ = ch;
+               *innerptr++ = (char)ch;
            *innerptr = '\0';
 
             if (innername[0] == '#')
@@ -474,33 +485,33 @@ cgi_copy(FILE *out,                       /* I - Output file */
              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;
        }
@@ -512,16 +523,49 @@ cgi_copy(FILE *out,                       /* I - Output file */
         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;
@@ -530,7 +574,7 @@ cgi_copy(FILE *out,                 /* I - Output file */
       }
 
       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)
@@ -539,10 +583,10 @@ cgi_copy(FILE *out,                       /* I - Output file */
        * 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
@@ -551,14 +595,14 @@ cgi_copy(FILE *out,                       /* I - Output file */
        * 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 */
@@ -572,11 +616,11 @@ cgi_copy(FILE *out,                       /* I - Output file */
       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)
@@ -602,43 +646,13 @@ cgi_puts(const char *s,                   /* I - String to output */
   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("&amp;", out);
-         else
-           putc(*s, out);
-
-         s ++;
-       }
-
-        if (*s)
-         s ++;
-
-       fputs("\">", out);
-      }
-      else if (!strncasecmp(s, "</A>", 4))
-      {
-        fputs("</A>", out);
-       s += 3;
-      }
-      else
-        fputs("&lt;", out);
-    }
+      fputs("&lt;", out);
     else if (*s == '>')
       fputs("&gt;", out);
     else if (*s == '\"')
       fputs("&quot;", out);
+    else if (*s == '\'')
+      fputs("&#39;", out);
     else if (*s == '&')
       fputs("&amp;", out);
     else
@@ -659,7 +673,7 @@ cgi_puturi(const char *s,           /* I - String to output */
 {
   while (*s)
   {
-    if (strchr("%&+ <>#=", *s) || *s & 128)
+    if (strchr("%@&+ <>#=", *s) || *s < ' ' || *s & 128)
       fprintf(out, "%%%02X", *s & 255);
     else
       putc(*s, out);
@@ -667,8 +681,3 @@ cgi_puturi(const char *s,           /* I - String to output */
     s ++;
   }
 }
-
-
-/*
- * End of "$Id: template.c 5548 2006-05-19 19:38:31Z mike $".
- */