]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/ppd-util.c
Greatly simplify the man page handling.
[thirdparty/cups.git] / cups / ppd-util.c
index 52754916404738f977277f56a271fc5130938a18..5e43615eb77b856c406b99e384c45284dfb1bd16 100644 (file)
@@ -1,16 +1,11 @@
 /*
  * PPD utilities for CUPS.
  *
- * Copyright 2007-2015 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products.
  *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file.  If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * This file is subject to the Apple OS-Developed Software exception.
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
 
 #include "cups-private.h"
 #include "ppd-private.h"
+#include "debug-internal.h"
 #include <fcntl.h>
 #include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
+#if defined(_WIN32) || defined(__EMX__)
 #  include <io.h>
 #else
 #  include <unistd.h>
-#endif /* WIN32 || __EMX__ */
+#endif /* _WIN32 || __EMX__ */
 
 
 /*
@@ -80,7 +76,7 @@ cupsGetPPD(const char *name)          /* I - Destination name */
  * each call to @link cupsGetPPD@ or @code cupsGetPPD2@.  The caller "owns" the
  * file that is created and must @code unlink@ the returned filename.
  *
- * @since CUPS 1.1.21/OS X 10.4@
+ * @since CUPS 1.1.21/macOS 10.4@
  */
 
 const char *                           /* O - Filename for PPD file */
@@ -121,7 +117,7 @@ cupsGetPPD2(http_t     *http,               /* I - Connection to server or @code CUPS_HTTP_DE
  * For classes, @code cupsGetPPD3@ returns the PPD file for the first printer
  * in the class.
  *
- * @since CUPS 1.4/OS X 10.6@
+ * @since CUPS 1.4/macOS 10.6@
  */
 
 http_status_t                          /* O  - HTTP status */
@@ -155,23 +151,26 @@ cupsGetPPD3(http_t     *http,             /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
 
   if (!name)
   {
+    DEBUG_puts("2cupsGetPPD3: No printer name, returning NULL.");
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No printer name"), 1);
     return (HTTP_STATUS_NOT_ACCEPTABLE);
   }
 
   if (!modtime)
   {
+    DEBUG_puts("2cupsGetPPD3: No modtime, returning NULL.");
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No modification time"), 1);
     return (HTTP_STATUS_NOT_ACCEPTABLE);
   }
 
   if (!buffer || bufsize <= 1)
   {
+    DEBUG_puts("2cupsGetPPD3: No filename buffer, returning NULL.");
     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad filename buffer"), 1);
     return (HTTP_STATUS_NOT_ACCEPTABLE);
   }
 
-#ifndef WIN32
+#ifndef _WIN32
  /*
   * See if the PPD file is available locally...
   */
@@ -201,6 +200,8 @@ cupsGetPPD3(http_t     *http,               /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
 
       if (buffer[0])
       {
+        DEBUG_printf(("2cupsGetPPD3: Using filename \"%s\".", buffer));
+
         unlink(buffer);
 
        if (symlink(ppdname, buffer) && errno != EEXIST)
@@ -216,6 +217,28 @@ cupsGetPPD3(http_t     *http,              /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
         const char     *tmpdir;        /* TMPDIR environment variable */
        struct timeval  curtime;        /* Current time */
 
+
+#ifdef __APPLE__
+       /*
+       * On macOS and iOS, the TMPDIR environment variable is not always the
+       * best location to place temporary files due to sandboxing.  Instead,
+       * the confstr function should be called to get the proper per-user,
+       * per-process TMPDIR value.
+       */
+
+        char           tmppath[1024];  /* Temporary directory */
+
+       if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK))
+         tmpdir = NULL;
+
+       if (!tmpdir)
+       {
+         if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath)))
+           tmpdir = tmppath;
+         else
+           tmpdir = "/private/tmp";            /* This should never happen */
+       }
+#else
        /*
        * Previously we put root temporary files in the default CUPS temporary
        * directory under /var/spool/cups.  However, since the scheduler cleans
@@ -224,11 +247,10 @@ cupsGetPPD3(http_t     *http,             /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
        */
 
        if ((tmpdir = getenv("TMPDIR")) == NULL)
-#  ifdef __APPLE__
-         tmpdir = "/private/tmp";      /* /tmp is a symlink to /private/tmp */
-#  else
-          tmpdir = "/tmp";
-#  endif /* __APPLE__ */
+         tmpdir = "/tmp";
+#endif /* __APPLE__ */
+
+        DEBUG_printf(("2cupsGetPPD3: tmpdir=\"%s\".", tmpdir));
 
        /*
        * Make the temporary name using the specified directory...
@@ -259,12 +281,16 @@ cupsGetPPD3(http_t     *http,             /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
          if (!symlink(ppdname, buffer))
            break;
 
+         DEBUG_printf(("2cupsGetPPD3: Symlink \"%s\" to \"%s\" failed: %s", ppdname, buffer, strerror(errno)));
+
          tries ++;
        }
        while (tries < 1000);
 
         if (tries >= 1000)
        {
+         DEBUG_puts("2cupsGetPPD3: Unable to symlink after 1000 tries, returning error.");
+
           _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
 
          return (HTTP_STATUS_SERVER_ERROR);
@@ -272,30 +298,42 @@ cupsGetPPD3(http_t     *http,             /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
       }
 
       if (*modtime >= ppdinfo.st_mtime)
+      {
+        DEBUG_printf(("2cupsGetPPD3: Returning not-modified, filename=\"%s\".", buffer));
         return (HTTP_STATUS_NOT_MODIFIED);
+      }
       else
       {
+        DEBUG_printf(("2cupsGetPPD3: Returning ok, filename=\"%s\", modtime=%ld.", buffer, (long)ppdinfo.st_mtime));
         *modtime = ppdinfo.st_mtime;
        return (HTTP_STATUS_OK);
       }
     }
   }
-#endif /* !WIN32 */
+#endif /* !_WIN32 */
 
  /*
   * Try finding a printer URI for this printer...
   */
 
+  DEBUG_puts("2cupsGetPPD3: Unable to access local file, copying...");
+
   if (!http)
+  {
     if ((http = _cupsConnect()) == NULL)
+    {
+      DEBUG_puts("2cupsGetPPD3: Unable to connect to scheduler.");
       return (HTTP_STATUS_SERVICE_UNAVAILABLE);
+    }
+  }
 
-  if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port,
-                            resource, sizeof(resource), 0))
+  if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port, resource, sizeof(resource), 0))
+  {
+    DEBUG_puts("2cupsGetPPD3: Unable to get printer URI.");
     return (HTTP_STATUS_NOT_FOUND);
+  }
 
-  DEBUG_printf(("2cupsGetPPD3: Printer hostname=\"%s\", port=%d", hostname,
-                port));
+  DEBUG_printf(("2cupsGetPPD3: Printer hostname=\"%s\", port=%d", hostname, port));
 
   if (cupsServer()[0] == '/' && !_cups_strcasecmp(hostname, "localhost") && port == ippPort())
   {
@@ -339,7 +377,7 @@ cupsGetPPD3(http_t     *http,               /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
   else if ((http2 = httpConnect2(hostname, port, NULL, AF_UNSPEC,
                                 cupsEncryption(), 1, 30000, NULL)) == NULL)
   {
-    DEBUG_puts("1cupsGetPPD3: Unable to connect to server");
+    DEBUG_puts("2cupsGetPPD3: Unable to connect to server");
 
     return (HTTP_STATUS_SERVICE_UNAVAILABLE);
   }
@@ -411,7 +449,7 @@ cupsGetPPD3(http_t     *http,               /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
   * Return the PPD file...
   */
 
-  DEBUG_printf(("1cupsGetPPD3: Returning status %d", status));
+  DEBUG_printf(("2cupsGetPPD3: Returning status %d", status));
 
   return (status);
 }
@@ -429,7 +467,7 @@ cupsGetPPD3(http_t     *http,               /* I  - HTTP connection or @code CUPS_HTTP_DEFAUL
  * overwritten on the next call to @link cupsGetPPD@, @link cupsGetPPD2@,
  * or @link cupsGetServerPPD@.
  *
- * @since CUPS 1.3/OS X 10.5@
+ * @since CUPS 1.3/macOS 10.5@
  */
 
 char *                                 /* O - Name of PPD file or @code NULL@ on error */
@@ -511,23 +549,16 @@ cups_get_printer_uri(
     int        depth)                  /* I - Depth of query */
 {
   int          i;                      /* Looping var */
-  int          http_port;              /* Port number */
-  http_t       *http2;                 /* Alternate HTTP connection */
   ipp_t                *request,               /* IPP request */
                *response;              /* IPP response */
   ipp_attribute_t *attr;               /* Current attribute */
   char         uri[HTTP_MAX_URI],      /* printer-uri attribute */
                scheme[HTTP_MAX_URI],   /* Scheme name */
-               username[HTTP_MAX_URI], /* Username:password */
-               classname[255],         /* Temporary class name */
-               http_hostname[HTTP_MAX_HOST];
-                                       /* Hostname associated with connection */
+               username[HTTP_MAX_URI]; /* Username:password */
   static const char * const requested_attrs[] =
                {                       /* Requested attributes */
-                 "device-uri",
                  "member-uris",
-                 "printer-uri-supported",
-                 "printer-type"
+                 "printer-uri-supported"
                };
 
 
@@ -549,15 +580,6 @@ cups_get_printer_uri(
 
   DEBUG_printf(("5cups_get_printer_uri: printer-uri=\"%s\"", uri));
 
- /*
-  * Get the hostname and port number we are connected to...
-  */
-
-  httpGetHostname(http, http_hostname, sizeof(http_hostname));
-  http_port = httpAddrPort(http->hostaddr);
-
-  DEBUG_printf(("5cups_get_printer_uri: http_hostname=\"%s\"", http_hostname));
-
  /*
   * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
   * attributes:
@@ -582,31 +604,7 @@ cups_get_printer_uri(
 
   if ((response = cupsDoRequest(http, request, resource)) != NULL)
   {
-    const char *device_uri = NULL;     /* device-uri value */
-
-    if ((attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI)) != NULL)
-    {
-      device_uri = attr->values[0].string.text;
-      DEBUG_printf(("5cups_get_printer_uri: device-uri=\"%s\"", device_uri));
-    }
-
-    if (device_uri &&
-        (((!strncmp(device_uri, "ipp://", 6) || !strncmp(device_uri, "ipps://", 7)) &&
-         (strstr(device_uri, "/printers/") != NULL || strstr(device_uri, "/classes/") != NULL)) ||
-         ((strstr(device_uri, "._ipp.") != NULL || strstr(device_uri, "._ipps.") != NULL) &&
-          !strcmp(device_uri + strlen(device_uri) - 5, "/cups"))))
-    {
-     /*
-      * Statically-configured shared printer.
-      */
-
-      httpSeparateURI(HTTP_URI_CODING_ALL, _httpResolveURI(device_uri, uri, sizeof(uri), _HTTP_RESOLVE_DEFAULT, NULL, NULL), scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize);
-      ippDelete(response);
-
-      DEBUG_printf(("5cups_get_printer_uri: Resolved to host=\"%s\", port=%d, resource=\"%s\"", host, *port, resource));
-      return (1);
-    }
-    else if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
+    if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
     {
      /*
       * Get the first actual printer name in the class...
@@ -631,55 +629,6 @@ cups_get_printer_uri(
          return (1);
        }
       }
-
-     /*
-      * No printers in this class - try recursively looking for a printer,
-      * but not more than 3 levels deep...
-      */
-
-      if (depth < 3)
-      {
-       for (i = 0; i < attr->num_values; i ++)
-       {
-         httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text,
-                         scheme, sizeof(scheme), username, sizeof(username),
-                         host, hostsize, port, resource, resourcesize);
-         if (!strncmp(resource, "/classes/", 9))
-         {
-          /*
-           * Found a class!  Connect to the right server...
-           */
-
-           if (!_cups_strcasecmp(http_hostname, host) && *port == http_port)
-             http2 = http;
-           else if ((http2 = httpConnect2(host, *port, NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL)
-           {
-             DEBUG_puts("8cups_get_printer_uri: Unable to connect to server");
-
-             continue;
-           }
-
-           /*
-           * Look up printers on that server...
-           */
-
-            strlcpy(classname, resource + 9, sizeof(classname));
-
-            cups_get_printer_uri(http2, classname, host, hostsize, port,
-                                resource, resourcesize, depth + 1);
-
-           /*
-           * Close the connection as needed...
-           */
-
-           if (http2 != http)
-             httpClose(http2);
-
-            if (*host)
-             return (1);
-         }
-       }
-      }
     }
     else if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
     {