]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Generate strings files for localizing PPD options (Issue #5194)
authorMichael R Sweet <michaelrsweet@gmail.com>
Tue, 19 Dec 2017 19:53:00 +0000 (14:53 -0500)
committerMichael R Sweet <michaelrsweet@gmail.com>
Tue, 19 Dec 2017 19:53:00 +0000 (14:53 -0500)
cups/language-private.h:
- New _cupsMessageAdd and _cupsMessageSave private APIs.

cups/language.c:
- Implement new _cupsMessageAdd and _cupsMessageSave private APIs.

cups/ppd-cache.c:
- Generate strings array when loading cache from PPD.
- Remove strings_uri (just pulling strings from PPD now).

cups/ppd-private.h:
- Remove strings_uri and add strings array to cache.

scheduler/client.c:
- Add support for /strings/NAME.strings
- Cleanup implementation of GET/HEAD/POST to files.

scheduler/ipp.c:
- Return local strings file URI.
- Clean up copy_printer_attrs implementation.

scheduler/printers.c:
- Save strings array to cache file, drop support for strings_uri.

scheduler/printers.h:
- Add strings filename to cupsd_printer_t structure.

CHANGES.md
cups/language-private.h
cups/language.c
cups/ppd-cache.c
cups/ppd-private.h
scheduler/client.c
scheduler/ipp.c
scheduler/printers.c
scheduler/printers.h

index cb56a4a089fa1fd55d562b37fd01c1924801db94..376334fb11dba717b14ba54c5d8cfdc07ec6d657 100644 (file)
@@ -1,4 +1,4 @@
-CHANGES - 2.3b1 - 2017-12-18
+CHANGES - 2.3b1 - 2017-12-19
 ============================
 
 
@@ -56,3 +56,5 @@ Changes in CUPS v2.3b1
 - The scheduler now substitutes default values for invalid job attributes when
   running in "relaxed conformance" mode (Issue #5186)
 - The scheduler did not work with older versions of uClibc (Issue #5188)
+- The scheduler now generates a strings file for localizing PPD options
+  (Issue #5194)
index 1f69c4edb1b24ee845900fa0529276e3e810a3cb..fb42a6b951bc033ce8eb899f91e34c6c6c391443 100644 (file)
@@ -76,6 +76,7 @@ extern void           _cupsMessageFree(cups_array_t *a);
 extern cups_array_t    *_cupsMessageLoad(const char *filename, int flags);
 extern const char      *_cupsMessageLookup(cups_array_t *a, const char *m);
 extern cups_array_t    *_cupsMessageNew(void *context);
+extern int             _cupsMessageSave(const char *filename, int flags, cups_array_t *a);
 extern void            _cupsSetLocale(char *argv[]);
 
 
index 1f2a125be8b923c0742a1ab5ecc1fe32f6f8dee5..78d7d1573d4e7302400acb7c6b0eaf2d2bd0c3e0 100644 (file)
@@ -147,6 +147,7 @@ static cups_lang_t  *cups_cache_lookup(const char *name, cups_encoding_t encoding
 static int             cups_message_compare(_cups_message_t *m1, _cups_message_t *m2);
 static void            cups_message_free(_cups_message_t *m);
 static void            cups_message_load(cups_lang_t *lang);
+static void            cups_message_puts(cups_file_t *fp, const char *s);
 static int             cups_read_strings(cups_file_t *fp, int flags, cups_array_t *a);
 static void            cups_unquote(char *d, const char *s);
 
@@ -1225,6 +1226,57 @@ _cupsMessageNew(void *context)           /* I - User data */
 }
 
 
+/*
+ * '_cupsMessageSave()' - Save a message catalog array.
+ */
+
+int                                    /* O - 0 on success, -1 on failure */
+_cupsMessageSave(const char   *filename,/* I - Output filename */
+                 int          flags,   /* I - Format flags */
+                 cups_array_t *a)      /* I - Message array */
+{
+  cups_file_t          *fp;            /* Output file */
+  _cups_message_t      *m;             /* Current message */
+
+
+ /*
+  * Output message catalog file...
+  */
+
+  if ((fp = cupsFileOpen(filename, "w")) == NULL)
+    return (-1);
+
+ /*
+  * Write each message...
+  */
+
+  if (flags & _CUPS_MESSAGE_STRINGS)
+  {
+    for (m = (_cups_message_t *)cupsArrayFirst(a); m; m = (_cups_message_t *)cupsArrayNext(a))
+    {
+      cupsFilePuts(fp, "\"");
+      cups_message_puts(fp, m->msg);
+      cupsFilePuts(fp, "\" = \"");
+      cups_message_puts(fp, m->str);
+      cupsFilePuts(fp, "\";\n");
+    }
+  }
+  else
+  {
+    for (m = (_cups_message_t *)cupsArrayFirst(a); m; m = (_cups_message_t *)cupsArrayNext(a))
+    {
+      cupsFilePuts(fp, "msgid \"");
+      cups_message_puts(fp, m->msg);
+      cupsFilePuts(fp, "\"\nmsgstr \"");
+      cups_message_puts(fp, m->str);
+      cupsFilePuts(fp, "\"\n");
+    }
+  }
+
+  return (cupsFileClose(fp));
+}
+
+
 #ifdef __APPLE__
 /*
  * 'appleLangDefault()' - Get the default locale string.
@@ -1669,6 +1721,44 @@ cups_message_load(cups_lang_t *lang)     /* I - Language */
 }
 
 
+/*
+ * 'cups_message_puts()' - Write a message string with quoting.
+ */
+
+static void
+cups_message_puts(cups_file_t *fp,     /* I - File to write to */
+                  const char  *s)      /* I - String to write */
+{
+  const char   *start,                 /* Start of substring */
+               *ptr;                   /* Pointer into string */
+
+
+  for (start = s, ptr = s; *ptr; ptr ++)
+  {
+    if (strchr("\\\"\n\t", *ptr))
+    {
+      if (ptr > start)
+      {
+       cupsFileWrite(fp, start, (size_t)(ptr - start));
+       start = ptr + 1;
+      }
+
+      if (*ptr == '\\')
+        cupsFileWrite(fp, "\\\\", 2);
+      else if (*ptr == '\"')
+        cupsFileWrite(fp, "\\\"", 2);
+      else if (*ptr == '\n')
+        cupsFileWrite(fp, "\\n", 2);
+      else /* if (*ptr == '\t') */
+        cupsFileWrite(fp, "\\t", 2);
+    }
+  }
+
+  if (ptr > start)
+    cupsFileWrite(fp, start, (size_t)(ptr - start));
+}
+
+
 /*
  * 'cups_read_strings()' - Read a pair of strings from a .strings file.
  */
index 23e34be4b81cdab55ef0160e33bc7c7dc6748a89..177db7b082a78b0173b0f2bbc01aa48d7180e420 100644 (file)
@@ -28,6 +28,7 @@
 
 static int     cups_get_url(http_t **http, const char *url, char *name, size_t namesize);
 static void    pwg_add_finishing(cups_array_t *finishings, ipp_finishings_t template, const char *name, const char *value);
+static void    pwg_add_message(cups_array_t *a, const char *msg, const char *str);
 static int     pwg_compare_finishings(_pwg_finishings_t *a, _pwg_finishings_t *b);
 static int     pwg_compare_sizes(cups_size_t *a, cups_size_t *b);
 static cups_size_t *pwg_copy_size(cups_size_t *size);
@@ -914,8 +915,6 @@ _ppdCacheCreateWithFile(
       else
         pc->mandatory = _cupsArrayNewStrings(value, ' ');
     }
-    else if (!_cups_strcasecmp(line, "StringsURI"))
-      pc->strings_uri = _cupsStrAlloc(value);
     else if (!_cups_strcasecmp(line, "SupportFile"))
     {
       if (!pc->support_files)
@@ -1028,6 +1027,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)   /* I - PPD file */
   pwg_size_t           *new_size;      /* New size to add, if any */
   const char           *filter;        /* Current filter */
   _pwg_finishings_t    *finishings;    /* Current finishings value */
+  char                 msg_id[256];    /* Message identifier */
 
 
   DEBUG_printf(("_ppdCacheCreateWithPPD(ppd=%p)", ppd));
@@ -1049,6 +1049,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)   /* I - PPD file */
     goto create_error;
   }
 
+  pc->strings = _cupsMessageNew(NULL);
+
  /*
   * Copy and convert size data...
   */
@@ -1285,6 +1287,13 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
 
       map->pwg = _cupsStrAlloc(pwg_name);
       map->ppd = _cupsStrAlloc(choice->choice);
+
+     /*
+      * Add localized text for PWG keyword to message catalog...
+      */
+
+      snprintf(msg_id, sizeof(msg_id), "media-source.%s", pwg_name);
+      pwg_add_message(pc->strings, msg_id, choice->text);
     }
   }
 
@@ -1349,6 +1358,13 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
 
       map->pwg = _cupsStrAlloc(pwg_name);
       map->ppd = _cupsStrAlloc(choice->choice);
+
+     /*
+      * Add localized text for PWG keyword to message catalog...
+      */
+
+      snprintf(msg_id, sizeof(msg_id), "media-type.%s", pwg_name);
+      pwg_add_message(pc->strings, msg_id, choice->text);
     }
   }
 
@@ -1376,6 +1392,13 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
 
       map->pwg = _cupsStrAlloc(pwg_keyword);
       map->ppd = _cupsStrAlloc(choice->choice);
+
+     /*
+      * Add localized text for PWG keyword to message catalog...
+      */
+
+      snprintf(msg_id, sizeof(msg_id), "output-bin.%s", pwg_name);
+      pwg_add_message(pc->strings, msg_id, choice->text);
     }
   }
 
@@ -1393,6 +1416,17 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
 
     do
     {
+     /*
+      * Add localized text for PWG keyword to message catalog...
+      */
+
+      snprintf(msg_id, sizeof(msg_id), "preset-name.%s", ppd_attr->spec);
+      pwg_add_message(pc->strings, msg_id, ppd_attr->text);
+
+     /*
+      * Get the options for this preset...
+      */
+
       num_options = _ppdParseOptions(ppd_attr->value, 0, &options,
                                      _PPD_PARSE_ALL);
 
@@ -1836,7 +1870,16 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
     pc->templates = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)_cupsStrAlloc, (cups_afree_func_t)_cupsStrFree);
 
     for (choice = ppd_option->choices, i = ppd_option->num_choices; i > 0; choice ++, i --)
+    {
       cupsArrayAdd(pc->templates, (void *)choice->choice);
+
+     /*
+      * Add localized text for PWG keyword to message catalog...
+      */
+
+      snprintf(msg_id, sizeof(msg_id), "finishing-template.%s", choice->choice);
+      pwg_add_message(pc->strings, msg_id, choice->text);
+    }
   }
 
  /*
@@ -1870,13 +1913,6 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
   if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL)
     pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' ');
 
- /*
-  * Strings (remote) file...
-  */
-
-  if ((ppd_attr = ppdFindAttr(ppd, "cupsStringsURI", NULL)) != NULL)
-    pc->strings_uri = _cupsStrAlloc(ppd_attr->value);
-
  /*
   * Support files...
   */
@@ -2000,6 +2036,8 @@ _ppdCacheDestroy(_ppd_cache_t *pc)        /* I - PPD cache and mapping data */
 
   cupsArrayDelete(pc->support_files);
 
+  cupsArrayDelete(pc->strings);
+
   free(pc);
 }
 
@@ -2947,13 +2985,6 @@ _ppdCacheWriteFile(
        value = (char *)cupsArrayNext(pc->mandatory))
     cupsFilePutConf(fp, "Mandatory", value);
 
- /*
-  * (Remote) strings file...
-  */
-
-  if (pc->strings_uri)
-    cupsFilePutConf(fp, "StringsURI", pc->strings_uri);
-
  /*
   * Support files...
   */
@@ -4613,6 +4644,27 @@ pwg_add_finishing(
 }
 
 
+/*
+ * 'pwg_add_message()' - Add a message to the PPD cached strings.
+ */
+
+static void
+pwg_add_message(cups_array_t *a,       /* I - Message catalog */
+                const char   *msg,     /* I - Message identifier */
+                const char   *str)     /* I - Localized string */
+{
+  _cups_message_t      *m;             /* New message */
+
+
+  if ((m = calloc(1, sizeof(_cups_message_t))) != NULL)
+  {
+    m->msg = strdup(msg);
+    m->str = strdup(str);
+    cupsArrayAdd(a, m);
+  }
+}
+
+
 /*
  * 'pwg_compare_finishings()' - Compare two finishings values.
  */
index 6cd16832774f2b15a3ac2e0051179793cafbd787..21e519ebd14c923f5c5d39d057d7247df9ffce83 100644 (file)
@@ -146,7 +146,7 @@ struct _ppd_cache_s                 /**** PPD cache and PWG conversion data ****/
   char         *password;              /* cupsJobPassword value */
   cups_array_t *mandatory;             /* cupsMandatory value */
   char         *charge_info_uri;       /* cupsChargeInfoURI value */
-  char         *strings_uri;           /* cupsStringsURI value */
+  cups_array_t *strings;               /* Localization strings */
   cups_array_t *support_files;         /* Support files - ICC profiles, etc. */
 };
 
index 775265a8940c87533d7bf70bd11f59928e2f6352..f388499dcf9da9de8ff1c7a88e7a5db4412a9c60 100644 (file)
@@ -556,7 +556,6 @@ cupsdReadClient(cupsd_client_t *con)        /* I - Client to read from */
   char                 buf[1024];      /* Buffer for real filename */
   struct stat          filestats;      /* File information */
   mime_type_t          *type;          /* MIME type of file */
-  cupsd_printer_t      *p;             /* Printer */
   static unsigned      request_id = 0; /* Request ID for temp files */
 
 
@@ -1039,130 +1038,57 @@ cupsdReadClient(cupsd_client_t *con)   /* I - Client to read from */
        case HTTP_STATE_GET_SEND :
             cupsdLogClient(con, CUPSD_LOG_DEBUG, "Processing GET %s", con->uri);
 
-            if ((!strncmp(con->uri, "/ppd/", 5) ||
-                !strncmp(con->uri, "/printers/", 10) ||
-                !strncmp(con->uri, "/classes/", 9)) &&
-               !strcmp(con->uri + strlen(con->uri) - 4, ".ppd"))
-           {
-            /*
-             * Send PPD file - get the real printer name since printer
-             * names are not case sensitive but filenames can be...
-             */
+            if ((filename = get_file(con, &filestats, buf, sizeof(buf))) != NULL)
+            {
+             type = mimeFileType(MimeDatabase, filename, NULL, NULL);
 
-              con->uri[strlen(con->uri) - 4] = '\0';   /* Drop ".ppd" */
+              cupsdLogClient(con, CUPSD_LOG_DEBUG, "filename=\"%s\", type=%s/%s", filename, type ? type->super : "", type ? type->type : "");
 
-             if (!strncmp(con->uri, "/ppd/", 5))
-               p = cupsdFindPrinter(con->uri + 5);
-             else if (!strncmp(con->uri, "/printers/", 10))
-               p = cupsdFindPrinter(con->uri + 10);
-             else
+              if (is_cgi(con, filename, &filestats, type))
              {
-               p = cupsdFindClass(con->uri + 9);
+              /*
+               * Note: con->command and con->options were set by is_cgi()...
+               */
 
-               if (p)
+               if (!cupsdSendCommand(con, con->command, con->options, 0))
                {
-                 int i;                /* Looping var */
-
-                 for (i = 0; i < p->num_printers; i ++)
+                 if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
                  {
-                   if (!(p->printers[i]->type & CUPS_PRINTER_CLASS))
-                   {
-                     char ppdname[1024];/* PPD filename */
-
-                     snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd",
-                              ServerRoot, p->printers[i]->name);
-                     if (!access(ppdname, 0))
-                     {
-                       p = p->printers[i];
-                       break;
-                     }
-                   }
+                   cupsdCloseClient(con);
+                   return;
                  }
+               }
+               else
+                 cupsdLogRequest(con, HTTP_STATUS_OK);
 
-                  if (i >= p->num_printers)
-                    p = NULL;
-               }
+               if (httpGetVersion(con->http) <= HTTP_VERSION_1_0)
+                 httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
+               break;
              }
 
-             if (p)
-             {
-               snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name);
-             }
-             else
-             {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
+             if (!check_if_modified(con, &filestats))
+              {
+               if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE))
                {
                  cupsdCloseClient(con);
                  return;
                }
-
-               break;
              }
-           }
-            else if ((!strncmp(con->uri, "/icons/", 7) ||
-                     !strncmp(con->uri, "/printers/", 10) ||
-                     !strncmp(con->uri, "/classes/", 9)) &&
-                    !strcmp(con->uri + strlen(con->uri) - 4, ".png"))
-           {
-            /*
-             * Send icon file - get the real queue name since queue names are
-             * not case sensitive but filenames can be...
-             */
-
-             con->uri[strlen(con->uri) - 4] = '\0';    /* Drop ".png" */
-
-              if (!strncmp(con->uri, "/icons/", 7))
-                p = cupsdFindPrinter(con->uri + 7);
-              else if (!strncmp(con->uri, "/printers/", 10))
-                p = cupsdFindPrinter(con->uri + 10);
-              else
+             else
               {
-               p = cupsdFindClass(con->uri + 9);
-
-               if (p)
-               {
-                 int i;                /* Looping var */
-
-                 for (i = 0; i < p->num_printers; i ++)
-                 {
-                   if (!(p->printers[i]->type & CUPS_PRINTER_CLASS))
-                   {
-                     char ppdname[1024];/* PPD filename */
-
-                     snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd",
-                              ServerRoot, p->printers[i]->name);
-                     if (!access(ppdname, 0))
-                     {
-                       p = p->printers[i];
-                       break;
-                     }
-                   }
-                 }
-
-                  if (i >= p->num_printers)
-                    p = NULL;
-               }
-             }
+               if (type == NULL)
+                 strlcpy(line, "text/plain", sizeof(line));
+               else
+                 snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
 
-              if (p)
-               snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name);
-             else
-             {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
+               if (!write_file(con, HTTP_STATUS_OK, filename, line, &filestats))
                {
                  cupsdCloseClient(con);
                  return;
                }
-
-               break;
              }
-           }
-
-           if ((!strncmp(con->uri, "/admin", 6) && strcmp(con->uri, "/admin/conf/cupsd.conf") && strncmp(con->uri, "/admin/log/", 11)) ||
-                !strncmp(con->uri, "/printers", 9) ||
-                !strncmp(con->uri, "/classes", 8) ||
-                !strncmp(con->uri, "/help", 5) ||
-                !strncmp(con->uri, "/jobs", 5))
+            }
+            else if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/printers", 9) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/help", 5) || !strncmp(con->uri, "/jobs", 5))
            {
              if (!WebInterface)
              {
@@ -1185,16 +1111,12 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
 
               if (!strncmp(con->uri, "/admin", 6))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", ServerBin);
                cupsdSetString(&con->options, strchr(con->uri + 6, '?'));
              }
               else if (!strncmp(con->uri, "/printers", 9))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", ServerBin);
                 if (con->uri[9] && con->uri[10])
                  cupsdSetString(&con->options, con->uri + 9);
                else
@@ -1202,9 +1124,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              }
              else if (!strncmp(con->uri, "/classes", 8))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", ServerBin);
                 if (con->uri[8] && con->uri[9])
                  cupsdSetString(&con->options, con->uri + 8);
                else
@@ -1212,9 +1132,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              }
              else if (!strncmp(con->uri, "/jobs", 5))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", ServerBin);
                 if (con->uri[5] && con->uri[6])
                  cupsdSetString(&con->options, con->uri + 5);
                else
@@ -1222,9 +1140,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              }
              else
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", ServerBin);
                 if (con->uri[5] && con->uri[6])
                  cupsdSetString(&con->options, con->uri + 5);
                else
@@ -1245,89 +1161,13 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
              if (httpGetVersion(con->http) <= HTTP_VERSION_1_0)
                httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
            }
-            else if (!strncmp(con->uri, "/admin/log/", 11) && (strchr(con->uri + 11, '/') || strlen(con->uri) == 11))
+           else
            {
-            /*
-             * GET can only be done to configuration files directly under
-             * /admin/conf...
-             */
-
-             cupsdLogClient(con, CUPSD_LOG_ERROR, "Request for subdirectory \"%s\".", con->uri);
-
-             if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
+             if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
              {
                cupsdCloseClient(con);
                return;
              }
-
-             break;
-           }
-           else
-           {
-            /*
-             * Serve a file...
-             */
-
-              if ((filename = get_file(con, &filestats, buf,
-                                      sizeof(buf))) == NULL)
-             {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
-               {
-                 cupsdCloseClient(con);
-                 return;
-               }
-
-               break;
-             }
-
-             type = mimeFileType(MimeDatabase, filename, NULL, NULL);
-
-              cupsdLogClient(con, CUPSD_LOG_DEBUG, "filename=\"%s\", type=%s/%s", filename, type ? type->super : "", type ? type->type : "");
-
-              if (is_cgi(con, filename, &filestats, type))
-             {
-              /*
-               * Note: con->command and con->options were set by
-               * is_cgi()...
-               */
-
-               if (!cupsdSendCommand(con, con->command, con->options, 0))
-               {
-                 if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
-                 {
-                   cupsdCloseClient(con);
-                   return;
-                 }
-               }
-               else
-                 cupsdLogRequest(con, HTTP_STATUS_OK);
-
-               if (httpGetVersion(con->http) <= HTTP_VERSION_1_0)
-                 httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
-               break;
-             }
-
-             if (!check_if_modified(con, &filestats))
-              {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE))
-               {
-                 cupsdCloseClient(con);
-                 return;
-               }
-             }
-             else
-              {
-               if (type == NULL)
-                 strlcpy(line, "text/plain", sizeof(line));
-               else
-                 snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
-
-               if (!write_file(con, HTTP_STATUS_OK, filename, line, &filestats))
-               {
-                 cupsdCloseClient(con);
-                 return;
-               }
-             }
            }
             break;
 
@@ -1337,9 +1177,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            * so check the length against any limits that are set...
            */
 
-            if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] &&
-               MaxRequestSize > 0 &&
-               httpGetLength2(con->http) > MaxRequestSize)
+            if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] && MaxRequestSize > 0 && httpGetLength2(con->http) > MaxRequestSize)
            {
             /*
              * Request too large...
@@ -1373,9 +1211,11 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
            * content-type field will be "application/ipp"...
            */
 
-           if (!strcmp(httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE),
-                       "application/ipp"))
+           if (!strcmp(httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE), "application/ipp"))
+           {
               con->request = ippNew();
+              break;
+            }
             else if (!WebInterface)
            {
             /*
@@ -1390,11 +1230,29 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
 
              break;
            }
-           else if ((!strncmp(con->uri, "/admin", 6) && strncmp(con->uri, "/admin/log/", 11)) ||
-                    !strncmp(con->uri, "/printers", 9) ||
-                    !strncmp(con->uri, "/classes", 8) ||
-                    !strncmp(con->uri, "/help", 5) ||
-                    !strncmp(con->uri, "/jobs", 5))
+
+           if ((filename = get_file(con, &filestats, buf, sizeof(buf))) != NULL)
+            {
+            /*
+             * POST to a file...
+             */
+
+             type = mimeFileType(MimeDatabase, filename, NULL, NULL);
+
+              if (!is_cgi(con, filename, &filestats, type))
+             {
+              /*
+               * Only POST to CGI's...
+               */
+
+               if (!cupsdSendError(con, HTTP_STATUS_UNAUTHORIZED, CUPSD_AUTH_NONE))
+               {
+                 cupsdCloseClient(con);
+                 return;
+               }
+             }
+            }
+           else if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/printers", 9) ||  !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/help", 5) || !strncmp(con->uri, "/jobs", 5))
            {
             /*
              * CGI request...
@@ -1402,16 +1260,12 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
 
               if (!strncmp(con->uri, "/admin", 6))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", ServerBin);
                cupsdSetString(&con->options, strchr(con->uri + 6, '?'));
              }
               else if (!strncmp(con->uri, "/printers", 9))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", ServerBin);
                 if (con->uri[9] && con->uri[10])
                  cupsdSetString(&con->options, con->uri + 9);
                else
@@ -1419,9 +1273,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              }
              else if (!strncmp(con->uri, "/classes", 8))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", ServerBin);
                 if (con->uri[8] && con->uri[9])
                  cupsdSetString(&con->options, con->uri + 8);
                else
@@ -1429,9 +1281,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              }
              else if (!strncmp(con->uri, "/jobs", 5))
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", ServerBin);
                 if (con->uri[5] && con->uri[6])
                  cupsdSetString(&con->options, con->uri + 5);
                else
@@ -1439,9 +1289,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              }
              else
              {
-               cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi",
-                               ServerBin);
-
+               cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", ServerBin);
                 if (con->uri[5] && con->uri[6])
                  cupsdSetString(&con->options, con->uri + 5);
                else
@@ -1453,35 +1301,10 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
            }
            else
            {
-            /*
-             * POST to a file...
-             */
-
-              if ((filename = get_file(con, &filestats, buf,
-                                      sizeof(buf))) == NULL)
-             {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
-               {
-                 cupsdCloseClient(con);
-                 return;
-               }
-
-               break;
-             }
-
-             type = mimeFileType(MimeDatabase, filename, NULL, NULL);
-
-              if (!is_cgi(con, filename, &filestats, type))
+             if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
              {
-              /*
-               * Only POST to CGI's...
-               */
-
-               if (!cupsdSendError(con, HTTP_STATUS_UNAUTHORIZED, CUPSD_AUTH_NONE))
-               {
-                 cupsdCloseClient(con);
-                 return;
-               }
+               cupsdCloseClient(con);
+               return;
              }
            }
            break;
@@ -1497,8 +1320,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
              * PUT can only be done to the cupsd.conf file...
              */
 
-             cupsdLogClient(con, CUPSD_LOG_ERROR,
-                            "Disallowed PUT request for \"%s\".", con->uri);
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "Disallowed PUT request for \"%s\".", con->uri);
 
              if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
              {
@@ -1514,9 +1336,7 @@ cupsdReadClient(cupsd_client_t *con)      /* I - Client to read from */
            * so check the length against any limits that are set...
            */
 
-            if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] &&
-               MaxRequestSize > 0 &&
-               httpGetLength2(con->http) > MaxRequestSize)
+            if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] && MaxRequestSize > 0 && httpGetLength2(con->http) > MaxRequestSize)
            {
             /*
              * Request too large...
@@ -1549,15 +1369,12 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
            * Open a temporary file to hold the request...
            */
 
-            cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot,
-                           request_id ++);
+            cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, request_id ++);
            con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640);
 
            if (con->file < 0)
            {
-             cupsdLogClient(con, CUPSD_LOG_ERROR,
-                            "Unable to create request file \"%s\": %s",
-                             con->filename, strerror(errno));
+             cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to create request file \"%s\": %s", con->filename, strerror(errno));
 
              if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
              {
@@ -1578,54 +1395,44 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
            return;
 
        case HTTP_STATE_HEAD :
-            if (!strncmp(con->uri, "/printers/", 10) &&
-               !strcmp(con->uri + strlen(con->uri) - 4, ".ppd"))
-           {
-            /*
-             * Send PPD file - get the real printer name since printer
-             * names are not case sensitive but filenames can be...
-             */
-
-              con->uri[strlen(con->uri) - 4] = '\0';   /* Drop ".ppd" */
-
-              if ((p = cupsdFindPrinter(con->uri + 10)) != NULL)
-               snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name);
-             else
+            if ((filename = get_file(con, &filestats, buf, sizeof(buf))) != NULL)
+            {
+             if (!check_if_modified(con, &filestats))
              {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
+               if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE))
                {
                  cupsdCloseClient(con);
                  return;
                }
 
-               cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
-               break;
+               cupsdLogRequest(con, HTTP_STATUS_NOT_MODIFIED);
              }
-           }
-            else if (!strncmp(con->uri, "/printers/", 10) &&
-                    !strcmp(con->uri + strlen(con->uri) - 4, ".png"))
-           {
-            /*
-             * Send PNG file - get the real printer name since printer
-             * names are not case sensitive but filenames can be...
-             */
-
-              con->uri[strlen(con->uri) - 4] = '\0';   /* Drop ".ppd" */
-
-              if ((p = cupsdFindPrinter(con->uri + 10)) != NULL)
-               snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name);
              else
              {
-               if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
+              /*
+               * Serve a file...
+               */
+
+               type = mimeFileType(MimeDatabase, filename, NULL, NULL);
+               if (type == NULL)
+                 strlcpy(line, "text/plain", sizeof(line));
+               else
+                 snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
+
+               httpClearFields(con->http);
+
+               httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED, httpGetDateString(filestats.st_mtime));
+               httpSetLength(con->http, (size_t)filestats.st_size);
+
+               if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE))
                {
                  cupsdCloseClient(con);
                  return;
                }
 
-               cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
-               break;
+               cupsdLogRequest(con, HTTP_STATUS_OK);
              }
-           }
+            }
            else if (!WebInterface)
            {
               httpClearFields(con->http);
@@ -1640,11 +1447,7 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
              break;
            }
 
-           if ((!strncmp(con->uri, "/admin", 6) && strcmp(con->uri, "/admin/conf/cupsd.conf") && strncmp(con->uri, "/admin/log/", 11)) ||
-               !strncmp(con->uri, "/printers", 9) ||
-               !strncmp(con->uri, "/classes", 8) ||
-               !strncmp(con->uri, "/help", 5) ||
-               !strncmp(con->uri, "/jobs", 5))
+           if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/printers", 9) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/help", 5) || !strncmp(con->uri, "/jobs", 5))
            {
             /*
              * CGI output...
@@ -1660,74 +1463,17 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
 
               cupsdLogRequest(con, HTTP_STATUS_OK);
            }
-            else if (!strncmp(con->uri, "/admin/log/", 11) && (strchr(con->uri + 11, '/') || strlen(con->uri) == 11))
-           {
-            /*
-             * HEAD can only be done to configuration files under
-             * /admin/conf...
-             */
-
-             cupsdLogClient(con, CUPSD_LOG_ERROR,
-                            "Request for subdirectory \"%s\".", con->uri);
-
-             if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
-             {
-               cupsdCloseClient(con);
-               return;
-             }
-
-              cupsdLogRequest(con, HTTP_STATUS_FORBIDDEN);
-             break;
-           }
-           else if ((filename = get_file(con, &filestats, buf,
-                                         sizeof(buf))) == NULL)
-           {
-              httpClearFields(con->http);
-
-             if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html",
-                                  CUPSD_AUTH_NONE))
-             {
-               cupsdCloseClient(con);
-               return;
-             }
-
-              cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
-           }
-           else if (!check_if_modified(con, &filestats))
-            {
-              if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE))
-             {
-               cupsdCloseClient(con);
-               return;
-             }
-
-              cupsdLogRequest(con, HTTP_STATUS_NOT_MODIFIED);
-           }
            else
            {
-            /*
-             * Serve a file...
-             */
-
-             type = mimeFileType(MimeDatabase, filename, NULL, NULL);
-             if (type == NULL)
-               strlcpy(line, "text/plain", sizeof(line));
-             else
-               snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
-
               httpClearFields(con->http);
 
-             httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED,
-                          httpGetDateString(filestats.st_mtime));
-             httpSetLength(con->http, (size_t)filestats.st_size);
-
-              if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE))
+             if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html", CUPSD_AUTH_NONE))
              {
                cupsdCloseClient(con);
                return;
              }
 
-              cupsdLogRequest(con, HTTP_STATUS_OK);
+              cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
            }
             break;
 
@@ -2936,6 +2682,7 @@ get_file(cupsd_client_t *con,             /* I  - Client connection */
   char         language[7],            /* Language subdirectory, if any */
                dest[1024];             /* Destination name */
   int          perm_check = 1;         /* Do permissions check? */
+  cupsd_printer_t *p;                  /* Printer */
 
 
  /*
@@ -2944,47 +2691,76 @@ get_file(cupsd_client_t *con,           /* I  - Client connection */
 
   language[0] = '\0';
 
-  if (!strncmp(con->uri, "/ppd/", 5) && !strchr(con->uri + 5, '/'))
+  if ((!strncmp(con->uri, "/ppd/", 5) || !strncmp(con->uri, "/printers/", 10) || !strncmp(con->uri, "/classes/", 9)) && !strcmp(con->uri + strlen(con->uri) - 4, ".ppd"))
   {
-    strlcpy(dest, con->uri + 5, sizeof(dest));
-    ptr = dest + strlen(dest) - 4;
+    strlcpy(dest, strchr(con->uri + 1, '/') + 1, sizeof(dest));
+    dest[strlen(dest) - 4] = '\0'; /* Strip .ppd */
 
-    if (ptr <= dest || strcmp(ptr, ".ppd"))
+    if ((p = cupsdFindDest(dest)) == NULL)
     {
-      cupsdLogClient(con, CUPSD_LOG_INFO, "Disallowed path \"%s\".", con->uri);
+      cupsdLogClient(con, CUPSD_LOG_INFO, "No destination \"%s\" found.", dest);
       return (NULL);
     }
 
-    *ptr = '\0';
-    if (!cupsdFindPrinter(dest))
+    if (p->type & CUPS_PRINTER_CLASS)
     {
-      cupsdLogClient(con, CUPSD_LOG_INFO, "No printer \"%s\" found.", dest);
-      return (NULL);
-    }
+      int i;                           /* Looping var */
 
-    snprintf(filename, len, "%s%s", ServerRoot, con->uri);
+      for (i = 0; i < p->num_printers; i ++)
+      {
+       if (!(p->printers[i]->type & CUPS_PRINTER_CLASS))
+       {
+         snprintf(filename, len, "%s/ppd/%s.ppd", ServerRoot, p->printers[i]->name);
+         if (!access(filename, 0))
+         {
+           p = p->printers[i];
+           break;
+         }
+       }
+      }
+
+      if (i >= p->num_printers)
+       p = NULL;
+    }
+    else
+      snprintf(filename, len, "%s/ppd/%s.ppd", ServerRoot, p->name);
 
     perm_check = 0;
   }
-  else if (!strncmp(con->uri, "/icons/", 7) && !strchr(con->uri + 7, '/'))
+  else if ((!strncmp(con->uri, "/icons/", 7) || !strncmp(con->uri, "/printers/", 10) || !strncmp(con->uri, "/classes/", 9)) && !strcmp(con->uri + strlen(con->uri) - 4, ".png"))
   {
-    strlcpy(dest, con->uri + 7, sizeof(dest));
-    ptr = dest + strlen(dest) - 4;
+    strlcpy(dest, strchr(con->uri + 1, '/') + 1, sizeof(dest));
+    dest[strlen(dest) - 4] = '\0'; /* Strip .png */
 
-    if (ptr <= dest || strcmp(ptr, ".png"))
+    if ((p = cupsdFindDest(dest)) == NULL)
     {
-      cupsdLogClient(con, CUPSD_LOG_INFO, "Disallowed path \"%s\".", con->uri);
+      cupsdLogClient(con, CUPSD_LOG_INFO, "No destination \"%s\" found.", dest);
       return (NULL);
     }
 
-    *ptr = '\0';
-    if (!cupsdFindDest(dest))
+    if (p->type & CUPS_PRINTER_CLASS)
     {
-      cupsdLogClient(con, CUPSD_LOG_INFO, "No printer \"%s\" found.", dest);
-      return (NULL);
+      int i;                           /* Looping var */
+
+      for (i = 0; i < p->num_printers; i ++)
+      {
+       if (!(p->printers[i]->type & CUPS_PRINTER_CLASS))
+       {
+         snprintf(filename, len, "%s/images/%s.png", CacheDir, p->printers[i]->name);
+         if (!access(filename, 0))
+         {
+           p = p->printers[i];
+           break;
+         }
+       }
+      }
+
+      if (i >= p->num_printers)
+       p = NULL;
     }
+    else
+      snprintf(filename, len, "%s/images/%s.png", CacheDir, p->name);
 
-    snprintf(filename, len, "%s/%s.png", CacheDir, dest);
     if (access(filename, F_OK) < 0)
       snprintf(filename, len, "%s/images/generic.png", DocumentRoot);
 
@@ -2992,6 +2768,27 @@ get_file(cupsd_client_t *con,            /* I  - Client connection */
   }
   else if (!strncmp(con->uri, "/rss/", 5) && !strchr(con->uri + 5, '/'))
     snprintf(filename, len, "%s/rss/%s", CacheDir, con->uri + 5);
+  else if (!strncmp(con->uri, "/strings/", 9) && !strcmp(con->uri + strlen(con->uri) - 8, ".strings"))
+  {
+    strlcpy(dest, con->uri + 9, sizeof(dest));
+    dest[strlen(dest) - 8] = '\0';
+
+    if ((p = cupsdFindDest(dest)) == NULL)
+    {
+      cupsdLogClient(con, CUPSD_LOG_INFO, "No destination \"%s\" found.", dest);
+      return (NULL);
+    }
+
+    if (!p->strings)
+    {
+      cupsdLogClient(con, CUPSD_LOG_INFO, "No strings files for \"%s\".", dest);
+      return (NULL);
+    }
+
+    strlcpy(filename, p->strings, len);
+
+    perm_check = 0;
+  }
   else if (!strcmp(con->uri, "/admin/conf/cupsd.conf"))
   {
     strlcpy(filename, ConfigurationFile, len);
@@ -3031,6 +2828,7 @@ get_file(cupsd_client_t *con,             /* I  - Client connection */
       strncmp(con->uri, "/icons/", 7) &&
       strncmp(con->uri, "/ppd/", 5) &&
       strncmp(con->uri, "/rss/", 5) &&
+      strncmp(con->uri, "/strings/", 9) &&
       strncmp(con->uri, "/admin/conf/", 12) &&
       strncmp(con->uri, "/admin/log/", 11))
   {
index 38afa5f45fcbee88e34210106cf46c12ac75f38f..92353a84d511eecb2172df32ec19a1a738328111 100644 (file)
@@ -4912,12 +4912,11 @@ copy_printer_attrs(
     cupsd_printer_t *printer,          /* I - Printer */
     cups_array_t    *ra)               /* I - Requested attributes array */
 {
-  char                 printer_uri[HTTP_MAX_URI];
-                                       /* Printer URI */
-  char                 printer_icons[HTTP_MAX_URI];
-                                       /* Printer icons */
-  time_t               curtime;        /* Current time */
-  int                  i;              /* Looping var */
+  char         uri[HTTP_MAX_URI];      /* URI value */
+  time_t       curtime;                /* Current time */
+  int          i;                      /* Looping var */
+  int          is_encrypted = httpIsEncrypted(con->http);
+                                       /* Is the connection encrypted? */
 
 
  /*
@@ -4928,107 +4927,83 @@ copy_printer_attrs(
   curtime = time(NULL);
 
   if (!ra || cupsArrayFind(ra, "marker-change-time"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                  "marker-change-time", printer->marker_time);
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "marker-change-time", printer->marker_time);
 
-  if (printer->num_printers > 0 &&
-      (!ra || cupsArrayFind(ra, "member-uris")))
+  if (printer->num_printers > 0 && (!ra || cupsArrayFind(ra, "member-uris")))
   {
     ipp_attribute_t    *member_uris;   /* member-uris attribute */
     cupsd_printer_t    *p2;            /* Printer in class */
     ipp_attribute_t    *p2_uri;        /* printer-uri-supported for class printer */
 
 
-    if ((member_uris = ippAddStrings(con->response, IPP_TAG_PRINTER,
-                                     IPP_TAG_URI, "member-uris",
-                                    printer->num_printers, NULL,
-                                    NULL)) != NULL)
+    if ((member_uris = ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", printer->num_printers, NULL, NULL)) != NULL)
     {
       for (i = 0; i < printer->num_printers; i ++)
       {
         p2 = printer->printers[i];
 
-        if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported",
-                                      IPP_TAG_URI)) != NULL)
-          member_uris->values[i].string.text =
-             _cupsStrRetain(p2_uri->values[0].string.text);
+        if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported", IPP_TAG_URI)) != NULL)
+        {
+          member_uris->values[i].string.text = _cupsStrRetain(p2_uri->values[0].string.text);
+        }
         else
        {
-         httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri,
-                          sizeof(printer_uri), "ipp", NULL, con->clientname,
-                          con->clientport,
-                          (p2->type & CUPS_PRINTER_CLASS) ?
-                              "/classes/%s" : "/printers/%s", p2->name);
-         member_uris->values[i].string.text = _cupsStrAlloc(printer_uri);
+         httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "ipps" : "ipp", NULL, con->clientname, con->clientport, (p2->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", p2->name);
+         member_uris->values[i].string.text = _cupsStrAlloc(uri);
         }
       }
     }
   }
 
   if (printer->alert && (!ra || cupsArrayFind(ra, "printer-alert")))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING,
-                 "printer-alert", NULL, printer->alert);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING, "printer-alert", NULL, printer->alert);
 
-  if (printer->alert_description &&
-      (!ra || cupsArrayFind(ra, "printer-alert-description")))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
-                 "printer-alert-description", NULL,
-                printer->alert_description);
+  if (printer->alert_description && (!ra || cupsArrayFind(ra, "printer-alert-description")))
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-alert-description", NULL, printer->alert_description);
 
   if (!ra || cupsArrayFind(ra, "printer-config-change-date-time"))
     ippAddDate(con->response, IPP_TAG_PRINTER, "printer-config-change-date-time", ippTimeToDate(printer->config_time));
 
   if (!ra || cupsArrayFind(ra, "printer-config-change-time"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                  "printer-config-change-time", printer->config_time);
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-config-change-time", printer->config_time);
 
   if (!ra || cupsArrayFind(ra, "printer-current-time"))
-    ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
-               ippTimeToDate(curtime));
+    ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", ippTimeToDate(curtime));
 
 #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
   if (!ra || cupsArrayFind(ra, "printer-dns-sd-name"))
   {
     if (printer->reg_name)
-      ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
-                   "printer-dns-sd-name", NULL, printer->reg_name);
+      ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-dns-sd-name", NULL, printer->reg_name);
     else
-      ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
-                   "printer-dns-sd-name", 0);
+      ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, "printer-dns-sd-name", 0);
   }
 #endif /* HAVE_DNSSD || HAVE_AVAHI */
 
   if (!ra || cupsArrayFind(ra, "printer-error-policy"))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
-                "printer-error-policy", NULL, printer->error_policy);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-error-policy", NULL, printer->error_policy);
 
   if (!ra || cupsArrayFind(ra, "printer-error-policy-supported"))
   {
     static const char * const errors[] =/* printer-error-policy-supported values */
-                 {
-                   "abort-job",
-                   "retry-current-job",
-                   "retry-job",
-                   "stop-printer"
-                 };
+    {
+      "abort-job",
+      "retry-current-job",
+      "retry-job",
+      "stop-printer"
+    };
 
     if (printer->type & CUPS_PRINTER_CLASS)
-      ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
-                   "printer-error-policy-supported", NULL, "retry-current-job");
+      ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, "printer-error-policy-supported", NULL, "retry-current-job");
     else
-      ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
-                   "printer-error-policy-supported",
-                   sizeof(errors) / sizeof(errors[0]), NULL, errors);
+      ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, "printer-error-policy-supported", sizeof(errors) / sizeof(errors[0]), NULL, errors);
   }
 
   if (!ra || cupsArrayFind(ra, "printer-icons"))
   {
-    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_icons, sizeof(printer_icons),
-                     "http", NULL, con->clientname, con->clientport,
-                    "/icons/%s.png", printer->name);
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons",
-                 NULL, printer_icons);
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-icons=\"%s\"", printer_icons);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "https" : "http", NULL, con->clientname, con->clientport, "/icons/%s.png", printer->name);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons", NULL, uri);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-icons=\"%s\"", uri);
   }
 
   if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs"))
@@ -5042,36 +5017,35 @@ copy_printer_attrs(
 
   if (!ra || cupsArrayFind(ra, "printer-more-info"))
   {
-    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
-                     "http", NULL, con->clientname, con->clientport,
-                    (printer->type & CUPS_PRINTER_CLASS) ?
-                        "/classes/%s" : "/printers/%s", printer->name);
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
-                "printer-more-info", NULL, printer_uri);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "https" : "http", NULL, con->clientname, con->clientport, (printer->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", printer->name);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info", NULL, uri);
   }
 
   if (!ra || cupsArrayFind(ra, "printer-op-policy"))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
-                "printer-op-policy", NULL, printer->op_policy);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-op-policy", NULL, printer->op_policy);
 
   if (!ra || cupsArrayFind(ra, "printer-state"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
-                  printer->state);
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", printer->state);
 
   if (!ra || cupsArrayFind(ra, "printer-state-change-date-time"))
     ippAddDate(con->response, IPP_TAG_PRINTER, "printer-state-change-date-time", ippTimeToDate(printer->state_time));
 
   if (!ra || cupsArrayFind(ra, "printer-state-change-time"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                  "printer-state-change-time", printer->state_time);
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-state-change-time", printer->state_time);
 
   if (!ra || cupsArrayFind(ra, "printer-state-message"))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
-                "printer-state-message", NULL, printer->state_message);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-state-message", NULL, printer->state_message);
 
   if (!ra || cupsArrayFind(ra, "printer-state-reasons"))
     add_printer_state_reasons(con, printer);
 
+  if (!ra || cupsArrayFind(ra, "printer-strings-uri"))
+  {
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "https" : "http", NULL, con->clientname, con->clientport, "/strings/%s.strings", printer->name);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-strings-uri", NULL, uri);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-strings-uri=\"%s\"", uri);
+  }
+
   if (!ra || cupsArrayFind(ra, "printer-type"))
   {
     cups_ptype_t type;                 /* printer-type value */
@@ -5095,19 +5069,13 @@ copy_printer_attrs(
   }
 
   if (!ra || cupsArrayFind(ra, "printer-up-time"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                  "printer-up-time", curtime);
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-up-time", curtime);
 
   if (!ra || cupsArrayFind(ra, "printer-uri-supported"))
   {
-    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
-                     "ipp", NULL, con->clientname, con->clientport,
-                    (printer->type & CUPS_PRINTER_CLASS) ?
-                        "/classes/%s" : "/printers/%s", printer->name);
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
-                "printer-uri-supported", NULL, printer_uri);
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"",
-                    printer_uri);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "ipps" : "ipp", NULL, con->clientname, con->clientport, (printer->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", printer->name);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported", NULL, uri);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"", uri);
   }
 
   if (!ra || cupsArrayFind(ra, "queued-job-count"))
index 557d7514f6854e189ef1323d54a60801dff37bdb..c4a009d3dd93aa7da4ed6dd44bda58f6fbf194a0 100644 (file)
@@ -805,6 +805,7 @@ cupsdDeletePrinter(
   cupsdClearString(&p->port_monitor);
   cupsdClearString(&p->op_policy);
   cupsdClearString(&p->error_policy);
+  cupsdClearString(&p->strings);
 
   cupsdClearString(&p->alert);
   cupsdClearString(&p->alert_description);
@@ -3824,6 +3825,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
   ppd_file_t   *ppd;                   /* PPD file */
   char         ppd_name[1024];         /* PPD filename */
   struct stat  ppd_info;               /* PPD file info */
+  char         strings_name[1024];     /* Strings filename */
   int          num_media;              /* Number of media options */
   ppd_size_t   *size;                  /* Current PPD size */
   ppd_option_t *duplex,                /* Duplex option */
@@ -3882,6 +3884,8 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
   if (stat(ppd_name, &ppd_info))
     ppd_info.st_mtime = 1;
 
+  snprintf(strings_name, sizeof(strings_name), "%s/%s.strings", CacheDir, p->name);
+
   ippDelete(p->ppd_attrs);
   p->ppd_attrs = NULL;
 
@@ -4053,8 +4057,13 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
     ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
                 "printer-make-and-model", NULL, p->make_model);
 
-    if (p->pc->strings_uri)
-      ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-strings-uri", NULL, p->pc->strings_uri);
+    if (p->pc && p->pc->strings)
+      _cupsMessageSave(strings_name, _CUPS_MESSAGE_STRINGS, p->pc->strings);
+
+    if (!access(strings_name, R_OK))
+      cupsdSetString(&p->strings, strings_name);
+    else
+      cupsdClearString(&p->strings);
 
    /*
     * Add media options from the PPD file...
index 6f8afc60f75d3c9783f0c947b30bf73246937b9e..4959bf27606c7e2e382868016bea9064f970dbeb 100644 (file)
@@ -65,6 +65,7 @@ struct cupsd_printer_s
                *info,                  /* Description */
                *organization,          /* Organization name */
                *organizational_unit,   /* Organizational unit (department, etc.) */
+               *strings,               /* Strings file, if any */
                *op_policy,             /* Operation policy name */
                *error_policy;          /* Error policy */
   cupsd_policy_t *op_policy_ptr;       /* Pointer to operation policy */