]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Support the 'everywhere' model in cupsd (Issue #201)
authorMichael R Sweet <msweet@msweet.org>
Wed, 23 Jun 2021 21:45:40 +0000 (17:45 -0400)
committerMichael R Sweet <msweet@msweet.org>
Wed, 23 Jun 2021 21:45:40 +0000 (17:45 -0400)
CHANGES.md
cgi-bin/admin.c
scheduler/ipp.c
systemv/lpadmin.c

index 5b67d817133ec9c8ef4e988bb36840ce5a34a641..f7aef3c69d2412c705d29d6230ed7f8790a39d57 100644 (file)
@@ -48,6 +48,7 @@ CUPS v2.4rc1 (Pending)
   and values are retained on an error (Issue #195)
 - Hardened `ippReadIO` to prevent invalid IPP messages from being propagated
   (Issue #195, Issue #196)
+- The scheduler now supports the "everywhere" model directly (Issue #201)
 - Documentation fixes (Issue #92, Issue #163, Issue #177, Issue #184)
 - Localization updates (Issue #123, Issue #129, Issue #134, Issue #146,
   Issue #164)
index c6489389f50f4bb33f0a9f4c654b22e3e79bc4c5..63b956e6280197ba8fa401d4e55d9ab9106a3f89 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Administration CGI for CUPS.
  *
- * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 2021 by OpenPrinting
+ * Copyright © 2007-2021 by Apple Inc.
  * Copyright © 1997-2007 by Easy Software Products.
  *
  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
@@ -50,7 +51,6 @@ static void   do_set_sharing(http_t *http);
 static char    *get_option_value(ppd_file_t *ppd, const char *name,
                                  char *buffer, size_t bufsize);
 static double  get_points(double number, const char *uval);
-static char    *get_printer_ppd(const char *uri, char *buffer, size_t bufsize);
 
 
 /*
@@ -1125,9 +1125,7 @@ do_am_printer(http_t *http,               /* I - HTTP connection */
     if (!file)
     {
       var = cgiGetVariable("PPD_NAME");
-      if (!strcmp(var, "everywhere"))
-        get_printer_ppd(cgiGetVariable("DEVICE_URI"), evefile, sizeof(evefile));
-      else if (strcmp(var, "__no_change__"))
+      if (strcmp(var, "__no_change__"))
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
                     NULL, var);
     }
@@ -3735,82 +3733,3 @@ get_points(double     number,            /* I - Original number */
   else                                 /* Points */
     return (number);
 }
-
-
-/*
- * 'get_printer_ppd()' - Get an IPP Everywhere PPD file for the given URI.
- */
-
-static char *                          /* O - Filename or NULL */
-get_printer_ppd(const char *uri,       /* I - Printer URI */
-                char       *buffer,    /* I - Filename buffer */
-               size_t     bufsize)     /* I - Size of filename buffer */
-{
-  http_t       *http;                  /* Connection to printer */
-  ipp_t                *request,               /* Get-Printer-Attributes request */
-               *response;              /* Get-Printer-Attributes response */
-  char         resolved[1024],         /* Resolved URI */
-               scheme[32],             /* URI scheme */
-               userpass[256],          /* Username:password */
-               host[256],              /* Hostname */
-               resource[256];          /* Resource path */
-  int          port;                   /* Port number */
-  static const char * const pattrs[] = /* Printer attributes we need */
-  {
-    "all",
-    "media-col-database"
-  };
-
-
- /*
-  * Connect to the printer...
-  */
-
-  if (strstr(uri, "._tcp"))
-  {
-   /*
-    * Resolve URI...
-    */
-
-    if (!_httpResolveURI(uri, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL))
-    {
-      fprintf(stderr, "ERROR: Unable to resolve \"%s\".\n", uri);
-      return (NULL);
-    }
-
-    uri = resolved;
-  }
-
-  if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
-  {
-    fprintf(stderr, "ERROR: Bad printer URI \"%s\".\n", uri);
-    return (NULL);
-  }
-
-  http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
-  if (!http)
-  {
-    fprintf(stderr, "ERROR: Unable to connect to \"%s:%d\": %s\n", host, port, cupsLastErrorString());
-    return (NULL);
-  }
-
- /*
-  * Send a Get-Printer-Attributes request...
-  */
-
-  request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes",  (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);
-  response = cupsDoRequest(http, request, resource);
-
-  if (!_ppdCreateFromIPP(buffer, bufsize, response))
-    fprintf(stderr, "ERROR: Unable to create PPD file: %s\n", strerror(errno));
-
-  ippDelete(response);
-  httpClose(http);
-
-  if (buffer[0])
-    return (buffer);
-  else
-    return (NULL);
-}
index 2104d46bbcda63e6c5d034898ba7338695637ac4..dd5172c668b6745594585d8d65c20676f24b079f 100644 (file)
@@ -2,7 +2,7 @@
  * IPP routines for the CUPS scheduler.
  *
  * Copyright © 2020-2021 by OpenPrinting
- * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 2007-2021 by Apple Inc.
  * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
  *
  * This file contains Kerberos support code, copyright 2006 by
@@ -73,6 +73,7 @@ static void   copy_subscription_attrs(cupsd_client_t *con,
                                        cups_array_t *ra,
                                        cups_array_t *exclude);
 static void    create_job(cupsd_client_t *con, ipp_attribute_t *uri);
+static void    *create_local_bg_thread(cupsd_printer_t *printer);
 static void    create_local_printer(cupsd_client_t *con);
 static cups_array_t *create_requested_array(ipp_t *request);
 static void    create_subscriptions(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -2692,7 +2693,22 @@ add_printer(cupsd_client_t  *con,        /* I - Client connection */
     need_restart_job = 1;
     changed_driver   = 1;
 
-    if (!strcmp(ppd_name, "raw"))
+    if (!strcmp(ppd_name, "everywhere"))
+    {
+      // Create IPP Everywhere PPD...
+      if (!printer->device_uri || (strncmp(printer->device_uri, "dnssd://", 8) && strncmp(printer->device_uri, "ipp://", 6) && strncmp(printer->device_uri, "ipps://", 7) && strncmp(printer->device_uri, "ippusb://", 9)))
+      {
+       send_ipp_status(con, IPP_INTERNAL_ERROR, _("IPP Everywhere driver requires an IPP connection."));
+       if (!modify)
+         cupsdDeletePrinter(printer, 0);
+
+       return;
+      }
+
+      // Run a background thread to create the PPD...
+      _cupsThreadCreate((_cups_thread_func_t)create_local_bg_thread, printer);
+    }
+    else if (!strcmp(ppd_name, "raw"))
     {
      /*
       * Raw driver, remove any existing PPD file.
index 00d0fc7c7215465e56c155e15ea2927b31150566..355dc8391c851710af7c78ec1b39054b355ae585 100644 (file)
@@ -2,7 +2,7 @@
  * "lpadmin" command for CUPS.
  *
  * Copyright © 2021 by OpenPrinting.
- * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 2007-2021 by Apple Inc.
  * Copyright © 1997-2006 by Easy Software Products.
  *
  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
@@ -29,7 +29,6 @@ static int            delete_printer_from_class(http_t *http, char *printer,
 static int             delete_printer_option(http_t *http, char *printer,
                                              char *option);
 static int             enable_printer(http_t *http, char *printer);
-static char            *get_printer_ppd(const char *uri, char *buffer, size_t bufsize, int *num_options, cups_option_t **options);
 static cups_ptype_t    get_printer_type(http_t *http, char *printer, char *uri,
                                         size_t urisize);
 static int             set_printer_options(http_t *http, char *printer,
@@ -626,14 +625,7 @@ main(int  argc,                            /* I - Number of command-line arguments */
     return (1);
 #endif /* __APPLE__ */
   }
-  else if (ppd_name && !strcmp(ppd_name, "everywhere") && device_uri)
-  {
-    if ((file = get_printer_ppd(device_uri, evefile, sizeof(evefile), &num_options, &options)) == NULL)
-      return (1);
-
-    num_options = cupsRemoveOption("ppd-name", num_options, &options);
-  }
-  else if (ppd_name || file)
+  else if ((ppd_name && strcmp(ppd_name, "everywhere")) || file)
   {
     _cupsLangPuts(stderr, _("lpadmin: Printer drivers are deprecated and will stop working in a future version of CUPS."));
   }
@@ -1157,105 +1149,6 @@ enable_printer(http_t *http,            /* I - Server connection */
 }
 
 
-/*
- * 'get_printer_ppd()' - Get an IPP Everywhere PPD file for the given URI.
- */
-
-static char *                          /* O  - Filename or NULL */
-get_printer_ppd(
-    const char    *uri,                        /* I  - Printer URI */
-    char          *buffer,             /* I  - Filename buffer */
-    size_t        bufsize,             /* I  - Size of filename buffer */
-    int           *num_options,                /* IO - Number of options */
-    cups_option_t **options)           /* IO - Options */
-{
-  http_t       *http;                  /* Connection to printer */
-  ipp_t                *request,               /* Get-Printer-Attributes request */
-               *response;              /* Get-Printer-Attributes response */
-  ipp_attribute_t *attr;               /* Attribute from response */
-  char         resolved[1024],         /* Resolved URI */
-               scheme[32],             /* URI scheme */
-               userpass[256],          /* Username:password */
-               host[256],              /* Hostname */
-               resource[256];          /* Resource path */
-  int          port;                   /* Port number */
-  static const char * const pattrs[] = /* Attributes to use */
-  {
-    "all",
-    "media-col-database"
-  };
-
-
- /*
-  * Connect to the printer...
-  */
-
-  if (strstr(uri, "._tcp"))
-  {
-   /*
-    * Resolve URI...
-    */
-
-    if (!_httpResolveURI(uri, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL))
-    {
-      _cupsLangPrintf(stderr, _("%s: Unable to resolve \"%s\"."), "lpadmin", uri);
-      return (NULL);
-    }
-
-    uri = resolved;
-  }
-
-  if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
-  {
-    _cupsLangPrintf(stderr, _("%s: Bad printer URI \"%s\"."), "lpadmin", uri);
-    return (NULL);
-  }
-
-  http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
-  if (!http)
-  {
-    _cupsLangPrintf(stderr, _("%s: Unable to connect to \"%s:%d\": %s"), "lpadmin", host, port, cupsLastErrorString());
-    return (NULL);
-  }
-
- /*
-  * Send a Get-Printer-Attributes request...
-  */
-
-  request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);
-  response = cupsDoRequest(http, request, resource);
-
-  if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE)
-  {
-    _cupsLangPrintf(stderr, _("%s: Unable to query printer: %s"), "lpadmin", cupsLastErrorString());
-    buffer[0] = '\0';
-  }
-  else if (_ppdCreateFromIPP(buffer, bufsize, response))
-  {
-    if (!cupsGetOption("printer-geo-location", *num_options, *options) && (attr = ippFindAttribute(response, "printer-geo-location", IPP_TAG_URI)) != NULL)
-      *num_options = cupsAddOption("printer-geo-location", ippGetString(attr, 0, NULL), *num_options, options);
-
-    if (!cupsGetOption("printer-info", *num_options, *options) && (attr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT)) != NULL)
-      *num_options = cupsAddOption("printer-info", ippGetString(attr, 0, NULL), *num_options, options);
-
-    if (!cupsGetOption("printer-location", *num_options, *options) && (attr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != NULL)
-      *num_options = cupsAddOption("printer-location", ippGetString(attr, 0, NULL), *num_options, options);
-  }
-  else
-    _cupsLangPrintf(stderr, _("%s: Unable to create PPD file: %s"), "lpadmin", strerror(errno));
-
-  ippDelete(response);
-  httpClose(http);
-
-  if (buffer[0])
-    return (buffer);
-  else
-    return (NULL);
-}
-
-
 /*
  * 'get_printer_type()' - Determine the printer type and URI.
  */