]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
Check driverless support and set device-info accordingly 235/head
authorZdenek Dohnal <zdohnal@redhat.com>
Mon, 18 May 2020 11:43:57 +0000 (13:43 +0200)
committerZdenek Dohnal <zdohnal@redhat.com>
Mon, 18 May 2020 11:43:57 +0000 (13:43 +0200)
cupsfilters/ipp.c
cupsfilters/ipp.h
utils/driverless.c

index b9f7bebc593f8c8c8417bd410ec3b44b147aaa2b..aa3ae6cdc00db8046c200510342989729b75ef4f 100644 (file)
@@ -73,6 +73,20 @@ resolve_uri(const char *raw_uri)
 }
 
 #ifdef HAVE_CUPS_1_6
+/* Check how the driverless support is provided */
+int
+check_driverless_support(const char* uri)
+{
+  int support_status = DRVLESS_CHECKERR;
+  ipp_t *response = NULL;
+
+  response = get_printer_attributes3(NULL, uri, NULL, 0, NULL, 0, 1, &support_status);
+  if (response != NULL)
+    ippDelete(response);
+
+  return support_status;
+}
+
 /* Get attributes of a printer specified only by URI */
 ipp_t *
 get_printer_attributes(const char* raw_uri,
@@ -96,6 +110,23 @@ get_printer_attributes2(http_t *http_printer,
                        const char* const req_attrs[],
                        int req_attrs_size,
                        int debug)
+{
+  return get_printer_attributes3(http_printer, raw_uri, pattrs, pattrs_size,
+                                req_attrs, req_attrs_size, debug, NULL);
+}
+
+/* Get attributes of a printer specified by URI and under a given HTTP
+   connection, for example via a domain socket, and give info about used
+   fallbacks */
+ipp_t *
+get_printer_attributes3(http_t *http_printer,
+                       const char* raw_uri,
+                       const char* const pattrs[],
+                       int pattrs_size,
+                       const char* const req_attrs[],
+                       int req_attrs_size,
+                       int debug,
+                        int* driverless_info)
 {
   const char *uri;
   int have_http, uri_status, host_port, i = 0, total_attrs = 0, fallback,
@@ -139,6 +170,10 @@ get_printer_attributes2(http_t *http_printer,
     "uri-security-supported"
   };
 
+  /* Expect a device capable of standard IPP Everywhere*/
+  if (driverless_info != NULL)
+    *driverless_info = FULL_DRVLESS;
+
   /* Request printer properties via IPP, for example to
       - generate a PPD file for the printer
         (mainly driverless-capable printers)
@@ -282,12 +317,18 @@ get_printer_attributes2(http_t *http_printer,
     if (fallback == 1 + cap) {
       log_printf(get_printer_attributes_log,
                 "No further fallback available, giving up\n");
+      if (driverless_info != NULL)
+        *driverless_info = DRVLESS_CHECKERR;
     } else if (cap && fallback == 1) {
       log_printf(get_printer_attributes_log,
                 "The server doesn't support the standard IPP request, trying request without media-col\n");
+      if (driverless_info != NULL)
+        *driverless_info = DRVLESS_INCOMPLETEIPP;
     } else if (fallback == 0) {
       log_printf(get_printer_attributes_log,
                 "The server doesn't support IPP2.0 request, trying IPP1.1 request\n");
+      if (driverless_info != NULL)
+        *driverless_info = DRVLESS_IPP11;
     }
   }
 
index 8e2bc9ec6cc68bb35af27ccc821b76ce65ff75ae..6d19b18ce47f85da0345b5d640575b8796be4969 100644 (file)
@@ -42,6 +42,23 @@ char get_printer_attributes_log[LOGSIZE];
 
 const char     *resolve_uri(const char *raw_uri);
 #ifdef HAVE_CUPS_1_6
+                                /* Enum of possible driverless options */
+enum driverless_support_modes {
+  DRVLESS_CHECKERR,             /* Unable to get get-printer-attributes response*/
+  FULL_DRVLESS,                 /* Standard IPP Everywhere support, works with 'everywhere' model */
+  DRVLESS_IPP11,                /* Driverless support via IPP 1.1 request */
+  DRVLESS_INCOMPLETEIPP         /* Driverless support without media-col-database attribute */
+};
+
+/* Array of text strings explaining available driverless support */
+const char * driverless_support_strs[] = {
+  "driverless - cannot check driverless status",
+  "fully driverless",
+  "driverless via IPP 1.1",
+  "driverless with incomplete IPP request"
+};
+
+int check_driverless_support(const char* uri);
 ipp_t   *get_printer_attributes(const char* raw_uri,
                                const char* const pattrs[],
                                int pattrs_size,
@@ -55,6 +72,14 @@ ipp_t   *get_printer_attributes2(http_t *http_printer,
                                 const char* const req_attrs[],
                                 int req_attrs_size,
                                 int debug);
+ipp_t   *get_printer_attributes3(http_t *http_printer,
+                                const char* raw_uri,
+                                const char* const pattrs[],
+                                int pattrs_size,
+                                const char* const req_attrs[],
+                                int req_attrs_size,
+                                int debug,
+                                int* driverless_support);
 #endif /* HAVE_CUPS_1_6 */
 
 #  ifdef __cplusplus
index 1bfab121b474414c8e3e021753a2e7fafafcf98d..4ec1f1d94f9330aec30546b8d68e54a0645d12de 100644 (file)
@@ -46,7 +46,8 @@ static void           cancel_job(int sig);
 int
 list_printers (int mode)
 {
-  int          ippfind_pid,            /* Process ID for ippfind */
+  int          driverless_support = 0, /* Process ID for ippfind */
+               ippfind_pid,            /* Process ID of ippfind */
                post_proc_pid = 0,      /* Process ID of post-processing */
                post_proc_pipe[2],      /* Pipe to post-processing */
                wait_children,          /* Number of child processes left */
@@ -75,6 +76,7 @@ list_printers (int mode)
                 make[512],              /* Manufacturer */
                model[256],             /* Model */
                pdl[256],               /* PDL */
+               driverless_info[256],   /* Driverless info string */
                device_id[2048];        /* 1284 device ID */
 
   /* 
@@ -362,14 +364,34 @@ list_printers (int mode)
        else
          strncpy(make_and_model, model, sizeof(make_and_model) - 1);
 
+       /* Check which driverless support is available for the found device:
+        * 0) DRVLESS_CHECKERR - the device failed to respond
+        *    to any get-printer-attributes request versions available.
+        * 1) FULL_DRVLESS - the device responded correctly to IPP 2.0 get-printer-attributes request.
+        *    The device is compatible with CUPS 'everywhere' model.
+        * 2) DRVLESS_IPP11 - the device responded correctly to IPP 1.1 get-printer-attributes request.
+        * 3) DRVLESS_INCOMPLETEIPP - the device responded correctly to IPP get-printer-attributes request
+        *    without media-col-database attribute
+        *
+        * If we know which driverless support is available, we can divide which devices can be supported
+        * by CUPS temporary queues and which devices need cups-browsed to run.
+        */
+       driverless_support = check_driverless_support(service_uri);
+
+       if (driverless_support == DRVLESS_CHECKERR)
+         fprintf(stderr, "Failed to get info about driverless support.");
+
+       snprintf(driverless_info, 255, "%s", driverless_support_strs[driverless_support]);
+       driverless_info[255] = '\0';
+
        if (mode == 1)
          /* Call with "list" argument (PPD generator in list mode */
-         printf("\"driverless:%s\" en \"%s\" \"%s, driverless, cups-filters " VERSION
-                "\" \"%s\"\n", service_uri, make, make_and_model, device_id);
+         printf("\"driverless:%s\" en \"%s\" \"%s, %s, cups-filters " VERSION
+                "\" \"%s\"\n", service_uri, make, make_and_model, driverless_info, device_id);
        else
          /* Call without arguments and env variable "SOFTWARE" starting
             with "CUPS" (Backend in discovery mode) */
-         printf("network %s \"%s\" \"%s (driverless)\" \"%s\" \"\"\n", service_uri, make_and_model, make_and_model, device_id);
+         printf("network %s \"%s\" \"%s (%s)\" \"%s\" \"\"\n", service_uri, make_and_model, make_and_model, driverless_info, device_id);
 
       read_error:
        continue;