]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Add support for more PPD filtering with CUPS-Get-PPDs (STR #1901)
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Thu, 3 May 2007 20:07:14 +0000 (20:07 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Thu, 3 May 2007 20:07:14 +0000 (20:07 +0000)
Add tests for new functionality.

Fix PSVersion (ppd-psversion) values.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@6508 7a7537e8-13f0-0310-91df-b6672ffda945

scheduler/cups-driverd.c
scheduler/ipp.c
test/get-ppds-language.test [new file with mode: 0644]
test/get-ppds-make-and-model.test [new file with mode: 0644]
test/get-ppds-make.test [new file with mode: 0644]
test/get-ppds-product.test [new file with mode: 0644]
test/get-ppds-psversion.test [new file with mode: 0644]

index 0a19ccf18c9ae6ac762fcbb7922eedbf1d382029..6bbe232d1eb7eb60fb1925b0923d73cc22ae7e8c 100644 (file)
@@ -557,14 +557,22 @@ list_ppds(int        request_id,  /* I - Request ID */
   int          num_options;            /* Number of options */
   cups_option_t        *options;               /* Options */
   const char   *requested,             /* requested-attributes option */
-               *make;                  /* ppd-make option */
-  int          send_natural_language,  /* Send ppd-natural-language? */
+               *device_id,             /* ppd-device-id option */
+               *language,              /* ppd-natural-language option */
+               *make,                  /* ppd-make option */
+               *make_and_model,        /* ppd-make-and-model option */
+               *product,               /* ppd-product option */
+               *psversion;             /* ppd-psversion option */
+  int          mam_len,                /* Length of ppd-make-and-model */
+               device_id_len,          /* Length of ppd-device-id */
+               send_natural_language,  /* Send ppd-natural-language? */
                send_make,              /* Send ppd-make? */
                send_make_and_model,    /* Send ppd-make-and-model? */
                send_name,              /* Send ppd-name? */
                send_device_id,         /* Send ppd-device-id? */
                send_product,           /* Send ppd-product? */
-               send_psversion;         /* Send ppd-psversion? */
+               send_psversion,         /* Send ppd-psversion? */
+               sent_header;            /* Sent the IPP header? */
 
 
   fprintf(stderr,
@@ -596,7 +604,7 @@ list_ppds(int        request_id,    /* I - Request ID */
             == sizeof(ppdsync) &&
         ppdsync == PPD_SYNC &&
         !stat(filename, &fileinfo) &&
-       (fileinfo.st_size - sizeof(ppdsync) % sizeof(ppd_rec_t)) == 0 &&
+       ((fileinfo.st_size - sizeof(ppdsync)) % sizeof(ppd_rec_t)) == 0 &&
        (NumPPDs = (fileinfo.st_size - sizeof(ppdsync)) /
                   sizeof(ppd_rec_t)) > 0)
     {
@@ -740,12 +748,46 @@ list_ppds(int        request_id,  /* I - Request ID */
   * Send IPP attributes...
   */
 
-  num_options = cupsParseOptions(opt, 0, &options);
-  requested   = cupsGetOption("requested-attributes", num_options, options);
-  make        = cupsGetOption("ppd-make", num_options, options);
+  num_options    = cupsParseOptions(opt, 0, &options);
+  requested      = cupsGetOption("requested-attributes", num_options, options);
+  device_id      = cupsGetOption("ppd-device-id", num_options, options);
+  language       = cupsGetOption("ppd-natural-language", num_options, options);
+  make           = cupsGetOption("ppd-make", num_options, options);
+  make_and_model = cupsGetOption("ppd-make-and-model", num_options, options);
+  product        = cupsGetOption("ppd-product", num_options, options);
+  psversion      = cupsGetOption("ppd-psversion", num_options, options);
+
+  if (make_and_model)
+    mam_len = strlen(make_and_model);
+  else
+    mam_len = 0;
 
-  fprintf(stderr, "DEBUG: [cups-driverd] requested=\"%s\"\n",
-          requested ? requested : "(nil)");
+  if (device_id)
+    device_id_len = strlen(device_id);
+  else
+    device_id_len = 0;
+
+  if (requested)
+    fprintf(stderr, "DEBUG: [cups-driverd] requested-attributes=\"%s\"\n",
+           requested);
+  if (device_id)
+    fprintf(stderr, "DEBUG: [cups-driverd] ppd-device-id=\"%s\"\n",
+           device_id);
+  if (language)
+    fprintf(stderr, "DEBUG: [cups-driverd] ppd-natural-language=\"%s\"\n",
+           language);
+  if (make)
+    fprintf(stderr, "DEBUG: [cups-driverd] ppd-make=\"%s\"\n",
+           make);
+  if (make_and_model)
+    fprintf(stderr, "DEBUG: [cups-driverd] ppd-make-and-model=\"%s\"\n",
+           make_and_model);
+  if (product)
+    fprintf(stderr, "DEBUG: [cups-driverd] ppd-product=\"%s\"\n",
+           product);
+  if (psversion)
+    fprintf(stderr, "DEBUG: [cups-driverd] ppd-psversion=\"%s\"\n",
+           psversion);
 
   if (!requested || strstr(requested, "all"))
   {
@@ -772,10 +814,7 @@ list_ppds(int        request_id,   /* I - Request ID */
 
   puts("Content-Type: application/ipp\n");
 
-  cupsdSendIPPHeader(IPP_OK, request_id);
-  cupsdSendIPPGroup(IPP_TAG_OPERATION);
-  cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
-  cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+  sent_header = 0;
 
   if (limit <= 0 || limit > NumPPDs)
     count = NumPPDs;
@@ -783,79 +822,144 @@ list_ppds(int        request_id, /* I - Request ID */
     count = limit;
 
   for (i = NumPPDs, ppd = PPDs; count > 0 && i > 0; i --, ppd ++)
-    if (!make || !strcasecmp(ppd->record.make, make))
+  {
+   /*
+    * Filter PPDs based on make, model, or device ID...
+    */
+
+    if (device_id && strncasecmp(ppd->record.device_id, device_id,
+                                 device_id_len))
+      continue;                                /* TODO: implement smart compare */
+
+    if (language)
     {
-     /*
-      * Send this PPD...
-      */
+      for (j = 0; j < PPD_MAX_LANG; j ++)
+       if (!ppd->record.languages[j][0] ||
+           !strcasecmp(ppd->record.languages[j], language))
+         break;
 
-      fprintf(stderr, "DEBUG: [cups-driverd] Sending %s (%s)...\n",
-              ppd->record.name, ppd->record.make_and_model);
+      if (j >= PPD_MAX_LANG || !ppd->record.languages[j][0])
+       continue;
+    }
 
-      count --;
+    if (make && strcasecmp(ppd->record.make, make))
+      continue;
 
-      cupsdSendIPPGroup(IPP_TAG_PRINTER);
+    if (make_and_model && strncasecmp(ppd->record.make_and_model,
+                                      make_and_model, mam_len))
+      continue;
 
-      if (send_name)
-        cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name);
+    if (product)
+    {
+      for (j = 0; j < PPD_MAX_PROD; j ++)
+       if (!ppd->record.products[j][0] ||
+           !strcasecmp(ppd->record.products[j], product))
+         break;
 
-      if (send_natural_language)
-      {
-        cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language",
-                          ppd->record.languages[0]);
+      if (j >= PPD_MAX_PROD || !ppd->record.products[j][0])
+       continue;
+    }
 
-        for (j = 1; j < PPD_MAX_LANG && ppd->record.languages[j][0]; j ++)
-         cupsdSendIPPString(IPP_TAG_LANGUAGE, "", ppd->record.languages[j]);
-      }
+    if (psversion)
+    {
+      for (j = 0; j < PPD_MAX_VERS; j ++)
+       if (!ppd->record.psversions[j][0] ||
+           !strcasecmp(ppd->record.psversions[j], psversion))
+         break;
 
-      if (send_make)
-        cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make);
+      if (j >= PPD_MAX_VERS || !ppd->record.psversions[j][0])
+       continue;
+    }
 
-      if (send_make_and_model)
-        cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model",
-                          ppd->record.make_and_model);
+   /*
+    * Send this PPD...
+    */
 
-      if (send_device_id)
-        cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id",
-                          ppd->record.device_id);
+    if (!sent_header)
+    {
+      sent_header = 1;
 
-      if (send_product)
-      {
-        cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product",
-                          ppd->record.products[0]);
+      cupsdSendIPPHeader(IPP_OK, request_id);
+      cupsdSendIPPGroup(IPP_TAG_OPERATION);
+      cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+      cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+    }
 
-        for (j = 1; j < PPD_MAX_PROD && ppd->record.products[j][0]; j ++)
-         cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.products[j]);
-      }
+    fprintf(stderr, "DEBUG: [cups-driverd] Sending %s (%s)...\n",
+           ppd->record.name, ppd->record.make_and_model);
 
-      if (send_psversion)
-      {
-        cupsdSendIPPString(IPP_TAG_TEXT, "ppd-psversion",
-                          ppd->record.psversions[0]);
+    count --;
 
-        for (j = 1; j < PPD_MAX_VERS && ppd->record.psversions[j][0]; j ++)
-         cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.psversions[j]);
-      }
+    cupsdSendIPPGroup(IPP_TAG_PRINTER);
 
-     /*
-      * If we have only requested the ppd-make attribute, then skip
-      * the remaining PPDs with this make...
-      */
+    if (send_name)
+      cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name);
 
-      if (requested && !strcmp(requested, "ppd-make"))
-      {
-        const char     *this_make;     /* This ppd-make */
+    if (send_natural_language)
+    {
+      cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language",
+                        ppd->record.languages[0]);
+
+      for (j = 1; j < PPD_MAX_LANG && ppd->record.languages[j][0]; j ++)
+       cupsdSendIPPString(IPP_TAG_LANGUAGE, "", ppd->record.languages[j]);
+    }
 
+    if (send_make)
+      cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make);
 
-        for (this_make = ppd->record.make, i --, ppd ++; i > 0; i --, ppd ++)
-         if (strcasecmp(this_make, ppd->record.make))
-           break;
+    if (send_make_and_model)
+      cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model",
+                        ppd->record.make_and_model);
 
-        i ++;
-       ppd --;
-      }
+    if (send_device_id)
+      cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id",
+                        ppd->record.device_id);
+
+    if (send_product)
+    {
+      cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product",
+                        ppd->record.products[0]);
+
+      for (j = 1; j < PPD_MAX_PROD && ppd->record.products[j][0]; j ++)
+       cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.products[j]);
+    }
+
+    if (send_psversion)
+    {
+      cupsdSendIPPString(IPP_TAG_TEXT, "ppd-psversion",
+                        ppd->record.psversions[0]);
+
+      for (j = 1; j < PPD_MAX_VERS && ppd->record.psversions[j][0]; j ++)
+       cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.psversions[j]);
     }
 
+   /*
+    * If we have only requested the ppd-make attribute, then skip
+    * the remaining PPDs with this make...
+    */
+
+    if (requested && !strcmp(requested, "ppd-make"))
+    {
+      const char       *this_make;     /* This ppd-make */
+
+
+      for (this_make = ppd->record.make, i --, ppd ++; i > 0; i --, ppd ++)
+       if (strcasecmp(this_make, ppd->record.make))
+         break;
+
+      i ++;
+      ppd --;
+    }
+  }
+
+  if (!sent_header)
+  {
+    cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
+    cupsdSendIPPGroup(IPP_TAG_OPERATION);
+    cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+    cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+  }
+
   cupsdSendIPPTrailer();
 
   return (0);
@@ -1049,7 +1153,7 @@ load_ppds(const char *d,          /* I - Actual directory */
       }
       else if (!strncasecmp(line, "*PSVersion:", 11))
       {
-       sscanf(line, "%*[^\"]\"(%255[^)]", psversion);
+       sscanf(line, "%*[^\"]\"%255[^\"]", psversion);
        cupsArrayAdd(psversions, strdup(psversion));
       }
       else if (!strncasecmp(line, "*cupsLanguages:", 15))
index c2cd1c8cbdd3a96d0e71a41a6090269786a0498d..bbc3cc102dae07b59857e34507af8993ab415254 100644 (file)
@@ -6062,13 +6062,26 @@ get_ppds(cupsd_client_t *con)           /* I - Client connection */
 {
   http_status_t                status;         /* Policy status */
   ipp_attribute_t      *limit,         /* Limit attribute */
+                       *device,        /* ppd-device-id attribute */
+                       *language,      /* ppd-natural-language attribute */
                        *make,          /* ppd-make attribute */
+                       *model,         /* ppd-make-and-model attribute */
+                       *product,       /* ppd-product attribute */
+                       *psversion,     /* ppd-psverion attribute */
                        *requested;     /* requested-attributes attribute */
   char                 command[1024],  /* cups-driverd command */
                        options[1024],  /* Options to pass to command */
-                       requested_str[256],
+                       device_str[256],/* Escaped ppd-device-id string */
+                       language_str[256],
+                                       /* Escaped ppd-natural-language string */
+                       make_str[256],  /* Escaped ppd-make string */
+                       model_str[256], /* Escaped ppd-make-and-model string */
+                       product_str[256],
+                                       /* Escaped ppd-product string */
+                       psversion_str[256],
+                                       /* Escaped ppd-psversion string */
+                       requested_str[256];
                                        /* String for requested attributes */
-                       make_str[256];  /* Escaped ppd-make string */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd);
@@ -6088,7 +6101,14 @@ get_ppds(cupsd_client_t *con)            /* I - Client connection */
   */
 
   limit     = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER);
+  device    = ippFindAttribute(con->request, "ppd-device-id", IPP_TAG_TEXT);
+  language  = ippFindAttribute(con->request, "ppd-natural-language",
+                               IPP_TAG_LANGUAGE);
   make      = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT);
+  model     = ippFindAttribute(con->request, "ppd-make-and-model",
+                               IPP_TAG_TEXT);
+  product   = ippFindAttribute(con->request, "ppd-product", IPP_TAG_TEXT);
+  psversion = ippFindAttribute(con->request, "ppd-psversion", IPP_TAG_TEXT);
   requested = ippFindAttribute(con->request, "requested-attributes",
                                IPP_TAG_KEYWORD);
 
@@ -6097,16 +6117,47 @@ get_ppds(cupsd_client_t *con)           /* I - Client connection */
   else
     strlcpy(requested_str, "requested-attributes=all", sizeof(requested_str));
 
+  if (device)
+    url_encode_attr(device, device_str, sizeof(device_str));
+  else
+    device_str[0] = '\0';
+
+  if (language)
+    url_encode_attr(language, language_str, sizeof(language_str));
+  else
+    language_str[0] = '\0';
+
   if (make)
     url_encode_attr(make, make_str, sizeof(make_str));
   else
     make_str[0] = '\0';
 
+  if (model)
+    url_encode_attr(model, model_str, sizeof(model_str));
+  else
+    model_str[0] = '\0';
+
+  if (product)
+    url_encode_attr(product, product_str, sizeof(product_str));
+  else
+    product_str[0] = '\0';
+
+  if (psversion)
+    url_encode_attr(psversion, psversion_str, sizeof(psversion_str));
+  else
+    psversion_str[0] = '\0';
+
   snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin);
-  snprintf(options, sizeof(options), "list+%d+%d+%s%s%s",
+  snprintf(options, sizeof(options), "list+%d+%d+%s%s%s%s%s%s%s%s%s%s%s%s%s",
            con->request->request.op.request_id,
            limit ? limit->values[0].integer : 0,
-          requested_str, make ? "%20" : "", make_str);
+          requested_str,
+          device ? "%20" : "", device_str,
+          language ? "%20" : "", language_str,
+          make ? "%20" : "", make_str,
+          model ? "%20" : "", model_str,
+          product ? "%20" : "", product_str,
+          psversion ? "%20" : "", psversion_str);
 
   if (cupsdSendCommand(con, command, options, 0))
   {
diff --git a/test/get-ppds-language.test b/test/get-ppds-language.test
new file mode 100644 (file)
index 0000000..2ed0118
--- /dev/null
@@ -0,0 +1,21 @@
+# Get PPD files using CUPS-Get-PPDs and language
+{
+       # The name of the test...
+       NAME "Get PPD files using CUPS-Get-PPDs and language"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-PPDs
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR uri printer-uri $uri
+       ATTR language ppd-natural-language $ENV[language]
+
+       # What statuses are OK?
+       STATUS successful-ok
+}
diff --git a/test/get-ppds-make-and-model.test b/test/get-ppds-make-and-model.test
new file mode 100644 (file)
index 0000000..c57b147
--- /dev/null
@@ -0,0 +1,21 @@
+# Get PPD files using CUPS-Get-PPDs and model
+{
+       # The name of the test...
+       NAME "Get PPD files using CUPS-Get-PPDs and model"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-PPDs
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR uri printer-uri $uri
+       ATTR text ppd-make-and-model $ENV[model]
+
+       # What statuses are OK?
+       STATUS successful-ok
+}
diff --git a/test/get-ppds-make.test b/test/get-ppds-make.test
new file mode 100644 (file)
index 0000000..ac3f736
--- /dev/null
@@ -0,0 +1,21 @@
+# Get PPD files using CUPS-Get-PPDs and make
+{
+       # The name of the test...
+       NAME "Get PPD files using CUPS-Get-PPDs and make"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-PPDs
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR uri printer-uri $uri
+       ATTR text ppd-make $ENV[make]
+
+       # What statuses are OK?
+       STATUS successful-ok
+}
diff --git a/test/get-ppds-product.test b/test/get-ppds-product.test
new file mode 100644 (file)
index 0000000..b0535f7
--- /dev/null
@@ -0,0 +1,21 @@
+# Get PPD files using CUPS-Get-PPDs and Product
+{
+       # The name of the test...
+       NAME "Get PPD files using CUPS-Get-PPDs and Product"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-PPDs
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR uri printer-uri $uri
+       ATTR text ppd-product $ENV[product]
+
+       # What statuses are OK?
+       STATUS successful-ok
+}
diff --git a/test/get-ppds-psversion.test b/test/get-ppds-psversion.test
new file mode 100644 (file)
index 0000000..b7f93b6
--- /dev/null
@@ -0,0 +1,21 @@
+# Get PPD files using CUPS-Get-PPDs and PSVersion
+{
+       # The name of the test...
+       NAME "Get PPD files using CUPS-Get-PPDs and PSVersion"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-PPDs
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR uri printer-uri $uri
+       ATTR text ppd-psversion $ENV[psversion]
+
+       # What statuses are OK?
+       STATUS successful-ok
+}