]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
implicitclass: If IPP poll of printer fails, use PPD file for capabilities
authorTill Kamppeter <till.kamppeter@gmail.com>
Sun, 6 Feb 2022 01:34:14 +0000 (22:34 -0300)
committerTill Kamppeter <till.kamppeter@gmail.com>
Sun, 6 Feb 2022 01:34:14 +0000 (22:34 -0300)
Member printers of a cups-browsed printer cluster are always IPP
printers, in most cases driverless IPP (IPP 2.x) printers and here a
get-printer-attributes IPP request gets all needed capability info
from the destination printer in order to run the filters to turn the
PDF input into the printer's data format.

If the destination printer is a legacy IPP (IPP 1.x) printer, our
get-printer-attributes IPP request fails (we accept only IPP 2.x here)
and then we fall back to using the PPD file. The PPD file is the
cluster's PPD, not the printer's, but all settings are supported by
our destination printer (otherwise it would not have gotten selected).

This way we recover support for legacy IPP printers which got dropped
with the recent commits to switch over to use filter functions instead
of external filter executables.

backend/implicitclass.c

index a7ff3a7b4722f9fc49124e1ff8a4e71c6d3d4b88..24dd5a021b3f0bd169a60fafb4e8e2c92ef9a861 100644 (file)
@@ -306,17 +306,44 @@ main(int  argc,                           /* I - Number of command-line args */
       filter_data.job_title = title;
       filter_data.copies = atoi(argv[4]);
       filter_data.job_attrs = NULL;        /* We use command line options */
-      filter_data.printer_attrs =
-       get_printer_attributes4(printer_uri, NULL, 0, NULL, 0, 1, 0);
+      if ((filter_data.printer_attrs =
+          get_printer_attributes4(printer_uri, NULL, 0, NULL, 0, 1, 0)) !=
+         NULL)
                                            /* Poll the printer attributes from
                                              the printer */
+       filter_data.ppdfile = NULL;        /* We have successfully polled
+                                             the IPP attributes from the
+                                             printer. This is the most
+                                             precise printer capability info.
+                                             As the queue's PPD is only
+                                             for the cluster we prefer the
+                                             IPP attributes */
+      else
+       filter_data.ppdfile = getenv("PPD");/*The polling of the printer's
+                                             IPP attribute failed, meaning
+                                             that it is most probably not a
+                                             driverless IPP printers (IPP 2.x)
+                                             but a legacy IPP printer (IPP
+                                             1.x) which usually has
+                                             unsufficient capability info.
+                                             Therefore we fall back to the
+                                             PPD file here which contains
+                                             some info from the printer's
+                                             DNS-SD record. */
+      if (filter_data.ppdfile)
+       filter_data.ppd = ppdOpenFile(filter_data.ppdfile);
+      else
+       filter_data.ppd = NULL;
+      if (filter_data.printer_attrs == NULL && filter_data.ppd == NULL)
+      {
+       ippDelete(response);
+       fprintf(stderr, "ERROR: Unable to get sufficient capability info of the destination printer.\n");
+       return (CUPS_BACKEND_FAILED);
+      }
+
       filter_data.num_options = num_options;
       filter_data.options = options;       /* Command line options from 5th
                                              arg */
-      filter_data.ppdfile = NULL;          /* We poll the IPP attributes from
-                                             printer as the queue's PPD is
-                                             for the cluster */
-      filter_data.ppd = NULL;
       filter_data.back_pipe[0] = -1;
       filter_data.back_pipe[1] = -1;
       filter_data.side_pipe[0] = -1;
@@ -355,14 +382,17 @@ main(int  argc,                           /* I - Number of command-line args */
       cupsArrayAdd(filter_chain, &ipp_in_chain);
 
       /* DEVICE_URI environment variable */
-      setenv("DEVICE_URI",printer_uri, 1);
+      setenv("DEVICE_URI", printer_uri, 1);
 
       /* FINAL_CONTENT_TYPE environment variable */
       setenv("FINAL_CONTENT_TYPE", document_format, 1);
 
       /* Mark the defaults and option settings in the PPD file */
-      ppdMarkDefaults(filter_data.ppd);
-      ppdMarkOptions(filter_data.ppd, num_options, options);
+      if (filter_data.ppd)
+      {
+       ppdMarkDefaults(filter_data.ppd);
+       ppdMarkOptions(filter_data.ppd, num_options, options);
+      }
 
       /* We call the IPP CUPS backend at the end of the chain, so we have
         no output */