]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/dest.c
More LGTM changes.
[thirdparty/cups.git] / cups / dest.c
index 7d08d78c7d3e3d6ae2e6f1ac48dee040bfcd013d..fd57d979461646440a818ee624c0feeb11e2bbd6 100644 (file)
@@ -1,10 +1,11 @@
 /*
  * User-defined destination (and option) support for CUPS.
  *
- * Copyright 2007-2018 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products.
+ * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products.
  *
- * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
@@ -12,6 +13,7 @@
  */
 
 #include "cups-private.h"
+#include "debug-internal.h"
 #include <sys/stat.h>
 
 #ifdef HAVE_NOTIFY_H
  */
 
 #ifdef __APPLE__
-#  if !TARGET_OS_IOS
+#  if HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
 #    include <SystemConfiguration/SystemConfiguration.h>
 #    define _CUPS_LOCATION_DEFAULTS 1
-#  endif /* !TARGET_OS_IOS */
+#  endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
 #  define kCUPSPrintingPrefs   CFSTR("org.cups.PrintingPrefs")
 #  define kDefaultPaperIDKey   CFSTR("DefaultPaperID")
 #  define kLastUsedPrintersKey CFSTR("LastUsedPrinters")
@@ -563,7 +565,7 @@ _cupsAppleSetUseLastPrinter(
 
 
 /*
- * 'cupsConnectDest()' - Open a conection to the destination.
+ * 'cupsConnectDest()' - Open a connection to the destination.
  *
  * Connect to the destination, returning a new @code http_t@ connection object
  * and optionally the resource path to use for the destination.  These calls
@@ -572,7 +574,7 @@ _cupsAppleSetUseLastPrinter(
  * returns 0.  The caller is responsible for calling @link httpClose@ on the
  * returned connection.
  *
- * Starting with CUPS 2.2.4, the caller can pass  @code CUPS_DEST_FLAGS_DEVICE@
+ * Starting with CUPS 2.2.4, the caller can pass @code CUPS_DEST_FLAGS_DEVICE@
  * for the "flags" argument to connect directly to the device associated with
  * the destination.  Otherwise, the connection is made to the CUPS scheduler
  * associated with the destination.
@@ -1094,20 +1096,23 @@ cupsGetDest(const char  *name,          /* I - Destination name or @code NULL@ for the d
  * '_cupsGetDestResource()' - Get the resource path and URI for a destination.
  */
 
-const char *                           /* O - Printer URI */
+const char *                           /* O - URI */
 _cupsGetDestResource(
     cups_dest_t *dest,                 /* I - Destination */
+    unsigned    flags,                 /* I - Destination flags */
     char        *resource,             /* I - Resource buffer */
     size_t      resourcesize)          /* I - Size of resource buffer */
 {
-  const char   *uri;                   /* Printer URI */
+  const char   *uri,                   /* URI */
+               *device_uri,            /* Device URI */
+               *printer_uri;           /* Printer URI */
   char         scheme[32],             /* URI scheme */
                userpass[256],          /* Username and password (unused) */
                hostname[256];          /* Hostname */
   int          port;                   /* Port number */
 
 
-  DEBUG_printf(("_cupsGetDestResource(dest=%p(%s), resource=%p, resourcesize=%d)", (void *)dest, dest->name, (void *)resource, (int)resourcesize));
+  DEBUG_printf(("_cupsGetDestResource(dest=%p(%s), flags=%u, resource=%p, resourcesize=%d)", (void *)dest, dest->name, flags, (void *)resource, (int)resourcesize));
 
  /*
   * Range check input...
@@ -1123,25 +1128,46 @@ _cupsGetDestResource(
   }
 
  /*
-  * Grab the printer URI...
+  * Grab the printer and device URIs...
   */
 
-  if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options)) == NULL)
+  device_uri  = cupsGetOption("device-uri", dest->num_options, dest->options);
+  printer_uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
+
+  DEBUG_printf(("1_cupsGetDestResource: device-uri=\"%s\", printer-uri-supported=\"%s\".", device_uri, printer_uri));
+
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+  if (((flags & CUPS_DEST_FLAGS_DEVICE) || !printer_uri) && strstr(device_uri, "._tcp"))
   {
-    if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL)
+    if ((device_uri = cups_dnssd_resolve(dest, device_uri, 5000, NULL, NULL, NULL)) != NULL)
     {
-#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
-      if (strstr(uri, "._tcp"))
-        uri = cups_dnssd_resolve(dest, uri, 5000, NULL, NULL, NULL);
-#endif /* HAVE_DNSSD || HAVE_AVAHI */
+      DEBUG_printf(("1_cupsGetDestResource: Resolved device-uri=\"%s\".", device_uri));
     }
-
-    if (uri)
+    else
     {
-      DEBUG_printf(("1_cupsGetDestResource: Resolved printer-uri-supported=\"%s\"", uri));
+      DEBUG_puts("1_cupsGetDestResource: Unable to resolve device.");
+
+      if (resource)
+       *resource = '\0';
 
-      uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, uri, resource, resourcesize);
+      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
+
+      return (NULL);
     }
+  }
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
+
+  if (flags & CUPS_DEST_FLAGS_DEVICE)
+  {
+    uri = device_uri;
+  }
+  else if (printer_uri)
+  {
+    uri = printer_uri;
+  }
+  else
+  {
+    uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, device_uri, resource, resourcesize);
 
     if (uri)
     {
@@ -1151,30 +1177,24 @@ _cupsGetDestResource(
 
       uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
     }
-    else
-    {
-      DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported found.");
+  }
 
-      if (resource)
-        *resource = '\0';
+  if (!uri)
+  {
+    DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported or device-uri found.");
 
-      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
+    if (resource)
+      *resource = '\0';
 
-      return (NULL);
-    }
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
+
+    return (NULL);
   }
-  else
+  else if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK)
   {
-    DEBUG_printf(("1_cupsGetDestResource: printer-uri-supported=\"%s\"", uri));
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad URI."), 1);
 
-    if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
-                        userpass, sizeof(userpass), hostname, sizeof(hostname),
-                        &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK)
-    {
-      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1);
-
-      return (NULL);
-    }
+    return (NULL);
   }
 
   DEBUG_printf(("1_cupsGetDestResource: resource=\"%s\"", resource));
@@ -1262,6 +1282,12 @@ cupsGetDestWithURI(const char *name,     /* I - Desired printer name or @code NULL@
       name = resource + 10;
       info = temp;
     }
+    else if (!strncmp(resource, "/ipp/print/", 11))
+    {
+      snprintf(temp, sizeof(temp), "%s @ %s", resource + 11, hostname);
+      name = resource + 11;
+      info = temp;
+    }
     else
     {
       name = hostname;
@@ -1722,7 +1748,6 @@ cupsGetNamedDest(http_t     *http,        /* I - Connection to server or @code CUPS_HTT
   cups_dest_t  *dest;                  /* Destination */
   char         filename[1024],         /* Path to lpoptions */
                defname[256];           /* Default printer name */
-  const char   *home = getenv("HOME"); /* Home directory */
   int          set_as_default = 0;     /* Set returned destination as default */
   ipp_op_t     op = IPP_OP_GET_PRINTER_ATTRIBUTES;
                                        /* IPP operation to get server ops */
@@ -1754,13 +1779,13 @@ cupsGetNamedDest(http_t     *http,      /* I - Connection to server or @code CUPS_HTT
       else
         instance = NULL;
     }
-    else if (home)
+    else if (cg->home)
     {
      /*
       * No default in the environment, try the user's lpoptions files...
       */
 
-      snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+      snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);
 
       dest_name = cups_get_default(filename, defname, sizeof(defname), &instance);
 
@@ -1866,9 +1891,9 @@ cupsGetNamedDest(http_t     *http,        /* I - Connection to server or @code CUPS_HTT
   snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
   cups_get_dests(filename, dest_name, instance, 0, 1, 1, &dest);
 
-  if (home)
+  if (cg->home)
   {
-    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);
 
     cups_get_dests(filename, dest_name, instance, 0, 1, 1, &dest);
   }
@@ -2006,9 +2031,6 @@ cupsSetDests2(http_t      *http,  /* I - Connection to server or @code CUPS_HTTP_
   cups_option_t        *option;                /* Current option */
   _ipp_option_t        *match;                 /* Matching attribute for option */
   FILE         *fp;                    /* File pointer */
-#ifndef WIN32
-  const char   *home;                  /* HOME environment variable */
-#endif /* WIN32 */
   char         filename[1024];         /* lpoptions file */
   int          num_temps;              /* Number of temporary destinations */
   cups_dest_t  *temps = NULL,          /* Temporary destinations */
@@ -2042,27 +2064,18 @@ cupsSetDests2(http_t      *http,        /* I - Connection to server or @code CUPS_HTTP_
 
   snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
 
-#ifndef WIN32
-  if (getuid())
+  if (cg->home)
   {
    /*
-    * Point to user defaults...
+    * Create ~/.cups subdirectory...
     */
 
-    if ((home = getenv("HOME")) != NULL)
-    {
-     /*
-      * Create ~/.cups subdirectory...
-      */
-
-      snprintf(filename, sizeof(filename), "%s/.cups", home);
-      if (access(filename, 0))
-        mkdir(filename, 0700);
+    snprintf(filename, sizeof(filename), "%s/.cups", cg->home);
+    if (access(filename, 0))
+      mkdir(filename, 0700);
 
-      snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
-    }
+    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);
   }
-#endif /* !WIN32 */
 
  /*
   * Try to open the file...
@@ -2074,7 +2087,7 @@ cupsSetDests2(http_t      *http,  /* I - Connection to server or @code CUPS_HTTP_
     return (-1);
   }
 
-#ifndef WIN32
+#ifndef _WIN32
  /*
   * Set the permissions to 0644 when saving to the /etc/cups/lpoptions
   * file...
@@ -2082,7 +2095,7 @@ cupsSetDests2(http_t      *http,  /* I - Connection to server or @code CUPS_HTTP_
 
   if (!getuid())
     fchmod(fileno(fp), 0644);
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
 
  /*
   * Write each printer; each line looks like:
@@ -3400,7 +3413,6 @@ cups_enum_dests(
 #else
   _cups_getdata_t data;                        /* Data for callback */
 #endif /* HAVE_DNSSD || HAVE_AVAHI */
-  const char   *home;                  /* HOME environment variable */
   char         filename[1024];         /* Local lpoptions file */
   _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals */
 
@@ -3449,13 +3461,23 @@ cups_enum_dests(
   snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
   data.num_dests = cups_get_dests(filename, NULL, NULL, 1, user_default != NULL, data.num_dests, &data.dests);
 
-  if ((home = getenv("HOME")) != NULL)
+  if (cg->home)
   {
-    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", cg->home);
 
     data.num_dests = cups_get_dests(filename, NULL, NULL, 1, user_default != NULL, data.num_dests, &data.dests);
   }
 
+  if (!data.def_name[0] && (user_dest = cupsGetDest(NULL, NULL, data.num_dests, data.dests)) != NULL)
+  {
+   /*
+    * Use an lpoptions default printer...
+    */
+
+    strlcpy(data.def_name, user_dest->name, sizeof(data.def_name));
+    data.def_instance = user_dest->instance;
+  }
+
  /*
   * Get ready to enumerate...
   */