]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Merge changes from CUPS 1.5svn-r9675.
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Mon, 11 Apr 2011 18:53:27 +0000 (18:53 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Mon, 11 Apr 2011 18:53:27 +0000 (18:53 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3122 a1ca3aef-8c08-0410-bb20-df032aa958be

41 files changed:
CHANGES.txt
backend/ipp.c
backend/snmp-supplies.c
backend/usb-darwin.c
conf/mime.convs.in
conf/mime.types
cups/auth.c
cups/backend.c
cups/conflicts.c
cups/cups-private.h
cups/http-private.h
cups/http-support.c
cups/libcups2.def
cups/libcups_s.exp
cups/raster.h
cups/testhttp.c
cups/usersys.c
cups/util.c
data/media.defs
data/testprint.in
filter/Makefile
filter/raster.c
filter/rastertopwg.c [new file with mode: 0644]
man/client.conf.man.in
man/lp.man
packaging/cups.list.in
scheduler/auth.c
scheduler/auth.h
scheduler/client.c
scheduler/client.h
scheduler/cups-driverd.cxx
scheduler/filter.c
scheduler/ipp.c
scheduler/job.c
scheduler/job.h
scheduler/main.c
scheduler/mime.h
scheduler/printers.c
scheduler/process.c
test/get-jobs.test
xcode/CUPS.xcodeproj/project.pbxproj

index 9bfca98918eedcddf9c67fb3d77eb81c1d815675..8fcf447801752c69d92240845c8736f3c5b32420 100644 (file)
@@ -1,8 +1,9 @@
-CHANGES.txt - 2011-03-18
+CHANGES.txt - 2011-03-31
 ------------------------
 
 CHANGES IN CUPS V1.5b1
 
+       - Added new PWG Raster filter for IPP Everywhere printer support.
        - Added printer-uuid attribute.
        - Added support for the cupsSingleFile PPD keyword.
        - Dropped support for the printer-state-history attribute (STR #3654)
index 95263a85e9ba34fa5ee39980e6bddaddfc027923..d54bd3def257dcd6b7d62187b9175f33e7f8b428 100644 (file)
@@ -95,6 +95,16 @@ static const char * const pattrs[] = /* Printer attributes we want */
   "printer-state-message",
   "printer-state-reasons",
 };
+static const char * const remote_job_states[] =
+{                                      /* Remote job state keywords */
+  "cups-remote-pending",
+  "cups-remote-pending-held",
+  "cups-remote-processing",
+  "cups-remote-stopped",
+  "cups-remote-canceled",
+  "cups-remote-aborted",
+  "cups-remote-completed"
+};
 static char    tmpfilename[1024] = ""; /* Temporary spool file name */
 
 
@@ -512,6 +522,16 @@ main(int  argc,                            /* I - Number of command-line args */
     password = getenv("AUTH_PASSWORD");
   }
 
+#ifdef HAVE_GSSAPI
+ /*
+  * For Kerberos, become the printing user (if we can) to get the credentials
+  * that way.
+  */
+
+  if (!getuid() && (value = getenv("AUTH_UID")) != NULL)
+    seteuid(atoi(value));
+#endif /* HAVE_GSSAPI */
+
  /*
   * Try finding the remote server...
   */
@@ -1421,6 +1441,23 @@ main(int  argc,                          /* I - Number of command-line args */
        if ((job_state = ippFindAttribute(response, "job-state",
                                          IPP_TAG_ENUM)) != NULL)
        {
+         /*
+         * Reflect the remote job state in the local queue...
+         */
+
+          fputs("STATE: -cups-remote-pending,"
+               "cups-remote-pending-held,"
+               "cups-remote-processing,"
+               "cups-remote-stopped,"
+               "cups-remote-canceled,"
+               "cups-remote-aborted,"
+               "cups-remote-completed\n", stderr);
+          if (job_state->values[0].integer >= IPP_JOB_PENDING &&
+             job_state->values[0].integer <= IPP_JOB_COMPLETED)
+           fprintf(stderr, "STATE: +%s\n",
+                   remote_job_states[job_state->values[0].integer -
+                                     IPP_JOB_PENDING]);
+
         /*
           * Stop polling if the job is finished or pending-held...
          */
index d6d8ae1b968e8771b30dc00e6c4fc4688cf3a596..86854b120a1f8af0536e081264c049b31012dc36 100644 (file)
@@ -233,7 +233,10 @@ backendSNMPSupplies(
 
     for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr))
     {
-      percent = 100 * supplies[i].level / supplies[i].max_capacity;
+      if (supplies[i].max_capacity > 0)
+       percent = 100 * supplies[i].level / supplies[i].max_capacity;
+      else
+        percent = 50;
 
       if (percent <= 10)
       {
index a41dfbf380cd3999dbf92ea9a75abc9a166f71fe..0733891b1ba9917c4f74a9a0c97acc7f4c879b00 100644 (file)
@@ -1,7 +1,7 @@
 /*
 * "$Id: usb-darwin.c 7953 2008-09-17 01:43:19Z mike $"
 *
-* Copyright 2005-2010 Apple Inc. All rights reserved.
+* Copyright 2005-2011 Apple Inc. All rights reserved.
 *
 * IMPORTANT:  This Apple software is supplied to you by Apple Computer,
 * Inc. ("Apple") in consideration of your agreement to the following
@@ -1435,9 +1435,15 @@ static kern_return_t load_classdriver(CFStringRef            driverPath,
                    "permissions (0%o/uid=%d/gid=%d).\n", bundlestr,
                    bundleinfo.st_mode, (int)bundleinfo.st_uid,
                    (int)bundleinfo.st_gid);
-    fputs("STATE: +cups-insecure-filter-warning\n", stderr);
-
-    if (bundleinfo.st_uid || (bundleinfo.st_mode & S_IWOTH))
+    if (bundleinfo.st_uid ||
+       (bundleinfo.st_gid && bundleinfo.st_gid != 80 &&
+        (bundleinfo.st_mode & S_IWGRP)) ||
+       (bundleinfo.st_mode & (S_ISUID | S_IWOTH)))
+      fputs("STATE: +cups-insecure-filter-warning\n", stderr);
+
+    if (bundleinfo.st_uid ||
+        (bundleinfo.st_gid && bundleinfo.st_gid != 80 &&
+        (bundleinfo.st_mode & S_IWOTH)))
     {
       if (driverPath)
         return (load_classdriver(NULL, intf, printerDriver));
index 9e6796ad4888a5564469a13fcf75040f6491fa83..804546c9e9afbfd6592e89938728ae1413a21ebd 100644 (file)
@@ -5,9 +5,9 @@
 #   VERSIONS OF CUPS.  Instead, create a "local.convs" file that
 #   reflects your local configuration changes.
 #
-#   MIME converts file for the Common UNIX Printing System (CUPS).
+#   Base MIME conversions file for CUPS.
 #
-#   Copyright 2007-2010 by Apple Inc.
+#   Copyright 2007-2011 by Apple Inc.
 #   Copyright 1997-2007 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -88,6 +88,9 @@ image/x-sun-raster            application/vnd.cups-raster     100     imagetoraster
 # pstoraster is part of GPL Ghostscript...
 application/vnd.cups-postscript        application/vnd.cups-raster     100     pstoraster
 
+# PWG Raster filter for IPP Everywhere...
+application/vnd.cups-raster    image/pwg-raster                100     rastertopwg
+
 ########################################################################
 #
 # Raw filter...
index dd28daaf603068b03e588f130b6344b45f4029db..77944f4bbf5c6fe8656a9c0c5adb6e786c2c7d6f 100644 (file)
@@ -1,13 +1,13 @@
 #
 # "$Id: mime.types 7670 2008-06-17 22:42:08Z mike $"
 #
-#   MIME types file for the Common UNIX Printing System (CUPS).
+#   Base MIME types file for CUPS.
 #
 #   DO NOT EDIT THIS FILE, AS IT IS OVERWRITTEN WHEN YOU INSTALL NEW
 #   VERSIONS OF CUPS.  Instead, create a "local.types" file that
 #   reflects your local configuration changes.
 #
-#   Copyright 2007-2010 by Apple Inc.
+#   Copyright 2007-2011 by Apple Inc.
 #   Copyright 1997-2007 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -92,6 +92,7 @@ image/jpeg                    jpeg jpg jpe string(0,<FFD8FF>) +\
                                 char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
                                 char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
                                 char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
+image/pwg-raster               string(0,"RaS2") + string(356,<0000000000000000>) priority(100)
 image/tiff                     tiff tif string(0,MM<002A>) string(0,II<2A00>)
 image/x-photocd                        pcd string(2048,PCD_IPI)
 image/x-portable-anymap                pnm
index f9054d222567701dbff0d2d896532da5dc5baa68..abc22eb904f10d3972aa4a4651457053d46aa9b3 100644 (file)
@@ -260,8 +260,8 @@ _cupsSetNegotiateAuthString(
   OM_uint32    minor_status,           /* Minor status code */
                major_status;           /* Major status code */
   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
-                                     /* Output token */
-  char         *gss_service_name;    /* GSS service name */
+                                       /* Output token */
+  _cups_globals_t *cg = _cupsGlobals();        /* Thread globals */
 
 
 #  ifdef __APPLE__
@@ -280,13 +280,10 @@ _cupsSetNegotiateAuthString(
 
   if (http->gssname == GSS_C_NO_NAME)
   {
-    if ((gss_service_name = getenv("CUPS_GSSSERVICENAME")) == NULL)
-      gss_service_name = CUPS_DEFAULT_GSSSERVICENAME;
-    else
-      DEBUG_puts("2_cupsSetNegotiateAuthString: GSS service name set via "
-                "environment variable");
+    if (!cg->gss_service_name[0])
+      _cupsSetDefaults();
 
-    http->gssname = cups_get_gssname(http, gss_service_name);
+    http->gssname = cups_get_gssname(http, cg->gss_service_name);
   }
 
   if (http->gssctx != GSS_C_NO_CONTEXT)
@@ -298,9 +295,6 @@ _cupsSetNegotiateAuthString(
   major_status  = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
                                       &http->gssctx,
                                       http->gssname, http->gssmech,
-#ifdef GSS_C_DELEG_POLICY_FLAG
-                                      GSS_C_DELEG_POLICY_FLAG |
-#endif /* GSS_C_DELEG_POLICY_FLAG */
                                       GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
                                       GSS_C_INDEFINITE,
                                       GSS_C_NO_CHANNEL_BINDINGS,
@@ -628,7 +622,7 @@ cups_local_auth(http_t *http)               /* I - HTTP connection to server */
     DEBUG_printf(("9cups_local_auth: Unable to open file %s: %s",
                   filename, strerror(errno)));
 
-#ifdef HAVE_GSSAPI
+#  ifdef HAVE_GSSAPI
     if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
     {
      /*
@@ -637,8 +631,19 @@ cups_local_auth(http_t *http)              /* I - HTTP connection to server */
 
       return (1);
     }
-#endif /* HAVE_GSSAPI */
+#  endif /* HAVE_GSSAPI */
 
+#  ifdef HAVE_AUTHORIZATION_H
+    if (httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey",
+                        auth_key, sizeof(auth_key)))
+    {
+     /*
+      * Don't use the root certificate as a replacement for an authkey...
+      */
+
+      return (1);
+    }
+#  endif /* HAVE_AUTHORIZATION_H */
     if (!httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "trc", trc,
                          sizeof(trc)))
     {
index 83613ea20e6110f2a53243932df2c3c0604c5ebb..818455f452ba76c9e8f0002960d93fe4ad2f3eaa 100644 (file)
@@ -63,7 +63,7 @@ cupsBackendDeviceURI(char **argv)     /* I - Command-line arguments */
   }
 
   return (_httpResolveURI(device_uri, cg->resolved_uri,
-                          sizeof(cg->resolved_uri), 1));
+                          sizeof(cg->resolved_uri), 1, NULL, NULL));
 }
 
 
index 56f800c1d3a63a68ae6e99578d60592e31851ce5..543b6aececcda2ce59353edb41c5c09d75ab5acf 100644 (file)
@@ -94,6 +94,7 @@ cupsGetConflicts(
   cups_array_t         *active;        /* Active conflicts */
   _ppd_cups_uiconsts_t *c;             /* Current constraints */
   _ppd_cups_uiconst_t  *cptr;          /* Current constraint */
+  ppd_choice_t         *marked;        /* Marked choice */
 
 
  /*
@@ -125,8 +126,16 @@ cupsGetConflicts(
          i > 0;
         i --, cptr ++)
       if (strcasecmp(cptr->option->keyword, option))
-        num_options = cupsAddOption(cptr->option->keyword, cptr->choice->choice,
-                                   num_options, options);
+      {
+        if (cptr->choice)
+         num_options = cupsAddOption(cptr->option->keyword,
+                                     cptr->choice->choice, num_options,
+                                     options);
+        else if ((marked = ppdFindMarkedChoice(ppd,
+                                              cptr->option->keyword)) != NULL)
+         num_options = cupsAddOption(cptr->option->keyword, marked->choice,
+                                     num_options, options);
+      }
   }
 
   cupsArrayDelete(active);
index 6e1677f8867a2bd7525784062aa5142e5940e5c0..0de2a37e6e121dc61d6fc5449736eb2b05051f17 100644 (file)
@@ -68,6 +68,12 @@ typedef struct _cups_globals_s               /**** CUPS global state data ****/
                                        /* Number of server settings */
   cups_option_t                *cupsd_settings;/* Server settings */
 
+  /* auth.c */
+#  ifdef HAVE_GSSAPI
+  char                 gss_service_name[32];
+                                       /* Kerberos service name */
+#  endif /* HAVE_GSSAPI */
+
   /* backend.c */
   char                 resolved_uri[1024];
                                        /* Buffer for cupsBackendDeviceURI */
index 6b8d031a516ba8aace17c61aa1e27c7b8e600ce9..79ff84d6e605b738798496a913a0c6976b5b0245 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Private HTTP definitions for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -79,6 +79,67 @@ typedef int socklen_t;
 #  include "md5-private.h"
 #  include "ipp-private.h"
 
+#  if defined HAVE_LIBSSL
+#    include <openssl/err.h>
+#    include <openssl/rand.h>
+#    include <openssl/ssl.h>
+#  elif defined HAVE_GNUTLS
+#    include <gnutls/gnutls.h>
+#    include <gnutls/x509.h>
+#    include <gcrypt.h>
+#  elif defined(HAVE_CDSASSL)
+#    include <CoreFoundation/CoreFoundation.h>
+#    include <Security/Security.h>
+#    include <Security/SecureTransport.h>
+#    ifdef HAVE_SECITEM_H
+#      include <Security/SecItem.h>
+#    endif /* HAVE_SECITEM_H */
+#    ifdef HAVE_SECBASEPRIV_H
+#      include <Security/SecBasePriv.h>
+#    endif /* HAVE_SECBASEPRIV_H */
+#    ifdef HAVE_SECCERTIFICATE_H
+#      include <Security/SecCertificate.h>
+#      include <Security/SecIdentity.h>
+#    endif /* HAVE_SECCERTIFICATE_H */
+#    ifdef HAVE_SECITEMPRIV_H
+#      include <Security/SecItemPriv.h>
+#    endif /* HAVE_SECITEMPRIV_H */
+#    ifdef HAVE_SECIDENTITYSEARCHPRIV_H
+#      include <Security/SecIdentitySearchPriv.h>
+#    endif /* HAVE_SECIDENTITYSEARCHPRIV_H */
+#    ifdef HAVE_SECPOLICYPRIV_H
+#      include <Security/SecPolicyPriv.h>
+#    endif /* HAVE_SECPOLICYPRIV_H */
+#  elif defined(HAVE_SSPISSL)
+#    include "sspi-private.h"
+#  endif /* HAVE_LIBSSL */
+
+#  ifndef WIN32
+#    include <net/if.h>
+#    ifdef HAVE_GETIFADDRS
+#      include <ifaddrs.h>
+#    else
+#      include <sys/ioctl.h>
+#      ifdef HAVE_SYS_SOCKIO_H
+#        include <sys/sockio.h>
+#      endif /* HAVE_SYS_SOCKIO_H */
+#    endif /* HAVE_GETIFADDRS */
+#  endif /* !WIN32 */
+
+
+/*
+ * C++ magic...
+ */
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+
+
+/*
+ * Types and functions for SSL support...
+ */
+
 #  if defined HAVE_LIBSSL
 /*
  * The OpenSSL library provides its own SSL/TLS context structure for its
@@ -86,10 +147,6 @@ typedef int socklen_t;
  * (basic IO) implementation to do timeouts...
  */
 
-#    include <openssl/err.h>
-#    include <openssl/rand.h>
-#    include <openssl/ssl.h>
-
 typedef SSL  *http_tls_t;
 typedef void *http_tls_credentials_t;
 
@@ -99,9 +156,6 @@ extern BIO_METHOD *_httpBIOMethods(void);
 /*
  * The GNU TLS library is more of a "bare metal" SSL/TLS library...
  */
-#    include <gnutls/gnutls.h>
-#    include <gnutls/x509.h>
-#    include <gcrypt.h>
 
 typedef gnutls_session http_tls_t;
 typedef void *http_tls_credentials_t;
@@ -117,42 +171,24 @@ extern ssize_t    _httpWriteGNUTLS(gnutls_transport_ptr ptr, const void *data,
  * for its IO and protocol management...
  */
 
-#    include <CoreFoundation/CoreFoundation.h>
-#    include <Security/Security.h>
-#    include <Security/SecureTransport.h>
-#    ifdef HAVE_SECITEM_H
-#      include <Security/SecItem.h>
-#    endif /* HAVE_SECITEM_H */
-#    ifdef HAVE_SECBASEPRIV_H
-#      include <Security/SecBasePriv.h>
-#    elif defined(HAVE_CSSMERRORSTRING) /* Declare prototype for function in that header... */
+#    if !defined(HAVE_SECBASEPRIV_H) && defined(HAVE_CSSMERRORSTRING) /* Declare prototype for function in that header... */
 extern const char *cssmErrorString(int error);
-#    endif /* HAVE_SECBASEPRIV_H */
-#    ifdef HAVE_SECCERTIFICATE_H
-#      include <Security/SecCertificate.h>
-#      include <Security/SecIdentity.h>
-#    endif /* HAVE_SECCERTIFICATE_H */
-#    ifdef HAVE_SECITEMPRIV_H
-#      include <Security/SecItemPriv.h>
-#    else /* Declare constants from that header... */
+#    endif /* !HAVE_SECBASEPRIV_H && HAVE_CSSMERRORSTRING */
+#    ifndef HAVE_SECITEMPRIV_H /* Declare constants from that header... */
 extern const CFTypeRef kSecClassCertificate;
 extern const CFTypeRef kSecClassIdentity;
-#    endif /* HAVE_SECITEMPRIV_H */
-#    ifdef HAVE_SECIDENTITYSEARCHPRIV_H
-#      include <Security/SecIdentitySearchPriv.h>
-#    elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) /* Declare prototype for function in that header... */
+#    endif /* !HAVE_SECITEMPRIV_H */
+#    if !defined(HAVE_SECIDENTITYSEARCHPRIV_H) && defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) /* Declare prototype for function in that header... */
 extern OSStatus SecIdentitySearchCreateWithPolicy(SecPolicyRef policy,
                                CFStringRef idString, CSSM_KEYUSE keyUsage,
                                CFTypeRef keychainOrArray,
                                Boolean returnOnlyValidIdentities,
                                SecIdentitySearchRef* searchRef);
-#    endif /* HAVE_SECIDENTITYSEARCHPRIV_H */
-#    ifdef HAVE_SECPOLICYPRIV_H
-#      include <Security/SecPolicyPriv.h>
-#    elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) /* Declare prototype for function in that header... */
+#    endif /* !HAVE_SECIDENTITYSEARCHPRIV_H && HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY */
+#    if !defined(HAVE_SECPOLICYPRIV_H) && defined(HAVE_SECPOLICYSETVALUE) /* Declare prototype for function in that header... */
 extern OSStatus SecPolicySetValue(SecPolicyRef policyRef,
                                   const CSSM_DATA *value);
-#    endif /* HAVE_SECPOLICYPRIV_H */
+#    endif /* !HAVE_SECPOLICYPRIV_H && HAVE_SECPOLICYSETVALUE */
 
 typedef SSLContextRef  http_tls_t;
 typedef CFArrayRef     http_tls_credentials_t;
@@ -163,11 +199,20 @@ extern OSStatus   _httpWriteCDSA(SSLConnectionRef connection, const void *data,
                               size_t *dataLength);
 
 #  elif defined(HAVE_SSPISSL)
-#    include "sspi-private.h"
+/*
+ * Windows' SSPI library gets a CUPS wrapper...
+ */
+
 typedef _sspi_struct_t * http_tls_t;
 typedef void *http_tls_credentials_t;
+
 #  else
+/*
+ * Otherwise define stub types since we have no SSL support...
+ */
+
 typedef void *http_tls_t;
+typedef void *http_tls_credentials_t;
 #  endif /* HAVE_LIBSSL */
 
 
@@ -258,22 +303,13 @@ extern const char *hstrerror(int error);
  * Some OS's don't have getifaddrs() and freeifaddrs()...
  */
 
-#  ifndef WIN32
-#    include <net/if.h>
-#    ifdef HAVE_GETIFADDRS
-#      include <ifaddrs.h>
-#    else
-#      include <sys/ioctl.h>
-#      ifdef HAVE_SYS_SOCKIO_H
-#        include <sys/sockio.h>
-#      endif /* HAVE_SYS_SOCKIO_H */
-
-#      ifdef ifa_dstaddr
-#        undef ifa_dstaddr
-#      endif /* ifa_dstaddr */
-#      ifndef ifr_netmask
-#        define ifr_netmask ifr_addr
-#      endif /* !ifr_netmask */
+#  if !defined(WIN32) && !defined(HAVE_GETIFADDRS)
+#    ifdef ifa_dstaddr
+#      undef ifa_dstaddr
+#    endif /* ifa_dstaddr */
+#    ifndef ifr_netmask
+#      define ifr_netmask ifr_addr
+#    endif /* !ifr_netmask */
 
 struct ifaddrs                         /**** Interface Structure ****/
 {
@@ -291,25 +327,28 @@ struct ifaddrs                            /**** Interface Structure ****/
   void                 *ifa_data;      /* Interface statistics */
 };
 
-#      ifndef ifa_broadaddr
-#        define ifa_broadaddr ifa_ifu.ifu_broadaddr
-#      endif /* !ifa_broadaddr */
-#      ifndef ifa_dstaddr
-#        define ifa_dstaddr ifa_ifu.ifu_dstaddr
-#      endif /* !ifa_dstaddr */
+#    ifndef ifa_broadaddr
+#      define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#    endif /* !ifa_broadaddr */
+#    ifndef ifa_dstaddr
+#      define ifa_dstaddr ifa_ifu.ifu_dstaddr
+#    endif /* !ifa_dstaddr */
 
 extern int     _cups_getifaddrs(struct ifaddrs **addrs);
-#      define getifaddrs _cups_getifaddrs
+#    define getifaddrs _cups_getifaddrs
 extern void    _cups_freeifaddrs(struct ifaddrs *addrs);
-#      define freeifaddrs _cups_freeifaddrs
-#    endif /* HAVE_GETIFADDRS */
-#  endif /* !WIN32 */
+#    define freeifaddrs _cups_freeifaddrs
+#  endif /* !WIN32 && !HAVE_GETIFADDRS */
+
 
 /*
  * Prototypes...
  */
 
 extern int             _httpAddrPort(http_addr_t *addr);
+extern char            *_httpAssembleUUID(const char *server, int port,
+                                          const char *name, int number,
+                                          char *buffer, size_t bufsize);
 extern http_tls_credentials_t
                        _httpConvertCredentials(cups_array_t *credentials);
 extern http_t          *_httpCreate(const char *host, int port,
@@ -324,13 +363,23 @@ extern char               *_httpEncodeURI(char *dst, const char *src,
 extern void            _httpFreeCredentials(http_tls_credentials_t credentials);
 extern ssize_t         _httpPeek(http_t *http, char *buffer, size_t length);
 extern const char      *_httpResolveURI(const char *uri, char *resolved_uri,
-                                        size_t resolved_size, int log);
+                                        size_t resolved_size, int log,
+                                        int (*cb)(void *context),
+                                        void *context);
 extern void            _httpSetTimeout(http_t *http, double timeout,
                                        _http_timeout_cb_t cb, void *user_data);
 extern int             _httpUpdate(http_t *http, http_status_t *status);
 extern int             _httpWait(http_t *http, int msec, int usessl);
 
 
+/*
+ * C++ magic...
+ */
+
+#  ifdef __cplusplus
+}
+#  endif /* __cplusplus */
+
 #endif /* !_CUPS_HTTP_PRIVATE_H_ */
 
 /*
index 1d73f7d4887e8767cbfbb71ff56508a103a682aa..f598bfbb5fc6ce1b706bde0fb5f848a51e4e26c7 100644 (file)
@@ -20,6 +20,7 @@
  *                          components.
  *   httpAssembleURIf()   - Assemble a uniform resource identifier from its
  *                          components with a formatted resource.
+ *   _httpAssembleUUID()  - Make a UUID URI conforming to RFC 4122.
  *   httpDecode64()       - Base64-decode a string.
  *   httpDecode64_2()     - Base64-decode a string.
  *   httpEncode64()       - Base64-encode a string.
@@ -436,6 +437,56 @@ httpAssembleURIf(
 }
 
 
+/*
+ * '_httpAssembleUUID()' - Make a UUID URI conforming to RFC 4122.
+ *
+ * The buffer needs to be at least 46 bytes in size.
+ */
+
+char *                                 /* I - UUID string */
+_httpAssembleUUID(const char *server,  /* I - Server name */
+                  int        port,     /* I - Port number */
+                 const char *name,     /* I - Object name or NULL */
+                  int        number,   /* I - Object number or 0 */
+                 char       *buffer,   /* I - String buffer */
+                 size_t     bufsize)   /* I - Size of buffer */
+{
+  char                 data[1024];     /* Source string for MD5 */
+  _cups_md5_state_t    md5state;       /* MD5 state */
+  unsigned char                md5sum[16];     /* MD5 digest/sum */
+
+
+ /*
+  * Build a version 3 UUID conforming to RFC 4122.
+  *
+  * Start with the MD5 sum of the server, port, object name and
+  * number, and some random data on the end.
+  */
+
+  snprintf(data, sizeof(data), "%s:%d:%s:%d:%04x:%04x", server,
+           port, name ? name : server, number,
+          CUPS_RAND() & 0xffff, CUPS_RAND() & 0xffff);
+
+  _cupsMD5Init(&md5state);
+  _cupsMD5Append(&md5state, (unsigned char *)data, strlen(data));
+  _cupsMD5Finish(&md5state, md5sum);
+
+ /*
+  * Generate the UUID from the MD5...
+  */
+
+  snprintf(buffer, bufsize,
+           "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
+          "%02x%02x%02x%02x%02x%02x",
+          md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5],
+          (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40,
+          md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13],
+          md5sum[14], md5sum[15]);
+
+  return (buffer);
+}
+
+
 /*
  * 'httpDecode64()' - Base64-decode a string.
  *
@@ -1331,7 +1382,9 @@ _httpResolveURI(
     const char *uri,                   /* I - DNS-SD URI */
     char       *resolved_uri,          /* I - Buffer for resolved URI */
     size_t     resolved_size,          /* I - Size of URI buffer */
-    int        logit)                  /* I - Log progress to stderr? */
+    int        logit,                  /* I - Log progress to stderr? */
+    int        (*cb)(void *context),   /* I - Continue callback function */
+    void       *context)               /* I - Context pointer for callback */
 {
   char                 scheme[32],     /* URI components... */
                        userpass[256],
@@ -1463,12 +1516,18 @@ _httpResolveURI(
          if (logit)
            _cupsLangPrintFilter(stderr, "INFO", _("Looking for printer."));
 
+         if (cb && !(*cb)(context))
+         {
+           DEBUG_puts("5_httpResolveURI: callback returned 0 (stop)");
+           break;
+         }
+
         /*
-         * For the first minute, wakeup every 2 seconds to emit a
-         * "looking for printer" message...
+         * For the first minute (or forever if we have a callback), wakeup
+         * every 2 seconds to emit a "looking for printer" message...
          */
 
-         timeout = (time(NULL) < (start_time + 60)) ? 2000 : -1;
+         timeout = (time(NULL) < (start_time + 60) || cb) ? 2000 : -1;
 
 #ifdef HAVE_POLL
          polldata.fd     = DNSServiceRefSockFD(ref);
index 6e9581823fc2483626e7df2940acde3fdb4c8013..13009f340ff2136db6c2efaaa647ce5598647ff9 100644 (file)
@@ -29,6 +29,7 @@ _cups_strcpy
 _cups_strlcat\r
 _cups_strlcpy\r
 _httpAddrPort\r
+_httpAssembleUUID\r
 _httpCreate\r
 _httpEncodeURI\r
 _httpPeek\r
index 80b347a75e0e71a5ae08d7bc154ff72c6d47d198..c36b87810b57513d2cbdf8566be49695f1d7161c 100644 (file)
@@ -41,6 +41,7 @@ _cups_strcpy
 _cups_strlcat
 _cups_strlcpy
 _httpAddrPort
+_httpAssembleUUID
 _httpBIOMethods
 _httpCreate
 _httpEncodeURI
index eabd190be72a76cfc43c5d6497bdd2e325b81d69..4437accb5ef384d5174c58c777f29897938d0e55 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Raster file definitions for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   This file is part of the CUPS Imaging library.
@@ -66,6 +66,19 @@ extern "C" {
 
 #  define CUPS_RASTER_HAVE_COLORIMETRIC 1
 
+/*
+ * The following definition can be used to determine if the
+ * device colorspaces (DEVICEn) are defined...
+ */
+
+#  define CUPS_RASTER_HAVE_DEVICE 1
+
+/*
+ * The following definition can be used to determine if PWG Raster is supported.
+ */
+
+#  define CUPS_RASTER_HAVE_PWGRASTER 1
+
 
 /*
  * Types...
index ccb7c19dd210391f814c74cc7c478604451f7771..f711e9ab95bac0e900025389d7bd82df4f0014ae 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   HTTP test program for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -468,7 +468,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
     printf("_httpResolveURI(%s): ", argv[1]);
     fflush(stdout);
 
-    if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 1))
+    if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 1, NULL, NULL))
     {
       puts("FAIL");
       return (1);
index 20a38db2d9dc58e7264bb72ae25fe56a715a8901..3b46d4cc8b81763176692195d86a5711cb3c8ff3 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   User, system, and password routines for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -57,6 +57,9 @@ static void   cups_read_client_conf(cups_file_t *fp,
                                      _cups_globals_t *cg,
                                      const char *cups_encryption,
                                      const char *cups_server,
+#ifdef HAVE_GSSAPI
+                                      const char *cups_gssservicename,
+#endif /* HAVE_GSSAPI */
                                      const char *cups_anyroot,
                                      const char *cups_expiredroot,
                                      const char *cups_expiredcerts);
@@ -519,6 +522,9 @@ _cupsSetDefaults(void)
   const char   *home,                  /* Home directory of user */
                *cups_encryption,       /* CUPS_ENCRYPTION env var */
                *cups_server,           /* CUPS_SERVER env var */
+#ifdef HAVE_GSSAPI
+               *cups_gssservicename,   /* CUPS_GSSSERVICENAME env var */
+#endif /* HAVE_GSSAPI */
                *cups_anyroot,          /* CUPS_ANYROOT env var */
                *cups_expiredroot,      /* CUPS_EXPIREDROOT env var */
                *cups_expiredcerts;     /* CUPS_EXPIREDCERTS env var */
@@ -532,11 +538,14 @@ _cupsSetDefaults(void)
   * First collect environment variables...
   */
 
-  cups_encryption   = getenv("CUPS_ENCRYPTION");
-  cups_server      = getenv("CUPS_SERVER");
-  cups_anyroot     = getenv("CUPS_ANYROOT");
-  cups_expiredroot  = getenv("CUPS_EXPIREDROOT");
-  cups_expiredcerts = getenv("CUPS_EXPIREDCERTS");
+  cups_encryption     = getenv("CUPS_ENCRYPTION");
+  cups_server        = getenv("CUPS_SERVER");
+#ifdef HAVE_GSSAPI
+  cups_gssservicename = getenv("CUPS_GSSSERVICENAME");
+#endif /* HAVE_GSSAPI */
+  cups_anyroot       = getenv("CUPS_ANYROOT");
+  cups_expiredroot    = getenv("CUPS_EXPIREDROOT");
+  cups_expiredcerts   = getenv("CUPS_EXPIREDCERTS");
 
  /*
   * Then, if needed, read the ~/.cups/client.conf or /etc/cups/client.conf
@@ -575,6 +584,9 @@ _cupsSetDefaults(void)
     */
 
     cups_read_client_conf(fp, cg, cups_encryption, cups_server,
+#ifdef HAVE_GSSAPI
+                         cups_gssservicename,
+#endif /* HAVE_GSSAPI */
                          cups_anyroot, cups_expiredroot,
                          cups_expiredcerts);
     cupsFileClose(fp);
@@ -592,6 +604,10 @@ cups_read_client_conf(
     _cups_globals_t *cg,               /* I - Global data */
     const char      *cups_encryption,  /* I - CUPS_ENCRYPTION env var */
     const char      *cups_server,      /* I - CUPS_SERVER env var */
+#ifdef HAVE_GSSAPI
+    const char      *cups_gssservicename,
+                                       /* I - CUPS_GSSSERVICENAME env var */
+#endif /* HAVE_GSSAPI */
     const char     *cups_anyroot,      /* I - CUPS_ANYROOT env var */
     const char     *cups_expiredroot,  /* I - CUPS_EXPIREDROOT env var */
     const char     *cups_expiredcerts) /* I - CUPS_EXPIREDCERTS env var */
@@ -604,6 +620,9 @@ cups_read_client_conf(
        any_root[1024],                 /* AllowAnyRoot value */
        expired_root[1024],             /* AllowExpiredRoot value */
        expired_certs[1024];            /* AllowExpiredCerts value */
+#ifdef HAVE_GSSAPI
+  char gss_service_name[32];           /* GSSServiceName value */
+#endif /* HAVE_GSSAPI */
 
 
  /*
@@ -642,6 +661,14 @@ cups_read_client_conf(
       strlcpy(expired_certs, value, sizeof(expired_certs));
       cups_expiredcerts = expired_certs;
     }
+#ifdef HAVE_GSSAPI
+    else if (!cups_gssservicename && !strcasecmp(line, "GSSServiceName") &&
+             value)
+    {
+      strlcpy(gss_service_name, value, sizeof(gss_service_name));
+      cups_gssservicename = gss_service_name;
+    }
+#endif /* HAVE_GSSAPI */
   }
 
  /*
@@ -730,6 +757,14 @@ cups_read_client_conf(
       cg->ipp_port = ntohs(service->s_port);
   }
 
+#ifdef HAVE_GSSAPI
+  if (!cups_gssservicename)
+    cups_gssservicename = CUPS_DEFAULT_GSSSERVICENAME;
+
+  strlcpy(cg->gss_service_name, cups_gssservicename,
+         sizeof(cg->gss_service_name));
+#endif /* HAVE_GSSAPI */
+
   if (cups_anyroot)
     cg->any_root = !strcasecmp(cups_anyroot, "yes") ||
                   !strcasecmp(cups_anyroot, "on")  ||
index 80f36d153a047cc5c9189233ac879d0a584b91aa..4e5c74035558a0eb65aff81df820b940f1f78091 100644 (file)
@@ -1762,7 +1762,7 @@ cups_get_printer_uri(
     {
       httpSeparateURI(HTTP_URI_CODING_ALL,
                       _httpResolveURI(attr->values[0].string.text, uri,
-                                     sizeof(uri), 0),
+                                     sizeof(uri), 0, NULL, NULL),
                       scheme, sizeof(scheme), username, sizeof(username),
                      host, hostsize, port, resource, resourcesize);
       ippDelete(response);
index 8d5d278e762b253e31636770a5dfdae99642235d..98148729eb5a594559f56cda10bd0335d78fcdac 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Adobe standard media size definitions for the CUPS PPD file compiler.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2005 by Easy Software Products.
  *
  *   These codedinstructions, statements, and computer programs are the
 #media "LetterPlus/US Letter Oversize" 612 914
 #media "LetterRotated/US Letter" 792 612
 #media "LetterSmall/US Letter Small" 612 792
-#media "Monarch/Monarch" 279 540
+#media "Monarch/Envelope Monarch" 279 540
 #media "Note/Note" 612 792
 #media "Postcard/Postcard" 284 419
 #media "PostcardRotated/Postcard" 419 284
index 5eff731400e728bde0e0cc67ce0cee71463695dc..8cee3ab4f9e831bc372e9b38a139adbdd156996b 100644 (file)
@@ -2,7 +2,6 @@
 Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area
 Header Printer Test Page
 Footer Printer Test Page
-Notice This test page was produced by CUPS @CUPS_VERSION@.
+Notice CUPS @CUPS_VERSION@.
 Image images/cups.png
 Image images/color-wheel.png
-
index a4d08770a5541e7b4bf90222f4b1ea0a9c97622d..104d4cda69e2b420e5a804c15d631a14d83ae128 100644 (file)
@@ -1,9 +1,9 @@
 #
 # "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $"
 #
-#   Filter makefile for the Common UNIX Printing System (CUPS).
+#   Filter makefile for CUPS.
 #
-#   Copyright 2007-2010 by Apple Inc.
+#   Copyright 2007-2011 by Apple Inc.
 #   Copyright 1997-2006 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -26,9 +26,10 @@ FILTERS      =       \
                pstops \
                $(IMGFILTERS) \
                $(PDFTOPS) \
-               rastertolabel \
                rastertoepson \
-               rastertohp
+               rastertohp \
+               rastertolabel \
+               rastertopwg
 LIBTARGETS =   \
                $(LIBCUPSIMAGE) \
                libcupsimage.a \
@@ -52,7 +53,7 @@ OBJS  =       $(IMAGEOBJS) \
                bannertops.o commandtops.o gziptoany.o imagetops.o \
                imagetoraster.o common.o pdftops.o pstext.o pstops.o \
                rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \
-               testimage.o testraster.o textcommon.o texttops.o
+               rastertopwg.o testimage.o testraster.o textcommon.o texttops.o
 
 
 #
@@ -446,15 +447,6 @@ pdftops:   pdftops.o common.o ../cups/$(LIBCUPS)
        $(CC) $(LDFLAGS) -o $@ pdftops.o common.o $(LIBS)
 
 
-#
-# rastertolabel
-#
-
-rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
-       echo Linking $@...
-       $(CC) $(LDFLAGS) -o $@ rastertolabel.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
-
-
 #
 # rastertoepson
 #
@@ -473,6 +465,24 @@ rastertohp:        rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
        $(CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
 
 
+#
+# rastertolabel
+#
+
+rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ rastertolabel.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+
+
+#
+# rastertopwg
+#
+
+rastertopwg:   rastertopwg.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ rastertopwg.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+
+
 #
 # testraster
 #
@@ -508,7 +518,7 @@ texttops:   texttops.o textcommon.o common.o \
 #
 # Dependencies...
 #
-  
+
 include Dependencies
 
 
index a57dd1874ee42e234b40187691d0b6cca699ccac..7e54b0ec388b6803c2e3e55b293745d8b24d431f 100644 (file)
@@ -1043,7 +1043,6 @@ cups_raster_read(cups_raster_t *r,        /* I - Raster stream */
 
       unsigned char    *bufptr;        /* Temporary buffer pointer */
 
-
       remaining -= count;
 
       for (bufptr = r->bufptr; count > 0; count --, total ++)
@@ -1241,7 +1240,7 @@ cups_raster_write(
   *wptr++ = r->count - 1;
 
  /*
-  * Write using a modified TIFF "packbits" compression...
+  * Write using a modified PackBits compression...
   */
 
   for (ptr = pixels; ptr < pend;)
@@ -1279,7 +1278,7 @@ cups_raster_write(
       * Encode a sequence of non-repeating pixels...
       */
 
-      for (count = 1; count < 127 && ptr < plast; count ++, ptr += bpp)
+      for (count = 1; count < 128 && ptr < plast; count ++, ptr += bpp)
         if (!memcmp(ptr, ptr + bpp, bpp))
          break;
 
diff --git a/filter/rastertopwg.c b/filter/rastertopwg.c
new file mode 100644 (file)
index 0000000..6f6497c
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * "$Id$"
+ *
+ *   CUPS raster to PWG raster format filter for CUPS.
+ *
+ *   Copyright 2011 Apple Inc.
+ *
+ *   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.
+ *
+ * Contents:
+ *
+ *   main() - Main entry for filter.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/language-private.h>
+#include <cups/raster.h>
+#include <cups/string-private.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+
+/*
+ * 'main()' - Main entry for filter.
+ */
+
+int                                    /* O - Exit status */
+main(int  argc,                                /* I - Number of command-line args */
+     char *argv[])                     /* I - Command-line arguments */
+{
+  int                  fd;             /* Raster file */
+  cups_raster_t                *inras,         /* Input raster stream */
+                       *outras;        /* Output raster stream */
+  cups_page_header2_t  inheader,       /* Input raster page header */
+                       outheader;      /* Output raster page header */
+  int                  y;              /* Current line */
+  unsigned char                *line;          /* Line buffer */
+  int                  page = 0,       /* Current page */
+                       page_width,     /* Actual page width */
+                       page_height,    /* Actual page height */
+                       page_top,       /* Top margin */
+                       page_bottom,    /* Bottom margin */
+                       page_left,      /* Left margin */
+                       linesize,       /* Bytes per line */
+                       lineoffset;     /* Offset into line */
+  unsigned char                white;          /* White pixel */
+
+
+  if (argc < 6 || argc > 7)
+  {
+    puts("Usage: rastertopwg job user title copies options [filename]");
+    return (1);
+  }
+  else if (argc == 7)
+  {
+    if ((fd = open(argv[6], O_RDONLY)) < 0)
+    {
+      perror("ERROR: Unable to open print file");
+      return (1);
+    }
+  }
+  else
+    fd = 0;
+
+  inras  = cupsRasterOpen(fd, CUPS_RASTER_READ);
+  outras = cupsRasterOpen(1, CUPS_RASTER_WRITE_PWG);
+
+  while (cupsRasterReadHeader2(inras, &inheader))
+  {
+   /*
+    * Compute the real raster size...
+    */
+
+    page ++;
+
+    fprintf(stderr, "PAGE: %d %d\n", page, inheader.NumCopies);
+
+    page_width  = (int)(inheader.cupsPageSize[0] * inheader.HWResolution[0] /
+                        72.0);
+    page_height = (int)(inheader.cupsPageSize[1] * inheader.HWResolution[1] /
+                        72.0);
+    page_left   = (int)(inheader.cupsImagingBBox[0] *
+                        inheader.HWResolution[0] / 72.0);
+    page_bottom = (int)(inheader.cupsImagingBBox[1] *
+                        inheader.HWResolution[1] / 72.0);
+    page_top    = page_height - page_bottom - inheader.cupsHeight;
+    linesize    = (page_width * inheader.cupsBitsPerPixel + 7) / 8;
+    lineoffset  = page_left * inheader.cupsBitsPerPixel / 8; /* Round down */
+
+    switch (inheader.cupsColorSpace)
+    {
+      case CUPS_CSPACE_W :
+      case CUPS_CSPACE_RGB :
+      case CUPS_CSPACE_SW :
+      case CUPS_CSPACE_SRGB :
+      case CUPS_CSPACE_ADOBERGB :
+          white = 255;
+         break;
+
+      case CUPS_CSPACE_K :
+      case CUPS_CSPACE_CMYK :
+      case CUPS_CSPACE_DEVICE1 :
+      case CUPS_CSPACE_DEVICE2 :
+      case CUPS_CSPACE_DEVICE3 :
+      case CUPS_CSPACE_DEVICE4 :
+      case CUPS_CSPACE_DEVICE5 :
+      case CUPS_CSPACE_DEVICE6 :
+      case CUPS_CSPACE_DEVICE7 :
+      case CUPS_CSPACE_DEVICE8 :
+      case CUPS_CSPACE_DEVICE9 :
+      case CUPS_CSPACE_DEVICEA :
+      case CUPS_CSPACE_DEVICEB :
+      case CUPS_CSPACE_DEVICEC :
+      case CUPS_CSPACE_DEVICED :
+      case CUPS_CSPACE_DEVICEE :
+      case CUPS_CSPACE_DEVICEF :
+          white = 0;
+         break;
+      default :
+         _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
+         fprintf(stderr, "DEBUG: Unsupported cupsColorSpace %d on page %d.\n",
+                 inheader.cupsColorSpace, page);
+         return (1);
+    }
+
+    if (inheader.cupsColorOrder != CUPS_ORDER_CHUNKED)
+    {
+      _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
+      fprintf(stderr, "DEBUG: Unsupported cupsColorOrder %d on page %d.\n",
+              inheader.cupsColorOrder, page);
+      return (1);
+    }
+
+    if (inheader.cupsBitsPerPixel != 1 &&
+        inheader.cupsBitsPerColor != 8 && inheader.cupsBitsPerColor != 16)
+    {
+      _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
+      fprintf(stderr, "DEBUG: Unsupported cupsBitsPerColor %d on page %d.\n",
+              inheader.cupsBitsPerColor, page);
+      return (1);
+    }
+
+    memcpy(&outheader, &inheader, sizeof(outheader));
+    outheader.cupsWidth  = page_width;
+    outheader.cupsHeight       = page_height;
+    outheader.cupsBytesPerLine = linesize;
+
+    if (!cupsRasterWriteHeader2(outras, &outheader))
+    {
+      _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
+      fprintf(stderr, "DEBUG: Unable to write header for page %d.\n", page);
+      return (1);
+    }
+
+   /*
+    * Copy raster data...
+    */
+
+    line = malloc(linesize);
+
+    memset(line, white, linesize);
+    for (y = page_top; y > 0; y --)
+      if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
+      {
+       _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
+       fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
+               page_top - y + 1, page);
+       return (1);
+      }
+
+    for (y = inheader.cupsHeight; y > 0; y --)
+    {
+      cupsRasterReadPixels(inras, line + lineoffset, inheader.cupsBytesPerLine);
+      if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
+      {
+       _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
+       fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
+               inheader.cupsHeight - y + page_top + 1, page);
+       return (1);
+      }
+    }
+
+    memset(line, white, linesize);
+    for (y = page_top; y > 0; y --)
+      if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
+      {
+       _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
+       fprintf(stderr, "DEBUG: Unable to write line %d for page %d.\n",
+               page_bottom - y + page_top + inheader.cupsHeight + 1, page);
+       return (1);
+      }
+
+    free(line);
+  }
+
+  cupsRasterClose(inras);
+  if (fd)
+    close(fd);
+
+  cupsRasterClose(outras);
+
+  return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
index 366236a122feadce4560ac7fb0a21303ba26692f..0f85f305f831abdd58de8a3d903a531972c06a76 100644 (file)
@@ -1,9 +1,9 @@
 .\"
 .\" "$Id: client.conf.man.in 6649 2007-07-11 21:46:42Z mike $"
 .\"
-.\"   client.conf man page for the Common UNIX Printing System (CUPS).
+.\"   client.conf man page for CUPS.
 .\"
-.\"   Copyright 2007-2009 by Apple Inc.
+.\"   Copyright 2007-2011 by Apple Inc.
 .\"   Copyright 2006 by Easy Software Products.
 .\"
 .\"   These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
 .\"   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/".
 .\"
-.TH client.conf 5 "CUPS" "25 February 2006" "Apple Inc."
+.TH client.conf 5 "CUPS" "28 March 2011" "Apple Inc."
 .SH NAME
 client.conf \- client configuration file for cups
 .SH DESCRIPTION
@@ -34,16 +34,22 @@ Encryption Required
 Specifies the level of encryption that is required for a particular
 location.
 .TP 5
+GSSServiceName name
+Specifies the Kerberos service name that is used for authentication, typically
+"host", "http", or "ipp". CUPS adds the remote hostname
+("name@server.example.com") for you. The default name is
+"@CUPS_DEFAULT_GSSSERVICENAME@".
+.TP 5
 ServerName hostname-or-ip-address[:port]
 .TP 5
 ServerName /domain/socket
 .br
-Specifies the address and optionally the port to use when
-connecting to the server
+Specifies the address and optionally the port to use when connecting to the
+server.
 .SH SEE ALSO
 http://localhost:631/help
 .SH COPYRIGHT
-Copyright 2007-2009 by Apple Inc.
+Copyright 2007-2011 by Apple Inc.
 .\"
 .\" End of "$Id: client.conf.man.in 6649 2007-07-11 21:46:42Z mike $".
 .\"
index 5b183556ce01666025c981d1f2f5cb45b278d6cc..c313b52df473f5f74080d2f44582cb8dc47068b9 100644 (file)
@@ -1,9 +1,9 @@
 .\"
 .\" "$Id: lp.man 7889 2008-08-29 22:03:35Z mike $"
 .\"
-.\"   lp man page for the Common UNIX Printing System (CUPS).
+.\"   lp man page for CUPS.
 .\"
-.\"   Copyright 2007-2010 by Apple Inc.
+.\"   Copyright 2007-2011 by Apple Inc.
 .\"   Copyright 1997-2006 by Easy Software Products.
 .\"
 .\"   These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
 .\"   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/".
 .\"
-.TH lp 1 "CUPS" "31 August 2010" "Apple Inc."
+.TH lp 1 "CUPS" "31 March 2011" "Apple Inc."
 .SH NAME
 lp - print files
 .SH SYNOPSIS
@@ -142,11 +142,10 @@ Submits jobs as \fIusername\fR.
 .TP 5
 -H resume
 .br
-Specifies when the job should be printed. A value of
-\fIimmediate\fR will print the file immediately, a value of
-\fIhold\fR will hold the job indefinitely, and a time value
-(HH:MM) will hold the job until the specified time. Use a value
-of \fIresume\fR with the \fI-i\fR option to resume a held job.
+Specifies when the job should be printed. A value of \fIimmediate\fR will print
+the file immediately, a value of \fIhold\fR will hold the job indefinitely, and
+a UTC time value (HH:MM) will hold the job until the specified UTC (not local)
+time. Use a value of \fIresume\fR with the \fI-i\fR option to resume a held job.
 Use a value of \fIrestart\fR with the \fI-i\fR option to restart
 a completed job.
 .TP 5
@@ -257,7 +256,7 @@ is highest priority).
 .br
 http://localhost:631/help
 .SH COPYRIGHT
-Copyright 2007-2010 by Apple Inc.
+Copyright 2007-2011 by Apple Inc.
 .\"
 .\" End of "$Id: lp.man 7889 2008-08-29 22:03:35Z mike $".
 .\"
index 79b996edf132fe24615e330d12a123665a03477d..ee2d64a49bcb8e5ba3ff61fdf9a342e58a99d43f 100644 (file)
@@ -3,7 +3,7 @@
 #
 #   ESP Package Manager (EPM) file list for CUPS.
 #
-#   Copyright 2007-2010 by Apple Inc.
+#   Copyright 2007-2011 by Apple Inc.
 #   Copyright 1997-2007 by Easy Software Products, all rights reserved.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -15,7 +15,7 @@
 
 # Product information
 %product CUPS
-%copyright 2007-2010 by Apple Inc.
+%copyright 2007-2011 by Apple Inc.
 %vendor Apple Inc.
 #%license LICENSE.txt
 %readme LICENSE.txt
@@ -309,6 +309,7 @@ l 0755 root sys $SERVERBIN/filter/rastertodymo rastertolabel
 f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson
 f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp
 f 0555 root sys $SERVERBIN/filter/rastertopclx driver/rastertopclx
+f 0555 root sys $SERVERBIN/filter/rastertopwg filter/rastertopwg
 f 0555 root sys $SERVERBIN/filter/texttops filter/texttops
 d 0755 root sys $SERVERBIN/notifier -
 f 0555 root sys $SERVERBIN/notifier/mailto notifier/mailto
index d2e1b1374a3e3844e62ef34bc1ab5da8f1894b40..4d99f2653e7710660af940c2c85b57ca19ccd6e0 100644 (file)
@@ -27,7 +27,6 @@
  *                               access a location.
  *   cupsdCheckAuth()          - Check authorization masks.
  *   cupsdCheckGroup()         - Check for a user's group membership.
- *   cupsdCopyKrb5Creds()      - Get a copy of the Kerberos credentials.
  *   cupsdCopyLocation()       - Make a copy of a location...
  *   cupsdDeleteAllLocations() - Free all memory used for location
  *                               authorization.
@@ -382,6 +381,10 @@ cupsdAuthorize(cupsd_client_t *con)        /* I - Client connection */
   username[0] = '\0';
   password[0] = '\0';
 
+#ifdef HAVE_GSSAPI
+  con->gss_uid = 0;
+#endif /* HAVE_GSSAPI */
+
 #ifdef HAVE_AUTHORIZATION_H
   if (con->authref)
   {
@@ -991,102 +994,6 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     con->type = CUPSD_AUTH_DIGEST;
   }
 #ifdef HAVE_GSSAPI
-#  ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
-  else if (con->http.hostaddr->addr.sa_family == AF_LOCAL &&
-           !strncmp(authorization, "Negotiate", 9))
-  {
-   /*
-    * Pull the credentials directly from the user...
-    */
-
-    krb5_error_code    error;          /* Kerberos error code */
-    cupsd_ucred_t      peercred;       /* Peer credentials */
-    socklen_t          peersize;       /* Size of peer credentials */
-    krb5_ccache                peerccache;     /* Peer Kerberos credentials */
-    krb5_principal     peerprncpl;     /* Peer's default principal */
-    char               *peername;      /* Peer username */
-
-    peersize = sizeof(peercred);
-
-#    ifdef __APPLE__
-    if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
-#    else
-    if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
-#    endif /* __APPLE__ */
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
-                     strerror(errno));
-      return;
-    }
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "cupsdAuthorize: Copying credentials for UID %d...",
-                   CUPSD_UCRED_UID(peercred));
-
-    if (!KerberosInitialized)
-    {
-     /*
-      * Setup a Kerberos context for the scheduler to use...
-      */
-
-      KerberosInitialized = 1;
-
-      if (krb5_init_context(&KerberosContext))
-      {
-       KerberosContext = NULL;
-
-       cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unable to initialize Kerberos context");
-       return;
-      }
-    }
-
-    krb5_ipc_client_set_target_uid(CUPSD_UCRED_UID(peercred));
-
-    if ((error = krb5_cc_default(KerberosContext, &peerccache)) != 0)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unable to get credentials cache for UID %d (%d/%s)",
-                     (int)CUPSD_UCRED_UID(peercred), error, strerror(errno));
-      krb5_ipc_client_clear_target();
-      return;
-    }
-
-    if (krb5_cc_get_principal(KerberosContext, peerccache, &peerprncpl))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unable to get Kerberos principal for UID %d",
-                     (int)CUPSD_UCRED_UID(peercred));
-      krb5_cc_close(KerberosContext, peerccache);
-      krb5_ipc_client_clear_target();
-      return;
-    }
-
-    if (krb5_unparse_name(KerberosContext, peerprncpl, &peername))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unable to get Kerberos name for UID %d",
-                     (int)CUPSD_UCRED_UID(peercred));
-      krb5_cc_close(KerberosContext, peerccache);
-      krb5_ipc_client_clear_target();
-      return;
-    }
-
-    strlcpy(username, peername, sizeof(username));
-
-    con->have_gss = 1;
-    con->type     = CUPSD_AUTH_NEGOTIATE;
-
-    free(peername);
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                   "cupsdAuthorize: Authorized as %s using Negotiate",
-                   username);
-
-    krb5_cc_close(KerberosContext, peerccache);
-    krb5_ipc_client_clear_target();
-  }
-#  endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
   else if (!strncmp(authorization, "Negotiate", 9))
   {
     int                        len;            /* Length of authorization string */
@@ -1115,8 +1022,6 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
     }
 #  endif /* __APPLE__ */
 
-    con->gss_output_token.length = 0;
-
    /*
     * Find the start of the Kerberos input token...
     */
@@ -1155,10 +1060,13 @@ cupsdAuthorize(cupsd_client_t *con)     /* I - Client connection */
                                          GSS_C_NO_CHANNEL_BINDINGS,
                                          &client_name,
                                          NULL,
-                                         &con->gss_output_token,
-                                         &con->gss_flags,
+                                         &output_token,
                                          NULL,
-                                         &con->gss_creds);
+                                         NULL,
+                                         NULL);
+
+    if (output_token.length > 0)
+      gss_release_buffer(&minor_status, &output_token);
 
     if (GSS_ERROR(major_status))
     {
@@ -1177,10 +1085,6 @@ cupsdAuthorize(cupsd_client_t *con)      /* I - Client connection */
     * Get the username associated with the client's credentials...
     */
 
-    if (!con->gss_creds)
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                     "cupsdAuthorize: No delegated credentials!");
-
     if (major_status == GSS_S_CONTINUE_NEEDED)
       cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
                         "cupsdAuthorize: Credentials not complete");
@@ -1193,7 +1097,6 @@ cupsdAuthorize(cupsd_client_t *con)       /* I - Client connection */
       {
        cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
                           "cupsdAuthorize: Error getting username");
-       gss_release_cred(&minor_status, &con->gss_creds);
        gss_release_name(&minor_status, &client_name);
        gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
        return;
@@ -1210,10 +1113,41 @@ cupsdAuthorize(cupsd_client_t *con)     /* I - Client connection */
 
       con->type = CUPSD_AUTH_NEGOTIATE;
     }
-    else
-      gss_release_cred(&minor_status, &con->gss_creds);
 
     gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
+
+#  if defined(SO_PEERCRED) && defined(AF_LOCAL)
+   /*
+    * Get the client's UID if we are printing locally - that allows a backend
+    * to run as the correct user to get Kerberos credentials of its own.
+    */
+
+    if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
+    {
+      cupsd_ucred_t    peercred;       /* Peer credentials */
+      socklen_t                peersize;       /* Size of peer credentials */
+
+      peersize = sizeof(peercred);
+
+#    ifdef __APPLE__
+      if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+#    else
+      if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred,
+                     &peersize))
+#    endif /* __APPLE__ */
+      {
+       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
+                       strerror(errno));
+      }
+      else
+      {
+       cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "cupsdAuthorize: Using credentials for UID %d...",
+                       CUPSD_UCRED_UID(peercred));
+        con->gss_uid = CUPSD_UCRED_UID(peercred);
+      }
+    }
+#  endif /* SO_PEERCRED && AF_LOCAL */
   }
 #endif /* HAVE_GSSAPI */
   else
@@ -1597,178 +1531,6 @@ cupsdCheckGroup(
 }
 
 
-#ifdef HAVE_GSSAPI
-/*
- * 'cupsdCopyKrb5Creds()' - Get a copy of the Kerberos credentials.
- */
-
-krb5_ccache                            /* O - Credentials or NULL */
-cupsdCopyKrb5Creds(cupsd_client_t *con)        /* I - Client connection */
-{
-#  if !defined(HAVE_KRB5_CC_NEW_UNIQUE) && !defined(HAVE_HEIMDAL)
-  cupsdLogMessage(CUPSD_LOG_INFO,
-                  "Sorry, your version of Kerberos does not support delegated "
-                 "credentials!");
-  return (NULL);
-
-#  else
-  krb5_ccache          ccache = NULL;  /* Credentials */
-  krb5_error_code      error;          /* Kerberos error code */
-  OM_uint32            major_status,   /* Major status code */
-                       minor_status;   /* Minor status code */
-  krb5_principal       principal;      /* Kerberos principal */
-
-
-#    ifdef __APPLE__
- /*
-  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
-  * to use it...
-  */
-
-  if (krb5_init_context == NULL)
-    return (NULL);
-#    endif /* __APPLE__ */
-
-  if (!KerberosInitialized)
-  {
-   /*
-    * Setup a Kerberos context for the scheduler to use...
-    */
-
-    KerberosInitialized = 1;
-
-    if (krb5_init_context(&KerberosContext))
-    {
-      KerberosContext = NULL;
-
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context");
-      return (NULL);
-    }
-  }
-
- /*
-  * We MUST create a file-based cache because memory-based caches are
-  * only valid for the current process/address space.
-  *
-  * Due to various bugs/features in different versions of Kerberos, we
-  * need either the krb5_cc_new_unique() function or Heimdal's version
-  * of krb5_cc_gen_new() to create a new FILE: credential cache that
-  * can be passed to the backend.  These functions create a temporary
-  * file (typically in /tmp) containing the cached credentials, which
-  * are removed when we have successfully printed a job.
-  */
-
-#    ifdef HAVE_KRB5_CC_NEW_UNIQUE
-  if ((error = krb5_cc_new_unique(KerberosContext, "FILE", NULL, &ccache)) != 0)
-#    else /* HAVE_HEIMDAL */
-  if ((error = krb5_cc_gen_new(KerberosContext, &krb5_fcc_ops, &ccache)) != 0)
-#    endif /* HAVE_KRB5_CC_NEW_UNIQUE */
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Unable to create new credentials cache (%d/%s)",
-                    error, strerror(errno));
-    return (NULL);
-  }
-
-  if ((error = krb5_parse_name(KerberosContext, con->username, &principal)) != 0)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Unable to parse kerberos username (%d/%s)", error,
-                    strerror(errno));
-    krb5_cc_destroy(KerberosContext, ccache);
-    return (NULL);
-  }
-
-  if ((error = krb5_cc_initialize(KerberosContext, ccache, principal)))
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "Unable to initialize credentials cache (%d/%s)", error,
-                   strerror(errno));
-    krb5_cc_destroy(KerberosContext, ccache);
-    krb5_free_principal(KerberosContext, principal);
-    return (NULL);
-  }
-
-  krb5_free_principal(KerberosContext, principal);
-
- /*
-  * Copy the user's credentials to the new cache file...
-  */
-
-#    ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
-  if (con->http.hostaddr->addr.sa_family == AF_LOCAL &&
-      !(con->gss_flags & GSS_C_DELEG_FLAG))
-  {
-   /*
-    * Pull the credentials directly from the user...
-    */
-
-    cupsd_ucred_t      peercred;       /* Peer credentials */
-    socklen_t          peersize;       /* Size of peer credentials */
-    krb5_ccache                peerccache;     /* Peer Kerberos credentials */
-
-    peersize = sizeof(peercred);
-
-#      ifdef __APPLE__
-    if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
-#      else
-    if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
-#      endif /* __APPLE__ */
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
-                      strerror(errno));
-      krb5_cc_destroy(KerberosContext, ccache);
-      return (NULL);
-    }
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "cupsdCopyKrb5Creds: Copying credentials for UID %d...",
-                   CUPSD_UCRED_UID(peercred));
-
-    krb5_ipc_client_set_target_uid(CUPSD_UCRED_UID(peercred));
-
-    if ((error = krb5_cc_default(KerberosContext, &peerccache)) != 0)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unable to get credentials cache for UID %d (%d/%s)",
-                     (int)CUPSD_UCRED_UID(peercred), error, strerror(errno));
-      krb5_cc_destroy(KerberosContext, ccache);
-      return (NULL);
-    }
-
-    error = krb5_cc_copy_creds(KerberosContext, peerccache, ccache);
-    krb5_cc_close(KerberosContext, peerccache);
-    krb5_ipc_client_clear_target();
-
-    if (error)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unable to copy credentials cache for UID %d (%d/%s)",
-                     (int)CUPSD_UCRED_UID(peercred), error, strerror(errno));
-      krb5_cc_destroy(KerberosContext, ccache);
-      return (NULL);
-    }
-  }
-  else
-#    endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
-  {
-    major_status = gss_krb5_copy_ccache(&minor_status, con->gss_creds, ccache);
-
-    if (GSS_ERROR(major_status))
-    {
-      cupsdLogGSSMessage(CUPSD_LOG_ERROR, major_status, minor_status,
-                        "Unable to copy client credentials cache");
-      krb5_cc_destroy(KerberosContext, ccache);
-      return (NULL);
-    }
-  }
-
-  return (ccache);
-#  endif /* !HAVE_KRB5_CC_NEW_UNIQUE && !HAVE_HEIMDAL */
-}
-#endif /* HAVE_GSSAPI */
-
-
 /*
  * 'cupsdCopyLocation()' - Make a copy of a location...
  */
index 5e7525cbc0e9a4c16d1c251dce42503a25e57a55..e836f418cec955fa068e921bc311bf10251cfddd 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Authorization definitions for the CUPS scheduler.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -138,9 +138,6 @@ extern int          cupsdCheckAuth(unsigned ip[4], char *name, int namelen,
 extern int             cupsdCheckGroup(const char *username,
                                        struct passwd *user,
                                        const char *groupname);
-#ifdef HAVE_GSSAPI
-extern krb5_ccache     cupsdCopyKrb5Creds(cupsd_client_t *con);
-#endif /* HAVE_GSSAPI */
 extern cupsd_location_t        *cupsdCopyLocation(cupsd_location_t *loc);
 extern void            cupsdDeleteAllLocations(void);
 extern cupsd_location_t        *cupsdFindBest(const char *path, http_state_t state);
index f1f219e0c172511ee8b9c6cdeed6d874fd1ad0c4..5db08bd39c6d206c8a6be33443601d88a9230829 100644 (file)
@@ -859,12 +859,7 @@ cupsdReadClient(cupsd_client_t *con)       /* I - Client to read from */
 
 #ifdef HAVE_GSSAPI
         con->have_gss = 0;
-
-       if (con->gss_creds)
-       {
-         OM_uint32 minor_status;
-         gss_release_cred(&minor_status, &con->gss_creds);
-       }
+       con->gss_uid  = 0;
 #endif /* HAVE_GSSAPI */
 
        /*
@@ -2548,7 +2543,7 @@ cupsdSendHeader(
     int            auth_type)          /* I - Type of authentication */
 {
   char         auth_str[1024];         /* Authorization string */
-#ifdef HAVE_GSSAPI
+#if 0 /* def HAVE_GSSAPI */
   static char  *gss_buf = NULL;        /* Kerberos auth data buffer */
   static int   gss_bufsize = 0;        /* Size of Kerberos auth data buffer */
 #endif /* HAVE_GSSAPI */
@@ -2619,7 +2614,7 @@ cupsdSendHeader(
       snprintf(auth_str, sizeof(auth_str), "Digest realm=\"CUPS\", nonce=\"%s\"",
               con->http.hostname);
 #ifdef HAVE_GSSAPI
-    else if (auth_type == CUPSD_AUTH_NEGOTIATE && con->gss_output_token.length == 0)
+    else if (auth_type == CUPSD_AUTH_NEGOTIATE /* && con->gss_output_token.length == 0 */)
       strlcpy(auth_str, "Negotiate", sizeof(auth_str));
 #endif /* HAVE_GSSAPI */
 
@@ -2660,7 +2655,7 @@ cupsdSendHeader(
 #ifdef HAVE_AUTHORIZATION_H
          if (SystemGroupAuthKey)
            snprintf(auth_key, auth_size,
-                    ", authkey=\"%s\", trc=\"y\"",
+                    ", authkey=\"%s\"",
                     SystemGroupAuthKey);
           else
 #else
@@ -2682,7 +2677,7 @@ cupsdSendHeader(
     }
   }
 
-#ifdef HAVE_GSSAPI
+#if 0 /* def HAVE_GSSAPI */
  /*
   * WWW-Authenticate: Negotiate can be included even for
   * non-401 replies...
@@ -4966,15 +4961,6 @@ pipe_command(cupsd_client_t *con,        /* I - Client connection */
     snprintf(remote_user, sizeof(remote_user), "REMOTE_USER=%s", con->username);
 
     envp[envc ++] = remote_user;
-
-   /*
-    * Save Kerberos credentials, if any...
-    */
-
-#ifdef HAVE_GSSAPI
-    if (con->gss_creds)
-      ccache = cupsdCopyKrb5Creds(con);
-#endif /* HAVE_GSSAPI */
   }
 
   if (con->http.version == HTTP_1_1)
index a88f9dcefa34a8145d598f41bee6d6ba6d556a63..ded57bd75f7ba6b509a750014d34d1583cc26a3c 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Client definitions for the CUPS scheduler.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -56,10 +56,7 @@ struct cupsd_client_s
   int                  serverport;     /* Server port for connection */
 #ifdef HAVE_GSSAPI
   int                  have_gss;       /* Have GSS credentials? */
-  gss_cred_id_t        gss_creds;      /* Delegated credentials from client */
-  unsigned             gss_flags;      /* Credential flags */
-  gss_buffer_desc      gss_output_token;
-                                       /* Output token for Negotiate header */
+  uid_t                        gss_uid;        /* User ID for local prints */
 #endif /* HAVE_GSSAPI */
 #ifdef HAVE_AUTHORIZATION_H
   AuthorizationRef     authref;        /* Authorization ref */
index 5ddf5b3cf13ebf23d14dfc86e270d30fbfa6c1fd..8f78df3b865f066a8e0653c3ffead2f82d103925 100644 (file)
@@ -30,9 +30,9 @@
  *   dump_ppds_dat()   - Dump the contents of the ppds.dat file.
  *   free_array()      - Free an array of strings.
  *   list_ppds()       - List PPD files.
- *   load_ppds()       - Load PPD files recursively.
  *   load_drv()        - Load the PPDs from a driver information file.
  *   load_drivers()    - Load driver-generated PPD files.
+ *   load_ppds()       - Load PPD files recursively.
  *   load_ppds_dat()   - Load the ppds.dat file.
  *   regex_device_id() - Compile a regular expression based on the 1284 device
  *                       ID.
@@ -922,11 +922,14 @@ list_ppds(int        request_id,  /* I - Request ID */
 
   if (ChangedPPD)
   {
-    if ((fp = cupsFileOpen(filename, "w")) != NULL)
+    char       newname[1024];          /* New filename */
+
+    snprintf(newname, sizeof(newname), "%s.%d", filename, (int)getpid());
+
+    if ((fp = cupsFileOpen(newname, "w")) != NULL)
     {
       unsigned ppdsync = PPD_SYNC;     /* Sync word */
 
-
       cupsFileWrite(fp, (char *)&ppdsync, sizeof(ppdsync));
 
       for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByName);
@@ -936,8 +939,12 @@ list_ppds(int        request_id,   /* I - Request ID */
 
       cupsFileClose(fp);
 
-      fprintf(stderr, "INFO: [cups-driverd] Wrote \"%s\", %d PPDs...\n",
-              filename, cupsArrayCount(PPDsByName));
+      if (rename(newname, filename))
+       fprintf(stderr, "ERROR: [cups-driverd] Unable to rename \"%s\" - %s\n",
+               newname, strerror(errno));
+      else
+       fprintf(stderr, "INFO: [cups-driverd] Wrote \"%s\", %d PPDs...\n",
+               filename, cupsArrayCount(PPDsByName));
     }
     else
       fprintf(stderr, "ERROR: [cups-driverd] Unable to write \"%s\" - %s\n",
@@ -1337,931 +1344,931 @@ list_ppds(int        request_id,      /* I - Request ID */
 
 
 /*
- * 'load_ppds()' - Load PPD files recursively.
+ * 'load_drv()' - Load the PPDs from a driver information file.
  */
 
 static int                             /* O - 1 on success, 0 on failure */
-load_ppds(const char *d,               /* I - Actual directory */
-          const char *p,               /* I - Virtual path in name */
-         int        descend)           /* I - Descend into directories? */
+load_drv(const char  *filename,                /* I - Actual filename */
+         const char  *name,            /* I - Name to the rest of the world */
+         cups_file_t *fp,              /* I - File to read from */
+        time_t      mtime,             /* I - Mod time of driver info file */
+        off_t       size)              /* I - Size of driver info file */
 {
-  struct stat  dinfo,                  /* Directory information */
-               *dinfoptr;              /* Pointer to match */
-  int          i;                      /* Looping var */
-  cups_file_t  *fp;                    /* Pointer to file */
-  cups_dir_t   *dir;                   /* Directory pointer */
-  cups_dentry_t        *dent;                  /* Directory entry */
-  char         filename[1024],         /* Name of PPD or directory */
-               line[256],              /* Line from backend */
-               *ptr,                   /* Pointer into name */
-               name[128],              /* Name of PPD file */
-               lang_version[64],       /* PPD LanguageVersion */
-               lang_encoding[64],      /* PPD LanguageEncoding */
-               country[64],            /* Country code */
-               manufacturer[256],      /* Manufacturer */
-               make_model[256],        /* Make and Model */
-               model_name[256],        /* ModelName */
-               nick_name[256],         /* NickName */
-               device_id[256],         /* 1284DeviceID */
-               product[256],           /* Product */
-               psversion[256],         /* PSVersion */
-               temp[512];              /* Temporary make and model */
-  int          model_number,           /* cupsModelNumber */
-               type;                   /* ppd-type */
-  cups_array_t *products,              /* Product array */
-               *psversions,            /* PSVersion array */
-               *cups_languages;        /* cupsLanguages array */
-  ppd_info_t   *ppd,                   /* New PPD file */
-               key;                    /* Search key */
-  int          new_ppd;                /* Is this a new PPD? */
-  struct                               /* LanguageVersion translation table */
-  {
-    const char *version,               /* LanguageVersion string */
-               *language;              /* Language code */
-  }            languages[] =
-  {
-    { "chinese",               "zh" },
-    { "czech",                 "cs" },
-    { "danish",                        "da" },
-    { "dutch",                 "nl" },
-    { "english",               "en" },
-    { "finnish",               "fi" },
-    { "french",                        "fr" },
-    { "german",                        "de" },
-    { "greek",                 "el" },
-    { "hungarian",             "hu" },
-    { "italian",               "it" },
-    { "japanese",              "ja" },
-    { "korean",                        "ko" },
-    { "norwegian",             "no" },
-    { "polish",                        "pl" },
-    { "portuguese",            "pt" },
-    { "russian",               "ru" },
-    { "simplified chinese",    "zh_CN" },
-    { "slovak",                        "sk" },
-    { "spanish",               "es" },
-    { "swedish",               "sv" },
-    { "traditional chinese",   "zh_TW" },
-    { "turkish",               "tr" }
-  };
+  ppdcSource   *src;                   // Driver information file
+  ppdcDriver   *d;                     // Current driver
+  ppdcAttr     *device_id,             // 1284DeviceID attribute
+               *product,               // Current product value
+               *ps_version,            // PSVersion attribute
+               *cups_fax,              // cupsFax attribute
+               *nick_name;             // NickName attribute
+  ppdcFilter   *filter;                // Current filter
+  ppd_info_t   *ppd;                   // Current PPD
+  int          products_found;         // Number of products found
+  char         uri[1024],              // Driver URI
+               make_model[1024];       // Make and model
+  int          type;                   // Driver type
 
 
  /*
-  * See if we've loaded this directory before...
+  * Load the driver info file...
   */
 
-  if (stat(d, &dinfo))
-  {
-    if (errno != ENOENT)
-      fprintf(stderr, "ERROR: [cups-driverd] Unable to stat \"%s\": %s\n", d,
-             strerror(errno));
+  src = new ppdcSource(filename, fp);
 
-    return (0);
-  }
-  else if (cupsArrayFind(Inodes, &dinfo))
+  if (src->drivers->count == 0)
   {
-    fprintf(stderr, "ERROR: [cups-driverd] Skipping \"%s\": loop detected!\n",
-            d);
+    fprintf(stderr,
+            "ERROR: [cups-driverd] Bad driver information file \"%s\"!\n",
+           filename);
+    src->release();
     return (0);
   }
 
  /*
-  * Nope, add it to the Inodes array and continue...
+  * Add a dummy entry for the file...
   */
 
-  dinfoptr = (struct stat *)malloc(sizeof(struct stat));
-  memcpy(dinfoptr, &dinfo, sizeof(struct stat));
-  cupsArrayAdd(Inodes, dinfoptr);
-
-  if ((dir = cupsDirOpen(d)) == NULL)
-  {
-    if (errno != ENOENT)
-      fprintf(stderr,
-             "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n",
-             d, strerror(errno));
-
-    return (0);
-  }
+  add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0,
+          PPD_TYPE_DRV, "drv");
+  ChangedPPD = 1;
 
-  fprintf(stderr, "DEBUG: [cups-driverd] Loading \"%s\"...\n", d);
+ /*
+  * Then the drivers in the file...
+  */
 
-  while ((dent = cupsDirRead(dir)) != NULL)
+  for (d = (ppdcDriver *)src->drivers->first();
+       d;
+       d = (ppdcDriver *)src->drivers->next())
   {
-   /*
-    * Skip files/directories starting with "."...
-    */
-
-    if (dent->filename[0] == '.')
-      continue;
-
-   /*
-    * See if this is a file...
-    */
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0,
+                     "/%s/%s", name,
+                    d->file_name ? d->file_name->value :
+                                   d->pc_file_name->value);
 
-    snprintf(filename, sizeof(filename), "%s/%s", d, dent->filename);
+    device_id  = d->find_attr("1284DeviceID", NULL);
+    ps_version = d->find_attr("PSVersion", NULL);
+    nick_name  = d->find_attr("NickName", NULL);
 
-    if (p[0])
-      snprintf(name, sizeof(name), "%s/%s", p, dent->filename);
+    if (nick_name)
+      strlcpy(make_model, nick_name->value->value, sizeof(make_model));
+    else if (strncasecmp(d->model_name->value, d->manufacturer->value,
+                         strlen(d->manufacturer->value)))
+      snprintf(make_model, sizeof(make_model), "%s %s, %s",
+               d->manufacturer->value, d->model_name->value,
+              d->version->value);
     else
-      strlcpy(name, dent->filename, sizeof(name));
-
-    if (S_ISDIR(dent->fileinfo.st_mode))
-    {
-     /*
-      * Do subdirectory...
-      */
-
-      if (descend)
-       if (!load_ppds(filename, name, 1))
-       {
-         cupsDirClose(dir);
-         return (1);
-       }
+      snprintf(make_model, sizeof(make_model), "%s, %s", d->model_name->value,
+               d->version->value);
 
-      continue;
-    }
-    else if ((ptr = filename + strlen(filename) - 6) > filename &&
-             !strcmp(ptr, ".plist"))
+    if ((cups_fax = d->find_attr("cupsFax", NULL)) != NULL &&
+        !strcasecmp(cups_fax->value->value, "true"))
+      type = PPD_TYPE_FAX;
+    else if (d->type == PPDC_DRIVER_PS)
+      type = PPD_TYPE_POSTSCRIPT;
+    else if (d->type != PPDC_DRIVER_CUSTOM)
+      type = PPD_TYPE_RASTER;
+    else
     {
-     /*
-      * Skip plist files in the PPDs directory...
-      */
-
-      continue;
+      for (filter = (ppdcFilter *)d->filters->first(),
+               type = PPD_TYPE_POSTSCRIPT;
+          filter;
+          filter = (ppdcFilter *)d->filters->next())
+        if (strcasecmp(filter->mime_type->value, "application/vnd.cups-raster"))
+         type = PPD_TYPE_RASTER;
+        else if (strcasecmp(filter->mime_type->value,
+                           "application/vnd.cups-pdf"))
+         type = PPD_TYPE_PDF;
     }
 
-   /*
-    * See if this file has been scanned before...
-    */
+    for (product = (ppdcAttr *)d->attrs->first(), products_found = 0,
+             ppd = NULL;
+         product;
+        product = (ppdcAttr *)d->attrs->next())
+      if (!strcmp(product->name->value, "Product"))
+      {
+        if (!products_found)
+         ppd = add_ppd(name, uri, "en", d->manufacturer->value, make_model,
+                       device_id ? device_id->value->value : "",
+                       product->value->value,
+                       ps_version ? ps_version->value->value : "(3010) 0",
+                       mtime, size, d->model_number, type, "drv");
+       else if (products_found < PPD_MAX_PROD)
+         strlcpy(ppd->record.products[products_found], product->value->value,
+                 sizeof(ppd->record.products[0]));
+       else
+         break;
 
-    strcpy(key.record.filename, name);
-    strcpy(key.record.name, name);
+       products_found ++;
+      }
 
-    ppd = (ppd_info_t *)cupsArrayFind(PPDsByName, &key);
+    if (!products_found)
+      add_ppd(name, uri, "en", d->manufacturer->value, make_model,
+             device_id ? device_id->value->value : "",
+             d->model_name->value,
+             ps_version ? ps_version->value->value : "(3010) 0",
+             mtime, size, d->model_number, type, "drv");
+  }
 
-    if (ppd &&
-       ppd->record.size == dent->fileinfo.st_size &&
-       ppd->record.mtime == dent->fileinfo.st_mtime)
-    {
-     /*
-      * Rewind to the first entry for this file...
-      */
+  src->release();
 
-      while ((ppd = (ppd_info_t *)cupsArrayPrev(PPDsByName)) != NULL &&
-            !strcmp(ppd->record.filename, name));
+  return (1);
+}
 
-     /*
-      * Then mark all of the matches for this file as found...
-      */
 
-      while ((ppd = (ppd_info_t *)cupsArrayNext(PPDsByName)) != NULL &&
-            !strcmp(ppd->record.filename, name))
-        ppd->found = 1;
+/*
+ * 'load_drivers()' - Load driver-generated PPD files.
+ */
 
-      continue;
-    }
+static int                             /* O - 1 on success, 0 on failure */
+load_drivers(cups_array_t *include,    /* I - Drivers to include */
+             cups_array_t *exclude)    /* I - Drivers to exclude */
+{
+  int          i;                      /* Looping var */
+  char         *start,                 /* Start of value */
+               *ptr;                   /* Pointer into string */
+  const char   *server_bin,            /* CUPS_SERVERBIN env variable */
+               *scheme,                /* Scheme for this driver */
+               *scheme_end;            /* Pointer to end of scheme */
+  char         drivers[1024];          /* Location of driver programs */
+  int          pid;                    /* Process ID for driver program */
+  cups_file_t  *fp;                    /* Pipe to driver program */
+  cups_dir_t   *dir;                   /* Directory pointer */
+  cups_dentry_t *dent;                 /* Directory entry */
+  char         *argv[3],               /* Arguments for command */
+               filename[1024],         /* Name of driver */
+               line[2048],             /* Line from driver */
+               name[512],              /* ppd-name */
+               make[128],              /* ppd-make */
+               make_and_model[128],    /* ppd-make-and-model */
+               device_id[128],         /* ppd-device-id */
+               languages[128],         /* ppd-natural-language */
+               product[128],           /* ppd-product */
+               psversion[128],         /* ppd-psversion */
+               type_str[128];          /* ppd-type */
+  int          type;                   /* PPD type */
+  ppd_info_t   *ppd;                   /* Newly added PPD */
+
+
+ /*
+  * Try opening the driver directory...
+  */
+
+  if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL)
+    server_bin = CUPS_SERVERBIN;
+
+  snprintf(drivers, sizeof(drivers), "%s/driver", server_bin);
+
+  if ((dir = cupsDirOpen(drivers)) == NULL)
+  {
+    fprintf(stderr, "ERROR: [cups-driverd] Unable to open driver directory "
+                   "\"%s\": %s\n",
+           drivers, strerror(errno));
+    return (0);
+  }
+
+ /*
+  * Loop through all of the device drivers...
+  */
+
+  argv[1] = (char *)"list";
+  argv[2] = NULL;
 
+  while ((dent = cupsDirRead(dir)) != NULL)
+  {
    /*
-    * No, file is new/changed, so re-scan it...
+    * Only look at executable files...
     */
 
-    if ((fp = cupsFileOpen(filename, "r")) == NULL)
+    if (!(dent->fileinfo.st_mode & 0111) || !S_ISREG(dent->fileinfo.st_mode))
       continue;
 
    /*
-    * Now see if this is a PPD file...
+    * Include/exclude specific drivers...
     */
 
-    line[0] = '\0';
-    cupsFileGets(fp, line, sizeof(line));
+    if (exclude)
+    {
+     /*
+      * Look for "scheme" or "scheme*" (prefix match), and skip any matches.
+      */
 
-    if (strncmp(line, "*PPD-Adobe:", 11))
+      for (scheme = (char *)cupsArrayFirst(exclude);
+          scheme;
+          scheme = (char *)cupsArrayNext(exclude))
+      {
+        fprintf(stderr, "DEBUG: [cups-driverd] Exclude \"%s\" with \"%s\"?\n",
+               dent->filename, scheme);
+       scheme_end = scheme + strlen(scheme) - 1;
+
+       if ((scheme_end > scheme && *scheme_end == '*' &&
+            !strncmp(scheme, dent->filename, scheme_end - scheme)) ||
+           !strcmp(scheme, dent->filename))
+       {
+         fputs("DEBUG: [cups-driverd] Yes, exclude!\n", stderr);
+         break;
+       }
+      }
+
+      if (scheme)
+        continue;
+    }
+
+    if (include)
     {
      /*
-      * Nope, treat it as a driver information file...
+      * Look for "scheme" or "scheme*" (prefix match), and skip any non-matches.
       */
 
-      load_drv(filename, name, fp, dent->fileinfo.st_mtime,
-               dent->fileinfo.st_size);
-      continue;
+      for (scheme = (char *)cupsArrayFirst(include);
+          scheme;
+          scheme = (char *)cupsArrayNext(include))
+      {
+        fprintf(stderr, "DEBUG: [cups-driverd] Include \"%s\" with \"%s\"?\n",
+               dent->filename, scheme);
+       scheme_end = scheme + strlen(scheme) - 1;
+
+       if ((scheme_end > scheme && *scheme_end == '*' &&
+            !strncmp(scheme, dent->filename, scheme_end - scheme)) ||
+           !strcmp(scheme, dent->filename))
+       {
+         fputs("DEBUG: [cups-driverd] Yes, include!\n", stderr);
+         break;
+       }
+      }
+
+      if (!scheme)
+        continue;
     }
+    else
+      scheme = dent->filename;
 
    /*
-    * Now read until we get the NickName field...
+    * Run the driver with no arguments and collect the output...
     */
 
-    cups_languages = cupsArrayNew(NULL, NULL);
-    products       = cupsArrayNew(NULL, NULL);
-    psversions     = cupsArrayNew(NULL, NULL);
-
-    model_name[0]    = '\0';
-    nick_name[0]     = '\0';
-    manufacturer[0]  = '\0';
-    device_id[0]     = '\0';
-    lang_encoding[0] = '\0';
-    strcpy(lang_version, "en");
-    model_number     = 0;
-    type             = PPD_TYPE_POSTSCRIPT;
+    argv[0] = dent->filename;
+    snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename);
 
-    while (cupsFileGets(fp, line, sizeof(line)) != NULL)
+    if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL)
     {
-      if (!strncmp(line, "*Manufacturer:", 14))
-       sscanf(line, "%*[^\"]\"%255[^\"]", manufacturer);
-      else if (!strncmp(line, "*ModelName:", 11))
-       sscanf(line, "%*[^\"]\"%127[^\"]", model_name);
-      else if (!strncmp(line, "*LanguageEncoding:", 18))
-       sscanf(line, "%*[^:]:%63s", lang_encoding);
-      else if (!strncmp(line, "*LanguageVersion:", 17))
-       sscanf(line, "%*[^:]:%63s", lang_version);
-      else if (!strncmp(line, "*NickName:", 10))
-       sscanf(line, "%*[^\"]\"%255[^\"]", nick_name);
-      else if (!strncasecmp(line, "*1284DeviceID:", 14))
+      while (cupsFileGets(fp, line, sizeof(line)))
       {
-       sscanf(line, "%*[^\"]\"%255[^\"]", device_id);
+       /*
+        * Each line is of the form:
+       *
+       *   "ppd-name" ppd-natural-language "ppd-make" "ppd-make-and-model" \
+       *       "ppd-device-id" "ppd-product" "ppd-psversion"
+       */
 
-        // Make sure device ID ends with a semicolon...
-       if (device_id[0] && device_id[strlen(device_id) - 1] != ';')
-         strlcat(device_id, ";", sizeof(device_id));
-      }
-      else if (!strncmp(line, "*Product:", 9))
-      {
-       if (sscanf(line, "%*[^\"]\"(%255[^\"]", product) == 1)
+        device_id[0] = '\0';
+       product[0]   = '\0';
+       psversion[0] = '\0';
+       strcpy(type_str, "postscript");
+
+        if (sscanf(line, "\"%511[^\"]\"%127s%*[ \t]\"%127[^\"]\""
+                        "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\""
+                        "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\""
+                        "%*[ \t]\"%127[^\"]\"",
+                  name, languages, make, make_and_model,
+                  device_id, product, psversion, type_str) < 4)
+        {
+        /*
+         * Bad format; strip trailing newline and write an error message.
+         */
+
+          if (line[strlen(line) - 1] == '\n')
+           line[strlen(line) - 1] = '\0';
+
+         fprintf(stderr, "ERROR: [cups-driverd] Bad line from \"%s\": %s\n",
+                 dent->filename, line);
+         break;
+        }
+       else
        {
         /*
-         * Make sure the value ends with a right parenthesis - can't stop at
-         * the first right paren since the product name may contain escaped
-         * parenthesis...
+         * Add the device to the array of available devices...
          */
 
-         ptr = product + strlen(product) - 1;
-         if (ptr > product && *ptr == ')')
-         {
-          /*
-           * Yes, ends with a parenthesis, so remove it from the end and
-           * add the product to the list...
-           */
+          if ((start = strchr(languages, ',')) != NULL)
+           *start++ = '\0';
 
-           *ptr = '\0';
-           cupsArrayAdd(products, strdup(product));
-         }
-       }
-      }
-      else if (!strncmp(line, "*PSVersion:", 11))
-      {
-       sscanf(line, "%*[^\"]\"%255[^\"]", psversion);
-       cupsArrayAdd(psversions, strdup(psversion));
-      }
-      else if (!strncmp(line, "*cupsLanguages:", 15))
-      {
-        char   *start;                 /* Start of language */
+         for (type = 0;
+               type < (int)(sizeof(ppd_types) / sizeof(ppd_types[0]));
+              type ++)
+           if (!strcmp(type_str, ppd_types[type]))
+              break;
 
+         if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
+         {
+           fprintf(stderr,
+                   "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
+                   type_str);
+           type = PPD_TYPE_UNKNOWN;
+         }
 
-        for (start = line + 15; *start && isspace(*start & 255); start ++);
+          ppd = add_ppd(filename, name, languages, make, make_and_model,
+                        device_id, product, psversion, 0, 0, 0, type, scheme);
 
-       if (*start++ == '\"')
-       {
-         while (*start)
+          if (!ppd)
          {
-           for (ptr = start + 1;
-                *ptr && *ptr != '\"' && !isspace(*ptr & 255);
-                ptr ++);
+            cupsDirClose(dir);
+           cupsFileClose(fp);
+           return (0);
+         }
 
-            if (*ptr)
+          if (start && *start)
+         {
+           for (i = 1; i < PPD_MAX_LANG && *start; i ++)
            {
-             *ptr++ = '\0';
-
-             while (isspace(*ptr & 255))
+             if ((ptr = strchr(start, ',')) != NULL)
                *ptr++ = '\0';
-            }
+             else
+               ptr = start + strlen(start);
 
-            cupsArrayAdd(cups_languages, strdup(start));
-           start = ptr;
-         }
-       }
-      }
-      else if (!strncmp(line, "*cupsFax:", 9))
-      {
-        for (ptr = line + 9; isspace(*ptr & 255); ptr ++);
+              strlcpy(ppd->record.languages[i], start,
+                     sizeof(ppd->record.languages[0]));
 
-       if (!strncasecmp(ptr, "true", 4))
-          type = PPD_TYPE_FAX;
-      }
-      else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT)
-      {
-        if (strstr(line + 12, "application/vnd.cups-raster"))
-         type = PPD_TYPE_RASTER;
-        else if (strstr(line + 12, "application/vnd.cups-pdf"))
-         type = PPD_TYPE_PDF;
-      }
-      else if (!strncmp(line, "*cupsModelNumber:", 17))
-        sscanf(line, "*cupsModelNumber:%d", &model_number);
-      else if (!strncmp(line, "*OpenUI", 7))
-      {
-       /*
-        * Stop early if we have a NickName or ModelName attributes
-       * before the first OpenUI...
-       */
+             start = ptr;
+           }
+          }
 
-        if ((model_name[0] || nick_name[0]) && cupsArrayCount(products) > 0 &&
-           cupsArrayCount(psversions) > 0)
-         break;
+          fprintf(stderr, "DEBUG2: [cups-driverd] Added dynamic PPD \"%s\"...\n",
+                 name);
+       }
       }
+
+      cupsFileClose(fp);
     }
+    else
+      fprintf(stderr, "WARNING: [cups-driverd] Unable to execute \"%s\": %s\n",
+              filename, strerror(errno));
+  }
 
-   /*
-    * Close the file...
-    */
+  cupsDirClose(dir);
 
-    cupsFileClose(fp);
+  return (1);
+}
 
-   /*
-    * See if we got all of the required info...
-    */
 
-    if (nick_name[0])
-      cupsCharsetToUTF8((cups_utf8_t *)make_model, nick_name,
-                        sizeof(make_model), _ppdGetEncoding(lang_encoding));
-    else
-      strcpy(make_model, model_name);
+/*
+ * 'load_ppds()' - Load PPD files recursively.
+ */
 
-    while (isspace(make_model[0] & 255))
-      _cups_strcpy(make_model, make_model + 1);
+static int                             /* O - 1 on success, 0 on failure */
+load_ppds(const char *d,               /* I - Actual directory */
+          const char *p,               /* I - Virtual path in name */
+         int        descend)           /* I - Descend into directories? */
+{
+  struct stat  dinfo,                  /* Directory information */
+               *dinfoptr;              /* Pointer to match */
+  int          i;                      /* Looping var */
+  cups_file_t  *fp;                    /* Pointer to file */
+  cups_dir_t   *dir;                   /* Directory pointer */
+  cups_dentry_t        *dent;                  /* Directory entry */
+  char         filename[1024],         /* Name of PPD or directory */
+               line[256],              /* Line from backend */
+               *ptr,                   /* Pointer into name */
+               name[128],              /* Name of PPD file */
+               lang_version[64],       /* PPD LanguageVersion */
+               lang_encoding[64],      /* PPD LanguageEncoding */
+               country[64],            /* Country code */
+               manufacturer[256],      /* Manufacturer */
+               make_model[256],        /* Make and Model */
+               model_name[256],        /* ModelName */
+               nick_name[256],         /* NickName */
+               device_id[256],         /* 1284DeviceID */
+               product[256],           /* Product */
+               psversion[256],         /* PSVersion */
+               temp[512];              /* Temporary make and model */
+  int          model_number,           /* cupsModelNumber */
+               type;                   /* ppd-type */
+  cups_array_t *products,              /* Product array */
+               *psversions,            /* PSVersion array */
+               *cups_languages;        /* cupsLanguages array */
+  ppd_info_t   *ppd,                   /* New PPD file */
+               key;                    /* Search key */
+  int          new_ppd;                /* Is this a new PPD? */
+  struct                               /* LanguageVersion translation table */
+  {
+    const char *version,               /* LanguageVersion string */
+               *language;              /* Language code */
+  }            languages[] =
+  {
+    { "chinese",               "zh" },
+    { "czech",                 "cs" },
+    { "danish",                        "da" },
+    { "dutch",                 "nl" },
+    { "english",               "en" },
+    { "finnish",               "fi" },
+    { "french",                        "fr" },
+    { "german",                        "de" },
+    { "greek",                 "el" },
+    { "hungarian",             "hu" },
+    { "italian",               "it" },
+    { "japanese",              "ja" },
+    { "korean",                        "ko" },
+    { "norwegian",             "no" },
+    { "polish",                        "pl" },
+    { "portuguese",            "pt" },
+    { "russian",               "ru" },
+    { "simplified chinese",    "zh_CN" },
+    { "slovak",                        "sk" },
+    { "spanish",               "es" },
+    { "swedish",               "sv" },
+    { "traditional chinese",   "zh_TW" },
+    { "turkish",               "tr" }
+  };
 
-    if (!make_model[0] || cupsArrayCount(products) == 0 ||
-        cupsArrayCount(psversions) == 0)
-    {
-     /*
-      * We don't have all the info needed, so skip this file...
-      */
 
-      if (!make_model[0])
-        fprintf(stderr, "WARNING: Missing NickName and ModelName in %s!\n",
-               filename);
+ /*
+  * See if we've loaded this directory before...
+  */
 
-      if (cupsArrayCount(products) == 0)
-        fprintf(stderr, "WARNING: Missing Product in %s!\n", filename);
+  if (stat(d, &dinfo))
+  {
+    if (errno != ENOENT)
+      fprintf(stderr, "ERROR: [cups-driverd] Unable to stat \"%s\": %s\n", d,
+             strerror(errno));
 
-      if (cupsArrayCount(psversions) == 0)
-        fprintf(stderr, "WARNING: Missing PSVersion in %s!\n", filename);
+    return (0);
+  }
+  else if (cupsArrayFind(Inodes, &dinfo))
+  {
+    fprintf(stderr, "ERROR: [cups-driverd] Skipping \"%s\": loop detected!\n",
+            d);
+    return (0);
+  }
 
-      free_array(products);
-      free_array(psversions);
-      free_array(cups_languages);
+ /*
+  * Nope, add it to the Inodes array and continue...
+  */
 
-      continue;
-    }
+  dinfoptr = (struct stat *)malloc(sizeof(struct stat));
+  memcpy(dinfoptr, &dinfo, sizeof(struct stat));
+  cupsArrayAdd(Inodes, dinfoptr);
 
-    if (model_name[0])
-      cupsArrayAdd(products, strdup(model_name));
+  if ((dir = cupsDirOpen(d)) == NULL)
+  {
+    if (errno != ENOENT)
+      fprintf(stderr,
+             "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n",
+             d, strerror(errno));
 
-   /*
-    * Normalize the make and model string...
-    */
+    return (0);
+  }
 
-    while (isspace(manufacturer[0] & 255))
-      _cups_strcpy(manufacturer, manufacturer + 1);
+  fprintf(stderr, "DEBUG: [cups-driverd] Loading \"%s\"...\n", d);
 
-    if (!strncasecmp(make_model, manufacturer, strlen(manufacturer)))
-      strlcpy(temp, make_model, sizeof(temp));
-    else
-      snprintf(temp, sizeof(temp), "%s %s", manufacturer, make_model);
+  while ((dent = cupsDirRead(dir)) != NULL)
+  {
+   /*
+    * Skip files/directories starting with "."...
+    */
 
-    _ppdNormalizeMakeAndModel(temp, make_model, sizeof(make_model));
+    if (dent->filename[0] == '.')
+      continue;
 
    /*
-    * See if we got a manufacturer...
+    * See if this is a file...
     */
 
-    if (!manufacturer[0] || !strcmp(manufacturer, "ESP"))
+    snprintf(filename, sizeof(filename), "%s/%s", d, dent->filename);
+
+    if (p[0])
+      snprintf(name, sizeof(name), "%s/%s", p, dent->filename);
+    else
+      strlcpy(name, dent->filename, sizeof(name));
+
+    if (S_ISDIR(dent->fileinfo.st_mode))
     {
      /*
-      * Nope, copy the first part of the make and model then...
+      * Do subdirectory...
       */
 
-      strlcpy(manufacturer, make_model, sizeof(manufacturer));
+      if (descend)
+       if (!load_ppds(filename, name, 1))
+       {
+         cupsDirClose(dir);
+         return (1);
+       }
 
+      continue;
+    }
+    else if ((ptr = filename + strlen(filename) - 6) > filename &&
+             !strcmp(ptr, ".plist"))
+    {
      /*
-      * Truncate at the first space, dash, or slash, or make the
-      * manufacturer "Other"...
+      * Skip plist files in the PPDs directory...
       */
 
-      for (ptr = manufacturer; *ptr; ptr ++)
-       if (*ptr == ' ' || *ptr == '-' || *ptr == '/')
-         break;
-
-      if (*ptr && ptr > manufacturer)
-       *ptr = '\0';
-      else
-       strcpy(manufacturer, "Other");
+      continue;
     }
-    else if (!strncasecmp(manufacturer, "LHAG", 4) ||
-             !strncasecmp(manufacturer, "linotype", 8))
-      strcpy(manufacturer, "LHAG");
-    else if (!strncasecmp(manufacturer, "Hewlett", 7))
-      strcpy(manufacturer, "HP");
 
    /*
-    * Fix the lang_version as needed...
+    * See if this file has been scanned before...
     */
 
-    if ((ptr = strchr(lang_version, '-')) != NULL)
-      *ptr++ = '\0';
-    else if ((ptr = strchr(lang_version, '_')) != NULL)
-      *ptr++ = '\0';
+    strcpy(key.record.filename, name);
+    strcpy(key.record.name, name);
 
-    if (ptr)
+    ppd = (ppd_info_t *)cupsArrayFind(PPDsByName, &key);
+
+    if (ppd &&
+       ppd->record.size == dent->fileinfo.st_size &&
+       ppd->record.mtime == dent->fileinfo.st_mtime)
     {
      /*
-      * Setup the country suffix...
+      * Rewind to the first entry for this file...
       */
 
-      country[0] = '_';
-      _cups_strcpy(country + 1, ptr);
-    }
-    else
-    {
+      while ((ppd = (ppd_info_t *)cupsArrayPrev(PPDsByName)) != NULL &&
+            !strcmp(ppd->record.filename, name));
+
      /*
-      * No country suffix...
+      * Then mark all of the matches for this file as found...
       */
 
-      country[0] = '\0';
-    }
-
-    for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
-      if (!strcasecmp(languages[i].version, lang_version))
-        break;
-
-    if (i < (int)(sizeof(languages) / sizeof(languages[0])))
-    {
-     /*
-      * Found a known language...
-      */
-
-      snprintf(lang_version, sizeof(lang_version), "%s%s",
-               languages[i].language, country);
-    }
-    else
-    {
-     /*
-      * Unknown language; use "xx"...
-      */
+      while ((ppd = (ppd_info_t *)cupsArrayNext(PPDsByName)) != NULL &&
+            !strcmp(ppd->record.filename, name))
+        ppd->found = 1;
 
-      strcpy(lang_version, "xx");
+      continue;
     }
 
    /*
-    * Record the PPD file...
+    * No, file is new/changed, so re-scan it...
     */
 
-    new_ppd = !ppd;
-
-    if (new_ppd)
-    {
-     /*
-      * Add new PPD file...
-      */
+    if ((fp = cupsFileOpen(filename, "r")) == NULL)
+      continue;
 
-      fprintf(stderr, "DEBUG2: [cups-driverd] Adding ppd \"%s\"...\n", name);
+   /*
+    * Now see if this is a PPD file...
+    */
 
-      ppd = add_ppd(name, name, lang_version, manufacturer, make_model,
-                    device_id, (char *)cupsArrayFirst(products),
-                    (char *)cupsArrayFirst(psversions),
-                    dent->fileinfo.st_mtime, dent->fileinfo.st_size,
-                   model_number, type, "file");
+    line[0] = '\0';
+    cupsFileGets(fp, line, sizeof(line));
 
-      if (!ppd)
-      {
-        cupsDirClose(dir);
-       return (0);
-      }
-    }
-    else
+    if (strncmp(line, "*PPD-Adobe:", 11))
     {
      /*
-      * Update existing record...
+      * Nope, treat it as a driver information file...
       */
 
-      fprintf(stderr, "DEBUG2: [cups-driverd] Updating ppd \"%s\"...\n", name);
-
-      memset(ppd, 0, sizeof(ppd_info_t));
-
-      ppd->found               = 1;
-      ppd->record.mtime        = dent->fileinfo.st_mtime;
-      ppd->record.size         = dent->fileinfo.st_size;
-      ppd->record.model_number = model_number;
-      ppd->record.type         = type;
-
-      strlcpy(ppd->record.name, name, sizeof(ppd->record.name));
-      strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
-      strlcpy(ppd->record.make_and_model, make_model,
-              sizeof(ppd->record.make_and_model));
-      strlcpy(ppd->record.languages[0], lang_version,
-              sizeof(ppd->record.languages[0]));
-      strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products),
-              sizeof(ppd->record.products[0]));
-      strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions),
-              sizeof(ppd->record.psversions[0]));
-      strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
+      load_drv(filename, name, fp, dent->fileinfo.st_mtime,
+               dent->fileinfo.st_size);
+      continue;
     }
 
    /*
-    * Add remaining products, versions, and languages...
-    */
-
-    for (i = 1;
-         i < PPD_MAX_PROD && (ptr = (char *)cupsArrayNext(products)) != NULL;
-        i ++)
-      strlcpy(ppd->record.products[i], ptr,
-              sizeof(ppd->record.products[0]));
-
-    for (i = 1;
-         i < PPD_MAX_VERS && (ptr = (char *)cupsArrayNext(psversions)) != NULL;
-        i ++)
-      strlcpy(ppd->record.psversions[i], ptr,
-              sizeof(ppd->record.psversions[0]));
-
-    for (i = 1, ptr = (char *)cupsArrayFirst(cups_languages);
-         i < PPD_MAX_LANG && ptr;
-        i ++, ptr = (char *)cupsArrayNext(cups_languages))
-      strlcpy(ppd->record.languages[i], ptr,
-              sizeof(ppd->record.languages[0]));
-
-   /*
-    * Free products, versions, and languages...
+    * Now read until we get the NickName field...
     */
 
-    free_array(cups_languages);
-    free_array(products);
-    free_array(psversions);
-
-    ChangedPPD = 1;
-  }
-
-  cupsDirClose(dir);
-
-  return (1);
-}
-
-
-/*
- * 'load_drv()' - Load the PPDs from a driver information file.
- */
+    cups_languages = cupsArrayNew(NULL, NULL);
+    products       = cupsArrayNew(NULL, NULL);
+    psversions     = cupsArrayNew(NULL, NULL);
 
-static int                             /* O - 1 on success, 0 on failure */
-load_drv(const char  *filename,                /* I - Actual filename */
-         const char  *name,            /* I - Name to the rest of the world */
-         cups_file_t *fp,              /* I - File to read from */
-        time_t      mtime,             /* I - Mod time of driver info file */
-        off_t       size)              /* I - Size of driver info file */
-{
-  ppdcSource   *src;                   // Driver information file
-  ppdcDriver   *d;                     // Current driver
-  ppdcAttr     *device_id,             // 1284DeviceID attribute
-               *product,               // Current product value
-               *ps_version,            // PSVersion attribute
-               *cups_fax,              // cupsFax attribute
-               *nick_name;             // NickName attribute
-  ppdcFilter   *filter;                // Current filter
-  ppd_info_t   *ppd;                   // Current PPD
-  int          products_found;         // Number of products found
-  char         uri[1024],              // Driver URI
-               make_model[1024];       // Make and model
-  int          type;                   // Driver type
+    model_name[0]    = '\0';
+    nick_name[0]     = '\0';
+    manufacturer[0]  = '\0';
+    device_id[0]     = '\0';
+    lang_encoding[0] = '\0';
+    strcpy(lang_version, "en");
+    model_number     = 0;
+    type             = PPD_TYPE_POSTSCRIPT;
 
+    while (cupsFileGets(fp, line, sizeof(line)) != NULL)
+    {
+      if (!strncmp(line, "*Manufacturer:", 14))
+       sscanf(line, "%*[^\"]\"%255[^\"]", manufacturer);
+      else if (!strncmp(line, "*ModelName:", 11))
+       sscanf(line, "%*[^\"]\"%127[^\"]", model_name);
+      else if (!strncmp(line, "*LanguageEncoding:", 18))
+       sscanf(line, "%*[^:]:%63s", lang_encoding);
+      else if (!strncmp(line, "*LanguageVersion:", 17))
+       sscanf(line, "%*[^:]:%63s", lang_version);
+      else if (!strncmp(line, "*NickName:", 10))
+       sscanf(line, "%*[^\"]\"%255[^\"]", nick_name);
+      else if (!strncasecmp(line, "*1284DeviceID:", 14))
+      {
+       sscanf(line, "%*[^\"]\"%255[^\"]", device_id);
 
- /*
-  * Load the driver info file...
-  */
+        // Make sure device ID ends with a semicolon...
+       if (device_id[0] && device_id[strlen(device_id) - 1] != ';')
+         strlcat(device_id, ";", sizeof(device_id));
+      }
+      else if (!strncmp(line, "*Product:", 9))
+      {
+       if (sscanf(line, "%*[^\"]\"(%255[^\"]", product) == 1)
+       {
+        /*
+         * Make sure the value ends with a right parenthesis - can't stop at
+         * the first right paren since the product name may contain escaped
+         * parenthesis...
+         */
 
-  src = new ppdcSource(filename, fp);
+         ptr = product + strlen(product) - 1;
+         if (ptr > product && *ptr == ')')
+         {
+          /*
+           * Yes, ends with a parenthesis, so remove it from the end and
+           * add the product to the list...
+           */
 
-  if (src->drivers->count == 0)
-  {
-    fprintf(stderr,
-            "ERROR: [cups-driverd] Bad driver information file \"%s\"!\n",
-           filename);
-    src->release();
-    return (0);
-  }
+           *ptr = '\0';
+           cupsArrayAdd(products, strdup(product));
+         }
+       }
+      }
+      else if (!strncmp(line, "*PSVersion:", 11))
+      {
+       sscanf(line, "%*[^\"]\"%255[^\"]", psversion);
+       cupsArrayAdd(psversions, strdup(psversion));
+      }
+      else if (!strncmp(line, "*cupsLanguages:", 15))
+      {
+        char   *start;                 /* Start of language */
 
- /*
-  * Add a dummy entry for the file...
-  */
 
-  add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0,
-          PPD_TYPE_DRV, "drv");
-  ChangedPPD = 1;
+        for (start = line + 15; *start && isspace(*start & 255); start ++);
 
- /*
-  * Then the drivers in the file...
-  */
+       if (*start++ == '\"')
+       {
+         while (*start)
+         {
+           for (ptr = start + 1;
+                *ptr && *ptr != '\"' && !isspace(*ptr & 255);
+                ptr ++);
 
-  for (d = (ppdcDriver *)src->drivers->first();
-       d;
-       d = (ppdcDriver *)src->drivers->next())
-  {
-    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0,
-                     "/%s/%s", name,
-                    d->file_name ? d->file_name->value :
-                                   d->pc_file_name->value);
+            if (*ptr)
+           {
+             *ptr++ = '\0';
 
-    device_id  = d->find_attr("1284DeviceID", NULL);
-    ps_version = d->find_attr("PSVersion", NULL);
-    nick_name  = d->find_attr("NickName", NULL);
+             while (isspace(*ptr & 255))
+               *ptr++ = '\0';
+            }
 
-    if (nick_name)
-      strlcpy(make_model, nick_name->value->value, sizeof(make_model));
-    else if (strncasecmp(d->model_name->value, d->manufacturer->value,
-                         strlen(d->manufacturer->value)))
-      snprintf(make_model, sizeof(make_model), "%s %s, %s",
-               d->manufacturer->value, d->model_name->value,
-              d->version->value);
-    else
-      snprintf(make_model, sizeof(make_model), "%s, %s", d->model_name->value,
-               d->version->value);
+            cupsArrayAdd(cups_languages, strdup(start));
+           start = ptr;
+         }
+       }
+      }
+      else if (!strncmp(line, "*cupsFax:", 9))
+      {
+        for (ptr = line + 9; isspace(*ptr & 255); ptr ++);
 
-    if ((cups_fax = d->find_attr("cupsFax", NULL)) != NULL &&
-        !strcasecmp(cups_fax->value->value, "true"))
-      type = PPD_TYPE_FAX;
-    else if (d->type == PPDC_DRIVER_PS)
-      type = PPD_TYPE_POSTSCRIPT;
-    else if (d->type != PPDC_DRIVER_CUSTOM)
-      type = PPD_TYPE_RASTER;
-    else
-    {
-      for (filter = (ppdcFilter *)d->filters->first(),
-               type = PPD_TYPE_POSTSCRIPT;
-          filter;
-          filter = (ppdcFilter *)d->filters->next())
-        if (strcasecmp(filter->mime_type->value, "application/vnd.cups-raster"))
+       if (!strncasecmp(ptr, "true", 4))
+          type = PPD_TYPE_FAX;
+      }
+      else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT)
+      {
+        if (strstr(line + 12, "application/vnd.cups-raster"))
          type = PPD_TYPE_RASTER;
-        else if (strcasecmp(filter->mime_type->value,
-                           "application/vnd.cups-pdf"))
+        else if (strstr(line + 12, "application/vnd.cups-pdf"))
          type = PPD_TYPE_PDF;
-    }
-
-    for (product = (ppdcAttr *)d->attrs->first(), products_found = 0,
-             ppd = NULL;
-         product;
-        product = (ppdcAttr *)d->attrs->next())
-      if (!strcmp(product->name->value, "Product"))
+      }
+      else if (!strncmp(line, "*cupsModelNumber:", 17))
+        sscanf(line, "*cupsModelNumber:%d", &model_number);
+      else if (!strncmp(line, "*OpenUI", 7))
       {
-        if (!products_found)
-         ppd = add_ppd(name, uri, "en", d->manufacturer->value, make_model,
-                       device_id ? device_id->value->value : "",
-                       product->value->value,
-                       ps_version ? ps_version->value->value : "(3010) 0",
-                       mtime, size, d->model_number, type, "drv");
-       else if (products_found < PPD_MAX_PROD)
-         strlcpy(ppd->record.products[products_found], product->value->value,
-                 sizeof(ppd->record.products[0]));
-       else
-         break;
+       /*
+        * Stop early if we have a NickName or ModelName attributes
+       * before the first OpenUI...
+       */
 
-       products_found ++;
+        if ((model_name[0] || nick_name[0]) && cupsArrayCount(products) > 0 &&
+           cupsArrayCount(psversions) > 0)
+         break;
       }
+    }
 
-    if (!products_found)
-      add_ppd(name, uri, "en", d->manufacturer->value, make_model,
-             device_id ? device_id->value->value : "",
-             d->model_name->value,
-             ps_version ? ps_version->value->value : "(3010) 0",
-             mtime, size, d->model_number, type, "drv");
-  }
-
-  src->release();
+   /*
+    * Close the file...
+    */
 
-  return (1);
-}
+    cupsFileClose(fp);
 
+   /*
+    * See if we got all of the required info...
+    */
 
-/*
- * 'load_drivers()' - Load driver-generated PPD files.
- */
+    if (nick_name[0])
+      cupsCharsetToUTF8((cups_utf8_t *)make_model, nick_name,
+                        sizeof(make_model), _ppdGetEncoding(lang_encoding));
+    else
+      strcpy(make_model, model_name);
 
-static int                             /* O - 1 on success, 0 on failure */
-load_drivers(cups_array_t *include,    /* I - Drivers to include */
-             cups_array_t *exclude)    /* I - Drivers to exclude */
-{
-  int          i;                      /* Looping var */
-  char         *start,                 /* Start of value */
-               *ptr;                   /* Pointer into string */
-  const char   *server_bin,            /* CUPS_SERVERBIN env variable */
-               *scheme,                /* Scheme for this driver */
-               *scheme_end;            /* Pointer to end of scheme */
-  char         drivers[1024];          /* Location of driver programs */
-  int          pid;                    /* Process ID for driver program */
-  cups_file_t  *fp;                    /* Pipe to driver program */
-  cups_dir_t   *dir;                   /* Directory pointer */
-  cups_dentry_t *dent;                 /* Directory entry */
-  char         *argv[3],               /* Arguments for command */
-               filename[1024],         /* Name of driver */
-               line[2048],             /* Line from driver */
-               name[512],              /* ppd-name */
-               make[128],              /* ppd-make */
-               make_and_model[128],    /* ppd-make-and-model */
-               device_id[128],         /* ppd-device-id */
-               languages[128],         /* ppd-natural-language */
-               product[128],           /* ppd-product */
-               psversion[128],         /* ppd-psversion */
-               type_str[128];          /* ppd-type */
-  int          type;                   /* PPD type */
-  ppd_info_t   *ppd;                   /* Newly added PPD */
+    while (isspace(make_model[0] & 255))
+      _cups_strcpy(make_model, make_model + 1);
 
+    if (!make_model[0] || cupsArrayCount(products) == 0 ||
+        cupsArrayCount(psversions) == 0)
+    {
+     /*
+      * We don't have all the info needed, so skip this file...
+      */
 
- /*
-  * Try opening the driver directory...
-  */
+      if (!make_model[0])
+        fprintf(stderr, "WARNING: Missing NickName and ModelName in %s!\n",
+               filename);
 
-  if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL)
-    server_bin = CUPS_SERVERBIN;
+      if (cupsArrayCount(products) == 0)
+        fprintf(stderr, "WARNING: Missing Product in %s!\n", filename);
 
-  snprintf(drivers, sizeof(drivers), "%s/driver", server_bin);
+      if (cupsArrayCount(psversions) == 0)
+        fprintf(stderr, "WARNING: Missing PSVersion in %s!\n", filename);
 
-  if ((dir = cupsDirOpen(drivers)) == NULL)
-  {
-    fprintf(stderr, "ERROR: [cups-driverd] Unable to open driver directory "
-                   "\"%s\": %s\n",
-           drivers, strerror(errno));
-    return (0);
-  }
+      free_array(products);
+      free_array(psversions);
+      free_array(cups_languages);
 
- /*
-  * Loop through all of the device drivers...
-  */
+      continue;
+    }
 
-  argv[1] = (char *)"list";
-  argv[2] = NULL;
+    if (model_name[0])
+      cupsArrayAdd(products, strdup(model_name));
 
-  while ((dent = cupsDirRead(dir)) != NULL)
-  {
    /*
-    * Only look at executable files...
+    * Normalize the make and model string...
     */
 
-    if (!(dent->fileinfo.st_mode & 0111) || !S_ISREG(dent->fileinfo.st_mode))
-      continue;
+    while (isspace(manufacturer[0] & 255))
+      _cups_strcpy(manufacturer, manufacturer + 1);
+
+    if (!strncasecmp(make_model, manufacturer, strlen(manufacturer)))
+      strlcpy(temp, make_model, sizeof(temp));
+    else
+      snprintf(temp, sizeof(temp), "%s %s", manufacturer, make_model);
+
+    _ppdNormalizeMakeAndModel(temp, make_model, sizeof(make_model));
 
    /*
-    * Include/exclude specific drivers...
+    * See if we got a manufacturer...
     */
 
-    if (exclude)
+    if (!manufacturer[0] || !strcmp(manufacturer, "ESP"))
     {
      /*
-      * Look for "scheme" or "scheme*" (prefix match), and skip any matches.
+      * Nope, copy the first part of the make and model then...
       */
 
-      for (scheme = (char *)cupsArrayFirst(exclude);
-          scheme;
-          scheme = (char *)cupsArrayNext(exclude))
-      {
-        fprintf(stderr, "DEBUG: [cups-driverd] Exclude \"%s\" with \"%s\"?\n",
-               dent->filename, scheme);
-       scheme_end = scheme + strlen(scheme) - 1;
+      strlcpy(manufacturer, make_model, sizeof(manufacturer));
 
-       if ((scheme_end > scheme && *scheme_end == '*' &&
-            !strncmp(scheme, dent->filename, scheme_end - scheme)) ||
-           !strcmp(scheme, dent->filename))
-       {
-         fputs("DEBUG: [cups-driverd] Yes, exclude!\n", stderr);
+     /*
+      * Truncate at the first space, dash, or slash, or make the
+      * manufacturer "Other"...
+      */
+
+      for (ptr = manufacturer; *ptr; ptr ++)
+       if (*ptr == ' ' || *ptr == '-' || *ptr == '/')
          break;
-       }
-      }
 
-      if (scheme)
-        continue;
+      if (*ptr && ptr > manufacturer)
+       *ptr = '\0';
+      else
+       strcpy(manufacturer, "Other");
     }
+    else if (!strncasecmp(manufacturer, "LHAG", 4) ||
+             !strncasecmp(manufacturer, "linotype", 8))
+      strcpy(manufacturer, "LHAG");
+    else if (!strncasecmp(manufacturer, "Hewlett", 7))
+      strcpy(manufacturer, "HP");
 
-    if (include)
+   /*
+    * Fix the lang_version as needed...
+    */
+
+    if ((ptr = strchr(lang_version, '-')) != NULL)
+      *ptr++ = '\0';
+    else if ((ptr = strchr(lang_version, '_')) != NULL)
+      *ptr++ = '\0';
+
+    if (ptr)
     {
      /*
-      * Look for "scheme" or "scheme*" (prefix match), and skip any non-matches.
+      * Setup the country suffix...
       */
 
-      for (scheme = (char *)cupsArrayFirst(include);
-          scheme;
-          scheme = (char *)cupsArrayNext(include))
-      {
-        fprintf(stderr, "DEBUG: [cups-driverd] Include \"%s\" with \"%s\"?\n",
-               dent->filename, scheme);
-       scheme_end = scheme + strlen(scheme) - 1;
+      country[0] = '_';
+      _cups_strcpy(country + 1, ptr);
+    }
+    else
+    {
+     /*
+      * No country suffix...
+      */
 
-       if ((scheme_end > scheme && *scheme_end == '*' &&
-            !strncmp(scheme, dent->filename, scheme_end - scheme)) ||
-           !strcmp(scheme, dent->filename))
-       {
-         fputs("DEBUG: [cups-driverd] Yes, include!\n", stderr);
-         break;
-       }
-      }
+      country[0] = '\0';
+    }
 
-      if (!scheme)
-        continue;
+    for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
+      if (!strcasecmp(languages[i].version, lang_version))
+        break;
+
+    if (i < (int)(sizeof(languages) / sizeof(languages[0])))
+    {
+     /*
+      * Found a known language...
+      */
+
+      snprintf(lang_version, sizeof(lang_version), "%s%s",
+               languages[i].language, country);
     }
     else
-      scheme = dent->filename;
+    {
+     /*
+      * Unknown language; use "xx"...
+      */
+
+      strcpy(lang_version, "xx");
+    }
 
    /*
-    * Run the driver with no arguments and collect the output...
+    * Record the PPD file...
     */
 
-    argv[0] = dent->filename;
-    snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename);
+    new_ppd = !ppd;
 
-    if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL)
+    if (new_ppd)
     {
-      while (cupsFileGets(fp, line, sizeof(line)))
-      {
-       /*
-        * Each line is of the form:
-       *
-       *   "ppd-name" ppd-natural-language "ppd-make" "ppd-make-and-model" \
-       *       "ppd-device-id" "ppd-product" "ppd-psversion"
-       */
+     /*
+      * Add new PPD file...
+      */
 
-        device_id[0] = '\0';
-       product[0]   = '\0';
-       psversion[0] = '\0';
-       strcpy(type_str, "postscript");
+      fprintf(stderr, "DEBUG2: [cups-driverd] Adding ppd \"%s\"...\n", name);
 
-        if (sscanf(line, "\"%511[^\"]\"%127s%*[ \t]\"%127[^\"]\""
-                        "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\""
-                        "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\""
-                        "%*[ \t]\"%127[^\"]\"",
-                  name, languages, make, make_and_model,
-                  device_id, product, psversion, type_str) < 4)
-        {
-        /*
-         * Bad format; strip trailing newline and write an error message.
-         */
+      ppd = add_ppd(name, name, lang_version, manufacturer, make_model,
+                    device_id, (char *)cupsArrayFirst(products),
+                    (char *)cupsArrayFirst(psversions),
+                    dent->fileinfo.st_mtime, dent->fileinfo.st_size,
+                   model_number, type, "file");
 
-          if (line[strlen(line) - 1] == '\n')
-           line[strlen(line) - 1] = '\0';
+      if (!ppd)
+      {
+        cupsDirClose(dir);
+       return (0);
+      }
+    }
+    else
+    {
+     /*
+      * Update existing record...
+      */
 
-         fprintf(stderr, "ERROR: [cups-driverd] Bad line from \"%s\": %s\n",
-                 dent->filename, line);
-         break;
-        }
-       else
-       {
-        /*
-         * Add the device to the array of available devices...
-         */
+      fprintf(stderr, "DEBUG2: [cups-driverd] Updating ppd \"%s\"...\n", name);
 
-          if ((start = strchr(languages, ',')) != NULL)
-           *start++ = '\0';
+      memset(ppd, 0, sizeof(ppd_info_t));
 
-         for (type = 0;
-               type < (int)(sizeof(ppd_types) / sizeof(ppd_types[0]));
-              type ++)
-           if (!strcmp(type_str, ppd_types[type]))
-              break;
+      ppd->found               = 1;
+      ppd->record.mtime        = dent->fileinfo.st_mtime;
+      ppd->record.size         = dent->fileinfo.st_size;
+      ppd->record.model_number = model_number;
+      ppd->record.type         = type;
 
-         if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
-         {
-           fprintf(stderr,
-                   "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
-                   type_str);
-           type = PPD_TYPE_UNKNOWN;
-         }
+      strlcpy(ppd->record.name, name, sizeof(ppd->record.name));
+      strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
+      strlcpy(ppd->record.make_and_model, make_model,
+              sizeof(ppd->record.make_and_model));
+      strlcpy(ppd->record.languages[0], lang_version,
+              sizeof(ppd->record.languages[0]));
+      strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products),
+              sizeof(ppd->record.products[0]));
+      strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions),
+              sizeof(ppd->record.psversions[0]));
+      strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
+    }
 
-          ppd = add_ppd(filename, name, languages, make, make_and_model,
-                        device_id, product, psversion, 0, 0, 0, type, scheme);
+   /*
+    * Add remaining products, versions, and languages...
+    */
 
-          if (!ppd)
-         {
-            cupsDirClose(dir);
-           cupsFileClose(fp);
-           return (0);
-         }
+    for (i = 1;
+         i < PPD_MAX_PROD && (ptr = (char *)cupsArrayNext(products)) != NULL;
+        i ++)
+      strlcpy(ppd->record.products[i], ptr,
+              sizeof(ppd->record.products[0]));
 
-          if (start && *start)
-         {
-           for (i = 1; i < PPD_MAX_LANG && *start; i ++)
-           {
-             if ((ptr = strchr(start, ',')) != NULL)
-               *ptr++ = '\0';
-             else
-               ptr = start + strlen(start);
+    for (i = 1;
+         i < PPD_MAX_VERS && (ptr = (char *)cupsArrayNext(psversions)) != NULL;
+        i ++)
+      strlcpy(ppd->record.psversions[i], ptr,
+              sizeof(ppd->record.psversions[0]));
 
-              strlcpy(ppd->record.languages[i], start,
-                     sizeof(ppd->record.languages[0]));
+    for (i = 1, ptr = (char *)cupsArrayFirst(cups_languages);
+         i < PPD_MAX_LANG && ptr;
+        i ++, ptr = (char *)cupsArrayNext(cups_languages))
+      strlcpy(ppd->record.languages[i], ptr,
+              sizeof(ppd->record.languages[0]));
 
-             start = ptr;
-           }
-          }
+   /*
+    * Free products, versions, and languages...
+    */
 
-          fprintf(stderr, "DEBUG2: [cups-driverd] Added dynamic PPD \"%s\"...\n",
-                 name);
-       }
-      }
+    free_array(cups_languages);
+    free_array(products);
+    free_array(psversions);
 
-      cupsFileClose(fp);
-    }
-    else
-      fprintf(stderr, "WARNING: [cups-driverd] Unable to execute \"%s\": %s\n",
-              filename, strerror(errno));
+    ChangedPPD = 1;
   }
 
   cupsDirClose(dir);
@@ -2302,7 +2309,6 @@ load_ppds_dat(char   *filename,           /* I - Filename buffer */
     unsigned ppdsync;                  /* Sync word */
     int      num_ppds;                 /* Number of PPDs */
 
-
     if (cupsFileRead(fp, (char *)&ppdsync, sizeof(ppdsync))
             == sizeof(ppdsync) &&
         ppdsync == PPD_SYNC &&
index 1234de52a957a90c38c1c1587c4ca8c3fe8ecd01..9f734da56dd38229442499da9a2888dacf8c85bf 100644 (file)
  *   mimeAddFilter()    - Add a filter to the current MIME database.
  *   mimeFilter()       - Find the fastest way to convert from one type to
  *                        another.
- *   mimeFilterLookup() - Lookup a filter...
- *   compare_filters()  - Compare two filters...
+ *   mimeFilter2()      - Find the fastest way to convert from one type to
+ *                        another, including the file size.
+ *   mimeFilterLookup() - Lookup a filter.
+ *   compare_filters()  - Compare two filters.
  *   find_filters()     - Find the filters to convert from one type to another.
  */
 
@@ -49,8 +51,8 @@ typedef struct _mime_typelist_s               /**** List of source types ****/
 static int             compare_filters(mime_filter_t *, mime_filter_t *);
 static int             compare_srcs(mime_filter_t *, mime_filter_t *);
 static cups_array_t    *find_filters(mime_t *mime, mime_type_t *src,
-                                     mime_type_t *dst, int *cost,
-                                     _mime_typelist_t *visited);
+                                     size_t srcsize, mime_type_t *dst,
+                                     int *cost, _mime_typelist_t *visited);
 
 
 /*
@@ -137,16 +139,37 @@ mimeFilter(mime_t      *mime,             /* I - MIME database */
           mime_type_t *dst,            /* I - Destination file type */
           int         *cost)           /* O - Cost of filters */
 {
- /*
-  * Range-check the input...
-  */
-
   DEBUG_printf(("mimeFilter(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), "
-                "cost=%p(%d))\n",
+                "cost=%p(%d))",
                mime, src, src ? src->super : "?", src ? src->type : "?",
                dst, dst ? dst->super : "?", dst ? dst->type : "?",
                cost, cost ? *cost : 0));
 
+  return (mimeFilter2(mime, src, 0, dst, cost));
+}
+
+
+/*
+ * 'mimeFilter2()' - Find the fastest way to convert from one type to another,
+ *                   including file size.
+ */
+
+cups_array_t *                         /* O - Array of filters to run */
+mimeFilter2(mime_t      *mime,         /* I - MIME database */
+            mime_type_t *src,          /* I - Source file type */
+           size_t      srcsize,        /* I - Size of source file */
+           mime_type_t *dst,           /* I - Destination file type */
+           int         *cost)          /* O - Cost of filters */
+{
+ /*
+  * Range-check the input...
+  */
+
+  DEBUG_printf(("mimeFilter2(mime=%p, src=%p(%s/%s), srcsize=" CUPS_LLFMT
+                ", dst=%p(%s/%s), cost=%p(%d))",
+               mime, src, src ? src->super : "?", src ? src->type : "?",
+               CUPS_LLCAST srcsize, dst, dst ? dst->super : "?",
+               dst ? dst->type : "?", cost, cost ? *cost : 0));
 
   if (cost)
     *cost = 0;
@@ -162,7 +185,6 @@ mimeFilter(mime_t      *mime,               /* I - MIME database */
   {
     mime_filter_t      *current;       /* Current filter */
 
-
     mime->srcs = cupsArrayNew((cups_array_func_t)compare_srcs, NULL);
 
     for (current = mimeFirstFilter(mime);
@@ -175,12 +197,12 @@ mimeFilter(mime_t      *mime,             /* I - MIME database */
   * Find the filters...
   */
 
-  return (find_filters(mime, src, dst, cost, NULL));
+  return (find_filters(mime, src, srcsize, dst, cost, NULL));
 }
 
 
 /*
- * 'mimeFilterLookup()' - Lookup a filter...
+ * 'mimeFilterLookup()' - Lookup a filter.
  */
 
 mime_filter_t *                                /* O - Filter for src->dst */
@@ -199,7 +221,7 @@ mimeFilterLookup(mime_t      *mime, /* I - MIME database */
 
 
 /*
- * 'compare_filters()' - Compare two filters...
+ * 'compare_filters()' - Compare two filters.
  */
 
 static int                             /* O - Comparison result */
@@ -243,6 +265,7 @@ compare_srcs(mime_filter_t *f0,             /* I - First filter */
 static cups_array_t *                  /* O - Array of filters to run */
 find_filters(mime_t           *mime,   /* I - MIME database */
              mime_type_t      *src,    /* I - Source file type */
+            size_t           srcsize,  /* I - Size of source file */
             mime_type_t      *dst,     /* I - Destination file type */
             int              *cost,    /* O - Cost of filters */
             _mime_typelist_t *list)    /* I - Source types we've used */
@@ -257,21 +280,23 @@ find_filters(mime_t           *mime,      /* I - MIME database */
                        *listptr;       /* Pointer in list */
 
 
-  DEBUG_printf(("find_filters(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), "
-                "cost=%p, list=%p)\n", mime, src, src->super, src->type,
-               dst, dst->super, dst->type, cost, list));
+  DEBUG_printf(("2find_filters(mime=%p, src=%p(%s/%s), srcsize=" CUPS_LLFMT
+                ", dst=%p(%s/%s), cost=%p, list=%p)", mime, src, src->super,
+               src->type, CUPS_LLCAST srcsize, dst, dst->super, dst->type,
+               cost, list));
 
  /*
   * See if there is a filter that can convert the files directly...
   */
 
-  if ((current = mimeFilterLookup(mime, src, dst)) != NULL)
+  if ((current = mimeFilterLookup(mime, src, dst)) != NULL &&
+      (current->maxsize == 0 || srcsize <= current->maxsize))
   {
    /*
     * Got a direct filter!
     */
 
-    DEBUG_puts("find_filters: Direct filter found!");
+    DEBUG_puts("2find_filters: Direct filter found!");
 
     if ((mintemp = cupsArrayNew(NULL, NULL)) == NULL)
       return (NULL);
@@ -283,8 +308,8 @@ find_filters(mime_t           *mime,        /* I - MIME database */
     if (!cost)
       return (mintemp);
 
-    DEBUG_puts("find_filters: Found direct filter:");
-    DEBUG_printf(("find_filters: %s (cost=%d)\n", current->filter, mincost));
+    DEBUG_puts("2find_filters: Found direct filter:");
+    DEBUG_printf(("2find_filters: %s (cost=%d)", current->filter, mincost));
   }
   else
   {
@@ -319,6 +344,8 @@ find_filters(mime_t           *mime,        /* I - MIME database */
 
     mime_type_t *current_dst;          /* Current destination type */
 
+    if (current->maxsize > 0 && srcsize > current->maxsize)
+      continue;
 
     for (listptr = list, current_dst = current->dst;
         listptr;
@@ -337,7 +364,7 @@ find_filters(mime_t           *mime,        /* I - MIME database */
     listnode.src = current->src;
 
     cupsArraySave(mime->srcs);
-    temp = find_filters(mime, current->dst, dst, &tempcost, &listnode);
+    temp = find_filters(mime, current->dst, srcsize, dst, &tempcost, &listnode);
     cupsArrayRestore(mime->srcs);
 
     if (!temp)
index ef466a1c827b616568990ee3d76593eca0cd2f99..d0011c03a7fd199f47aa5e3a59a04fd07dde56e3 100644 (file)
@@ -88,7 +88,6 @@
  *   renew_subscription()        - Renew an existing subscription...
  *   restart_job()               - Restart an old print job.
  *   save_auth_info()            - Save authentication information for a job.
- *   save_krb5_creds()           - Save Kerberos credentials for the job.
  *   send_document()             - Send a file to a printer or class.
  *   send_http_error()           - Send a HTTP error back to the IPP client.
  *   send_ipp_status()           - Send a status back to the IPP client.
@@ -224,9 +223,6 @@ static void renew_subscription(cupsd_client_t *con, int sub_id);
 static void    restart_job(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    save_auth_info(cupsd_client_t *con, cupsd_job_t *job,
                               ipp_attribute_t *auth_info);
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H)
-static void    save_krb5_creds(cupsd_client_t *con, cupsd_job_t *job);
-#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
 static void    send_document(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    send_http_error(cupsd_client_t *con, http_status_t status,
                                cupsd_printer_t *printer);
@@ -2341,7 +2337,8 @@ add_job_uuid(cupsd_client_t *con, /* I - Client connection */
 
   if (!ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI))
     ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL,
-                cupsdMakeUUID(job->dest, job->id, uuid, sizeof(uuid)));
+                _httpAssembleUUID(ServerName, RemotePort, job->dest, job->id,
+                                  uuid, sizeof(uuid)));
 }
 
 
@@ -2670,6 +2667,15 @@ add_printer(cupsd_client_t  *con,        /* I - Client connection */
   if ((attr = ippFindAttribute(con->request, "printer-is-shared",
                                IPP_TAG_BOOLEAN)) != NULL)
   {
+    if (attr->values[0].boolean &&
+        printer->num_auth_info_required == 1 &&
+       !strcmp(printer->auth_info_required[0], "negotiate"))
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Cannot share a remote Kerberized printer."));
+      return;
+    }
+
     if (printer->shared && !attr->values[0].boolean)
       cupsdDeregisterPrinter(printer, 1);
 
@@ -3812,7 +3818,6 @@ apple_register_profiles(
        kCFPreferencesCurrentHost
       };
       CFDictionaryRef  deviceDict;     /* Device dictionary */
-      CFStringRef      printerUUID;    /* Printer UUID */
       CFUUIDRef                deviceUUID;     /* Device UUID */
 
       deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
@@ -3822,21 +3827,12 @@ apple_register_profiles(
                                          sizeof(deviceDictKeys[0]),
                                      &kCFTypeDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks);
-      printerUUID = CFStringCreateWithCString(kCFAllocatorDefault,
-                                              p->uuid + 9, /* Skip urn:uuid: */
-                                             kCFStringEncodingUTF8);
-      if (printerUUID)
-      {
-        deviceUUID = CFUUIDCreateFromString(kCFAllocatorDefault, printerUUID);
-       CFRelease(printerUUID);
+      deviceUUID = ColorSyncCreateUUIDFromUInt32(device_id);
 
-       if (!deviceDict || !deviceUUID ||
-           !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
-                                    deviceDict))
-         error = 1001;
-      }
-      else
-        error = 1001;
+      if (!deviceDict || !deviceUUID ||
+         !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
+                                  deviceDict))
+       error = 1001;
 
       if (deviceUUID)
         CFRelease(deviceUUID);
@@ -3921,7 +3917,6 @@ apple_unregister_profiles(
     * printer.
     */
 
-    CFStringRef printerUUID;           /* Printer UUID */
     CFUUIDRef deviceUUID;              /* Device UUID */
 
     deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name));
@@ -3930,20 +3925,6 @@ apple_unregister_profiles(
       ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
       CFRelease(deviceUUID);
     }
-
-    printerUUID = CFStringCreateWithCString(kCFAllocatorDefault, p->uuid + 9,
-                                            kCFStringEncodingUTF8);
-    if (printerUUID)
-    {
-      deviceUUID = CFUUIDCreateFromString(kCFAllocatorDefault, printerUUID);
-      if (deviceUUID)
-      {
-       ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
-       CFRelease(deviceUUID);
-      }
-
-      CFRelease(printerUUID);
-    }
   }
 
 #  else
@@ -10377,6 +10358,14 @@ save_auth_info(
     cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", con->password);
   }
 
+#ifdef HAVE_GSSAPI
+  if (con->have_gss && con->gss_uid > 0)
+  {
+    cupsFilePrintf(fp, "%d\n", (int)con->gss_uid);
+    cupsdSetStringf(&job->auth_uid, "AUTH_UID=%d", (int)con->gss_uid);
+  }
+#endif /* HAVE_GSSAPI */
+
  /*
   * Write a random number of newlines to the end of the file...
   */
@@ -10389,52 +10378,7 @@ save_auth_info(
   */
 
   cupsFileClose(fp);
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H)
-#  ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
-  if (con->have_gss &&
-      (con->http.hostaddr->addr.sa_family == AF_LOCAL || con->gss_creds))
-#  else
-  if (con->have_gss && con->gss_creds)
-#  endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
-    save_krb5_creds(con, job);
-  else if (job->ccname)
-    cupsdClearString(&(job->ccname));
-#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
-}
-
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H)
-/*
- * 'save_krb5_creds()' - Save Kerberos credentials for the job.
- */
-
-static void
-save_krb5_creds(cupsd_client_t *con,   /* I - Client connection */
-                cupsd_job_t    *job)   /* I - Job */
-{
- /*
-  * Get the credentials...
-  */
-
-  job->ccache = cupsdCopyKrb5Creds(con);
-
- /*
-  * Add the KRB5CCNAME environment variable to the job so that the
-  * backend can use the credentials when printing.
-  */
-
-  if (job->ccache)
-  {
-    cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s",
-                   krb5_cc_get_name(KerberosContext, job->ccache));
-
-    cupsdLogJob(job, CUPSD_LOG_DEBUG2, "save_krb5_creds: %s", job->ccname);
-  }
-  else
-    cupsdClearString(&(job->ccname));
 }
-#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
 
 
 /*
index 96d26e12fafb8918276a332c3d7c6a8b7ee4b6f7..3d9c9e4e4e0ff63c31588380238f8382a0e448d7 100644 (file)
@@ -944,11 +944,8 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
     envp[envc ++] = job->auth_domain;
   if (job->auth_password)
     envp[envc ++] = job->auth_password;
-
-#ifdef HAVE_GSSAPI
-  if (job->ccname)
-    envp[envc ++] = job->ccname;
-#endif /* HAVE_GSSAPI */
+  if (job->auth_uid)
+    envp[envc ++] = job->auth_uid;
 
   envp[envc] = NULL;
 
@@ -1257,20 +1254,7 @@ cupsdDeleteJob(cupsd_job_t       *job,   /* I - Job */
   cupsdClearString(&job->auth_username);
   cupsdClearString(&job->auth_domain);
   cupsdClearString(&job->auth_password);
-
-#ifdef HAVE_GSSAPI
- /*
-  * Destroy the credential cache and clear the KRB5CCNAME env var string.
-  */
-
-  if (job->ccache)
-  {
-    krb5_cc_destroy(KerberosContext, job->ccache);
-    job->ccache = NULL;
-  }
-
-  cupsdClearString(&job->ccname);
-#endif /* HAVE_GSSAPI */
+  cupsdClearString(&job->auth_uid);
 
   if (job->num_files > 0)
   {
@@ -1712,6 +1696,7 @@ cupsdLoadJob(cupsd_job_t *job)            /* I - Job */
     cupsdClearString(&job->auth_username);
     cupsdClearString(&job->auth_domain);
     cupsdClearString(&job->auth_password);
+    cupsdClearString(&job->auth_uid);
 
     if ((fp = cupsFileOpen(jobfile, "r")) != NULL)
     {
@@ -1737,6 +1722,9 @@ cupsdLoadJob(cupsd_job_t *job)            /* I - Job */
          cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", data);
       }
 
+      if (cupsFileGets(fp, line, sizeof(line)) && isdigit(line[0] & 255))
+        cupsdSetStringf(&job->auth_uid, "AUTH_UID=%s", line);
+
       cupsFileClose(fp);
     }
   }
@@ -2391,20 +2379,7 @@ cupsdSetJobState(
        cupsdClearString(&job->auth_username);
        cupsdClearString(&job->auth_domain);
        cupsdClearString(&job->auth_password);
-
-#ifdef HAVE_GSSAPI
-       /*
-       * Destroy the credential cache and clear the KRB5CCNAME env var string.
-       */
-
-       if (job->ccache)
-       {
-         krb5_cc_destroy(KerberosContext, job->ccache);
-         job->ccache = NULL;
-       }
-
-       cupsdClearString(&job->ccname);
-#endif /* HAVE_GSSAPI */
+       cupsdClearString(&job->auth_uid);
 
        /*
        * Remove the print file for good if we aren't preserving jobs or
@@ -2705,10 +2680,17 @@ finalize_job(cupsd_job_t *job,          /* I - Job */
 
  /*
   * Clear the "connecting-to-device" reason, which is only valid when a printer
-  * is processing...
+  * is processing, along with any remote printing job state...
   */
 
-  cupsdSetPrinterReasons(job->printer, "-connecting-to-device");
+  cupsdSetPrinterReasons(job->printer, "-connecting-to-device,"
+                                      "cups-remote-pending,"
+                                      "cups-remote-pending-held,"
+                                      "cups-remote-processing,"
+                                      "cups-remote-stopped,"
+                                      "cups-remote-canceled,"
+                                      "cups-remote-aborted,"
+                                      "cups-remote-completed");
 
  /*
   * Similarly, clear the "offline-report" reason for non-USB devices since we
@@ -3946,6 +3928,13 @@ start_job(cupsd_job_t     *job,          /* I - Job ID */
 
   cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
   cupsdSetPrinterState(printer, IPP_PRINTER_PROCESSING, 0);
+  cupsdSetPrinterReasons(printer, "-cups-remote-pending,"
+                                 "cups-remote-pending-held,"
+                                 "cups-remote-processing,"
+                                 "cups-remote-stopped,"
+                                 "cups-remote-canceled,"
+                                 "cups-remote-aborted,"
+                                 "cups-remote-completed");
 
   job->cost         = 0;
   job->current_file = 0;
index 2268886b04ccb3ffdb0cff20a69a6482438e4b15..03a8dff871c5264856118fa3bc5f2df34d9748a6 100644 (file)
@@ -74,15 +74,13 @@ struct cupsd_job_s                  /**** Job request ****/
                                          * if any */
                        *auth_domain,   /* AUTH_DOMAIN environment variable,
                                         * if any */
-                       *auth_password; /* AUTH_PASSWORD environment variable,
+                       *auth_password, /* AUTH_PASSWORD environment variable,
+                                        * if any */
+                       *auth_uid;      /* AUTH_UID environment variable,
                                         * if any */
   void                 *profile;       /* Security profile */
   cups_array_t         *history;       /* Debug log history */
   int                  progress;       /* Printing progress */
-#ifdef HAVE_GSSAPI
-  krb5_ccache          ccache;         /* Kerberos credential cache */
-  char                 *ccname;        /* KRB5CCNAME environment variable */
-#endif /* HAVE_GSSAPI */
 };
 
 typedef struct cupsd_joblog_s          /**** Job log message ****/
index d043875cc46a09d1ededadbc78542f06c9921f22..411c6521084a4bfccd92fa6a492745950e366ffe 100644 (file)
@@ -21,7 +21,6 @@
  *   cupsdClosePipe()      - Close a pipe as necessary.
  *   cupsdFreeStrings()    - Free an array of strings.
  *   cupsdHoldSignals()    - Hold child and termination signals.
- *   cupsdMakeUUID()       - Make a UUID URI conforming to RFC 4122.
  *   cupsdOpenPipe()       - Create a pipe which is closed on exec.
  *   cupsdReleaseSignals() - Release signals for delivery.
  *   cupsdSetString()      - Set a string value.
@@ -947,6 +946,7 @@ main(int  argc,                             /* I - Number of command-line args */
       browse_time = current_time;
     }
 
+#ifndef HAVE_AUTHORIZATION_H
    /*
     * Update the root certificate once every 5 minutes if we have client
     * connections...
@@ -962,6 +962,7 @@ main(int  argc,                             /* I - Number of command-line args */
       cupsdDeleteCert(0);
       cupsdAddCert(0, "root", NULL);
     }
+#endif /* !HAVE_AUTHORIZATION_H */
 
    /*
     * Check for new data on the client sockets...
@@ -1298,54 +1299,6 @@ cupsdHoldSignals(void)
 }
 
 
-/*
- * 'cupsdMakeUUID()' - Make a UUID URI conforming to RFC 4122.
- *
- * The buffer needs to be at least 46 bytes in size.
- */
-
-char *                                 /* I - UUID string */
-cupsdMakeUUID(const char *name,                /* I - Object name */
-              int        number,       /* I - Object number */
-             char       *buffer,       /* I - String buffer */
-             size_t     bufsize)       /* I - Size of buffer */
-{
-  char                 data[1024];     /* Source string for MD5 */
-  _cups_md5_state_t    md5state;       /* MD5 state */
-  unsigned char                md5sum[16];     /* MD5 digest/sum */
-
-
- /*
-  * Build a version 3 UUID conforming to RFC 4122.
-  *
-  * Start with the MD5 sum of the ServerName, RemotePort, object name and
-  * number, and some random data on the end.
-  */
-
-  snprintf(data, sizeof(data), "%s:%d:%s:%d:%04x:%04x", ServerName,
-           RemotePort, name ? name : ServerName, number,
-          CUPS_RAND() & 0xffff, CUPS_RAND() & 0xffff);
-
-  _cupsMD5Init(&md5state);
-  _cupsMD5Append(&md5state, (unsigned char *)data, strlen(data));
-  _cupsMD5Finish(&md5state, md5sum);
-
- /*
-  * Generate the UUID from the MD5...
-  */
-
-  snprintf(buffer, bufsize,
-           "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
-          "%02x%02x%02x%02x%02x%02x",
-          md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5],
-          (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40,
-          md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13],
-          md5sum[14], md5sum[15]);
-
-  return (buffer);
-}
-
-
 /*
  * 'cupsdOpenPipe()' - Create a pipe which is closed on exec.
  */
index 630b2d763441538a44b7c404e20c61bd8f6d3fce..e3f214b379fe1b8029a62ae220d01137dc54e8c5 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   MIME type/conversion database definitions for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -97,6 +97,7 @@ typedef struct _mime_filter_s         /**** MIME Conversion Filter Data ****/
                *dst;                   /* Destination type */
   int          cost;                   /* Relative cost */
   char         filter[MIME_MAX_FILTER];/* Filter program to use */
+  size_t       maxsize;                /* Maximum file size for this filter */
 } mime_filter_t;
 
 typedef struct _mime_s                 /**** MIME Database ****/
@@ -135,6 +136,9 @@ extern mime_filter_t        *mimeAddFilter(mime_t *mime, mime_type_t *src,
 extern void            mimeDeleteFilter(mime_t *mime, mime_filter_t *filter);
 extern cups_array_t    *mimeFilter(mime_t *mime, mime_type_t *src,
                                    mime_type_t *dst, int *cost);
+extern cups_array_t    *mimeFilter2(mime_t *mime, mime_type_t *src,
+                                    size_t srcsize, mime_type_t *dst,
+                                    int *cost);
 extern mime_filter_t   *mimeFilterLookup(mime_t *mime, mime_type_t *src,
                                          mime_type_t *dst);
 extern mime_filter_t   *mimeFirstFilter(mime_t *mime);
index 5331ca7bbc891894337de24e90e33730ea425fe0..de4b637dec87f887b6d3bced366e2e910d5992a1 100644 (file)
@@ -135,7 +135,8 @@ cupsdAddPrinter(const char *name)   /* I - Name of printer */
   httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   ServerName, RemotePort, "/printers/%s", name);
   cupsdSetString(&p->uri, uri);
-  cupsdSetString(&p->uuid, cupsdMakeUUID(name, 0, uuid, sizeof(uuid)));
+  cupsdSetString(&p->uuid, _httpAssembleUUID(ServerName, RemotePort, name, 0,
+                                             uuid, sizeof(uuid)));
   cupsdSetDeviceURI(p, "file:///dev/null");
 
   p->state      = IPP_PRINTER_STOPPED;
@@ -1804,6 +1805,16 @@ cupsdSetAuthInfoRequired(
 
         p->auth_info_required[p->num_auth_info_required] = "negotiate";
        p->num_auth_info_required ++;
+
+       /*
+        * Don't allow sharing of queues that require Kerberos authentication.
+       */
+
+       if (p->shared)
+       {
+         cupsdDeregisterPrinter(p, 1);
+         p->shared = 0;
+       }
       }
       else if ((end - values) == 6 && !strncmp(values, "domain", 6))
       {
@@ -1882,6 +1893,16 @@ cupsdSetAuthInfoRequired(
       p->auth_info_required[p->num_auth_info_required] = "negotiate";
       p->num_auth_info_required ++;
 
+     /*
+      * Don't allow sharing of queues that require Kerberos authentication.
+      */
+
+      if (p->shared)
+      {
+       cupsdDeregisterPrinter(p, 1);
+       p->shared = 0;
+      }
+
       return (1);
     }
     else if (!strcmp(attr->values[i].string.text, "domain"))
@@ -3539,6 +3560,7 @@ add_printer_filter(
                                        /* Destination super/type */
                program[1024];          /* Program/filter name */
   int          cost;                   /* Cost of filter */
+  size_t       maxsize = 0;            /* Maximum supported file size */
   mime_type_t  *temptype,              /* MIME type looping var */
                *desttype;              /* Destination MIME type */
   char         filename[1024],         /* Full filter filename */
@@ -3555,7 +3577,9 @@ add_printer_filter(
   * Parse the filter string; it should be in one of the following formats:
   *
   *     source/type cost program
+  *     source/type cost maxsize(nnnn) program
   *     source/type dest/type cost program
+  *     source/type dest/type cost maxsize(nnnn) program
   */
 
   if (sscanf(filter, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
@@ -3588,6 +3612,26 @@ add_printer_filter(
     }
   }
 
+  if (!strncmp(program, "maxsize(", 8))
+  {
+    char       *ptr;                   /* Pointer into maxsize(nnnn) program */
+
+    maxsize = strtoll(program + 8, &ptr, 10);
+
+    if (*ptr != ')')
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "%s: invalid filter string \"%s\"!",
+                      p->name, filter);
+      return;
+    }
+
+    ptr ++;
+    while (_cups_isspace(*ptr))
+      ptr ++;
+
+    _cups_strcpy(program, ptr);
+  }
+
  /*
   * See if the filter program exists; if not, stop the printer and flag
   * the error!
@@ -3632,6 +3676,12 @@ add_printer_filter(
                 "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode,
                 (int)fileinfo.st_uid, (int)fileinfo.st_gid);
 
+#ifdef __APPLE__ /* Don't flag filters with group write for "admin" */
+        if (fileinfo.st_uid ||
+           (fileinfo.st_gid && fileinfo.st_gid != 80 &&
+            (fileinfo.st_mode & S_IWGRP)) ||
+           (fileinfo.st_mode & (S_ISUID | S_IWOTH)))
+#endif /* __APPLE__ */
        cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning");
 
        cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message);
index 2260249f127576924ed7b5ca99532f64bb517d75..80c3fcb5995b5825491979f91137d73c6ae94224 100644 (file)
@@ -435,7 +435,11 @@ cupsdStartProcess(
                    command, commandinfo.st_mode,
                    (int)commandinfo.st_uid, (int)commandinfo.st_gid);
 
+#ifdef __APPLE__ /* Don't flag filters with group write for "admin" */
+    if (commandinfo.st_gid != 80 && job && job->printer)
+#else
     if (job && job->printer)
+#endif /* __APPLE__ */
     {
       if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning"))
        cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL,
index b40ea15d9f8f6e327e02dc9c662df84d258b5129..8ad6c5b9f3d51d1663f4b471452aa11f6fa8b466 100644 (file)
@@ -31,7 +31,7 @@
        ATTR language attributes-natural-language en
        ATTR uri printer-uri $uri
        ATTR keyword requested-attributes
-            job-id,job-state,job-name,job-originating-user-name
+            job-id,job-state,job-name,job-originating-user-name,job-media-sheets,job-media-sheets-completed,job-impressions,job-impressions-completed
 
        # What statuses are OK?
        STATUS successful-ok
        DISPLAY job-state
        DISPLAY job-name
        DISPLAY job-originating-user-name
+       DISPLAY job-impressions
+       DISPLAY job-impressions-completed
+       DISPLAY job-media-sheets
+       DISPLAY job-media-sheets-completed
 }
 
 
index 5aa8f861d40cfc9861ba6ae5f7b2d7364b4f66e7..07f865b421d1c0db54273cef653170ef0569d010 100644 (file)
@@ -47,6 +47,7 @@
                                276683DB1337B24A000D33D0 /* PBXTargetDependency */,
                                276683DD1337B24A000D33D0 /* PBXTargetDependency */,
                                276683DF1337B24A000D33D0 /* PBXTargetDependency */,
+                               7258EAEF13459ADA009286F1 /* PBXTargetDependency */,
                                7243793F1333FD23009631B9 /* PBXTargetDependency */,
                                724379C31333FF7D009631B9 /* PBXTargetDependency */,
                        );
                724379C71333FFC7009631B9 /* usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 724379C51333FFC7009631B9 /* usb.c */; };
                724379C91333FFF3009631B9 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 724379C81333FFF3009631B9 /* CoreFoundation.framework */; };
                724379CB1334000E009631B9 /* ieee1284.c in Sources */ = {isa = PBXBuildFile; fileRef = 724379CA1334000E009631B9 /* ieee1284.c */; };
+               7258EAED134594EB009286F1 /* rastertopwg.c in Sources */ = {isa = PBXBuildFile; fileRef = 7258EAEC134594EB009286F1 /* rastertopwg.c */; };
+               7258EAF413459B6D009286F1 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; };
+               7258EAF513459B6D009286F1 /* libcupsimage.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72F75A611336F9A3004BB496 /* libcupsimage.dylib */; };
                7263EE2713330D2800BA4D44 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7263EE2613330D2800BA4D44 /* libpam.dylib */; };
                7263EE2C13330D5C00BA4D44 /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7263EE2913330D5C00BA4D44 /* Kerberos.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
                7263EE2D13330D5C00BA4D44 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7263EE2A13330D5C00BA4D44 /* Security.framework */; };
                        remoteGlobalIDString = 7243795A1333FF1D009631B9;
                        remoteInfo = usb;
                };
+               7258EAEE13459ADA009286F1 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 7258EAE1134594C4009286F1;
+                       remoteInfo = rastertopwg;
+               };
+               7258EAF013459B67009286F1 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72220EAD1333047D00FCA411;
+                       remoteInfo = libcups;
+               };
+               7258EAF213459B67009286F1 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 72F75A601336F9A3004BB496;
+                       remoteInfo = libcupsimage;
+               };
                72F75A651336FA30004BB496 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               7258EAE0134594C4009286F1 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
                72F75A501336F950004BB496 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 2147483647;
                276683F91337F7A9000D33D0 /* ipptool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ipptool.c; path = ../test/ipptool.c; sourceTree = "<group>"; };
                276684041337FA1D000D33D0 /* cupsaddsmb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cupsaddsmb; sourceTree = BUILT_PRODUCTS_DIR; };
                276684101337FA7C000D33D0 /* cupsaddsmb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cupsaddsmb.c; path = ../systemv/cupsaddsmb.c; sourceTree = "<group>"; };
+               27D3037C134148CB00F022B1 /* libcups_s.exp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.exports; name = libcups_s.exp; path = ../cups/libcups_s.exp; sourceTree = "<group>"; };
+               27D3037D134148CB00F022B1 /* libcups2.def */ = {isa = PBXFileReference; lastKnownFileType = text; name = libcups2.def; path = ../cups/libcups2.def; sourceTree = "<group>"; };
                72220EAE1333047D00FCA411 /* libcups.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcups.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                72220EB51333052D00FCA411 /* adminutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = adminutil.c; path = ../cups/adminutil.c; sourceTree = "<group>"; };
                72220EB71333056300FCA411 /* adminutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = adminutil.h; path = ../cups/adminutil.h; sourceTree = "<group>"; };
                724379C51333FFC7009631B9 /* usb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = usb.c; path = ../backend/usb.c; sourceTree = "<group>"; };
                724379C81333FFF3009631B9 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
                724379CA1334000E009631B9 /* ieee1284.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ieee1284.c; path = ../backend/ieee1284.c; sourceTree = "<group>"; };
+               7258EAE2134594C4009286F1 /* rastertopwg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = rastertopwg; sourceTree = BUILT_PRODUCTS_DIR; };
+               7258EAEC134594EB009286F1 /* rastertopwg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rastertopwg.c; path = ../filter/rastertopwg.c; sourceTree = "<group>"; };
                7263EE2613330D2800BA4D44 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = SDKs/MacOSX10.6.sdk/usr/lib/libpam.dylib; sourceTree = DEVELOPER_DIR; };
                7263EE2913330D5C00BA4D44 /* Kerberos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kerberos.framework; path = SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Kerberos.framework; sourceTree = DEVELOPER_DIR; };
                7263EE2A13330D5C00BA4D44 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               7258EADF134594C4009286F1 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               7258EAF413459B6D009286F1 /* libcups.dylib in Frameworks */,
+                               7258EAF513459B6D009286F1 /* libcupsimage.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                72F75A4F1336F950004BB496 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                                276683A41337ACAB000D33D0 /* ppdpo */,
                                276683F01337F78E000D33D0 /* ipptool */,
                                276684041337FA1D000D33D0 /* cupsaddsmb */,
+                               7258EAE2134594C4009286F1 /* rastertopwg */,
                        );
                        name = Products;
                        sourceTree = "<group>";
                72220EB41333050100FCA411 /* libcups */ = {
                        isa = PBXGroup;
                        children = (
+                               27D3037C134148CB00F022B1 /* libcups_s.exp */,
+                               27D3037D134148CB00F022B1 /* libcups2.def */,
                                276683561337A8C5000D33D0 /* cups.strings */,
                                72220EB51333052D00FCA411 /* adminutil.c */,
                                72220EB81333056300FCA411 /* array.c */,
                        name = backends;
                        sourceTree = "<group>";
                };
+               7258EADC134594A8009286F1 /* filters */ = {
+                       isa = PBXGroup;
+                       children = (
+                               7258EAEC134594EB009286F1 /* rastertopwg.c */,
+                       );
+                       name = filters;
+                       sourceTree = "<group>";
+               };
                72BF96351333042100B1EAD7 = {
                        isa = PBXGroup;
                        children = (
                                274FF67313333B0A00317ECB /* commands */,
                                72220F5D13330A5A00FCA411 /* cupsd */,
                                274FF5D513332C2C00317ECB /* daemon */,
+                               7258EADC134594A8009286F1 /* filters */,
                                276683CB1337B1CC000D33D0 /* ppdc tools */,
                                273BF6B81333B4A90022CAAB /* tests */,
                                72220EAF1333047D00FCA411 /* Products */,
                        productReference = 7243795B1333FF1D009631B9 /* usb */;
                        productType = "com.apple.product-type.tool";
                };
+               7258EAE1134594C4009286F1 /* rastertopwg */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 7258EAE9134594C4009286F1 /* Build configuration list for PBXNativeTarget "rastertopwg" */;
+                       buildPhases = (
+                               7258EADE134594C4009286F1 /* Sources */,
+                               7258EADF134594C4009286F1 /* Frameworks */,
+                               7258EAE0134594C4009286F1 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               7258EAF113459B67009286F1 /* PBXTargetDependency */,
+                               7258EAF313459B67009286F1 /* PBXTargetDependency */,
+                       );
+                       name = rastertopwg;
+                       productName = rastertopwg;
+                       productReference = 7258EAE2134594C4009286F1 /* rastertopwg */;
+                       productType = "com.apple.product-type.tool";
+               };
                72F75A511336F950004BB496 /* cupstestppd */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 72F75A581336F951004BB496 /* Build configuration list for PBXNativeTarget "cupstestppd" */;
                                276683891337AC97000D33D0 /* ppdi */,
                                276683961337ACA2000D33D0 /* ppdmerge */,
                                276683A31337ACAB000D33D0 /* ppdpo */,
+                               7258EAE1134594C4009286F1 /* rastertopwg */,
                                7243792F1333FB85009631B9 /* socket */,
                                273BF6BC1333B5000022CAAB /* testcups */,
                                7243795A1333FF1D009631B9 /* usb */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               7258EADE134594C4009286F1 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               7258EAED134594EB009286F1 /* rastertopwg.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                72F75A4E1336F950004BB496 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        target = 7243795A1333FF1D009631B9 /* usb */;
                        targetProxy = 724379C21333FF7D009631B9 /* PBXContainerItemProxy */;
                };
+               7258EAEF13459ADA009286F1 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 7258EAE1134594C4009286F1 /* rastertopwg */;
+                       targetProxy = 7258EAEE13459ADA009286F1 /* PBXContainerItemProxy */;
+               };
+               7258EAF113459B67009286F1 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72220EAD1333047D00FCA411 /* libcups */;
+                       targetProxy = 7258EAF013459B67009286F1 /* PBXContainerItemProxy */;
+               };
+               7258EAF313459B67009286F1 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 72F75A601336F9A3004BB496 /* libcupsimage */;
+                       targetProxy = 7258EAF213459B67009286F1 /* PBXContainerItemProxy */;
+               };
                72F75A661336FA30004BB496 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 72220EAD1333047D00FCA411 /* libcups */;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/lib;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/lib;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/libexec/cups/daemon;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/sbin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/sbin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/local/lib;
                                MACH_O_TYPE = staticlib;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups;
                                PRODUCT_NAME = libcups_static;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/local/lib;
                                MACH_O_TYPE = staticlib;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups;
                                PRODUCT_NAME = libcups_static;
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/sbin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/sbin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/sbin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/sbin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/lib;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                ONLY_ACTIVE_ARCH = YES;
                                PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                INSTALL_PATH = /usr/lib;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
                                PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
+                               INSTALL_PATH = /usr/sbin;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
+                               INSTALL_PATH = /usr/sbin;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
+                               INSTALL_PATH = /usr/lib;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               MACOSX_DEPLOYMENT_TARGET = 10.6;
+                               INSTALL_PATH = /usr/lib;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = /usr/libexec/cups/backend;
                                LIBRARY_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "\"$(SRCROOT)/../backend\"",
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = /usr/libexec/cups/backend;
                                LIBRARY_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "\"$(SRCROOT)/../backend\"",
                        };
                        name = Release;
                };
+               7258EAEA134594C4009286F1 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = /usr/libexec/cups/filter;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               7258EAEB134594C4009286F1 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = /usr/libexec/cups/filter;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
                72BF963C1333042100B1EAD7 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                        .,
                                        ..,
                                );
+                               MACOSX_DEPLOYMENT_TARGET = "";
                                OTHER_CFLAGS = (
                                        "-D_CUPS_SOURCE",
                                        "-Wno-shorten-64-to-32",
                                        .,
                                        ..,
                                );
+                               MACOSX_DEPLOYMENT_TARGET = "";
                                OTHER_CFLAGS = (
                                        "-D_CUPS_SOURCE",
                                        "-Wno-shorten-64-to-32",
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = /usr/bin;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = /usr/bin;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                        };
                        name = Release;
                                276683641337A9B6000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                276683761337AC79000D33D0 /* Build configuration list for PBXNativeTarget "ppdc" */ = {
                        isa = XCConfigurationList;
                                276683781337AC79000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                276683831337AC8C000D33D0 /* Build configuration list for PBXNativeTarget "ppdhtml" */ = {
                        isa = XCConfigurationList;
                                276683851337AC8C000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                276683901337AC97000D33D0 /* Build configuration list for PBXNativeTarget "ppdi" */ = {
                        isa = XCConfigurationList;
                                276683921337AC97000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                2766839D1337ACA2000D33D0 /* Build configuration list for PBXNativeTarget "ppdmerge" */ = {
                        isa = XCConfigurationList;
                                2766839F1337ACA2000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                276683AA1337ACAB000D33D0 /* Build configuration list for PBXNativeTarget "ppdpo" */ = {
                        isa = XCConfigurationList;
                                276683AC1337ACAB000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                276683F61337F78F000D33D0 /* Build configuration list for PBXNativeTarget "ipptool" */ = {
                        isa = XCConfigurationList;
                                276683F81337F78F000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                2766840A1337FA1E000D33D0 /* Build configuration list for PBXNativeTarget "cupsaddsmb" */ = {
                        isa = XCConfigurationList;
                                2766840C1337FA1E000D33D0 /* Release */,
                        );
                        defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
                };
                72220EB21333047D00FCA411 /* Build configuration list for PBXNativeTarget "libcups" */ = {
                        isa = XCConfigurationList;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               7258EAE9134594C4009286F1 /* Build configuration list for PBXNativeTarget "rastertopwg" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               7258EAEA134594C4009286F1 /* Debug */,
+                               7258EAEB134594C4009286F1 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                72BF963A1333042100B1EAD7 /* Build configuration list for PBXProject "CUPS" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (