printing: Get PPD from original host if needed
authorMarek Kasik <mkasik@redhat.com>
Thu, 19 Sep 2019 16:35:23 +0000 (18:35 +0200)
committerMarek Kasik <mkasik@redhat.com>
Thu, 19 Sep 2019 16:35:23 +0000 (18:35 +0200)
Try to get PPD from original host if there is no PPD for remote printer
on current CUPS server.

modules/printbackends/gtkprintbackendcups.c
modules/printbackends/gtkprintercups.c
modules/printbackends/gtkprintercups.h

index 87cf6d3ce364865ba326fba1a4c4629cf7af590c..c0f6d98439cd0371e57345ce120b296af78a3204 100644 (file)
@@ -2458,13 +2458,25 @@ cups_create_printer (GtkPrintBackendCups *cups_backend,
   cups_printer->default_cover_before = g_strdup (info->default_cover_before);
   cups_printer->default_cover_after = g_strdup (info->default_cover_after);
   cups_printer->original_device_uri = g_strdup (info->original_device_uri);
+  cups_printer->hostname = g_strdup (hostname);
+  cups_printer->port = port;
+
+  if (cups_printer->original_device_uri != NULL)
+    {
+      httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->original_device_uri,
+                       method, sizeof (method),
+                       username, sizeof (username),
+                       hostname, sizeof (hostname),
+                       &port,
+                       resource, sizeof (resource));
+      cups_printer->original_hostname = g_strdup (hostname);
+      cups_printer->original_resource = g_strdup (resource);
+      cups_printer->original_port = port;
+    }
 
   if (info->default_number_up > 0)
     cups_printer->default_number_up = info->default_number_up;
 
-  cups_printer->hostname = g_strdup (hostname);
-  cups_printer->port = port;
-
   cups_printer->auth_info_required = g_strdupv (info->auth_info_required);
   g_strfreev (info->auth_info_required);
 
@@ -3760,10 +3772,47 @@ cups_request_ppd_cb (GtkPrintBackendCups *print_backend,
        ((gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_HTTP) &&
          (gtk_cups_result_get_error_status (result) == HTTP_NOT_FOUND))))
     {
-      cups_request_printer_info (GTK_PRINTER_CUPS (printer)->printer_uri,
-                                 GTK_PRINTER_CUPS (printer)->hostname,
-                                 GTK_PRINTER_CUPS (printer)->port,
-                                 GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer)));
+      GtkPrinterCups *cups_printer = GTK_PRINTER_CUPS (printer);
+
+      /* Try to get the PPD from original host if it is not
+       * available on current CUPS server.
+       */
+      if (!cups_printer->avahi_browsed &&
+          (gtk_cups_result_is_error (result) &&
+           ((gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_HTTP) &&
+            (gtk_cups_result_get_error_status (result) == HTTP_NOT_FOUND))) &&
+          cups_printer->remote &&
+          !cups_printer->request_original_uri &&
+          cups_printer->original_device_uri != NULL &&
+          (g_str_has_prefix (cups_printer->original_device_uri, "ipp://") ||
+           g_str_has_prefix (cups_printer->original_device_uri, "ipps://")))
+        {
+          cups_printer->request_original_uri = TRUE;
+
+          gtk_cups_connection_test_free (cups_printer->remote_cups_connection_test);
+          g_clear_handle_id (&cups_printer->get_remote_ppd_poll, g_source_remove);
+          cups_printer->get_remote_ppd_attempts = 0;
+
+          cups_printer->remote_cups_connection_test =
+            gtk_cups_connection_test_new (cups_printer->original_hostname,
+                                          cups_printer->original_port);
+
+          if (cups_request_ppd (printer))
+            {
+              cups_printer->get_remote_ppd_poll = g_timeout_add (50, (GSourceFunc) cups_request_ppd, printer);
+              g_source_set_name_by_id (cups_printer->get_remote_ppd_poll, "[gtk] cups_request_ppd");
+            }
+        }
+      else
+        {
+          if (cups_printer->request_original_uri)
+            cups_printer->request_original_uri = FALSE;
+
+          cups_request_printer_info (cups_printer->printer_uri,
+                                     cups_printer->hostname,
+                                     cups_printer->port,
+                                     GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer)));
+        }
 
       return;
     }
@@ -3784,6 +3833,8 @@ cups_request_ppd (GtkPrinter *printer)
   http_t *http;
   GetPPDData *data;
   int fd;
+  const gchar *hostname;
+  gint port;
 
   cups_printer = GTK_PRINTER_CUPS (printer);
 
@@ -3826,7 +3877,21 @@ cups_request_ppd (GtkPrinter *printer)
         }
     }
 
-  http = httpConnect2 (cups_printer->hostname, cups_printer->port,
+  if (cups_printer->request_original_uri)
+    {
+      hostname = cups_printer->original_hostname;
+      port = cups_printer->original_port;
+      resource = g_strdup_printf ("%s.ppd", cups_printer->original_resource);
+    }
+  else
+    {
+      hostname = cups_printer->hostname;
+      port = cups_printer->port;
+      resource = g_strdup_printf ("/printers/%s.ppd",
+                                  gtk_printer_cups_get_ppd_name (GTK_PRINTER_CUPS (printer)));
+    }
+
+  http = httpConnect2 (hostname, port,
                        NULL, AF_UNSPEC,
                        cupsEncryption (),
                        1, 30000, NULL);
@@ -3867,16 +3932,13 @@ cups_request_ppd (GtkPrinter *printer)
 
   data->printer = (GtkPrinterCups *) g_object_ref (printer);
 
-  resource = g_strdup_printf ("/printers/%s.ppd",
-                              gtk_printer_cups_get_ppd_name (GTK_PRINTER_CUPS (printer)));
-
   print_backend = gtk_printer_get_backend (printer);
 
   request = gtk_cups_request_new_with_username (data->http,
                                                 GTK_CUPS_GET,
                                                 0,
                                                 data->ppd_io,
-                                                cups_printer->hostname,
+                                                hostname,
                                                 resource,
                                                 GTK_PRINT_BACKEND_CUPS (print_backend)->username);
 
index d358d19eabb018e6924bb5d4060fd9656d805f71..e50dcf7d984705fdd3dadaa7aecfaf81565ac7ac 100644 (file)
@@ -105,6 +105,10 @@ gtk_printer_cups_init (GtkPrinterCups *printer)
   printer->state = 0;
   printer->hostname = NULL;
   printer->port = 0;
+  printer->original_hostname = NULL;
+  printer->original_resource = NULL;
+  printer->original_port = 0;
+  printer->request_original_uri = FALSE;
   printer->ppd_name = NULL;
   printer->ppd_file = NULL;
   printer->default_cover_before = NULL;
@@ -153,6 +157,8 @@ gtk_printer_cups_finalize (GObject *object)
   g_free (printer->original_device_uri);
   g_free (printer->printer_uri);
   g_free (printer->hostname);
+  g_free (printer->original_hostname);
+  g_free (printer->original_resource);
   g_free (printer->ppd_name);
   g_free (printer->default_cover_before);
   g_free (printer->default_cover_after);
index 7517e4b99fd6c0f9399cd2db5041b89bebf46977..02a440b4e5c8a0587587ce6b192e71a56fa17ba8 100644 (file)
@@ -53,6 +53,10 @@ struct _GtkPrinterCups
   gchar *hostname;
   gint port;
   gchar **auth_info_required;
+  gchar *original_hostname;
+  gchar *original_resource;
+  gint original_port;
+  gboolean request_original_uri; /* Request PPD from original host */
 
   ipp_pstate_t state;
   gboolean reading_ppd;