]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/ppd-cache.c
Merge changes from CUPS 1.7svn-r10629.
[thirdparty/cups.git] / cups / ppd-cache.c
index d39bf14e5b2cd5ef8b87e7301c0643f8b03f1167..2e7a5d626d61361ac94db38046183efc6872e580 100644 (file)
@@ -329,7 +329,7 @@ _ppdCacheCreateWithFile(
        goto create_error;
       }
 
-      if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536)
+      if ((num_sizes = atoi(value)) < 0 || num_sizes > 65536)
       {
         DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSizes value %d on line "
                      "%d.", num_sizes, linenum));
@@ -337,12 +337,15 @@ _ppdCacheCreateWithFile(
        goto create_error;
       }
 
-      if ((pc->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
+      if (num_sizes > 0)
       {
-        DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
-                     num_sizes));
-       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-       goto create_error;
+       if ((pc->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
+       {
+         DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
+                       num_sizes));
+         _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+         goto create_error;
+       }
       }
     }
     else if (!_cups_strcasecmp(line, "Size"))
@@ -557,6 +560,19 @@ _ppdCacheCreateWithFile(
     }
     else if (!_cups_strcasecmp(line, "MaxCopies"))
       pc->max_copies = atoi(value);
+    else if (!_cups_strcasecmp(line, "JobAccountId"))
+      pc->account_id = !_cups_strcasecmp(value, "true");
+    else if (!_cups_strcasecmp(line, "JobAccountingUserId"))
+      pc->accounting_user_id = !_cups_strcasecmp(value, "true");
+    else if (!_cups_strcasecmp(line, "JobPassword"))
+      pc->password = _cupsStrAlloc(value);
+    else if (!_cups_strcasecmp(line, "Mandatory"))
+    {
+      if (pc->mandatory)
+        _cupsArrayAddStrings(pc->mandatory, value, ' ');
+      else
+        pc->mandatory = _cupsArrayNewStrings(value, ' ');
+    }
     else
     {
       DEBUG_printf(("_ppdCacheCreateWithFile: Unknown %s on line %d.", line,
@@ -684,148 +700,145 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
   * Copy and convert size data...
   */
 
-  if (ppd->num_sizes == 0)
-  {
-    DEBUG_puts("_ppdCacheCreateWithPPD: No page sizes in PPD.");
-    goto create_error;
-  }
-
-  if ((pc->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
-  {
-    DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
-                  "_pwg_size_t's.", ppd->num_sizes));
-    goto create_error;
-  }
-
-  for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
-       i > 0;
-       i --, ppd_size ++)
+  if (ppd->num_sizes > 0)
   {
-   /*
-    * Don't copy over custom size...
-    */
-
-    if (!_cups_strcasecmp(ppd_size->name, "Custom"))
-      continue;
-
-   /*
-    * Convert the PPD size name to the corresponding PWG keyword name.
-    */
-
-    if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL)
+    if ((pc->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
     {
-     /*
-      * Standard name, do we have conflicts?
-      */
-
-      for (j = 0; j < pc->num_sizes; j ++)
-        if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
-       {
-         pwg_media = NULL;
-         break;
-       }
+      DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+                   "_pwg_size_t's.", ppd->num_sizes));
+      goto create_error;
     }
 
-    if (pwg_media)
+    for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
+        i > 0;
+        i --, ppd_size ++)
     {
      /*
-      * Standard name and no conflicts, use it!
+      * Don't copy over custom size...
       */
 
-      pwg_name      = pwg_media->pwg;
-      new_known_pwg = 1;
-    }
-    else
-    {
+      if (!_cups_strcasecmp(ppd_size->name, "Custom"))
+       continue;
+
      /*
-      * Not a standard name; convert it to a PWG vendor name of the form:
-      *
-      *     pp_lowerppd_WIDTHxHEIGHTuu
+      * Convert the PPD size name to the corresponding PWG keyword name.
       */
 
-      pwg_name      = pwg_keyword;
-      new_known_pwg = 0;
+      if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL)
+      {
+       /*
+       * Standard name, do we have conflicts?
+       */
 
-      pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name));
-      _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
-                      _PWG_FROMPTS(ppd_size->width),
-                      _PWG_FROMPTS(ppd_size->length));
-    }
+       for (j = 0; j < pc->num_sizes; j ++)
+         if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
+         {
+           pwg_media = NULL;
+           break;
+         }
+      }
 
-   /*
-    * If we have a similar paper with non-zero margins then we only want to
-    * keep it if it has a larger imageable area length.  The NULL check is for
-    * dimensions that are <= 0...
-    */
+      if (pwg_media)
+      {
+       /*
+       * Standard name and no conflicts, use it!
+       */
 
-    if ((pwg_media = _pwgMediaForSize(_PWG_FROMPTS(ppd_size->width),
-                                      _PWG_FROMPTS(ppd_size->length))) == NULL)
-      continue;
-
-    new_width      = pwg_media->width;
-    new_length     = pwg_media->length;
-    new_left       = _PWG_FROMPTS(ppd_size->left);
-    new_bottom     = _PWG_FROMPTS(ppd_size->bottom);
-    new_right      = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
-    new_top        = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
-    new_imageable  = new_length - new_top - new_bottom;
-    new_borderless = new_bottom == 0 && new_top == 0 &&
-                     new_left == 0 && new_right == 0;
-
-    for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
-         k > 0 && !similar;
-         k --, old_size ++)
-    {
-      old_imageable  = old_size->length - old_size->top - old_size->bottom;
-      old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
-                      old_size->right == 0 && old_size->top == 0;
-      old_known_pwg  = strncmp(old_size->map.pwg, "oe_", 3) &&
-                      strncmp(old_size->map.pwg, "om_", 3);
-
-      similar = old_borderless == new_borderless &&
-                _PWG_EQUIVALENT(old_size->width, new_width) &&
-               _PWG_EQUIVALENT(old_size->length, new_length);
-
-      if (similar &&
-          (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
+       pwg_name      = pwg_media->pwg;
+       new_known_pwg = 1;
+      }
+      else
       {
        /*
-       * The new paper has a larger imageable area so it could replace
-       * the older paper.  Regardless of the imageable area, we always
-       * prefer the size with a well-known PWG name.
+       * Not a standard name; convert it to a PWG vendor name of the form:
+       *
+       *     pp_lowerppd_WIDTHxHEIGHTuu
        */
 
-       new_size = old_size;
-       _cupsStrFree(old_size->map.ppd);
-       _cupsStrFree(old_size->map.pwg);
+       pwg_name      = pwg_keyword;
+       new_known_pwg = 0;
+
+       pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name));
+       _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
+                        _PWG_FROMPTS(ppd_size->width),
+                        _PWG_FROMPTS(ppd_size->length));
       }
-    }
 
-    if (!similar)
-    {
      /*
-      * The paper was unique enough to deserve its own entry so add it to the
-      * end.
+      * If we have a similar paper with non-zero margins then we only want to
+      * keep it if it has a larger imageable area length.  The NULL check is for
+      * dimensions that are <= 0...
       */
 
-      new_size = pwg_size ++;
-      pc->num_sizes ++;
-    }
+      if ((pwg_media = _pwgMediaForSize(_PWG_FROMPTS(ppd_size->width),
+                                       _PWG_FROMPTS(ppd_size->length))) == NULL)
+       continue;
 
-    if (new_size)
-    {
-     /*
-      * Save this size...
-      */
+      new_width      = pwg_media->width;
+      new_length     = pwg_media->length;
+      new_left       = _PWG_FROMPTS(ppd_size->left);
+      new_bottom     = _PWG_FROMPTS(ppd_size->bottom);
+      new_right      = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
+      new_top        = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
+      new_imageable  = new_length - new_top - new_bottom;
+      new_borderless = new_bottom == 0 && new_top == 0 &&
+                      new_left == 0 && new_right == 0;
+
+      for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
+          k > 0 && !similar;
+          k --, old_size ++)
+      {
+       old_imageable  = old_size->length - old_size->top - old_size->bottom;
+       old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
+                        old_size->right == 0 && old_size->top == 0;
+       old_known_pwg  = strncmp(old_size->map.pwg, "oe_", 3) &&
+                        strncmp(old_size->map.pwg, "om_", 3);
+
+       similar = old_borderless == new_borderless &&
+                 _PWG_EQUIVALENT(old_size->width, new_width) &&
+                 _PWG_EQUIVALENT(old_size->length, new_length);
+
+       if (similar &&
+           (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
+       {
+        /*
+         * The new paper has a larger imageable area so it could replace
+         * the older paper.  Regardless of the imageable area, we always
+         * prefer the size with a well-known PWG name.
+         */
+
+         new_size = old_size;
+         _cupsStrFree(old_size->map.ppd);
+         _cupsStrFree(old_size->map.pwg);
+       }
+      }
+
+      if (!similar)
+      {
+       /*
+       * The paper was unique enough to deserve its own entry so add it to the
+       * end.
+       */
+
+       new_size = pwg_size ++;
+       pc->num_sizes ++;
+      }
+
+      if (new_size)
+      {
+       /*
+       * Save this size...
+       */
 
-      new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
-      new_size->map.pwg = _cupsStrAlloc(pwg_name);
-      new_size->width   = new_width;
-      new_size->length  = new_length;
-      new_size->left    = new_left;
-      new_size->bottom  = new_bottom;
-      new_size->right   = new_right;
-      new_size->top     = new_top;
+       new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
+       new_size->map.pwg = _cupsStrAlloc(pwg_name);
+       new_size->width   = new_width;
+       new_size->length  = new_length;
+       new_size->left    = new_left;
+       new_size->bottom  = new_bottom;
+       new_size->right   = new_right;
+       new_size->top     = new_top;
+      }
     }
   }
 
@@ -1366,6 +1379,23 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
   else
     pc->max_copies = 9999;
 
+ /*
+  * cupsJobAccountId, cupsJobAccountingUserId, cupsJobPassword, and
+  * cupsMandatory.
+  */
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountId", NULL)) != NULL)
+    pc->account_id = !_cups_strcasecmp(ppd_attr->value, "true");
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountingUserId", NULL)) != NULL)
+    pc->accounting_user_id = !_cups_strcasecmp(ppd_attr->value, "true");
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsJobPassword", NULL)) != NULL)
+    pc->password = _cupsStrAlloc(ppd_attr->value);
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL)
+    pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' ');
+
  /*
   * Return the cache data...
   */
@@ -1466,6 +1496,10 @@ _ppdCacheDestroy(_ppd_cache_t *pc)       /* I - PPD cache and mapping data */
   cupsArrayDelete(pc->prefilters);
   cupsArrayDelete(pc->finishings);
 
+  _cupsStrFree(pc->password);
+
+  cupsArrayDelete(pc->mandatory);
+
   free(pc);
 }
 
@@ -2357,6 +2391,22 @@ _ppdCacheWriteFile(
 
   cupsFilePrintf(fp, "MaxCopies %d\n", pc->max_copies);
 
+ /*
+  * Accounting/quota/PIN/managed printing values...
+  */
+
+  cupsFilePrintf(fp, "AccountId %s\n", pc->account_id ? "true" : "false");
+  cupsFilePrintf(fp, "AccountingUserId %s\n",
+                 pc->accounting_user_id ? "true" : "false");
+
+  if (pc->password)
+    cupsFilePutConf(fp, "Password", pc->password);
+
+  for (value = (char *)cupsArrayFirst(pc->mandatory);
+       value;
+       value = (char *)cupsArrayNext(pc->mandatory))
+    cupsFilePutConf(fp, "Mandatory", value);
+
  /*
   * IPP attributes, if any...
   */