]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Load cups into easysw/current.
authorjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>
Tue, 28 Feb 2006 17:54:14 +0000 (17:54 +0000)
committerjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>
Tue, 28 Feb 2006 17:54:14 +0000 (17:54 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@69 a1ca3aef-8c08-0410-bb20-df032aa958be

109 files changed:
CHANGES.txt
CREDITS.txt
Makedefs.in
Makefile
backend/ieee1284.c
backend/ipp.c
backend/parallel.c
backend/serial.c
backend/usb-unix.c
backend/usb.c
cgi-bin/classes.c
cgi-bin/help.c
cgi-bin/ipp-var.c
cgi-bin/printers.c
conf/Makefile
config-scripts/cups-ldap.m4 [new file with mode: 0644]
config-scripts/cups-scripting.m4
config-scripts/cups-threads.m4
config.h.in
configure.in
cups/cups.h
cups/dest.c
cups/encode.c
cups/file.c
cups/getputfile.c
cups/http-addr.c
cups/http-support.c
cups/http.c
cups/http.h
cups/mark.c
cups/options.c
cups/ppd.c
cups/ppd.h
cups/request.c
cups/testfile.c
cups/testi18n.c
cups/usersys.c
cups/util.c
doc/Makefile
doc/help/api-array.html
doc/help/api-cups.html
doc/help/api-filedir.html
doc/help/api-filter.html
doc/help/api-httpipp.html
doc/help/api-ppd.html
doc/help/api-raster.html [new file with mode: 0644]
doc/help/cupsd-conf-reference.html
doc/help/spec-command.html [new file with mode: 0644]
doc/help/spec-ppd.html
doc/images/clean-print-heads.gif [new file with mode: 0644]
doc/images/print-self-test-page.gif [new file with mode: 0644]
filter/Makefile
filter/api-raster.shtml [new file with mode: 0644]
filter/hpgl-input.c
filter/image-private.h
filter/image-zoom.c
filter/image.h
filter/imagetoraster.c
filter/raster.c
filter/raster.h
locale/Makefile
locale/cups.pot
locale/cups_fr.po [deleted file]
locale/cups_ja.po
man/Makefile
man/client.conf.man.in [new file with mode: 0644]
man/lpoptions.man.in [moved from man/lpoptions.man with 92% similarity]
packaging/cups.list.in
packaging/cups.spec.in
scheduler/Makefile
scheduler/auth.c
scheduler/classes.c
scheduler/client.c
scheduler/conf.c
scheduler/conf.h
scheduler/cups-deviced.c
scheduler/cups-lpd.c
scheduler/cupsd.h
scheduler/dirsvc.c
scheduler/dirsvc.h
scheduler/filter.c
scheduler/ipp.c
scheduler/job.c
scheduler/log.c
scheduler/main.c
scheduler/printers.c
scheduler/printers.h
scheduler/server.c
scheduler/testdirsvc.c
scheduler/type.c
scripting/java/src/com/easysw/cups/Cups.java
scripting/php/Dependencies
scripting/php/Example/phpcups.inc.php4 [deleted file]
scripting/php/Makefile
scripting/php/README
scripting/php/config.m4 [deleted file]
scripting/php/php_phpcups.h [deleted file]
scripting/php/phpcups.c
scripting/php/phpcups.h [new file with mode: 0644]
scripting/php/phpcups.php [changed mode: 0644->0755]
systemv/cupsaddsmb.c
systemv/cupstestppd.c
systemv/lpadmin.c
systemv/lpstat.c
templates/Makefile
templates/maintenance.tmpl [new file with mode: 0644]
templates/printers.tmpl
templates/test-page.tmpl
tools/makesrcdist

index a9d78226d0ffb21ce45fe9a71d8c734c72cb513f..e684a4d2afb833589c84e2018a64a33cb628acd5 100644 (file)
@@ -1,8 +1,28 @@
-CHANGES.txt - 02/17/2006
+CHANGES.txt - 02/25/2006
 ------------------------
 
 CHANGES IN CUPS V1.2.0b1
 
+       - The serial backend now supports Equinox 8-port serial
+         hubs (STR #526)
+       - The IPP backend now supports a compression option to
+         compress print files as they are sent to the remote
+         server (STR #956)
+       - The CUPS browse protocol now supports passing of
+         default options and browse timeout values from the
+         server to the clients (STR #800)
+       - Implicit classes that timed out could cause the
+         scheduler to crash (STR #1439)
+       - Added DragonFly support in local device backends (STR
+         #1362)
+       - Added LDAP printer browsing support (STR #338)
+       - Added official support for printer maintenance commands
+         via the CUPS Command file format and hooks in the
+         printer-type and web interfaces (STR #932)
+       - The HP-GL/2 filter could get in an infinite loop trying
+         to convert HP-PCL files (STR #1415)
+       - CUPS now implements the HTTP/1.1 Expect header (STR
+         #1407)
        - Options in PPD files are no longer automatically put in
          an "Extra" group; rather, all options that are not
          inside an Open/CloseGroup will be placed in the
index 585072bb32cd8003dbcca034bc5a0626ee03f80d..00d3fa4485efb85856a5c804d38f262a58d77742 100644 (file)
@@ -1,4 +1,4 @@
-CREDITS.txt - 02/17/2006
+CREDITS.txt - 02/23/2006
 ------------------------
 
 Few projects are completed by one person, and CUPS is no exception.  We'd
@@ -31,6 +31,7 @@ like to thank the following individuals for their contributions:
     Andrea Suatoni      - IRIX desktop integration and testing.
     Tomohiro Kato       - Japanese localization.
     Tim Waugh           - Lots of patches, testing, and Linux integration.
+    Yugami              - LDAP browsing support.
 
 If I've missed someone, please let me know by sending an email to
 "mike@easysw.com".
index 06a2ceb9b188cd0ebed2a52d923ef1dcacde0250..4520f8b2f38994cc8e815f78c20553300ce01936 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makedefs.in 5136 2006-02-19 18:46:46Z mike $"
+# "$Id: Makedefs.in 5194 2006-02-27 20:57:07Z mike $"
 #
 #   Common makefile definitions for the Common UNIX Printing System (CUPS).
 #
@@ -37,6 +37,7 @@ LD            =       @LD@
 LIBTOOL                =       @LIBTOOL@
 LN             =       @LN@ -sf
 MV             =       @MV@
+PHPCONFIG      =       @PHPCONFIG@
 RANLIB         =       @RANLIB@
 RM             =       @RM@ -f
 SED            =       @SED@
@@ -78,6 +79,7 @@ CUPS_LOG_FILE_PERM = @CUPS_LOG_FILE_PERM@
 LIBCUPS                =       @LIBCUPS@
 LIBCUPSIMAGE   =       @LIBCUPSIMAGE@
 LIBJPEG                =       @LIBJPEG@
+LIBLDAP                =       @LIBLDAP@
 LIBMALLOC      =       @LIBMALLOC@
 LIBPAPER       =       @LIBPAPER@
 LIBPNG         =       @LIBPNG@
@@ -102,11 +104,11 @@ INSTALLSTATIC     =       @INSTALLSTATIC@
 ARFLAGS                =       @ARFLAGS@
 BACKLIBS       =       @BACKLIBS@
 CFLAGS         =       -I.. $(RC_CFLAGS) $(SSLFLAGS) @CPPFLAGS@ @CFLAGS@ \
-                       @LARGEFILE@ $(OPTIONS)
+                       @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
 COMMONLIBS     =       @LIBS@
 CUPSDLIBS      =       @CUPSDLIBS@
 CXXFLAGS       =       -I.. $(RC_CFLAGS) $(SSLFLAGS) @CPPFLAGS@ @CXXFLAGS@ \
-                       @LARGEFILE@ $(OPTIONS)
+                       @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
 CXXLIBS                =       @CXXLIBS@
 DSOFLAGS       =       @DSOFLAGS@
 DSOLIBS                =       @DSOLIBS@ $(COMMONLIBS)
@@ -118,6 +120,7 @@ LIBS                =       $(LINKCUPS) $(COMMONLIBS)
 OPTIM          =       @OPTIM@
 OPTIONS                =
 PAMLIBS                =       @PAMLIBS@
+PHPDIR         =       @PHPDIR@
 SSLFLAGS       =       @SSLFLAGS@
 SSLLIBS                =       @SSLLIBS@
 LAUNCHDLIBS    =       @LAUNCHDLIBS@
@@ -178,10 +181,10 @@ MAN7EXT           =       @MAN7EXT@
 MAN8EXT                =       @MAN8EXT@
 MAN8DIR                =       @MAN8DIR@
 
-PAMDIR         =       $(BUILDROOT)@PAMDIR@
+PAMDIR         =       @PAMDIR@
 PAMFILE                =       @PAMFILE@
 
-DEFAULT_LAUNCHD_CONF   =       @DEFAULT_LAUNCHD_CONF@
+DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
 DBUSDIR                =       @DBUSDIR@
 
 
@@ -212,5 +215,5 @@ DBUSDIR             =       @DBUSDIR@
 
 
 #
-# End of "$Id: Makedefs.in 5136 2006-02-19 18:46:46Z mike $"
+# End of "$Id: Makedefs.in 5194 2006-02-27 20:57:07Z mike $"
 #
index 428bf20fe92548d2fd5c3a2c0afebe0c0c851cc9..053f65f7fe6a7c65035a848353ede8c294d0acf6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5136 2006-02-19 18:46:46Z mike $"
+# "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $"
 #
 #   Top-level Makefile for the Common UNIX Printing System (CUPS).
 #
@@ -29,7 +29,8 @@ include Makedefs
 #
 
 DIRS   =       cups backend berkeley cgi-bin filter locale man monitor \
-               notifier pdftops scheduler systemv test
+               notifier pdftops scheduler systemv test \
+               $(PHPDIR)
 
 
 #
@@ -117,6 +118,7 @@ install:    installhdrs
                fi \
        fi
        if test "x$(DBUSDIR)" != "x"; then \
+               echo Installing cups.conf in $(DBUSDIR)...;\
                $(INSTALL_DIR) $(BUILDROOT)$(DBUSDIR); \
                $(INSTALL_DATA) packaging/cups-dbus.conf $(BUILDROOT)$(DBUSDIR)/cups.conf; \
        fi
@@ -175,5 +177,5 @@ tardist:
 
 
 #
-# End of "$Id: Makefile 5136 2006-02-19 18:46:46Z mike $".
+# End of "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $".
 #
index 6152c4c7a27a1a15cf24d298bbcdf2a81ca9fe0d..52f27db18d190940f669448982bdf49dca954d50 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ieee1284.c 4903 2006-01-10 20:02:46Z mike $"
+ * "$Id: ieee1284.c 5198 2006-02-27 21:58:43Z mike $"
  *
  *   IEEE-1284 support functions for the Common UNIX Printing System (CUPS).
  *
@@ -76,9 +76,9 @@ get_device_id(
 #ifdef __linux
   int  length;                         /* Length of device ID info */
 #endif /* __linux */
-#ifdef __sun
+#if defined(__sun) && defined(ECPPIOC_GETDEVID)
   struct ecpp_device_id did;           /* Device ID buffer */
-#endif /* __sun */
+#endif /* __sun && ECPPIOC_GETDEVID */
 
   DEBUG_printf(("get_device_id(fd=%d, device_id=%p, device_id_size=%d, "
                 "make_model=%p, make_model_size=%d, scheme=\"%s\", "
@@ -369,5 +369,5 @@ get_device_id(
 
 
 /*
- * End of "$Id: ieee1284.c 4903 2006-01-10 20:02:46Z mike $".
+ * End of "$Id: ieee1284.c 5198 2006-02-27 21:58:43Z mike $".
  */
index 9feb672b094950f94047b73ce479b79960352d74..07699d655e54ce68fa66cb9eb868bfdb6fe6d11e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ipp.c 5133 2006-02-19 15:01:12Z mike $"
+ * "$Id: ipp.c 5180 2006-02-26 01:31:45Z mike $"
  *
  *   IPP backend for the Common UNIX Printing System (CUPS).
  *
@@ -26,7 +26,9 @@
  * Contents:
  *
  *   main()                 - Send a file to the printer or server.
+ *   cancel_job()           - Cancel a print job.
  *   check_printer_state()  - Check the printer state...
+ *   compress_files()       - Compress print files...
  *   password_cb()          - Disable the password prompt for
  *                            cupsDoFileRequest().
  *   report_printer_state() - Report the printer state.
@@ -74,6 +76,9 @@ static void   cancel_job(http_t *http, const char *uri, int id,
 static void    check_printer_state(http_t *http, const char *uri,
                                    const char *resource, const char *user,
                                    int version);
+#ifdef HAVE_LIBZ
+static void    compress_files(int num_files, char **files);
+#endif /* HAVE_LIBZ */
 static const char *password_cb(const char *);
 static int     report_printer_state(ipp_t *ipp);
 
@@ -116,7 +121,8 @@ main(int  argc,                             /* I - Number of command-line args */
   ipp_t                *request,               /* IPP request */
                *response,              /* IPP response */
                *supported;             /* get-printer-attributes response */
-  int          waitjob,                /* Wait for job complete? */
+  int          compression,            /* Do compression of the job data? */
+               waitjob,                /* Wait for job complete? */
                waitprinter;            /* Wait for printer ready? */
   ipp_attribute_t *job_id_attr;                /* job-id attribute */
   int          job_id;                 /* job-id value */
@@ -224,64 +230,11 @@ main(int  argc,                           /* I - Number of command-line args */
   if (!strcmp(method, "https"))
     cupsSetEncryption(HTTP_ENCRYPT_ALWAYS);
 
- /*
-  * If we have 7 arguments, print the file named on the command-line.
-  * Otherwise, copy stdin to a temporary file and print the temporary
-  * file.
-  */
-
-  if (argc == 6)
-  {
-   /*
-    * Copy stdin to a temporary file...
-    */
-
-    int  fd;           /* Temporary file */
-    char buffer[8192]; /* Buffer for copying */
-    int  bytes;                /* Number of bytes read */
-
-
-    if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
-    {
-      perror("ERROR: unable to create temporary file");
-      return (CUPS_BACKEND_FAILED);
-    }
-
-    while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
-      if (write(fd, buffer, bytes) < bytes)
-      {
-        perror("ERROR: unable to write to temporary file");
-       close(fd);
-       unlink(tmpfilename);
-       return (CUPS_BACKEND_FAILED);
-      }
-
-    close(fd);
-
-   /*
-    * Point to the single file from stdin...
-    */
-
-    filename  = tmpfilename;
-    files     = &filename;
-    num_files = 1;
-  }
-  else
-  {
-   /*
-    * Point to the files on the command-line...
-    */
-
-    num_files = argc - 6;
-    files     = argv + 6;
-  }
-
-  fprintf(stderr, "DEBUG: %d files to send in job...\n", num_files);
-
  /*
   * See if there are any options...
   */
 
+  compression = 0;
   version     = 1;
   waitjob     = 1;
   waitprinter = 1;
@@ -385,6 +338,15 @@ main(int  argc,                            /* I - Number of command-line args */
                  value);
        }
       }
+#ifdef HAVE_LIBZ
+      else if (!strcasecmp(name, "compression"))
+      {
+        compression = !strcasecmp(value, "true") ||
+                     !strcasecmp(value, "yes") ||
+                     !strcasecmp(value, "on") ||
+                     !strcasecmp(value, "gzip");
+      }
+#endif /* HAVE_LIBZ */
       else
       {
        /*
@@ -397,6 +359,74 @@ main(int  argc,                            /* I - Number of command-line args */
     }
   }
 
+ /*
+  * If we have 7 arguments, print the file named on the command-line.
+  * Otherwise, copy stdin to a temporary file and print the temporary
+  * file.
+  */
+
+  if (argc == 6)
+  {
+   /*
+    * Copy stdin to a temporary file...
+    */
+
+    int                fd;                     /* File descriptor */
+    cups_file_t        *fp;                    /* Temporary file */
+    char       buffer[8192];           /* Buffer for copying */
+    int                bytes;                  /* Number of bytes read */
+
+
+    if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
+    {
+      perror("ERROR: unable to create temporary file");
+      return (CUPS_BACKEND_FAILED);
+    }
+
+    if ((fp = cupsFileOpenFd(fd, compression ? "w9" : "w")) == NULL)
+    {
+      perror("ERROR: unable to open temporary file");
+      close(fd);
+      unlink(tmpfilename);
+      return (CUPS_BACKEND_FAILED);
+    }
+
+    while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+      if (cupsFileWrite(fp, buffer, bytes) < bytes)
+      {
+        perror("ERROR: unable to write to temporary file");
+       cupsFileClose(fp);
+       unlink(tmpfilename);
+       return (CUPS_BACKEND_FAILED);
+      }
+
+    cupsFileClose(fp);
+
+   /*
+    * Point to the single file from stdin...
+    */
+
+    filename  = tmpfilename;
+    files     = &filename;
+    num_files = 1;
+  }
+  else
+  {
+   /*
+    * Point to the files on the command-line...
+    */
+
+    num_files = argc - 6;
+    files     = argv + 6;
+
+#ifdef HAVE_LIBZ
+    if (compression)
+      compress_files(num_files, files);
+#endif /* HAVE_LIBZ */
+  }
+
+  fprintf(stderr, "DEBUG: %d files to send in job...\n", num_files);
+
  /*
   * Set the authentication info, if any...
   */
@@ -745,6 +775,12 @@ main(int  argc,                            /* I - Number of command-line args */
 
     fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]);
 
+#ifdef HAVE_LIBZ
+    if (compression)
+      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+                   "compression", NULL, "gzip");
+#endif /* HAVE_LIBZ */
+
    /*
     * Handle options on the command-line...
     */
@@ -1053,6 +1089,14 @@ main(int  argc,                          /* I - Number of command-line args */
   if (tmpfilename[0])
     unlink(tmpfilename);
 
+#ifdef HAVE_LIBZ
+  if (compression)
+  {
+    for (i = 0; i < num_files; i ++)
+      unlink(files[i]);
+  }
+#endif /* HAVE_LIBZ */
+
 #ifdef __APPLE__
   if (pstmpname[0])
     unlink(pstmpname);
@@ -1151,6 +1195,77 @@ check_printer_state(
 }
 
 
+#ifdef HAVE_LIBZ
+/*
+ * 'compress_files()' - Compress print files...
+ */
+
+static void
+compress_files(int  num_files,         /* I - Number of files */
+               char **files)           /* I - Files */
+{
+  int          i,                      /* Looping var */
+               fd;                     /* Temporary file descriptor */
+  ssize_t      bytes;                  /* Bytes read/written */
+  size_t       total;                  /* Total bytes read */
+  cups_file_t  *in,                    /* Input file */
+               *out;                   /* Output file */
+  struct stat  outinfo;                /* Output file information */
+  char         filename[1024],         /* Temporary filename */
+               buffer[65536];          /* Copy buffer */
+
+
+  fprintf(stderr, "DEBUG: Compressing %d job files...\n", num_files);
+  for (i = 0; i < num_files; i ++)
+  {
+    if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+    {
+      perror("ERROR: Unable to create temporary compressed print file");
+      exit(CUPS_BACKEND_FAILED);
+    }
+
+    if ((out = cupsFileOpenFd(fd, "w9")) == NULL)
+    {
+      perror("ERROR: Unable to open temporary compressed print file");
+      exit(CUPS_BACKEND_FAILED);
+    }
+
+    if ((in = cupsFileOpen(files[i], "r")) == NULL)
+    {
+      fprintf(stderr, "ERROR: Unable to open print file \"%s\": %s\n",
+              files[i], strerror(errno));
+      cupsFileClose(out);
+      exit(CUPS_BACKEND_FAILED);
+    }
+
+    total = 0;
+    while ((bytes = cupsFileRead(in, buffer, sizeof(buffer))) > 0)
+      if (cupsFileWrite(out, buffer, bytes) < bytes)
+      {
+        fprintf(stderr, "ERROR: Unable to write %d bytes to \"%s\": %s\n",
+               bytes, filename, strerror(errno));
+        cupsFileClose(in);
+        cupsFileClose(out);
+       exit(CUPS_BACKEND_FAILED);
+      }
+      else
+        total += bytes;
+
+    cupsFileClose(out);
+    cupsFileClose(in);
+
+    files[i] = strdup(filename);
+
+    if (!stat(filename, &outinfo))
+      fprintf(stderr,
+              "DEBUG: File %d compressed to %.1f%% of original size, "
+             CUPS_LLFMT " bytes...\n",
+              i + 1, 100.0 * outinfo.st_size / total, outinfo.st_size);
+  }
+}
+#endif /* HAVE_LIBZ */
+
+
 /*
  * 'password_cb()' - Disable the password prompt for cupsDoFileRequest().
  */
@@ -1500,5 +1615,5 @@ sigterm_handler(int sig)          /* I - Signal */
 
 
 /*
- * End of "$Id: ipp.c 5133 2006-02-19 15:01:12Z mike $".
+ * End of "$Id: ipp.c 5180 2006-02-26 01:31:45Z mike $".
  */
index 1f559ffaf958d7052a347fa88f2eab7a683b3235..3731b378c54f952daccbc88572ba9669a78dc919 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: parallel.c 5099 2006-02-13 02:46:10Z mike $"
+ * "$Id: parallel.c 5194 2006-02-27 20:57:07Z mike $"
  *
  *   Parallel port backend for the Common UNIX Printing System (CUPS).
  *
 #include <errno.h>
 #include <cups/string.h>
 #include <signal.h>
-#include <sys/select.h>
 #include "ieee1284.c"
 
+#ifdef __hpux
+#  include <sys/time.h>
+#else
+#  include <sys/select.h>
+#endif /* __hpux */
+
 #ifdef WIN32
 #  include <io.h>
 #else
@@ -686,7 +691,7 @@ list_devices(void)
       printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
     }
   }
-#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
   int  i;                      /* Looping var */
   int  fd;                     /* File descriptor */
   char device[255];            /* Device filename */
@@ -728,5 +733,5 @@ list_devices(void)
 
 
 /*
- * End of "$Id: parallel.c 5099 2006-02-13 02:46:10Z mike $".
+ * End of "$Id: parallel.c 5194 2006-02-27 20:57:07Z mike $".
  */
index 66a0354cf2b8bb5867e6a3dc33ca6f8b7a25a98f..7d8abe786e9e35aaa226368ace8842e692c25579 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: serial.c 5099 2006-02-13 02:46:10Z mike $"
+ * "$Id: serial.c 5194 2006-02-27 20:57:07Z mike $"
  *
  *   Serial port backend for the Common UNIX Printing System (CUPS).
  *
 #  include <unistd.h>
 #  include <fcntl.h>
 #  include <termios.h>
-#  include <sys/select.h>
+#  ifdef __hpux
+#    include <sys/time.h>
+#  else
+#    include <sys/select.h>
+#  endif /* __hpux */
 #  ifdef HAVE_SYS_IOCTL_H
 #    include <sys/ioctl.h>
 #  endif /* HAVE_SYS_IOCTL_H */
@@ -653,13 +657,13 @@ main(int  argc,                           /* I - Number of command-line arguments (6 or 7) */
 void
 list_devices(void)
 {
-#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__)
+#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
   static char  *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
                                /* Funky hex numbering used for some devices */
 #endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ */
 
 #if defined(__linux) || defined(linux) || defined(__linux__)
-  int  i;              /* Looping var */
+  int  i, j;           /* Looping vars */
   int  fd;             /* File descriptor */
   char device[255];    /* Device filename */
 
@@ -690,6 +694,21 @@ list_devices(void)
              device, i + 1);
     }
   }
+
+  for (i = 0; i < 64; i ++)
+  {
+    for (j = 0; j < 8; j ++)
+    {
+      sprintf(device, "/dev/ttyQ%02de%d", i, j);
+      if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+      {
+        close(fd);
+        printf("serial serial:%s?baud=115200 \"Unknown\" "
+              "\"Equinox ESP %d Port #%d\"\n",
+               device, i, j + 1);
+      }
+    }
+  }
 #elif defined(__sgi)
   int          i, j, n;        /* Looping vars */
   char         device[255];    /* Device filename */
@@ -903,7 +922,7 @@ list_devices(void)
       printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
              device, i + 1);
   }
-#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
   int  i, j;           /* Looping vars */
   int  fd;             /* File descriptor */
   char device[255];    /* Device filename */
@@ -1111,5 +1130,5 @@ list_devices(void)
 
 
 /*
- * End of "$Id: serial.c 5099 2006-02-13 02:46:10Z mike $".
+ * End of "$Id: serial.c 5194 2006-02-27 20:57:07Z mike $".
  */
index b5aeb454873d1a536cf96e3a7391ed8aad8145c0..b28222202ce9b0692b473b5cedcc47effe219b0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: usb-unix.c 5099 2006-02-13 02:46:10Z mike $"
+ * "$Id: usb-unix.c 5162 2006-02-24 03:15:13Z mike $"
  *
  *   USB port backend for the Common UNIX Printing System (CUPS).
  *
@@ -394,7 +394,7 @@ list_devices(void)
   }
 #elif defined(__hpux)
 #elif defined(__osf)
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
   int   i;                      /* Looping var */
   char  device[255];            /* Device filename */
 
@@ -616,5 +616,5 @@ open_device(const char *uri)                /* I - Device URI */
 
 
 /*
- * End of "$Id: usb-unix.c 5099 2006-02-13 02:46:10Z mike $".
+ * End of "$Id: usb-unix.c 5162 2006-02-24 03:15:13Z mike $".
  */
index 92fae2eddaed36a746e02127ec3f55befa50e2ba..ede0292d74a901079c5206e2d57e17244f9f7305 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: usb.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: usb.c 5162 2006-02-24 03:15:13Z mike $"
  *
  *   USB port backend for the Common UNIX Printing System (CUPS).
  *
@@ -72,7 +72,7 @@ int   print_device(const char *uri, const char *hostname,
 
 #ifdef __APPLE__
 #  include "usb-darwin.c"
-#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
 #  include "usb-unix.c"
 #else
 /*
@@ -265,5 +265,5 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
 
 
 /*
- * End of "$Id: usb.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: usb.c 5162 2006-02-24 03:15:13Z mike $".
  */
index abf19ffffa1658e3f399cb44fd1f8496a7d02dcd..2aa9bed788c52d69dc3fc26479168f1d54932975 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: classes.c 5097 2006-02-10 04:06:23Z mike $"
+ * "$Id: classes.c 5160 2006-02-24 01:14:18Z mike $"
  *
  *   Class status CGI for the Common UNIX Printing System (CUPS).
  *
@@ -83,10 +83,8 @@ main(int  argc,                              /* I - Number of command-line arguments */
   * See if we are displaying a printer or all classes...
   */
 
-  if (!strcmp(argv[0], "/") || strstr(argv[0], "classes.cgi"))
-    pclass = NULL;
-  else
-    pclass = argv[0];
+  if ((pclass = getenv("PATH_INFO")) != NULL)
+    pclass ++;
 
  /*
   * See who is logged in...
@@ -460,5 +458,5 @@ show_class(http_t     *http,                /* I - Connection to server */
 
 
 /*
- * End of "$Id: classes.c 5097 2006-02-10 04:06:23Z mike $".
+ * End of "$Id: classes.c 5160 2006-02-24 01:14:18Z mike $".
  */
index d616f28bdff381cfb8239327471b1c965319dd7f..efee0fe5b9b37152a00deb53feb494f83973a287 100644 (file)
@@ -111,11 +111,12 @@ main(int  argc,                           /* I - Number of command-line arguments */
     fprintf(stderr, "argv[%d]=\"%s\"\n", i, argv[i]);
 
   if ((helpfile = getenv("PATH_INFO")) != NULL)
+  {
     helpfile ++;
-  else if (strstr(argv[0], "help.cgi"))
-    helpfile = NULL;
-  else
-    helpfile = argv[0];
+
+    if (!*helpfile)
+      helpfile = NULL;
+  }
 
   if (helpfile)
   {
@@ -180,6 +181,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
   topic = cgiGetVariable("TOPIC");
   si    = helpSearchIndex(hi, query, topic, helpfile);
 
+  fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n", query, topic);
+
   if (si)
   {
     help_node_t        *nn;                    /* Parent node */
@@ -189,9 +192,9 @@ main(int  argc,                             /* I - Number of command-line arguments */
             "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si,
             si->sorted, cupsArrayCount(si->sorted));
 
-    for (n = (help_node_t *)cupsArrayFirst(si->sorted);
+    for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted);
          n;
-        n = (help_node_t *)cupsArrayNext(si->sorted))
+        i ++, n = (help_node_t *)cupsArrayNext(si->sorted))
     {
       if (helpfile && n->anchor)
         snprintf(line, sizeof(line), "#%s", n->anchor);
index dbc2ea2a5c69a9e53405f95dcbbc638a49670d73..fb598f84fc5370829168e3a38bd63a40f14fdf42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ipp-var.c 5097 2006-02-10 04:06:23Z mike $"
+ * "$Id: ipp-var.c 5184 2006-02-26 15:13:44Z mike $"
  *
  *   CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS).
  *
@@ -896,7 +896,8 @@ cgiSetIPPObjectVars(
            break;
 
        case IPP_TAG_URI :
-           if (strchr(attr->values[i].string.text, ':') != NULL)
+           if (strchr(attr->values[i].string.text, ':') &&
+               strcmp(name, "device_uri"))
            {
             /*
              * Rewrite URIs...
@@ -1151,7 +1152,10 @@ cgiShowJobs(http_t     *http,            /* I - Connection to server */
     if ((var = cgiGetVariable("ORDER")) != NULL)
       ascending = !strcasecmp(var, "asc");
     else
-      ascending = 1;
+    {
+      ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed");
+      cgiSetVariable("ORDER", ascending ? "asc" : "dec");
+    }
 
     if (ascending)
     {
@@ -1273,5 +1277,5 @@ cgiText(const char *message)              /* I - Message */
 
 
 /*
- * End of "$Id: ipp-var.c 5097 2006-02-10 04:06:23Z mike $".
+ * End of "$Id: ipp-var.c 5184 2006-02-26 15:13:44Z mike $".
  */
index b745e2336f86b3eed2b8ce9e086977a4e574c7f6..0b4a3a8cba1c66e92691b88b08b52df867e34a33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: printers.c 5104 2006-02-15 03:21:04Z mike $"
+ * "$Id: printers.c 5160 2006-02-24 01:14:18Z mike $"
  *
  *   Printer status CGI for the Common UNIX Printing System (CUPS).
  *
@@ -24,6 +24,7 @@
  * Contents:
  *
  *   main()              - Main entry for CGI.
+ *   print_command()     - Send a print command to the printer.
  *   show_all_printers() - Show all printers...
  *   show_printer()      - Show a single printer.
  */
  */
 
 #include "cgi-private.h"
+#include <errno.h>
 
 
 /*
  * Local functions...
  */
 
+void   print_command(http_t *http, const char *printer, const char *command);
 void   show_all_printers(http_t *http, const char *username);
 void   show_printer(http_t *http, const char *printer);
 
@@ -83,10 +86,8 @@ main(int  argc,                              /* I - Number of command-line arguments */
   * See if we are displaying a printer or all printers...
   */
 
-  if (!strcmp(argv[0], "/") || strstr(argv[0], "printers.cgi"))
-    printer = NULL;
-  else
-    printer = argv[0];
+  if ((printer = getenv("PATH_INFO")) != NULL)
+    printer ++;
 
  /*
   * See who is logged in...
@@ -145,6 +146,10 @@ main(int  argc,                            /* I - Number of command-line arguments */
     else
       show_printer(http, printer);
   }
+  else if (!strcasecmp(op, "print-self-test-page") && printer)
+    print_command(http, printer, "PrintSelfTestPage");
+  else if (!strcasecmp(op, "clean-print-heads") && printer)
+    print_command(http, printer, "Clean all");
   else if (!strcasecmp(op, "print-test-page") && printer)
     cgiPrintTestPage(http, printer);
   else if (!strcasecmp(op, "move-jobs") && printer)
@@ -178,6 +183,124 @@ main(int  argc,                           /* I - Number of command-line arguments */
 }
 
 
+/*
+ * 'print_command()' - Send a print command to the printer.
+ */
+
+void
+print_command(http_t     *http,                /* I - Connection to server */
+              const char *printer,     /* I - Printer */
+             const char *command)      /* I - Command to send */
+{
+  cups_file_t  *fp;                    /* File pointer */
+  char         filename[1024];         /* Temporary file */
+  ipp_t                *request,               /* IPP request */
+               *response;              /* IPP response */
+  char         uri[HTTP_MAX_URI],      /* Printer URI */
+               resource[1024],         /* POST resource path */
+               refresh[1024];          /* Refresh URL */
+  const char   *user;                  /* Username */
+
+
+ /*
+  * See who is logged in...
+  */
+
+  if ((user = getenv("REMOTE_USER")) == NULL)
+    user = "guest";
+
+ /*
+  * Create the CUPS command file to print...
+  */
+
+  if ((fp = cupsTempFile2(filename, sizeof(filename))) == NULL)
+  {
+    cgiStartHTML(cgiText(_("Printer Maintenance")));
+    cgiSetVariable("MESSAGE", _("Unable to create temporary file:"));
+    cgiSetVariable("ERROR", strerror(errno));
+    cgiCopyTemplateLang("error.tmpl");
+    cgiEndHTML();
+    return;
+  }
+
+  cupsFilePuts(fp, "#CUPS-COMMAND\n");
+  cupsFilePrintf(fp, "%s\n", command);
+  cupsFileClose(fp);
+
+ /*
+  * Point to the printer...
+  */
+
+  snprintf(resource, sizeof(resource), "/printers/%s", printer);
+
+  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                   "localhost", ippPort(), "/printers/%s", printer);
+
+ /*
+  * Build an IPP_PRINT_JOB request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  *    printer-uri
+  *    requesting-user-name
+  *    document-format
+  */
+
+  request = ippNewRequest(IPP_PRINT_JOB);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+               NULL, uri);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+               "requesting-user-name", NULL, user);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+               NULL, "Printer Maintenance");
+
+  ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
+               NULL, "application/postscript");
+
+ /*
+  * Do the request and get back a response...
+  */
+
+  if ((response = cupsDoFileRequest(http, request, resource,
+                                    filename)) != NULL)
+  {
+    cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+
+    ippDelete(response);
+  }
+
+  unlink(filename);
+
+  if (cupsLastError() <= IPP_OK_CONFLICT)
+  {
+   /*
+    * Automatically reload the printer status page...
+    */
+
+    cgiFormEncode(uri, resource, sizeof(uri));
+    snprintf(refresh, sizeof(refresh), "2;%s", uri);
+    cgiSetVariable("refresh_page", refresh);
+  }
+
+  cgiStartHTML(cgiText(_("Printer Maintenance")));
+
+  if (cupsLastError() > IPP_OK_CONFLICT)
+    cgiShowIPPError(_("Unable to send maintenance job:"));
+  else
+  {
+    cgiSetVariable("PRINTER_NAME", printer);
+
+    cgiCopyTemplateLang("maintenance.tmpl");
+  }
+
+  cgiEndHTML();
+}
+
+
 /*
  * 'show_all_printers()' - Show all printers...
  */
@@ -190,7 +313,8 @@ show_all_printers(http_t     *http, /* I - Connection to server */
   ipp_t                        *request,       /* IPP request */
                        *response;      /* IPP response */
   cups_array_t         *printers;      /* Array of printer objects */
-  ipp_attribute_t      *printer;       /* Printer object */
+  ipp_attribute_t      *printer,       /* Printer object */
+                       *attr;          /* Current attribute */
   int                  ascending,      /* Order of printers (0 = descending) */
                        first,          /* First printer to show */
                        count;          /* Number of printers */
@@ -284,14 +408,42 @@ show_all_printers(http_t     *http,       /* I - Connection to server */
       for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first);
           i < CUPS_PAGE_MAX && printer;
           i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers))
+      {
         cgiSetIPPObjectVars(printer, NULL, i);
+
+        cgiSetArray("cupscommand", i, "0");
+
+       for (attr = printer; attr; attr = attr->next)
+         if (attr->group_tag != IPP_TAG_PRINTER || !attr->name)
+           break;
+         else if (!strcmp(attr->name, "printer-type"))
+         {
+            if (attr->values[0].integer & CUPS_PRINTER_COMMANDS)
+             cgiSetArray("cupscommand", i, "1");
+           break;
+         }
+      }
     }
     else
     {
       for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1);
           i < CUPS_PAGE_MAX && printer;
           i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers))
+      {
         cgiSetIPPObjectVars(printer, NULL, i);
+
+        cgiSetArray("cupscommand", i, "0");
+
+       for (attr = printer; attr; attr = attr->next)
+         if (attr->group_tag == IPP_TAG_ZERO || !attr->name)
+           break;
+         else if (!strcmp(attr->name, "printer-type"))
+         {
+            if (attr->values[0].integer & CUPS_PRINTER_COMMANDS)
+             cgiSetArray("cupscommand", i, "1");
+           break;
+         }
+      }
     }
 
    /*
@@ -419,6 +571,14 @@ show_printer(http_t     *http,             /* I - Connection to server */
 
     cgiSetIPPVars(response, NULL, NULL, NULL, 0);
 
+    if ((attr = ippFindAttribute(response, "printer-type",
+                                 IPP_TAG_ENUM)) != NULL)
+    {
+      cgiSetVariable("cupscommand",
+                     (attr->values[0].integer & CUPS_PRINTER_COMMANDS) ?
+                        "1" : "0");
+    }
+
     if (printer && (attr = ippFindAttribute(response, "printer-state",
                                             IPP_TAG_ENUM)) != NULL &&
         attr->values[0].integer == IPP_PRINTER_PROCESSING)
@@ -473,5 +633,5 @@ show_printer(http_t     *http,              /* I - Connection to server */
 
 
 /*
- * End of "$Id: printers.c 5104 2006-02-15 03:21:04Z mike $".
+ * End of "$Id: printers.c 5160 2006-02-24 01:14:18Z mike $".
  */
index 6949cb3db773dd776cbf60b778910b8be44e6fec..82a796509bf1562908aa8245673de7372e4ba3b9 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5126 2006-02-17 16:11:30Z mike $"
+# "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $"
 #
 #   Configuration file makefile for the Common UNIX Printing System (CUPS).
 #
@@ -70,16 +70,16 @@ install:    all
                $(INSTALL_CONFIG) $$file $(SERVERROOT) ; \
                chgrp $(CUPS_GROUP) $(SERVERROOT)/$$file || true; \
        done
-       -if test x$(PAMDIR) != x$(BUILDROOT); then \
-               $(INSTALL_DIR) -m 755 $(PAMDIR); \
-               if test -r $(PAMDIR)/cups/$(PAMFILE) ; then \
-                       $(INSTALL_DATA) $(PAMFILE) $(PAMDIR)/cups.N ; \
+       -if test x$(PAMDIR) != x; then \
+               $(INSTALL_DIR) -m 755 $(BUILDROOT)$(PAMDIR); \
+               if test -r $(BUILDROOT)$(PAMDIR)/cups/$(PAMFILE) ; then \
+                       $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \
                else \
-                       $(INSTALL_DATA) $(PAMFILE) $(PAMDIR)/cups ; \
+                       $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \
                fi ; \
        fi
 
 
 #
-# End of "$Id: Makefile 5126 2006-02-17 16:11:30Z mike $".
+# End of "$Id: Makefile 5185 2006-02-26 15:27:14Z mike $".
 #
diff --git a/config-scripts/cups-ldap.m4 b/config-scripts/cups-ldap.m4
new file mode 100644 (file)
index 0000000..3c3e8ed
--- /dev/null
@@ -0,0 +1,50 @@
+dnl
+dnl "$Id$"
+dnl
+dnl   LDAP configuration stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl   Copyright 2003-2006 by Easy Software Products, all rights reserved.
+dnl
+dnl   These coded instructions, statements, and computer programs are the
+dnl   property of Easy Software Products and are protected by Federal
+dnl   copyright law.  Distribution and use rights are outlined in the file
+dnl   "LICENSE.txt" which should have been included with this file.  If this
+dnl   file is missing or damaged please contact Easy Software Products
+dnl   at:
+dnl
+dnl       Attn: CUPS Licensing Information
+dnl       Easy Software Products
+dnl       44141 Airport View Drive, Suite 204
+dnl       Hollywood, Maryland 20636 USA
+dnl
+dnl       Voice: (301) 373-9600
+dnl       EMail: cups-info@cups.org
+dnl         WWW: http://www.cups.org/
+dnl
+
+AC_ARG_ENABLE(ldap, [  --enable-ldap           turn on LDAP support, default=yes])
+AC_ARG_WITH(openldap-libs, [  --with-openldap-libs    set directory for OpenLDAP library],
+    LDFLAGS="-L$withval $LDFLAGS"
+    DSOFLAGS="-L$withval $DSOFLAGS",)
+AC_ARG_WITH(openldap-includes, [  --with-openldap-includes
+                          set directory for OpenLDAP includes],
+    CFLAGS="-I$withval $CFLAGS"
+    CXXFLAGS="-I$withval $CXXFLAGS"
+    CPPFLAGS="-I$withval $CPPFLAGS",)
+
+LIBLDAP=""
+
+if test x$enable_ldap != xno; then
+    AC_CHECK_HEADER(ldap.h,
+       AC_CHECK_LIB(ldap, ldap_value_free,
+            AC_DEFINE(HAVE_LDAP)
+            AC_DEFINE(HAVE_OPENLDAP)
+           LIBLDAP="-lldap"))
+fi
+
+AC_SUBST(LIBLDAP)
+
+
+dnl
+dnl End of "$Id$".
+dnl
index e0c6832c6291e0d9420cd5a5a2a842f64fcb6630..68221a91ed731ef8a154cd1efbedad815c90db8e 100644 (file)
@@ -1,9 +1,9 @@
 dnl
-dnl "$Id: cups-scripting.m4 4494 2005-02-18 02:18:11Z mike $"
+dnl "$Id: cups-scripting.m4 5176 2006-02-25 18:14:10Z mike $"
 dnl
 dnl   Scripting configuration stuff for the Common UNIX Printing System (CUPS).
 dnl
-dnl   Copyright 1997-2005 by Easy Software Products, all rights reserved.
+dnl   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 dnl
 dnl   These coded instructions, statements, and computer programs are the
 dnl   property of Easy Software Products and are protected by Federal
@@ -66,10 +66,23 @@ fi
 
 AC_DEFINE_UNQUOTED(CUPS_PHP, "$CUPS_PHP")
 
-if test "x$CUPS_PHP" != x; then
+if test "x$CUPS_PHP" = x; then
+       CUPS_PHP="no"
+else
        AC_DEFINE(HAVE_PHP)
 fi
 
+PHPDIR=""
+if test "x$CUPS_PHP" != xno; then
+       AC_PATH_PROG(PHPCONFIG, php-config)
+
+       if test "x$PHPCONFIG" != x; then
+               PHPDIR="scripting/php"
+       fi
+fi
+
+AC_SUBST(PHPDIR)
+
 dnl Do we have Python?
 AC_ARG_WITH(python, [  --with-python           set Python interpreter for web interfaces ],
        CUPS_PYTHON="$withval",
@@ -87,5 +100,5 @@ if test "x$CUPS_PYTHON" != x; then
 fi
 
 dnl
-dnl End of "$Id: cups-scripting.m4 4494 2005-02-18 02:18:11Z mike $".
+dnl End of "$Id: cups-scripting.m4 5176 2006-02-25 18:14:10Z mike $".
 dnl
index 788ce838ce9e1cfe9ecd251004f3350d666d5ebd..639eb741437fbb74f04b6f947371a3c2e44aa49a 100644 (file)
@@ -25,26 +25,32 @@ dnl
 AC_ARG_ENABLE(threads, [  --enable-threads        enable multi-threading support])
 
 have_pthread=no
+PTHREAD_FLAGS=""
 
 if test "x$enable_threads" != xno; then
        AC_CHECK_HEADER(pthread.h, AC_DEFINE(HAVE_PTHREAD_H))
-       AC_CHECK_LIB(pthread, pthread_create)
 
-       if test "x$ac_cv_lib_pthread_pthread_create" = xyes -a x$ac_cv_header_pthread_h = xyes; then
-               have_pthread=yes
-       else
-               dnl *BSD uses -pthread option...
-               AC_MSG_CHECKING([for pthread_create using -pthread])
-               SAVELIBS="$LIBS"
-               LIBS="-pthread $LIBS"
-               AC_TRY_LINK([#include <pthread.h>],
-                       [pthread_create(0, 0, 0, 0);],
-                       have_pthread=yes,
-                       LIBS="$SAVELIBS")
-               AC_MSG_RESULT([$have_pthread])
+       if test x$ac_cv_header_pthread_h = xyes; then
+               dnl Check various threading options for the platforms we support
+               for flag in -lpthreads -lpthread -pthread; do
+                       AC_MSG_CHECKING([for pthread_create using $flag])
+                       SAVELIBS="$LIBS"
+                       LIBS="$flag $LIBS"
+                       AC_TRY_LINK([#include <pthread.h>],
+                               [pthread_create(0, 0, 0, 0);],
+                               have_pthread=yes,
+                               LIBS="$SAVELIBS")
+                       AC_MSG_RESULT([$have_pthread])
+
+                       if test $have_pthread = yes; then
+                               PTHREAD_FLAGS="-D_THREAD_SAFE -D_REENTRANT"
+                               break
+                       fi
+               done
        fi
 fi
 
+AC_SUBST(PTHREAD_FLAGS)
 
 dnl
 dnl End of "$Id$".
index 4b81c2c5745284afae0780fc111758f1e32700d7..911a9e8eb12e1d583376999c585d40705aec0bf7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: config.h.in 5144 2006-02-21 20:44:01Z mike $"
+ * "$Id: config.h.in 5157 2006-02-23 20:58:57Z mike $"
  *
  *   Configuration file for the Common UNIX Printing System (CUPS).
  *
 
 
 /*
- * Do we have the OpenSLP library?
+ * Do we have the SLP library?
  */
 
 #undef HAVE_LIBSLP
 
 
+/*
+ * Do we have an LDAP library?
+ */
+
+#undef HAVE_LDAP
+#undef HAVE_OPENLDAP
+
+
 /*
  * Do we have libpaper?
  */
 #endif /* !_CUPS_CONFIG_H_ */
 
 /*
- * End of "$Id: config.h.in 5144 2006-02-21 20:44:01Z mike $".
+ * End of "$Id: config.h.in 5157 2006-02-23 20:58:57Z mike $".
  */
index 636edc724e208bc5c2b0a4aaf509c6e730cef239..6942e28a43777fde44a9085e257ba44459db4957 100644 (file)
@@ -1,5 +1,5 @@
 dnl
-dnl "$Id: configure.in 5124 2006-02-17 16:05:21Z mike $"
+dnl "$Id: configure.in 5182 2006-02-26 04:10:27Z mike $"
 dnl
 dnl   Configuration script for the Common UNIX Printing System (CUPS).
 dnl
@@ -37,6 +37,7 @@ sinclude(config-scripts/cups-compiler.m4)
 sinclude(config-scripts/cups-image.m4)
 sinclude(config-scripts/cups-network.m4)
 sinclude(config-scripts/cups-slp.m4)
+sinclude(config-scripts/cups-ldap.m4)
 sinclude(config-scripts/cups-ssl.m4)
 sinclude(config-scripts/cups-pam.m4)
 sinclude(config-scripts/cups-threads.m4)
@@ -50,14 +51,14 @@ sinclude(config-scripts/cups-scripting.m4)
 
 AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh cups-config
           conf/cupsd.conf conf/pam.std doc/index.html doc/ja/index.html
-         doc/help/standard.html man/cups-deviced.man
+         doc/help/standard.html man/client.conf.man man/cups-deviced.man
          man/cups-driverd.man man/cups-lpd.man man/cupsaddsmb.man
-         man/cupsd.man man/cupsd.conf.man
+         man/cupsd.man man/cupsd.conf.man man/lpoptions.man
          templates/edit-config.tmpl templates/header.tmpl
          templates/ja/header.tmpl)
 
 chmod +x cups-config
 
 dnl
-dnl End of "$Id: configure.in 5124 2006-02-17 16:05:21Z mike $".
+dnl End of "$Id: configure.in 5182 2006-02-26 04:10:27Z mike $".
 dnl
index 9d4fe2fa9ed2bd22f2dfdcf086e464dad7be1e23..17db3d1d0c1cc24ed69ee6a85fac333ebf898c22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cups.h 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: cups.h 5156 2006-02-23 04:24:32Z mike $"
  *
  *   API definitions for the Common UNIX Printing System (CUPS).
  *
@@ -99,7 +99,8 @@ enum cups_ptype_e                     /* Not a typedef'd enum so we can OR */
   CUPS_PRINTER_DELETE = 0x100000,      /* Delete printer @since CUPS 1.2@ */
   CUPS_PRINTER_NOT_SHARED = 0x200000,  /* Printer is not shared @since CUPS 1.2@ */
   CUPS_PRINTER_AUTHENTICATED = 0x400000,/* Printer requires authentication @since CUPS 1.2@ */
-  CUPS_PRINTER_OPTIONS = 0x66fffc      /* ~(CLASS | REMOTE | IMPLICIT) */
+  CUPS_PRINTER_COMMANDS = 0x800000,    /* Printer supports maintenance commands @since CUPS 1.2@ */
+  CUPS_PRINTER_OPTIONS = 0xe6fffc      /* ~(CLASS | REMOTE | IMPLICIT) */
 };
 
 typedef const char *(*cups_password_cb_t)(const char *);
@@ -179,10 +180,10 @@ extern void               cupsEncodeOptions(ipp_t *ipp, int num_options,
 extern void            cupsFreeOptions(int num_options, cups_option_t *options);
 extern const char      *cupsGetOption(const char *name, int num_options,
                                       cups_option_t *options);
-extern int             cupsParseOptions(const char *arg, int num_options,
-                                        cups_option_t **options);
 extern int             cupsMarkOptions(ppd_file_t *ppd, int num_options,
                                        cups_option_t *options);
+extern int             cupsParseOptions(const char *arg, int num_options,
+                                        cups_option_t **options);
 
 extern const char      *cupsGetPassword(const char *prompt);
 extern const char      *cupsServer(void);
@@ -231,6 +232,8 @@ extern void         cupsEncodeOptions2(ipp_t *ipp, int num_options,
 extern const char      *cupsLastErrorString(void);
 extern char            *cupsNotifySubject(cups_lang_t *lang, ipp_t *event);
 extern char            *cupsNotifyText(cups_lang_t *lang, ipp_t *event);
+extern int             cupsRemoveOption(const char *name, int num_options,
+                                        cups_option_t **options);
 extern cups_file_t     *cupsTempFile2(char *filename, int len);
 
 
@@ -241,5 +244,5 @@ extern cups_file_t  *cupsTempFile2(char *filename, int len);
 #endif /* !_CUPS_CUPS_H_ */
 
 /*
- * End of "$Id: cups.h 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: cups.h 5156 2006-02-23 04:24:32Z mike $".
  */
index 0d8ffd95db5305ae631cdaa70c38d8185e2abd57..81e02faf8638caf10a5c88c90667537a6c79b352 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: dest.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: dest.c 5182 2006-02-26 04:10:27Z mike $"
  *
  *   User-defined destination (and option) support for the Common UNIX
  *   Printing System (CUPS).
@@ -44,6 +44,7 @@
 #include "globals.h"
 #include <stdlib.h>
 #include <ctype.h>
+#include <sys/stat.h>
 
 #ifdef HAVE_NOTIFY_H
 #  include <notify.h>
@@ -100,7 +101,7 @@ cupsAddDest(const char  *name,              /* I  - Name of destination */
   for (i = num_dests; i > 0; i --, dest ++)
     if (strcasecmp(name, dest->name) < 0)
       break;
-    else if (strcasecmp(name, dest->name) == 0 &&
+    else if (!strcasecmp(name, dest->name) &&
              instance != NULL && dest->instance != NULL &&
              strcasecmp(instance, dest->instance) < 0)
       break;
@@ -262,7 +263,7 @@ cupsGetDests2(http_t      *http,    /* I - HTTP connection */
   int          num_dests;              /* Number of destinations */
   cups_dest_t  *dest;                  /* Destination pointer */
   const char   *home;                  /* HOME environment variable */
-  char         filename[1024];         /* Local ~/.lpoptions file */
+  char         filename[1024];         /* Local ~/.cups/lpoptions file */
   const char   *defprinter;            /* Default printer */
   char         name[1024],             /* Copy of printer name */
                *instance;              /* Pointer to instance name */
@@ -345,7 +346,7 @@ cupsGetDests2(http_t      *http,    /* I - HTTP connection */
   }
 
  /*
-  * Load the /etc/cups/lpoptions and ~/.lpoptions files...
+  * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files...
   */
 
   snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
@@ -353,13 +354,16 @@ cupsGetDests2(http_t      *http,  /* I - HTTP connection */
 
   if ((home = getenv("HOME")) != NULL)
   {
-    snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+    snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+    if (access(filename, 0))
+      snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+
     num_dests = cups_get_dests(filename, num_dests, dests);
   }
 
  /*
   * Validate the current default destination - this prevents old
-  * Default lines in /etc/cups/lpoptions and ~/.lpoptions from
+  * Default lines in /etc/cups/lpoptions and ~/.cups/lpoptions from
   * pointing to a non-existent printer or class...
   */
 
@@ -411,7 +415,7 @@ cupsGetDests2(http_t      *http,    /* I - HTTP connection */
  * 'cupsSetDests()' - Save the list of destinations for the default server.
  *
  * This function saves the destinations to /etc/cups/lpoptions when run
- * as root and ~/.lpoptions when run as a normal user.
+ * as root and ~/.cups/lpoptions when run as a normal user.
  */
 
 void
@@ -438,7 +442,7 @@ cupsSetDests(int         num_dests, /* I - Number of destinations */
  * 'cupsSetDests2()' - Save the list of destinations for the specified server.
  *
  * This function saves the destinations to /etc/cups/lpoptions when run
- * as root and ~/.lpoptions when run as a normal user.
+ * as root and ~/.cups/lpoptions when run as a normal user.
  *
  * @since CUPS 1.1.21@
  */
@@ -496,7 +500,24 @@ cupsSetDests2(http_t      *http,   /* I - HTTP connection */
     */
 
     if ((home = getenv("HOME")) != NULL)
+    {
+     /*
+      * Remove the old ~/.lpoptions file...
+      */
+
       snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+      unlink(filename);
+
+     /*
+      * Create ~/.cups subdirectory...
+      */
+
+      snprintf(filename, sizeof(filename), "%s/.cups", home);
+      if (access(filename, 0))
+        mkdir(filename, 0700);
+
+      snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+    }
   }
 #endif /* !WIN32 */
 
@@ -544,7 +565,7 @@ cupsSetDests2(http_t      *http,    /* I - HTTP connection */
         if (temp && (val = cupsGetOption(option->name, temp->num_options,
                                         temp->options)) != NULL)
        {
-         if (strcasecmp(val, option->value) == 0)
+         if (!strcasecmp(val, option->value))
            continue;
        }
 
@@ -977,5 +998,5 @@ cups_get_sdests(http_t      *http,  /* I - HTTP connection */
 
 
 /*
- * End of "$Id: dest.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: dest.c 5182 2006-02-26 04:10:27Z mike $".
  */
index 071b29ea17d5062dec4bddf8833d879d06d3e602..b0bbdda5a0909d517861be2ead8fce7133452932 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: encode.c 5128 2006-02-17 18:59:03Z mike $"
+ * "$Id: encode.c 5151 2006-02-22 22:43:17Z mike $"
  *
  *   Option encoding routines for the Common UNIX Printing System (CUPS).
  *
@@ -59,14 +59,22 @@ typedef struct
 static const _ipp_option_t ipp_options[] =
 {
   { "blackplot",               IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { "blackplot-default",       IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
   { "brightness",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "brightness-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "columns",                 IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "columns-default",         IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "copies",                  IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "copies-default",          IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "document-format",         IPP_TAG_MIMETYPE,       IPP_TAG_OPERATION },
   { "finishings",              IPP_TAG_ENUM,           IPP_TAG_JOB },
+  { "finishings-default",      IPP_TAG_ENUM,           IPP_TAG_PRINTER },
   { "fitplot",                 IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { "fitplot-default",         IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
   { "gamma",                   IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "gamma-default",           IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "hue",                     IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "hue-default",             IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "job-k-limit",             IPP_TAG_INTEGER,        IPP_TAG_JOB },
   { "job-page-limit",          IPP_TAG_INTEGER,        IPP_TAG_JOB },
   { "job-priority",            IPP_TAG_INTEGER,        IPP_TAG_JOB },
@@ -75,7 +83,9 @@ static const _ipp_option_t ipp_options[] =
   { "landscape",               IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
   { "media",                   IPP_TAG_KEYWORD,        IPP_TAG_JOB },
   { "mirror",                  IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { "mirror-default",          IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
   { "natural-scaling",         IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "natural-scaling-default", IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "notify-charset",          IPP_TAG_CHARSET,        IPP_TAG_SUBSCRIPTION },
   { "notify-events",           IPP_TAG_KEYWORD,        IPP_TAG_SUBSCRIPTION },
   { "notify-lease-time",       IPP_TAG_INTEGER,        IPP_TAG_SUBSCRIPTION },
@@ -85,15 +95,25 @@ static const _ipp_option_t ipp_options[] =
   { "notify-time-interval",    IPP_TAG_INTEGER,        IPP_TAG_SUBSCRIPTION },
   { "notify-user-data",                IPP_TAG_STRING,         IPP_TAG_SUBSCRIPTION },
   { "number-up",               IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "number-up-default",       IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "orientation-requested",   IPP_TAG_ENUM,           IPP_TAG_JOB },
+  { "orientation-requested-default", IPP_TAG_ENUM,     IPP_TAG_PRINTER },
   { "page-bottom",             IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "page-bottom-default",     IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "page-left",               IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "page-left-default",       IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "page-ranges",             IPP_TAG_RANGE,          IPP_TAG_JOB },
+  { "page-ranges-default",     IPP_TAG_RANGE,          IPP_TAG_PRINTER },
   { "page-right",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "page-right-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "page-top",                        IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "page-top-default",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "penwidth",                        IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "penwidth-default",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "ppi",                     IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "ppi-default",             IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "prettyprint",             IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { "prettyprint-default",     IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
   { "printer-info",            IPP_TAG_TEXT,           IPP_TAG_PRINTER },
   { "printer-is-accepting-jobs",IPP_TAG_BOOLEAN,       IPP_TAG_PRINTER },
   { "printer-is-shared",       IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
@@ -106,12 +126,19 @@ static const _ipp_option_t ipp_options[] =
   { "printer-type",            IPP_TAG_ENUM,           IPP_TAG_PRINTER },
   { "printer-uri",             IPP_TAG_URI,            IPP_TAG_OPERATION },
   { "print-quality",           IPP_TAG_ENUM,           IPP_TAG_JOB },
+  { "print-quality-default",   IPP_TAG_ENUM,           IPP_TAG_PRINTER },
   { "queued-job-count",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "raw",                     IPP_TAG_MIMETYPE,       IPP_TAG_OPERATION },
+  { "resolution",              IPP_TAG_RESOLUTION,     IPP_TAG_JOB },
+  { "resolution-default",      IPP_TAG_RESOLUTION,     IPP_TAG_PRINTER },
   { "saturation",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "saturation-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "scaling",                 IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { "scaling-default",         IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
   { "sides",                   IPP_TAG_KEYWORD,        IPP_TAG_JOB },
-  { "wrap",                    IPP_TAG_BOOLEAN,        IPP_TAG_JOB }
+  { "sides-default",           IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
+  { "wrap",                    IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { "wrap-default",            IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER }
 };
 
 
@@ -172,16 +199,17 @@ cupsEncodeOptions2(
                *sep;                   /* Option separator */
   ipp_attribute_t *attr;               /* IPP attribute */
   ipp_tag_t    value_tag;              /* IPP value tag */
+  cups_option_t        *option;                /* Current option */
 
 
-  DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, group_tag=%x)\n",
-                ipp, num_options, options, group_tag));
+  DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, "
+                "group_tag=%x)\n", ipp, num_options, options, group_tag));
 
  /*
   * Range check input...
   */
 
-  if (ipp == NULL || num_options < 1 || options == NULL)
+  if (!ipp || num_options < 1 || !options)
     return;
 
  /*
@@ -209,7 +237,7 @@ cupsEncodeOptions2(
   * Then loop through the options...
   */
 
-  for (i = 0; i < num_options; i ++)
+  for (i = num_options, option = options; i > 0; i --, option ++)
   {
     _ipp_option_t      key,            /* Search key */
                        *match;         /* Matching attribute */
@@ -219,16 +247,16 @@ cupsEncodeOptions2(
     * Skip document format options that are handled above...
     */
 
-    if (!strcasecmp(options[i].name, "raw") ||
-        !strcasecmp(options[i].name, "document-format") ||
-       !options[i].name[0])
+    if (!strcasecmp(option->name, "raw") ||
+        !strcasecmp(option->name, "document-format") ||
+       !option->name[0])
       continue;
 
    /*
     * Figure out the proper value and group tags for this option...
     */
 
-    key.name = options[i].name;
+    key.name = option->name;
     match    = (_ipp_option_t *)bsearch(&key, ipp_options,
                                         sizeof(ipp_options) /
                                            sizeof(ipp_options[0]),
@@ -244,19 +272,33 @@ cupsEncodeOptions2(
 
       value_tag = match->value_tag;
     }
-    else if (group_tag != IPP_TAG_JOB)
-      continue;
-    else if (!strcasecmp(options[i].value, "true") ||
-             !strcasecmp(options[i].value, "false"))
-      value_tag = IPP_TAG_BOOLEAN;
     else
-      value_tag = IPP_TAG_NAME;
+    {
+      int      namelen;                /* Length of name */
+
+
+      namelen = strlen(option->name);
+
+      if (namelen < 9 || strcmp(option->name + namelen - 8, "-default"))
+      {
+       if (group_tag != IPP_TAG_JOB)
+          continue;
+      }
+      else if (group_tag != IPP_TAG_PRINTER)
+        continue;
+
+      if (!strcasecmp(option->value, "true") ||
+          !strcasecmp(option->value, "false"))
+       value_tag = IPP_TAG_BOOLEAN;
+      else
+       value_tag = IPP_TAG_NAME;
+    }
 
    /*
     * Count the number of values...
     */
 
-    for (count = 1, sep = options[i].value; *sep; sep ++)
+    for (count = 1, sep = option->value; *sep; sep ++)
     {
       if (*sep == '\'')
       {
@@ -293,7 +335,7 @@ cupsEncodeOptions2(
     }
 
     DEBUG_printf(("cupsEncodeOptions2: option = \'%s\', count = %d\n",
-                  options[i].name, count));
+                  option->name, count));
 
    /*
     * Allocate memory for the attribute values...
@@ -320,7 +362,7 @@ cupsEncodeOptions2(
     * Copy the name over...
     */
 
-    if ((attr->name = strdup(options[i].name)) == NULL)
+    if ((attr->name = strdup(option->name)) == NULL)
     {
      /*
       * Ran out of memory!
@@ -336,7 +378,7 @@ cupsEncodeOptions2(
       * Make a copy of the value we can fiddle with...
       */
 
-      if ((copy = strdup(options[i].value)) == NULL)
+      if ((copy = strdup(option->value)) == NULL)
       {
        /*
        * Ran out of memory!
@@ -354,7 +396,7 @@ cupsEncodeOptions2(
       * Since we have a single value, use the value directly...
       */
 
-      val  = options[i].value;
+      val  = option->value;
       copy = NULL;
     }
 
@@ -456,7 +498,7 @@ cupsEncodeOptions2(
            else
              attr->values[j].resolution.yres = attr->values[j].resolution.xres;
 
-           if (strcasecmp(s, "dpc") == 0)
+           if (!strcasecmp(s, "dpc"))
               attr->values[j].resolution.units = IPP_RES_PER_CM;
             else
               attr->values[j].resolution.units = IPP_RES_PER_INCH;
@@ -510,5 +552,5 @@ compare_ipp_options(_ipp_option_t *a,       /* I - First option */
 
 
 /*
- * End of "$Id: encode.c 5128 2006-02-17 18:59:03Z mike $".
+ * End of "$Id: encode.c 5151 2006-02-22 22:43:17Z mike $".
  */
index 791663a272f92c3548d2b563b5a71b415db55f86..20aae7247947725318354f2b8a5546a34dee936a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: file.c 5143 2006-02-21 19:13:01Z mike $"
+ * "$Id: file.c 5186 2006-02-26 18:56:05Z mike $"
  *
  *   File functions for the Common UNIX Printing System (CUPS).
  *
@@ -684,6 +684,9 @@ cupsFileOpen(const char *filename,  /* I - Name of file */
   http_addrlist_t *addrlist;           /* Host address list */
 
 
+  DEBUG_printf(("cupsFileOpen(filename=\"%s\", mode=\"%s\")\n", filename,
+                mode));
+
  /*
   * Range check input...
   */
@@ -774,6 +777,8 @@ cupsFileOpenFd(int        fd,               /* I - File descriptor */
   cups_file_t  *fp;                    /* New CUPS file */
 
 
+  DEBUG_printf(("cupsFileOpenFd(fd=%d, mode=\"%s\")\n", fd, mode));
+
  /*
   * Range check input...
   */
@@ -1149,8 +1154,9 @@ cupsFileSeek(cups_file_t *fp,             /* I - CUPS file */
   size_t       bytes;                  /* Number bytes in buffer */
 
 
-  DEBUG_printf(("cupsFileSeek(fp=%p, pos=%ld)\n", fp, (long)pos));
-  DEBUG_printf(("    fp->pos=%ld\n", (long)fp->pos));
+  DEBUG_printf(("cupsFileSeek(fp=%p, pos=" CUPS_LLFMT ")\n", fp, pos));
+  DEBUG_printf(("    fp->pos=" CUPS_LLFMT "\n", fp->pos));
+  DEBUG_printf(("    fp->ptr=%p, fp->end=%p\n", fp->ptr, fp->end));
 
  /*
   * Range check input...
@@ -1159,6 +1165,21 @@ cupsFileSeek(cups_file_t *fp,            /* I - CUPS file */
   if (!fp || pos < 0 || fp->mode != 'r')
     return (-1);
 
+  if (fp->pos == pos)
+  {
+   /*
+    * No seeking necessary...
+    */
+
+    if (fp->ptr)
+    {
+      fp->ptr = fp->buf;
+      fp->eof = 0;
+    }
+
+    return (pos);
+  }
+
  /*
   * Figure out the number of bytes in the current buffer, and then
   * see if we are outside of it...
@@ -1206,7 +1227,7 @@ cupsFileSeek(cups_file_t *fp,             /* I - CUPS file */
     */
 
 #ifdef HAVE_LIBZ
-    if (fp->compressed)
+    if (fp->compressed || !fp->ptr)
     {
       while ((bytes = cups_fill(fp)) > 0)
         if (pos >= fp->pos && pos < (fp->pos + bytes))
@@ -1219,7 +1240,7 @@ cupsFileSeek(cups_file_t *fp,             /* I - CUPS file */
 #endif /* HAVE_LIBZ */
     {
       fp->pos = lseek(fp->fd, pos, SEEK_SET);
-      DEBUG_printf(("    lseek() returned %ld...\n", (long)fp->pos));
+      DEBUG_printf(("    lseek() returned " CUPS_LLFMT "...\n", fp->pos));
       fp->ptr = NULL;
       fp->end = NULL;
     }
@@ -1400,8 +1421,9 @@ cups_fill(cups_file_t *fp)                /* I - CUPS file */
 
 
   DEBUG_printf(("cups_fill(fp=%p)\n", fp));
-  DEBUG_printf(("    fp->ptr=%p, fp->end=%p, fp->buf=%p, fp->pos=%ld\n",
-                fp->ptr, fp->end, fp->buf, (long)fp->pos));
+  DEBUG_printf(("    fp->ptr=%p, fp->end=%p, fp->buf=%p, "
+                "fp->pos=" CUPS_LLFMT ", fp->eof=%d\n",
+                fp->ptr, fp->end, fp->buf, fp->pos, fp->eof));
 
  /*
   * Update the "pos" element as needed...
@@ -1411,6 +1433,8 @@ cups_fill(cups_file_t *fp)                /* I - CUPS file */
     fp->pos += fp->end - fp->buf;
 
 #ifdef HAVE_LIBZ
+  DEBUG_printf(("    fp->compressed=%d\n", fp->compressed));
+
   while (!fp->ptr || fp->compressed)
   {
    /*
@@ -1425,7 +1449,6 @@ cups_fill(cups_file_t *fp)                /* I - CUPS file */
       */
 
       fp->compressed = 0;
-      fp->pos        = 0;
 
      /*
       * Read the first bytes in the file to determine if we have a gzip'd
@@ -1438,6 +1461,9 @@ cups_fill(cups_file_t *fp)                /* I - CUPS file */
        * Can't read from file!
        */
 
+        DEBUG_printf(("    cups_read() returned " CUPS_LLFMT "!\n",
+                     CUPS_LLCAST bytes));
+
        return (-1);
       }
 
@@ -1452,6 +1478,8 @@ cups_fill(cups_file_t *fp)                /* I - CUPS file */
        fp->ptr = fp->buf;
        fp->end = fp->buf + bytes;
 
+        DEBUG_printf(("    returning " CUPS_LLFMT "!\n", CUPS_LLCAST bytes));
+
        return (bytes);
       }
 
@@ -1796,5 +1824,5 @@ cups_write(cups_file_t *fp,               /* I - CUPS file */
 
 
 /*
- * End of "$Id: file.c 5143 2006-02-21 19:13:01Z mike $".
+ * End of "$Id: file.c 5186 2006-02-26 18:56:05Z mike $".
  */
index 4a78a42df2367309244c4f4057f9d43d1f74e803..6c534a70f0eceb8de2563df74f6e13651033d161 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: getputfile.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: getputfile.c 5147 2006-02-22 16:37:44Z mike $"
  *
  *   Get/put file functions for the Common UNIX Printing System (CUPS).
  *
@@ -295,6 +295,7 @@ cupsPutFd(http_t     *http,         /* I - HTTP connection to server */
     httpClearFields(http);
     httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
     httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
+    httpSetExpect(http, HTTP_CONTINUE);
 
     if (httpPut(http, resource))
     {
@@ -311,21 +312,31 @@ cupsPutFd(http_t     *http,               /* I - HTTP connection to server */
     }
 
    /*
-    * Copy the file...
+    * Wait up to 1 second for a 100-continue response...
     */
 
-    lseek(fd, 0, SEEK_SET);
+    if (httpWait(http, 1000))
+      status = httpUpdate(http);
+    else
+      status = HTTP_CONTINUE;
 
-    status = HTTP_CONTINUE;
+    if (status == HTTP_CONTINUE)
+    {
+     /*
+      * Copy the file...
+      */
 
-    while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
-      if (httpCheck(http))
-      {
-        if ((status = httpUpdate(http)) != HTTP_CONTINUE)
-          break;
-      }
-      else
-        httpWrite2(http, buffer, bytes);
+      lseek(fd, 0, SEEK_SET);
+
+      while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
+       if (httpCheck(http))
+       {
+          if ((status = httpUpdate(http)) != HTTP_CONTINUE)
+            break;
+       }
+       else
+          httpWrite2(http, buffer, bytes);
+    }
 
     if (status == HTTP_CONTINUE)
     {
@@ -471,5 +482,5 @@ cupsPutFile(http_t     *http,               /* I - HTTP connection to server */
 
 
 /*
- * End of "$Id: getputfile.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: getputfile.c 5147 2006-02-22 16:37:44Z mike $".
  */
index 4dd9064eab4b96dd4afbc5882b4d8c93b0af266e..ec0f7b269035a022405488fa62551bd26eeabc7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: http-addr.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: http-addr.c 5161 2006-02-24 03:11:46Z mike $"
  *
  *   HTTP address routines for the Common UNIX Printing System (CUPS).
  *
@@ -191,11 +191,8 @@ httpAddrLookup(
 #endif /* AF_LOCAL */
 #ifdef HAVE_GETNAMEINFO
   {
-    char       servname[1024];                 /* Service name (not used) */
-
-
     if (getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen,
-                    servname, sizeof(servname), 0))
+                    NULL, 0, 0))
     {
      /*
       * If we get an error back, then the address type is not supported
@@ -270,13 +267,22 @@ httpAddrString(const http_addr_t *addr,   /* I - Address to convert */
     strlcpy(s, addr->un.sun_path, slen);
   else
 #endif /* AF_LOCAL */
-#ifdef HAVE_GETNAMEINFO
+  if (addr->addr.sa_family == AF_INET)
   {
-    char       servname[1024];         /* Service name (not used) */
+    unsigned temp;                     /* Temporary address */
 
 
+    temp = ntohl(addr->ipv4.sin_addr.s_addr);
+
+    snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255,
+             (temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
+  }
+#ifdef AF_INET6
+  else if (addr->addr.sa_family == AF_INET6)
+  {
+#  ifdef HAVE_GETNAMEINFO
     if (getnameinfo(&addr->addr, httpAddrLength(addr), s, slen,
-                    servname, sizeof(servname), NI_NUMERICHOST))
+                    NULL, 0, NI_NUMERICHOST))
     {
      /*
       * If we get an error back, then the address type is not supported
@@ -287,104 +293,87 @@ httpAddrString(const http_addr_t *addr,  /* I - Address to convert */
 
       return (NULL);
     }
-  }
-#else
-  {
-#ifdef AF_INET6
-    if (addr->addr.sa_family == AF_INET6)
+#  else
+    char       *sptr;                  /* Pointer into string */
+    int                i;                      /* Looping var */
+    unsigned   temp;                   /* Current value */
+    const char *prefix;                /* Prefix for address */
+
+
+    prefix = "";
+    for (sptr = s, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++)
     {
-      char             *sptr;          /* Pointer into string */
-      int              i;              /* Looping var */
-      unsigned         temp;           /* Current value */
-      const char       *prefix;        /* Prefix for address */
+      temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
 
+      snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff);
+      prefix = ":";
+      slen -= strlen(sptr);
+      sptr += strlen(sptr);
 
-      prefix = "";
-      for (sptr = s, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++)
-      {
-        temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
+      temp &= 0xffff;
 
-        snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff);
-       prefix = ":";
+      if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1])
+      {
+        snprintf(sptr, slen, "%s%x", prefix, temp);
        slen -= strlen(sptr);
        sptr += strlen(sptr);
-
-        temp &= 0xffff;
-
-       if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1])
-       {
-          snprintf(sptr, slen, "%s%x", prefix, temp);
-         slen -= strlen(sptr);
-         sptr += strlen(sptr);
-       }
       }
+    }
+
+    if (i < 4)
+    {
+      while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i])
+       i ++;
 
       if (i < 4)
       {
-       while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i])
-         i ++;
+        snprintf(sptr, slen, "%s:", prefix);
+       prefix = ":";
+       slen -= strlen(sptr);
+       sptr += strlen(sptr);
 
-        if (i < 4)
+       for (; i < 4; i ++)
        {
-          snprintf(sptr, slen, "%s:", prefix);
-         prefix = ":";
-         slen -= strlen(sptr);
-         sptr += strlen(sptr);
+          temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
 
-         for (; i < 4; i ++)
+          if ((temp & 0xffff0000) || addr->ipv6.sin6_addr.s6_addr32[i - 1])
          {
-            temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
-
-            if ((temp & 0xffff0000) || addr->ipv6.sin6_addr.s6_addr32[i - 1])
-           {
-              snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff);
-             slen -= strlen(sptr);
-             sptr += strlen(sptr);
-            }
-
-            snprintf(sptr, slen, "%s%x", prefix, temp & 0xffff);
+            snprintf(sptr, slen, "%s%x", prefix, (temp >> 16) & 0xffff);
            slen -= strlen(sptr);
            sptr += strlen(sptr);
-         }
-       }
-       else if (sptr == s)
-       {
-        /*
-          * Empty address...
-         */
+          }
 
-          strlcpy(s, "::", slen);
-         sptr = s + 2;
-         slen -= 2;
-       }
-       else
-       {
-        /*
-         * Empty at end...
-         */
-
-          strlcpy(sptr, "::", slen);
-         sptr += 2;
-         slen -= 2;
+          snprintf(sptr, slen, "%s%x", prefix, temp & 0xffff);
+         slen -= strlen(sptr);
+         sptr += strlen(sptr);
        }
       }
-    }
-    else
-#endif /* AF_INET6 */
-    if (addr->addr.sa_family == AF_INET)
-    {
-      unsigned temp;                           /* Temporary address */
-
+      else if (sptr == s)
+      {
+       /*
+        * Empty address...
+       */
 
-      temp = ntohl(addr->ipv4.sin_addr.s_addr);
+        strlcpy(s, "::", slen);
+       sptr = s + 2;
+       slen -= 2;
+      }
+      else
+      {
+       /*
+       * Empty at end...
+       */
 
-      snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255,
-               (temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
+        strlcpy(sptr, "::", slen);
+       sptr += 2;
+       slen -= 2;
+      }
     }
-    else
-      strlcpy(s, "UNKNOWN", slen);
+#  endif /* HAVE_GETNAMEINFO */
   }
-#endif /* HAVE_GETNAMEINFO */
+#endif /* AF_INET6 */
+  else
+    strlcpy(s, "UNKNOWN", slen);
 
   DEBUG_printf(("httpAddrString: returning \"%s\"...\n", s));
 
@@ -541,5 +530,5 @@ httpGetHostname(char *s,            /* I - String buffer for name */
 
 
 /*
- * End of "$Id: http-addr.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: http-addr.c 5161 2006-02-24 03:11:46Z mike $".
  */
index a7380769299c1be9faf6200a02041a791748483d..ea5e06de1bd36eca35eff299863bdc5c4432b160 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: http-support.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: http-support.c 5149 2006-02-22 19:10:22Z mike $"
  *
  *   HTTP support routines for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -1003,7 +1003,25 @@ httpSeparateURI(
     else
     {
      /*
-      * Grab hostname or IPv4 address...
+      * Validate the hostname or IPv4 address first...
+      */
+
+      for (ptr = (char *)uri; *ptr; ptr ++)
+        if (strchr(":?/", *ptr))
+         break;
+        else if (!strchr("abcdefghijklmnopqrstuvwxyz"
+                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                        "0123456789"
+                        "-._~"
+                        "%"
+                        "!$&'()*+,;=", *ptr))
+       {
+         *host = '\0';
+         return (HTTP_URI_BAD_HOSTNAME);
+       }
+
+     /*
+      * Then copy the hostname or IPv4 address to the buffer...
       */
 
       uri = http_copy_decode(host, uri, hostlen, ":?/",
@@ -1014,21 +1032,6 @@ httpSeparateURI(
         *host = '\0';
         return (HTTP_URI_BAD_HOSTNAME);
       }
-
-     /*
-      * Validate value...
-      */
-
-      for (ptr = host; *ptr; ptr ++)
-        if (!strchr("abcdefghijklmnopqrstuvwxyz"
-                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                   "0123456789"
-                   "-._~"
-                   "!$&'()*+,;=", *ptr))
-       {
-         *host = '\0';
-         return (HTTP_URI_BAD_HOSTNAME);
-       }
     }
 
    /*
@@ -1158,6 +1161,9 @@ httpStatus(http_status_t status)  /* I - HTTP status code */
         return ("Not Implemented");
     case HTTP_NOT_SUPPORTED :
         return ("Not Supported");
+    case HTTP_EXPECTATION_FAILED :
+        return ("Expectation Failed");
+
     default :
         return ("Unknown");
   }
@@ -1306,5 +1312,5 @@ http_copy_encode(char       *dst, /* O - Destination buffer */
 
 
 /*
- * End of "$Id: http-support.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: http-support.c 5149 2006-02-22 19:10:22Z mike $".
  */
index 0b5c9c57e89081d80dcefc9f42b98c75708cd252..da2279344c1905a90dfc1d0e86a395e9b287df7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: http.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: http.c 5200 2006-02-28 00:10:32Z mike $"
  *
  *   HTTP routines for the Common UNIX Printing System (CUPS).
  *
@@ -63,6 +63,7 @@
  *   _httpReadCDSA()      - Read function for CDSA decryption code.
  *   httpReconnect()      - Reconnect to a HTTP server...
  *   httpSetCookie()      - Set the cookie value(s)...
+ *   httpSetExpect()      - Set the Expect: header in a request.
  *   httpSetField()       - Set the value of an HTTP header.
  *   httpSetLength()      - Set the content-length and transfer-encoding.
  *   httpTrace()          - Send an TRACE request to the server.
@@ -222,6 +223,8 @@ httpClearFields(http_t *http)               /* I - HTTP connection */
   {
     memset(http->fields, 0, sizeof(http->fields));
     httpSetField(http, HTTP_FIELD_HOST, http->hostname);
+
+    http->expect = (http_status_t)0;
   }
 }
 
@@ -1386,31 +1389,32 @@ _httpReadCDSA(
   OSStatus     result;                 /* Return value */
   ssize_t      bytes;                  /* Number of bytes read */
 
-
-  for (;;)
-  {
+  do
     bytes = recv((int)connection, data, *dataLength, 0);
+  while (bytes == -1 && errno == EINTR);
 
-    if (bytes > 0)
-    {
-      result      = (bytes == *dataLength);
-      *dataLength = bytes;
-
-      return (result);
-    }
+  if (bytes == *dataLength)
+    result = 0;
+  else if (bytes > 0)
+  {
+    *dataLength = bytes;
+    result = errSSLWouldBlock;
+  }
+  else
+  {
+    *dataLength = 0;
 
     if (bytes == 0)
-      return (errSSLClosedAbort);
-
-    if (errno == EAGAIN)
-      return (errSSLWouldBlock);
-
-    if (errno == EPIPE)
-      return (errSSLClosedAbort);
-
-    if (errno != EINTR)
-      return (errSSLInternal);
+      result = errSSLClosedAbort;
+    else if (errno == EAGAIN)
+      result = errSSLWouldBlock;
+    else if (errno == EPIPE)
+      result = errSSLClosedAbort;
+    else
+      result = errSSLInternal;
   }
+
+  return result;
 }
 #endif /* HAVE_SSL && HAVE_CDSASSL */
 
@@ -1523,6 +1527,23 @@ httpSetCookie(http_t     *http,          /* I - Connection */
 }
 
 
+/*
+ * 'httpSetExpect()' - Set the Expect: header in a request.
+ *
+ * Currently only HTTP_CONTINUE is supported for the "expect" argument.
+ *
+ * @since CUPS 1.2@
+ */
+
+void
+httpSetExpect(http_t        *http,     /* I - HTTP connection */
+              http_status_t expect)    /* I - HTTP status to expect (HTTP_CONTINUE) */
+{
+  if (http)
+    http->expect = expect;
+}
+
+
 /*
  * 'httpSetField()' - Set the value of an HTTP header.
  */
@@ -1941,28 +1962,30 @@ _httpWriteCDSA(
   OSStatus     result;                 /* Return value */
   ssize_t      bytes;                  /* Number of bytes read */
 
-
-  for (;;)
-  {
+  do
     bytes = write((int)connection, data, *dataLength);
+  while (bytes == -1 && errno == EINTR);
 
-    if (bytes >= 0)
-    {
-      result      = (bytes == *dataLength) ? 0 : errSSLWouldBlock;
-      *dataLength = bytes;
-
-      return (result);
-    }
-
+  if (bytes == *dataLength)
+    result = 0;
+  else if (bytes >= 0)
+  {
+    *dataLength = bytes;
+    result = errSSLWouldBlock;
+  }
+  else
+  {
+    *dataLength = 0;
+  
     if (errno == EAGAIN)
-      return (errSSLWouldBlock);
-
-    if (errno == EPIPE)
-      return (errSSLClosedAbort);
-
-    if (errno != EINTR)
-      return (errSSLInternal);
+      result = errSSLWouldBlock;
+    else if (errno == EPIPE)
+      result = errSSLClosedAbort;
+    else
+      result = errSSLInternal;
   }
+
+  return result;
 }
 #endif /* HAVE_SSL && HAVE_CDSASSL */
 
@@ -2018,8 +2041,13 @@ http_read_ssl(http_t *http,              /* I - HTTP connection */
        result = 0;
        break;
     case errSSLWouldBlock :
-       errno = EAGAIN;
-       result = -1;
+       if (processed)
+         result = (int)processed;
+       else
+       {
+         result = -1;
+         errno = EINTR;
+       }
        break;
     default :
        errno = EPIPE;
@@ -2148,6 +2176,14 @@ http_send(http_t       *http,    /* I - HTTP connection */
       return (-1);
     }
 
+  if (http->expect == HTTP_CONTINUE &&
+      (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV))
+    if (httpPrintf(http, "Expect: 100-continue\r\n") < 1)
+    {
+      http->status = HTTP_ERROR;
+      return (-1);
+    }
+
   if (httpPrintf(http, "\r\n") < 1)
   {
     http->status = HTTP_ERROR;
@@ -2270,7 +2306,10 @@ http_setup_ssl(http_t *http)             /* I - HTTP connection */
     error = SSLSetAllowsAnyRoot(conn, true);
 
   if (!error)
-    error = SSLHandshake(conn);
+  {
+    while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+      usleep(1000);
+  }
 
   if (error != 0)
   {
@@ -2327,7 +2366,9 @@ http_shutdown_ssl(http_t *http)   /* I - HTTP connection */
   free(conn);
 
 #  elif defined(HAVE_CDSASSL)
-  SSLClose((SSLContextRef)http->tls);
+  while (SSLClose((SSLContextRef)http->tls) == errSSLWouldBlock)
+    usleep(1000);
+
   SSLDisposeContext((SSLContextRef)http->tls);
 #  endif /* HAVE_LIBSSL */
 
@@ -2692,8 +2733,13 @@ http_write_ssl(http_t     *http, /* I - HTTP connection */
        result = 0;
        break;
     case errSSLWouldBlock :
-       errno = EAGAIN;
-       result = -1;
+       if (processed)
+         result = (int)processed;
+       else
+       {
+         result = -1;
+         errno = EINTR;
+       }
        break;
     default :
        errno = EPIPE;
@@ -2708,5 +2754,5 @@ http_write_ssl(http_t     *http,  /* I - HTTP connection */
 
 
 /*
- * End of "$Id: http.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: http.c 5200 2006-02-28 00:10:32Z mike $".
  */
index 0b13ba6c10be4a664e5a1c7063d5da00cea44988..6ff09a20fcd1c5e4c98a3a869e9a65fa773bf0b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: http.h 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: http.h 5147 2006-02-22 16:37:44Z mike $"
  *
  *   Hyper-Text Transport Protocol definitions for the Common UNIX Printing
  *   System (CUPS).
@@ -242,6 +242,8 @@ typedef enum http_status_e          /**** HTTP status codes ****/
   HTTP_REQUEST_TOO_LARGE,              /* Request entity too large */
   HTTP_URI_TOO_LONG,                   /* URI too long */
   HTTP_UNSUPPORTED_MEDIATYPE,          /* The requested media type is unsupported */
+  HTTP_REQUESTED_RANGE,                        /* The requested range is not satisfiable */
+  HTTP_EXPECTATION_FAILED,             /* The expectation given in an Expect header field was not met */
   HTTP_UPGRADE_REQUIRED = 426,         /* Upgrade to SSL/TLS required */
 
   HTTP_SERVER_ERROR = 500,             /* Internal server error */
@@ -473,6 +475,7 @@ extern http_uri_status_t httpSeparateURI(http_uri_coding_t decoding,
                                         char *username, int usernamelen,
                                         char *host, int hostlen, int *port,
                                         char *resource, int resourcelen);
+extern void            httpSetExpect(http_t *http, http_status_t expect);
 extern void            httpSetLength(http_t *http, size_t length);
 extern ssize_t         httpWrite2(http_t *http, const char *buffer,
                                   size_t length);
@@ -488,5 +491,5 @@ extern ssize_t              httpWrite2(http_t *http, const char *buffer,
 #endif /* !_CUPS_HTTP_H_ */
 
 /*
- * End of "$Id: http.h 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: http.h 5147 2006-02-22 16:37:44Z mike $".
  */
index c901781db7230713e56e24a74be6a38b753e0e38..bb29bcbcfceac78eb56cb8422b11fbbf9d98099c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: mark.c 5119 2006-02-16 15:52:06Z mike $"
+ * "$Id: mark.c 5190 2006-02-27 02:42:07Z mike $"
  *
  *   Option marking routines for the Common UNIX Printing System (CUPS).
  *
@@ -43,7 +43,7 @@
  * Include necessary headers...
  */
 
-#include "ppd.h"
+#include "cups.h"
 #include "string.h"
 #include "debug.h"
 
@@ -355,7 +355,7 @@ ppdMarkOption(ppd_file_t *ppd,              /* I - PPD file record */
     return (0);
 
 
-  if (!strncasecmp(choice, "Custom.", 7) /* TODO || strchr(choice, '=') */ )
+  if (!strncasecmp(choice, "Custom.", 7))
   {
    /*
     * Handle a custom option...
@@ -382,13 +382,6 @@ ppdMarkOption(ppd_file_t *ppd,             /* I - PPD file record */
       ppd_cparam_t     *cparam;        /* Custom parameter */
       char             units[33];      /* Custom points units */
 
-
-     /*
-      * TODO: Detect and support custom option values using the
-      * collection format "{Name1=foo Name2=bar}".  For now, just
-      * support Custom.value for single-valued custom options.
-      */
-
       if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
       {
         if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL)
@@ -435,6 +428,75 @@ ppdMarkOption(ppd_file_t *ppd,             /* I - PPD file record */
       }
     }
   }
+  else if (choice[0] == '{')
+  {
+   /*
+    * Handle multi-value custom options...
+    */
+
+    ppd_coption_t      *coption;       /* Custom option */
+    ppd_cparam_t       *cparam;        /* Custom parameter */
+    char               units[33];      /* Custom points units */
+    int                        num_vals;       /* Number of values */
+    cups_option_t      *vals,          /* Values */
+                       *val;           /* Value */
+
+
+    if ((c = ppdFindChoice(o, "Custom")) == NULL)
+      return (0);
+
+    if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
+    {
+      num_vals = cupsParseOptions(choice + 1, 0, &vals);
+
+      for (i = 0, val = vals; i < num_vals; i ++, val ++)
+      {
+        if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL)
+         continue;
+
+       switch (cparam->type)
+       {
+         case PPD_CUSTOM_CURVE :
+         case PPD_CUSTOM_INVCURVE :
+         case PPD_CUSTOM_REAL :
+             cparam->current.custom_real = atof(val->value);
+             break;
+
+         case PPD_CUSTOM_POINTS :
+             if (sscanf(val->value, "%f%s", &(cparam->current.custom_points),
+                        units) < 2)
+               strcpy(units, "pt");
+
+              if (!strcasecmp(units, "cm"))
+               cparam->current.custom_points *= 72.0 / 2.54;         
+              else if (!strcasecmp(units, "mm"))
+               cparam->current.custom_points *= 72.0 / 25.4;         
+              else if (!strcasecmp(units, "m"))
+               cparam->current.custom_points *= 72.0 / 0.0254;       
+              else if (!strcasecmp(units, "in"))
+               cparam->current.custom_points *= 72.0;        
+              else if (!strcasecmp(units, "ft"))
+               cparam->current.custom_points *= 12 * 72.0;           
+             break;
+
+         case PPD_CUSTOM_INT :
+             cparam->current.custom_int = atoi(val->value);
+             break;
+
+         case PPD_CUSTOM_PASSCODE :
+         case PPD_CUSTOM_PASSWORD :
+         case PPD_CUSTOM_STRING :
+             if (cparam->current.custom_string)
+               free(cparam->current.custom_string);
+
+             cparam->current.custom_string = strdup(val->value);
+             break;
+       }
+      }
+
+      cupsFreeOptions(num_vals, vals);
+    }
+  }
   else
   {
     for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
@@ -586,5 +648,5 @@ ppd_defaults(ppd_file_t  *ppd,      /* I - PPD file */
 
 
 /*
- * End of "$Id: mark.c 5119 2006-02-16 15:52:06Z mike $".
+ * End of "$Id: mark.c 5190 2006-02-27 02:42:07Z mike $".
  */
index cbaa5919064c0bc1277b7759ae489bdf505b62a1..e232caaad0b7c8fb7df150c892909510aa07017a 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: options.c 4980 2006-01-25 19:57:45Z mike $"
+ * "$Id: options.c 5151 2006-02-22 22:43:17Z mike $"
  *
  *   Option routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1997-2005 by Easy Software Products.
+ *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
  *
  * Contents:
  *
- *   cupsAddOption()    - Add an option to an option array.
- *   cupsFreeOptions()  - Free all memory used by options.
- *   cupsGetOption()    - Get an option value.
- *   cupsParseOptions() - Parse options from a command-line argument.
- *   cupsMarkOptions()  - Mark command-line options in a PPD file.
+ *   cupsAddOption()     - Add an option to an option array.
+ *   cupsFreeOptions()   - Free all memory used by options.
+ *   cupsGetOption()     - Get an option value.
+ *   cupsMarkOptions()   - Mark command-line options in a PPD file.
+ *   cupsParseOptions()  - Parse options from a command-line argument.
+ *   cupsRemoveOptions() - Remove an option from an option array.
  */
 
 /*
@@ -152,206 +153,6 @@ cupsGetOption(const char    *name,        /* I - Name of option */
 }
 
 
-/*
- * 'cupsParseOptions()' - Parse options from a command-line argument.
- *
- * This function converts space-delimited name/value pairs according
- * to the PAPI text option ABNF specification. Collection values
- * ("name={a=... b=... c=...}") are stored with the curley brackets
- * intact - use cupsParseOptions() on the value to extract the collection
- * attributes.
- */
-
-int                                    /* O - Number of options found */
-cupsParseOptions(
-    const char    *arg,                        /* I - Argument to parse */
-    int           num_options,         /* I - Number of options */
-    cups_option_t **options)           /* O - Options found */
-{
-  char *copyarg,                       /* Copy of input string */
-       *ptr,                           /* Pointer into string */
-       *name,                          /* Pointer to name */
-       *value;                         /* Pointer to value */
-
-
-  if (arg == NULL || options == NULL || num_options < 0)
-    return (0);
-
- /*
-  * Make a copy of the argument string and then divide it up...
-  */
-
-  copyarg     = strdup(arg);
-  ptr         = copyarg;
-
- /*
-  * Skip leading spaces...
-  */
-
-  while (isspace(*ptr & 255))
-    ptr ++;
-
- /*
-  * Loop through the string...
-  */
-
-  while (*ptr != '\0')
-  {
-   /*
-    * Get the name up to a SPACE, =, or end-of-string...
-    */
-
-    name = ptr;
-    while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0')
-      ptr ++;
-
-   /*
-    * Avoid an empty name...
-    */
-
-    if (ptr == name)
-      break;
-
-   /*
-    * Skip trailing spaces...
-    */
-
-    while (isspace(*ptr & 255))
-      *ptr++ = '\0';
-
-    if (*ptr != '=')
-    {
-     /*
-      * Start of another option...
-      */
-
-      if (strncasecmp(name, "no", 2) == 0)
-        num_options = cupsAddOption(name + 2, "false", num_options,
-                                   options);
-      else
-        num_options = cupsAddOption(name, "true", num_options, options);
-
-      continue;
-    }
-
-   /*
-    * Remove = and parse the value...
-    */
-
-    *ptr++ = '\0';
-
-    if (*ptr == '\'')
-    {
-     /*
-      * Quoted string constant...
-      */
-
-      ptr ++;
-      value = ptr;
-
-      while (*ptr != '\'' && *ptr != '\0')
-      {
-        if (*ptr == '\\')
-         _cups_strcpy(ptr, ptr + 1);
-
-        ptr ++;
-      }
-
-      if (*ptr != '\0')
-        *ptr++ = '\0';
-    }
-    else if (*ptr == '\"')
-    {
-     /*
-      * Double-quoted string constant...
-      */
-
-      ptr ++;
-      value = ptr;
-
-      while (*ptr != '\"' && *ptr != '\0')
-      {
-        if (*ptr == '\\')
-         _cups_strcpy(ptr, ptr + 1);
-
-        ptr ++;
-      }
-
-      if (*ptr != '\0')
-        *ptr++ = '\0';
-    }
-    else if (*ptr == '{')
-    {
-     /*
-      * Collection value...
-      */
-
-      int depth;
-
-      value = ptr;
-
-      for (depth = 1; *ptr; ptr ++)
-        if (*ptr == '{')
-         depth ++;
-       else if (*ptr == '}')
-       {
-         depth --;
-         if (!depth)
-         {
-           ptr ++;
-
-           if (*ptr != ',')
-             break;
-         }
-        }
-        else if (*ptr == '\\')
-         _cups_strcpy(ptr, ptr + 1);
-
-      if (*ptr != '\0')
-        *ptr++ = '\0';
-    }
-    else
-    {
-     /*
-      * Normal space-delimited string...
-      */
-
-      value = ptr;
-
-      while (!isspace(*ptr & 255) && *ptr != '\0')
-      {
-        if (*ptr == '\\')
-         _cups_strcpy(ptr, ptr + 1);
-
-        ptr ++;
-      }
-    }
-
-   /*
-    * Skip trailing whitespace...
-    */
-
-    while (isspace(*ptr & 255))
-      *ptr++ = '\0';
-
-   /*
-    * Add the string value...
-    */
-
-    num_options = cupsAddOption(name, value, num_options, options);
-  }
-
- /*
-  * Free the copy of the argument we made and return the number of options
-  * found.
-  */
-
-  free(copyarg);
-
-  return (num_options);
-}
-
-
 /*
  * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
  */
@@ -577,5 +378,261 @@ cupsMarkOptions(
 
 
 /*
- * End of "$Id: options.c 4980 2006-01-25 19:57:45Z mike $".
+ * 'cupsParseOptions()' - Parse options from a command-line argument.
+ *
+ * This function converts space-delimited name/value pairs according
+ * to the PAPI text option ABNF specification. Collection values
+ * ("name={a=... b=... c=...}") are stored with the curley brackets
+ * intact - use cupsParseOptions() on the value to extract the collection
+ * attributes.
+ */
+
+int                                    /* O - Number of options found */
+cupsParseOptions(
+    const char    *arg,                        /* I - Argument to parse */
+    int           num_options,         /* I - Number of options */
+    cups_option_t **options)           /* O - Options found */
+{
+  char *copyarg,                       /* Copy of input string */
+       *ptr,                           /* Pointer into string */
+       *name,                          /* Pointer to name */
+       *value;                         /* Pointer to value */
+
+
+  if (arg == NULL || options == NULL || num_options < 0)
+    return (0);
+
+ /*
+  * Make a copy of the argument string and then divide it up...
+  */
+
+  copyarg     = strdup(arg);
+  ptr         = copyarg;
+
+ /*
+  * Skip leading spaces...
+  */
+
+  while (isspace(*ptr & 255))
+    ptr ++;
+
+ /*
+  * Loop through the string...
+  */
+
+  while (*ptr != '\0')
+  {
+   /*
+    * Get the name up to a SPACE, =, or end-of-string...
+    */
+
+    name = ptr;
+    while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0')
+      ptr ++;
+
+   /*
+    * Avoid an empty name...
+    */
+
+    if (ptr == name)
+      break;
+
+   /*
+    * Skip trailing spaces...
+    */
+
+    while (isspace(*ptr & 255))
+      *ptr++ = '\0';
+
+    if (*ptr != '=')
+    {
+     /*
+      * Start of another option...
+      */
+
+      if (strncasecmp(name, "no", 2) == 0)
+        num_options = cupsAddOption(name + 2, "false", num_options,
+                                   options);
+      else
+        num_options = cupsAddOption(name, "true", num_options, options);
+
+      continue;
+    }
+
+   /*
+    * Remove = and parse the value...
+    */
+
+    *ptr++ = '\0';
+
+    if (*ptr == '\'')
+    {
+     /*
+      * Quoted string constant...
+      */
+
+      ptr ++;
+      value = ptr;
+
+      while (*ptr != '\'' && *ptr != '\0')
+      {
+        if (*ptr == '\\')
+         _cups_strcpy(ptr, ptr + 1);
+
+        ptr ++;
+      }
+
+      if (*ptr != '\0')
+        *ptr++ = '\0';
+    }
+    else if (*ptr == '\"')
+    {
+     /*
+      * Double-quoted string constant...
+      */
+
+      ptr ++;
+      value = ptr;
+
+      while (*ptr != '\"' && *ptr != '\0')
+      {
+        if (*ptr == '\\')
+         _cups_strcpy(ptr, ptr + 1);
+
+        ptr ++;
+      }
+
+      if (*ptr != '\0')
+        *ptr++ = '\0';
+    }
+    else if (*ptr == '{')
+    {
+     /*
+      * Collection value...
+      */
+
+      int depth;
+
+      value = ptr;
+
+      for (depth = 1; *ptr; ptr ++)
+        if (*ptr == '{')
+         depth ++;
+       else if (*ptr == '}')
+       {
+         depth --;
+         if (!depth)
+         {
+           ptr ++;
+
+           if (*ptr != ',')
+             break;
+         }
+        }
+        else if (*ptr == '\\')
+         _cups_strcpy(ptr, ptr + 1);
+
+      if (*ptr != '\0')
+        *ptr++ = '\0';
+    }
+    else
+    {
+     /*
+      * Normal space-delimited string...
+      */
+
+      value = ptr;
+
+      while (!isspace(*ptr & 255) && *ptr != '\0')
+      {
+        if (*ptr == '\\')
+         _cups_strcpy(ptr, ptr + 1);
+
+        ptr ++;
+      }
+    }
+
+   /*
+    * Skip trailing whitespace...
+    */
+
+    while (isspace(*ptr & 255))
+      *ptr++ = '\0';
+
+   /*
+    * Add the string value...
+    */
+
+    num_options = cupsAddOption(name, value, num_options, options);
+  }
+
+ /*
+  * Free the copy of the argument we made and return the number of options
+  * found.
+  */
+
+  free(copyarg);
+
+  return (num_options);
+}
+
+
+/*
+ * 'cupsRemoveOptions()' - Remove an option from an option array.
+ *
+ * @since CUPS 1.2@
+ */
+
+int                                    /* O  - New number of options */
+cupsRemoveOption(
+    const char    *name,               /* I  - Option name */
+    int           num_options,         /* I  - Current number of options */
+    cups_option_t **options)           /* IO - Options */
+{
+  int          i;                      /* Looping var */
+  cups_option_t        *option;                /* Current option */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!name || num_options < 1 || !options)
+    return (num_options);
+
+ /*
+  * Loop for the option...
+  */
+
+  for (i = num_options, option = *options; i > 0; i --, option ++)
+    if (!strcasecmp(name, option->name))
+      break;
+
+  if (i)
+  {
+   /*
+    * Remove this option from the array...
+    */
+
+    num_options --;
+    i --;
+
+    free(option->name);
+    if (option->value)
+      free(option->value);
+
+    if (i > 0)
+      memmove(option, option + 1, i * sizeof(cups_option_t *));
+  }
+
+ /*
+  * Return the new number of options...
+  */
+
+  return (num_options);
+}
+
+
+/*
+ * End of "$Id: options.c 5151 2006-02-22 22:43:17Z mike $".
  */
index 1b0ed647121074aed380990f6cd74e39208b4b42..c131493202f49cb5eb38f2bbcdc8f9666240ce9c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ppd.c 5119 2006-02-16 15:52:06Z mike $"
+ * "$Id: ppd.c 5200 2006-02-28 00:10:32Z mike $"
  *
  *   PPD file routines for the Common UNIX Printing System (CUPS).
  *
@@ -244,6 +244,8 @@ ppdClose(ppd_file_t *ppd)           /* I - PPD file record */
     ppd_free(ppd->attrs);
   }
 
+  cupsArrayDelete(ppd->sorted_attrs);
+
  /*
   * Free custom options...
   */
@@ -262,8 +264,6 @@ ppdClose(ppd_file_t *ppd)           /* I - PPD file record */
         case PPD_CUSTOM_PASSWORD :
         case PPD_CUSTOM_STRING :
             ppd_free(cparam->current.custom_string);
-            ppd_free(cparam->minimum.custom_string);
-            ppd_free(cparam->maximum.custom_string);
            break;
 
        default :
@@ -832,17 +832,6 @@ ppdOpen2(cups_file_t *fp)          /* I - File to read from */
       ppd->fonts[ppd->num_fonts] = strdup(name);
       ppd->num_fonts ++;
     }
-#if 0
-    else if (!strcmp(keyword, "ParamCustomPageSize"))
-    {
-      if (!strcmp(name, "Width"))
-        sscanf(string, "%*s%*s%f%f", ppd->custom_min + 0,
-              ppd->custom_max + 0);
-      else if (!strcmp(name, "Height"))
-        sscanf(string, "%*s%*s%f%f", ppd->custom_min + 1,
-              ppd->custom_max + 1);
-    }
-#endif /* 0 */
     else if (!strncmp(keyword, "ParamCustom", 11))
     {
       ppd_coption_t    *coption;       /* Custom option */
@@ -906,14 +895,14 @@ ppdOpen2(cups_file_t *fp)         /* I - File to read from */
       else if (!strcmp(ctype, "passcode"))
       {
         cparam->type = PPD_CUSTOM_PASSCODE;
-       cparam->minimum.custom_passcode = strdup(cminimum);
-       cparam->maximum.custom_passcode = strdup(cmaximum);
+       cparam->minimum.custom_passcode = atoi(cminimum);
+       cparam->maximum.custom_passcode = atoi(cmaximum);
       }
       else if (!strcmp(ctype, "password"))
       {
         cparam->type = PPD_CUSTOM_PASSWORD;
-       cparam->minimum.custom_password = strdup(cminimum);
-       cparam->maximum.custom_password = strdup(cmaximum);
+       cparam->minimum.custom_password = atoi(cminimum);
+       cparam->maximum.custom_password = atoi(cmaximum);
       }
       else if (!strcmp(ctype, "points"))
       {
@@ -930,8 +919,8 @@ ppdOpen2(cups_file_t *fp)           /* I - File to read from */
       else if (!strcmp(ctype, "string"))
       {
         cparam->type = PPD_CUSTOM_STRING;
-       cparam->minimum.custom_string = strdup(cminimum);
-       cparam->maximum.custom_string = strdup(cmaximum);
+       cparam->minimum.custom_string = atoi(cminimum);
+       cparam->maximum.custom_string = atoi(cmaximum);
       }
       else
       {
@@ -2896,5 +2885,5 @@ ppd_read(cups_file_t    *fp,              /* I - File to read from */
 
 
 /*
- * End of "$Id: ppd.c 5119 2006-02-16 15:52:06Z mike $".
+ * End of "$Id: ppd.c 5200 2006-02-28 00:10:32Z mike $".
  */
index 196394deac8a19555207fe32bc9fc2095d9b1c73..2ec40c21ff7acaba0ed561fc9969ace1ab710356 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ppd.h 5139 2006-02-21 12:56:27Z mike $"
+ * "$Id: ppd.h 5190 2006-02-27 02:42:07Z mike $"
  *
  *   PostScript Printer Description definitions for the Common UNIX Printing
  *   System (CUPS).
@@ -232,6 +232,18 @@ typedef enum ppd_cptype_e          /**** Custom Parameter Type @since CUPS 1.2@ ****/
   PPD_CUSTOM_STRING                    /* String of characters */
 } ppd_cptype_t;
 
+typedef union ppd_cplimit_u            /**** Custom Parameter Limit @since CUPS 1.2@ ****/
+{
+  float                custom_curve;           /* Gamma value */
+  int          custom_int;             /* Integer value */
+  float                custom_invcurve;        /* Gamma value */
+  int          custom_passcode;        /* Passcode length */
+  int          custom_password;        /* Password length */
+  float                custom_points;          /* Measurement value */
+  float                custom_real;            /* Real value */
+  int          custom_string;          /* String length */
+} ppd_cplimit_t;
+
 typedef union ppd_cpvalue_u            /**** Custom Parameter Value @since CUPS 1.2@ ****/
 {
   float                custom_curve;           /* Gamma value */
@@ -250,9 +262,9 @@ typedef struct ppd_cparam_s         /**** Custom Parameter @since CUPS 1.2@ ****/
   char         text[PPD_MAX_TEXT];     /* Human-readable text */
   int          order;                  /* Order (0 to N) */
   ppd_cptype_t type;                   /* Parameter type */
-  ppd_cpvalue_t        minimum,                /* Minimum value */
-               maximum,                /* Maximum value */
-               current;                /* Current value */
+  ppd_cplimit_t        minimum,                /* Minimum value */
+               maximum;                /* Maximum value */
+  ppd_cpvalue_t        current;                /* Current value */
 } ppd_cparam_t;
 
 typedef struct ppd_coption_s           /**** Custom Option @since CUPS 1.2@ ****/
@@ -391,5 +403,5 @@ extern ppd_file_t   *ppdOpen2(cups_file_t *fp);
 #endif /* !_CUPS_PPD_H_ */
 
 /*
- * End of "$Id: ppd.h 5139 2006-02-21 12:56:27Z mike $".
+ * End of "$Id: ppd.h 5190 2006-02-27 02:42:07Z mike $".
  */
index 14e83f4da2f646ef4aa19ba23b729950451656b4..5f44ad961706356698b570de378102d015514bdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: request.c 5139 2006-02-21 12:56:27Z mike $"
+ * "$Id: request.c 5147 2006-02-22 16:37:44Z mike $"
  *
  *   IPP utilities for the Common UNIX Printing System (CUPS).
  *
@@ -64,6 +64,7 @@ cupsDoFileRequest(http_t     *http,   /* I - HTTP connection to server */
   ipp_t                *response;              /* IPP response data */
   size_t       length;                 /* Content-Length value */
   http_status_t        status;                 /* Status of HTTP request */
+  ipp_state_t  state;                  /* State of IPP processing */
   FILE         *file;                  /* File to send */
   struct stat  fileinfo;               /* File information */
   int          bytes;                  /* Number of bytes read/written */
@@ -161,6 +162,7 @@ cupsDoFileRequest(http_t     *http, /* I - HTTP connection to server */
     httpSetLength(http, length);
     httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
     httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
+    httpSetExpect(http, HTTP_CONTINUE);
 
     DEBUG_printf(("cupsDoFileRequest: authstring=\"%s\"\n", http->authstring));
 
@@ -182,16 +184,34 @@ cupsDoFileRequest(http_t     *http,       /* I - HTTP connection to server */
     }
 
    /*
-    * Send the IPP data and wait for the response...
+    * Wait up to 1 second for a 100-continue response...
     */
 
-    DEBUG_puts("cupsDoFileRequest: ipp write...");
+    if (httpWait(http, 1000))
+      status = httpUpdate(http);
+    else
+      status = HTTP_CONTINUE;
+
+    if (status == HTTP_CONTINUE)
+    {
+     /*
+      * Send the IPP data...
+      */
 
-    request->state = IPP_IDLE;
-    status         = HTTP_CONTINUE;
+      DEBUG_puts("cupsDoFileRequest: ipp write...");
 
-    if (ippWrite(http, request) != IPP_ERROR)
-      if (filename != NULL)
+      request->state = IPP_IDLE;
+
+      while ((state = ippWrite(http, request)) != IPP_DATA)
+        if (state == IPP_ERROR)
+         break;
+       else if (httpCheck(http))
+       {
+         if ((status = httpUpdate(http)) != HTTP_CONTINUE)
+           break;
+        }
+
+      if (state == IPP_DATA && filename)
       {
         DEBUG_puts("cupsDoFileRequest: file write...");
 
@@ -213,6 +233,7 @@ cupsDoFileRequest(http_t     *http, /* I - HTTP connection to server */
             break;
         }
       }
+    }
 
    /*
     * Get the server's return status...
@@ -437,5 +458,5 @@ _cupsSetError(ipp_status_t status,  /* I - IPP status code */
 
 
 /*
- * End of "$Id: request.c 5139 2006-02-21 12:56:27Z mike $".
+ * End of "$Id: request.c 5147 2006-02-22 16:37:44Z mike $".
  */
index aa4a6fd7a0ede96ace9bc197ad50e3460ea4c1fa..7bd0c2b14b46a6fecc9c452f8f0a76c64c9115a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: testfile.c 5057 2006-02-02 20:38:29Z mike $"
+ * "$Id: testfile.c 5194 2006-02-27 20:57:07Z mike $"
  *
  *   File test program for the Common UNIX Printing System (CUPS).
  *
@@ -39,7 +39,9 @@
 #include "string.h"
 #include "file.h"
 #include "debug.h"
-#include <zlib.h>
+#ifdef HAVE_LIBZ
+#  include <zlib.h>
+#endif /* HAVE_LIBZ */
 
 
 /*
@@ -442,5 +444,5 @@ read_write_tests(int compression)   /* I - Use compression? */
 
 
 /*
- * End of "$Id: testfile.c 5057 2006-02-02 20:38:29Z mike $".
+ * End of "$Id: testfile.c 5194 2006-02-27 20:57:07Z mike $".
  */
index a141d80f4315adb30a620ab5c5007382ad0269ea..8b0fbad2f6c5dd6470601f2579066cca01ed97e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: testi18n.c 4767 2005-10-10 19:23:23Z mike $"
+ * "$Id: testi18n.c 5195 2006-02-27 21:05:46Z mike $"
  *
  *   Internationalization test for Common UNIX Printing System (CUPS).
  *
@@ -156,7 +156,7 @@ print_synopsis(void)
  * 'print_utf8()' - Print UTF-8 string with (optional) message.
  */
 
-void
+static void
 print_utf8(const char       *msg,      /* I - Message String */
           const cups_utf8_t *src)      /* I - UTF-8 Source String */
 {
@@ -174,7 +174,7 @@ print_utf8(const char            *msg,      /* I - Message String */
  * 'print_utf16()' - Print UTF-16 string with (optional) message.
  */
 
-void
+static void
 print_utf16(const char        *msg,    /* I - Message String */
            const cups_utf16_t *src)    /* I - UTF-16 Source String */
 {
@@ -191,7 +191,7 @@ print_utf16(const char             *msg,    /* I - Message String */
  * 'print_utf32()' - Print UTF-32 string with (optional) message.
  */
 
-void
+static void
 print_utf32(const char        *msg,    /* I - Message String */
            const cups_utf32_t *src)    /* I - UTF-32 Source String */
 {
@@ -787,5 +787,5 @@ test_normalize(const int verbose)   /* I - Verbose flag */
 
 
 /*
- * End of "$Id: testi18n.c 4767 2005-10-10 19:23:23Z mike $"
+ * End of "$Id: testi18n.c 5195 2006-02-27 21:05:46Z mike $"
  */
index 2dbcbdd447a88c488b70113d64a079be9a24ecca..b75dc3790539bfa51a550717cba9765562a9f686 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: usersys.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: usersys.c 5182 2006-02-26 04:10:27Z mike $"
  *
  *   User, system, and password routines for the Common UNIX Printing
  *   System (CUPS).
  *
  * Contents:
  *
- *   cupsEncryption()    - Get the default encryption settings.
- *   cupsGetPassword()   - Get a password from the user.
- *   cupsServer()        - Return the hostname of the default server.
- *   cupsSetEncryption() - Set the encryption preference.
- *   cupsSetPasswordCB() - Set the password callback for CUPS.
- *   cupsSetServer()     - Set the default server name.
- *   cupsSetUser()       - Set the default user name.
- *   cupsUser()          - Return the current users name.
- *   _cupsGetPassword()  - Get a password from the user.
+ *   cupsEncryption()        - Get the default encryption settings.
+ *   cupsGetPassword()       - Get a password from the user.
+ *   cupsServer()            - Return the hostname of the default server.
+ *   cupsSetEncryption()     - Set the encryption preference.
+ *   cupsSetPasswordCB()     - Set the password callback for CUPS.
+ *   cupsSetServer()         - Set the default server name.
+ *   cupsSetUser()           - Set the default user name.
+ *   cupsUser()              - Return the current users name.
+ *   _cupsGetPassword()      - Get a password from the user.
+ *   cups_open_client_conf() - Open the client.conf file.
  */
 
 /*
 #endif /* WIN32 */
 
 
+/*
+ * Local functions...
+ */
+
+static cups_file_t     *cups_open_client_conf(void);
+
+
 /*
  * 'cupsEncryption()' - Get the default encryption settings.
  *
@@ -64,7 +72,6 @@ cupsEncryption(void)
 {
   cups_file_t  *fp;                    /* client.conf file */
   char         *encryption;            /* CUPS_ENCRYPTION variable */
-  const char   *home;                  /* Home directory of user */
   char         line[1024],             /* Line from file */
                *value;                 /* Value on line */
   int          linenum;                /* Line number */
@@ -84,26 +91,13 @@ cupsEncryption(void)
     if ((encryption = getenv("CUPS_ENCRYPTION")) == NULL)
     {
      /*
-      * Next check to see if we have a $HOME/.cupsrc or client.conf file...
+      * No, open the client.conf file...
       */
 
-      if ((home = getenv("HOME")) != NULL)
-      {
-       snprintf(line, sizeof(line), "%s/.cupsrc", home);
-       fp = cupsFileOpen(line, "r");
-      }
-      else
-       fp = NULL;
-
-      if (fp == NULL)
-      {
-       snprintf(line, sizeof(line), "%s/client.conf", cg->cups_serverroot);
-       fp = cupsFileOpen(line, "r");
-      }
-
+      fp         = cups_open_client_conf();
       encryption = "IfRequested";
 
-      if (fp != NULL)
+      if (fp)
       {
        /*
        * Read the config file and look for an Encryption line...
@@ -181,7 +175,6 @@ cupsServer(void)
 {
   cups_file_t  *fp;                    /* client.conf file */
   char         *server;                /* Pointer to server name */
-  const char   *home;                  /* Home directory of user */
   char         *port;                  /* Port number */
   char         line[1024],             /* Line from file */
                *value;                 /* Value on line */
@@ -205,22 +198,10 @@ cupsServer(void)
     if ((server = getenv("CUPS_SERVER")) == NULL)
     {
      /*
-      * Next check to see if we have a $HOME/.cupsrc or client.conf file...
+      * No environment variable, try the client.conf file...
       */
 
-      if ((home = getenv("HOME")) != NULL)
-      {
-       snprintf(line, sizeof(line), "%s/.cupsrc", home);
-       fp = cupsFileOpen(line, "r");
-      }
-      else
-       fp = NULL;
-
-      if (fp == NULL)
-      {
-       snprintf(line, sizeof(line), "%s/client.conf", cg->cups_serverroot);
-       fp = cupsFileOpen(line, "r");
-      }
+      fp = cups_open_client_conf();
 
 #ifdef CUPS_DEFAULT_DOMAINSOCKET
      /*
@@ -235,7 +216,7 @@ cupsServer(void)
 #endif /* CUPS_DEFAULT_DOMAINSOCKET */
       server = "localhost";
 
-      if (fp != NULL)
+      if (fp)
       {
        /*
        * Read the config file and look for a ServerName line...
@@ -470,5 +451,38 @@ _cupsGetPassword(const char *prompt)       /* I - Prompt string */
 
 
 /*
- * End of "$Id: usersys.c 5138 2006-02-21 10:49:06Z mike $".
+ * 'cups_open_client_conf()' - Open the client.conf file.
+ */
+
+static cups_file_t *                   /* O - File or NULL */
+cups_open_client_conf(void)
+{
+  cups_file_t  *fp;                    /* File */
+  const char   *home;                  /* Home directory of user */
+  char         filename[1024];         /* Filename */
+  _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals */
+
+
+  if ((home = getenv("HOME")) != NULL)
+  {
+   /*
+    * Look for ~/.cups/client.conf or ~/.cupsrc...
+    */
+
+    snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home);
+    if ((fp = cupsFileOpen(filename, "r")) != NULL)
+      return (fp);
+
+    snprintf(filename, sizeof(filename), "%s/.cupsrc", home);
+    if ((fp = cupsFileOpen(filename, "r")) != NULL)
+      return (fp);
+  }
+
+  snprintf(filename, sizeof(filename), "%s/client.conf", cg->cups_serverroot);
+  return (cupsFileOpen(filename, "r"));
+}
+
+
+/*
+ * End of "$Id: usersys.c 5182 2006-02-26 04:10:27Z mike $".
  */
index 25565073798a00ec17241d4c00ddf312bead2839..5a018b66f1c9fbec16ce6889358610f5a2ef27f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: util.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: util.c 5165 2006-02-24 21:20:30Z mike $"
  *
  *   Printing utilities for the Common UNIX Printing System (CUPS).
  *
@@ -819,7 +819,10 @@ cupsGetPPD2(http_t     *http,              /* I - HTTP connection */
 
   if (!http || !name)
   {
-    _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+    if (!http)
+      _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
+    else
+      _cupsSetError(IPP_INTERNAL_ERROR, "No printer name!");
 
     return (NULL);
   }
@@ -1491,7 +1494,7 @@ cups_get_printer_uri(
   if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                        "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
   {
-    _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+    _cupsSetError(IPP_INTERNAL_ERROR, "Unable to create printer-uri!");
 
     *host     = '\0';
     *resource = '\0';
@@ -1628,6 +1631,8 @@ cups_get_printer_uri(
     ippDelete(response);
   }
 
+  _cupsSetError(IPP_INTERNAL_ERROR, "No printer-uri found!");
+
   *host     = '\0';
   *resource = '\0';
 
@@ -1636,5 +1641,5 @@ cups_get_printer_uri(
 
 
 /*
- * End of "$Id: util.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: util.c 5165 2006-02-24 21:20:30Z mike $".
  */
index 373f5b09cfc4108ea0e59727ca9b882c6063e14a..443fda185b23abfb4967942ffaebb71feeecb725 100644 (file)
@@ -1,9 +1,9 @@
 #
-# "$Id: Makefile 5124 2006-02-17 16:05:21Z mike $"
+# "$Id: Makefile 5192 2006-02-27 03:08:47Z mike $"
 #
 #   Documentation makefile for the Common UNIX Printing System (CUPS).
 #
-#   Copyright 1993-2006 by Easy Software Products.
+#   Copyright 1997-2006 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
 #   property of Easy Software Products and are protected by Federal
@@ -39,6 +39,7 @@ WEBBUTTONS    =       \
                        images/cancel-all-jobs.gif \
                        images/cancel-job.gif \
                        images/change-settings.gif \
+                       images/clean-print-heads.gif \
                        images/continue.gif \
                        images/delete-class.gif \
                        images/delete-printer.gif \
@@ -54,6 +55,7 @@ WEBBUTTONS    =       \
                        images/modify-printer.gif \
                        images/move-job.gif \
                        images/move-jobs.gif \
+                       images/print-self-test-page.gif \
                        images/print-test-page.gif \
                        images/publish-printer.gif \
                        images/reject-jobs.gif \
@@ -104,6 +106,7 @@ HELPFILES   =       \
                        help/api-filter.html \
                        help/api-httpipp.html \
                        help/api-ppd.html \
+                       help/api-raster.html \
                        help/classes-conf-reference.html \
                        help/client-conf-reference.html \
                        help/cupsd-conf-reference.html \
@@ -115,6 +118,7 @@ HELPFILES   =       \
                        help/man-backend.html \
                        help/man-cancel.html \
                        help/man-classes.conf.html \
+                       help/man-client.conf.html \
                        help/man-cupsaddsmb.html \
                        help/man-cups-config.html \
                        help/man-cupsd.html \
@@ -140,6 +144,7 @@ HELPFILES   =       \
                        help/man-printers.conf.html \
                        help/network.html \
                        help/overview.html \
+                       help/spec-command.html \
                        help/spec-ipp.html \
                        help/spec-ppd.html \
                        help/standard.html \
index a9e4ca979accfda683982bc703209dbf21d333bf..bc77e7d61595ba2f78bbc6d30ac02c9bb1995743 100644 (file)
@@ -16,7 +16,7 @@
 </head>
 <body>
 <!--
-  "$Id$"
+  "$Id: api-array.shtml 5138 2006-02-21 10:49:06Z mike $"
 
   Array API introduction for the Common UNIX Printing System (CUPS).
 
index 4e829066ed34cb41453f4d2847e6f3c2c92ff6b6..e6f32fabe2389384c8549e45f8651b97da199030 100644 (file)
@@ -16,7 +16,7 @@
 </head>
 <body>
 <!--
-  "$Id$"
+  "$Id: api-cups.shtml 5138 2006-02-21 10:49:06Z mike $"
 
   CUPS API introduction for the Common UNIX Printing System (CUPS).
 
index 51fc07fb1777554b42e8b9d0fcdbe470200fd02b..107ef7906033fc3ef28d2099762f946075050e8b 100644 (file)
@@ -16,7 +16,7 @@
 </head>
 <body>
 <!--
-  "$Id$"
+  "$Id: api-filedir.shtml 5138 2006-02-21 10:49:06Z mike $"
 
   File and directory API introduction for the Common UNIX Printing System (CUPS).
 
index 308d0ce07a14999016e977f819b5b9244ae47a54..63607f38b2dcf222467f14123b66049f915692e8 100644 (file)
@@ -16,7 +16,7 @@
 </head>
 <body>
 <!--
-  "$Id$"
+  "$Id: api-filter.shtml 5138 2006-02-21 10:49:06Z mike $"
 
   Filter and backend API introduction for the Common UNIX Printing System (CUPS).
 
index 2b084f9187f03567b7f42a6dcbb01cc7fc39ee35..575a80767edcde8a993148b1f560e78ab2f62985 100644 (file)
@@ -16,7 +16,7 @@
 </head>
 <body>
 <!--
-  "$Id$"
+  "$Id: api-httpipp.shtml 5138 2006-02-21 10:49:06Z mike $"
 
   HTTP and IPP API introduction for the Common UNIX Printing System (CUPS).
 
index 61ad7d67b4b56a19e8176ef0eacfbec6dadbff96..3e99de7c31f98b259601d507f865ed01820f4d18 100644 (file)
 </head>
 <body>
 <!--
-  "$Id$"
+  "$Id: api-ppd.shtml 5138 2006-02-21 10:49:06Z mike $"
 
   PPD API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 1997-2005 by Easy Software Products.
+  Copyright 1997-2006 by Easy Software Products.
 
   These coded instructions, statements, and computer programs are the
   property of Easy Software Products and are protected by Federal
 
 <h2 class='title'>Introduction</h2>
 
-<p>The CUPS PPD API provides...</p>
+<p>The CUPS PPD API provides read-only access the data in
+PostScript Printer Description ("PPD") files. With it you can
+display printer options to users, mark option choices and check
+for conflicting choices, and output marked choices in PostScript
+output.</p>
 
 <h2 class='title'>General Usage</h2>
 
diff --git a/doc/help/api-raster.html b/doc/help/api-raster.html
new file mode 100644 (file)
index 0000000..645d221
--- /dev/null
@@ -0,0 +1,573 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<!-- SECTION: Programming -->
+<head>
+       <title>Raster API</title>
+       <meta name='keywords' content='Programming'>
+       <meta name='creator' content='Mini-XML v2.3'>
+       <style type='text/css'><!--
+       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
+       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
+       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
+       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
+       h3 span.info { float: right; font-size: 100%; }
+       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
+       --></style>
+</head>
+<body>
+<!--
+  "$Id$"
+
+  Raster API introduction for the Common UNIX Printing System (CUPS).
+
+  Copyright 1997-2006 by Easy Software Products.
+
+  These coded instructions, statements, and computer programs are the
+  property of Easy Software Products 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 missing or damaged please contact Easy Software Products
+  at:
+
+      Attn: CUPS Licensing Information
+      Easy Software Products
+      44141 Airport View Drive, Suite 204
+      Hollywood, Maryland 20636 USA
+
+      Voice: (301) 373-9600
+      EMail: cups-info@cups.org
+       WWW: http://www.cups.org
+-->
+
+<h2 class='title'>Introduction</h2>
+
+<p>The CUPS raster API provides a standard interface for reading
+and writing CUPS raster streams which are used for printing to
+raster printers. Because the raster format is updated from time
+to time, it is important to use this API to avoid
+incompatibilities with newer versions of CUPS.</p>
+
+<h2 class='title'>General Usage</h2>
+
+<p>The <var>&lt;cups/raster.h&gt;</var> header file must be
+included to use the <tt>cupsRaster</tt> functions.</p>
+
+<p>Programs using these functions must be linked to the CUPS
+imaging library: <var>libcupsimage.a</var>,
+<var>libcupsimage.so.2</var>, <var>libcupsimage.2.dylib</var>,
+<var>libcupsimage_s.a</var>, or <var>libcupsimage2.lib</var>
+depending on the platform. The following command compiles
+<var>myprogram.c</var> using GCC and the CUPS imaging
+library:</p>
+
+<pre class='command'>
+<kbd>gcc -o myprogram myprogram.c -lcupsimage</kbd>
+</pre>
+
+<h2 class='title'>Compatibility</h2>
+
+<p>Unless otherwise specified, the raster API functions require
+CUPS 1.1 or higher.</p>
+
+<h2 class='title'>Licensing</h2>
+
+<p>The CUPS raster API is provided under the terms of the GNU
+General Public License, with exceptions for MacOS X-based
+programs. Please see the CUPS license agreement for more
+information.</p>
+<h2 class='title'>Contents</h2>
+<ul>
+       <li><a href='#ENUMERATIONS'>Enumerations</a></li>
+       <li><a href='#FUNCTIONS'>Functions</a></li>
+       <li><a href='#STRUCTURES'>Structures</a></li>
+       <li><a href='#TYPES'>Types</a></li>
+</ul>
+<!-- NEW PAGE -->
+<h2 class='title'><a name='ENUMERATIONS'>Enumerations</a></h2>
+<ul>
+       <li><a href='#cups_bool_e'><tt>cups_bool_e</tt></a> </li>
+       <li><a href='#cups_mode_e'><tt>cups_mode_e</tt></a> </li>
+</ul>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cups_bool_e'>cups_bool_e</a></h3>
+<h4>Description</h4>
+<p>Types...</p>
+<h4>Values</h4>
+<div class='table'><table align='center' border='1' width='80%'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>CUPS_FALSE</tt> </td><td>Logical false</td></tr>
+<tr><td><tt>CUPS_TRUE</tt> </td><td>Logical true</td></tr>
+</tbody></table></div>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cups_mode_e'>cups_mode_e</a></h3>
+<h4>Description</h4>
+<p>Raster modes</p>
+<h4>Values</h4>
+<div class='table'><table align='center' border='1' width='80%'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>CUPS_RASTER_READ</tt> </td><td>Open stream for reading</td></tr>
+<tr><td><tt>CUPS_RASTER_WRITE</tt> </td><td>Open stream for writing</td></tr>
+</tbody></table></div>
+<!-- NEW PAGE -->
+<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
+<ul>
+       <li><a href='#cupsRasterClose'><tt>cupsRasterClose()</tt></a> </li>
+       <li><a href='#cupsRasterInterpretPPD'><tt>cupsRasterInterpretPPD()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
+       <li><a href='#cupsRasterOpen'><tt>cupsRasterOpen()</tt></a> </li>
+       <li><a href='#cupsRasterReadHeader'><tt>cupsRasterReadHeader()</tt></a> </li>
+       <li><a href='#cupsRasterReadHeader2'><tt>cupsRasterReadHeader2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
+       <li><a href='#cupsRasterReadPixels'><tt>cupsRasterReadPixels()</tt></a> </li>
+       <li><a href='#cupsRasterWriteHeader'><tt>cupsRasterWriteHeader()</tt></a> </li>
+       <li><a href='#cupsRasterWriteHeader2'><tt>cupsRasterWriteHeader2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
+       <li><a href='#cupsRasterWritePixels'><tt>cupsRasterWritePixels()</tt></a> </li>
+</ul>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cupsRasterClose'>cupsRasterClose()</a></h3>
+<h4>Description</h4>
+<p>Close a raster stream.</p>
+<h4>Syntax</h4>
+<pre>
+void
+cupsRasterClose(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Stream to close</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>Nothing.</p>
+<!-- NEW PAGE -->
+<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRasterInterpretPPD'>cupsRasterInterpretPPD()</a></h3>
+<h4>Description</h4>
+<p>Interpret PPD commands to create a page header.
+
+This function does not mark the options in the PPD using the &quot;num_options&quot;
+and &quot;options&quot; arguments.  Instead, mark the options prior to calling
+cupsRasterInterpretPPD() - this allows you to do per-page options
+without manipulating the options array.
+
+</p>
+<h4>Syntax</h4>
+<pre>
+int
+cupsRasterInterpretPPD(
+    <a href='#cups_page_header2_t'>cups_page_header2_t</a> * h,
+    ppd_file_t * ppd,
+    int num_options,
+    cups_option_t * options);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>h</tt></td><td>Page header</td></tr>
+<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
+<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
+<tr><td><tt>options</tt></td><td>Options</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>0 on success, -1 on failure</p>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cupsRasterOpen'>cupsRasterOpen()</a></h3>
+<h4>Description</h4>
+<p>Open a raster stream.</p>
+<h4>Syntax</h4>
+<pre>
+<a href='#cups_raster_t'>cups_raster_t</a> *
+cupsRasterOpen(
+    int fd,
+    cups_mode_t mode);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>fd</tt></td><td>File descriptor</td></tr>
+<tr><td><tt>mode</tt></td><td>Mode</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>New stream</p>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cupsRasterReadHeader'>cupsRasterReadHeader()</a></h3>
+<h4>Description</h4>
+<p>Read a raster page header and store it in a
+V1 page header structure.</p>
+<h4>Syntax</h4>
+<pre>
+unsigned
+cupsRasterReadHeader(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r,
+    <a href='#cups_page_header_t'>cups_page_header_t</a> * h);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
+<tr><td><tt>h</tt></td><td>Pointer to header data</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>1 on success, 0 on fail</p>
+<!-- NEW PAGE -->
+<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRasterReadHeader2'>cupsRasterReadHeader2()</a></h3>
+<h4>Description</h4>
+<p>Read a raster page header and store it in a
+V2 page header structure.
+
+</p>
+<h4>Syntax</h4>
+<pre>
+unsigned
+cupsRasterReadHeader2(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r,
+    <a href='#cups_page_header2_t'>cups_page_header2_t</a> * h);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
+<tr><td><tt>h</tt></td><td>Pointer to header data</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>1 on success, 0 on fail</p>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cupsRasterReadPixels'>cupsRasterReadPixels()</a></h3>
+<h4>Description</h4>
+<p>Read raster pixels.</p>
+<h4>Syntax</h4>
+<pre>
+unsigned
+cupsRasterReadPixels(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r,
+    unsigned char * p,
+    unsigned len);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
+<tr><td><tt>p</tt></td><td>Pointer to pixel buffer</td></tr>
+<tr><td><tt>len</tt></td><td>Number of bytes to read</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>Number of bytes read</p>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cupsRasterWriteHeader'>cupsRasterWriteHeader()</a></h3>
+<h4>Description</h4>
+<p>Write a raster page header from a V1 page
+header structure.</p>
+<h4>Syntax</h4>
+<pre>
+unsigned
+cupsRasterWriteHeader(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r,
+    <a href='#cups_page_header_t'>cups_page_header_t</a> * h);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
+<tr><td><tt>h</tt></td><td>Raster page header</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>1 on success, 0 on failure</p>
+<!-- NEW PAGE -->
+<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRasterWriteHeader2'>cupsRasterWriteHeader2()</a></h3>
+<h4>Description</h4>
+<p>Write a raster page header from a V2 page
+header structure.
+
+</p>
+<h4>Syntax</h4>
+<pre>
+unsigned
+cupsRasterWriteHeader2(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r,
+    <a href='#cups_page_header2_t'>cups_page_header2_t</a> * h);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
+<tr><td><tt>h</tt></td><td>Raster page header</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>1 on success, 0 on failure</p>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cupsRasterWritePixels'>cupsRasterWritePixels()</a></h3>
+<h4>Description</h4>
+<p>Write raster pixels.</p>
+<h4>Syntax</h4>
+<pre>
+unsigned
+cupsRasterWritePixels(
+    <a href='#cups_raster_t'>cups_raster_t</a> * r,
+    unsigned char * p,
+    unsigned len);
+</pre>
+<h4>Arguments</h4>
+<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
+<tr><td><tt>p</tt></td><td>Bytes to write</td></tr>
+<tr><td><tt>len</tt></td><td>Number of bytes to write</td></tr>
+</tbody></table></div>
+<h4>Returns</h4>
+<p>Number of bytes written</p>
+<!-- NEW PAGE -->
+<h2 class='title'><a name='STRUCTURES'>Structures</a></h2>
+<ul>
+       <li><a href='#cups_page_header2_s'><tt>cups_page_header2_s</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
+       <li><a href='#cups_page_header_s'><tt>cups_page_header_s</tt></a> </li>
+</ul>
+<!-- NEW PAGE -->
+<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cups_page_header2_s'>cups_page_header2_s</a></h3>
+<h4>Description</h4>
+<p>Version 2 Page Header </p>
+<h4>Definition</h4>
+<pre>
+struct cups_page_header2_s
+{
+  unsigned AdvanceDistance;
+  cups_adv_t AdvanceMedia;
+  cups_bool_t Collate;
+  cups_cut_t CutMedia;
+  cups_bool_t Duplex;
+  unsigned HWResolution[2];
+  unsigned ImagingBoundingBox[4];
+  cups_bool_t InsertSheet;
+  cups_jog_t Jog;
+  cups_edge_t LeadingEdge;
+  cups_bool_t ManualFeed;
+  unsigned Margins[2];
+  char MediaClass[64];
+  char MediaColor[64];
+  unsigned MediaPosition;
+  char MediaType[64];
+  unsigned MediaWeight;
+  cups_bool_t MirrorPrint;
+  cups_bool_t NegativePrint;
+  unsigned NumCopies;
+  cups_orient_t Orientation;
+  cups_bool_t OutputFaceUp;
+  char OutputType[64];
+  unsigned PageSize[2];
+  cups_bool_t Separations;
+  cups_bool_t TraySwitch;
+  cups_bool_t Tumble;
+  unsigned cupsBitsPerColor;
+  unsigned cupsBitsPerPixel;
+  float cupsBorderlessScalingFactor;
+  unsigned cupsBytesPerLine;
+  cups_order_t cupsColorOrder;
+  cups_cspace_t cupsColorSpace;
+  unsigned cupsCompression;
+  unsigned cupsHeight;
+  float cupsImagingBBox[4];
+  unsigned cupsInteger[16];
+  char cupsMarkerType[64];
+  unsigned cupsMediaType;
+  unsigned cupsNumColors;
+  char cupsPageSizeName[64];
+  float cupsPageSize[2];
+  float cupsReal[16];
+  char cupsRenderingIntent[64];
+  unsigned cupsRowCount;
+  unsigned cupsRowFeed;
+  unsigned cupsRowStep;
+  char cupsString[16][64];
+  unsigned cupsWidth;
+};
+</pre>
+<h4>Members</h4>
+<div class='table'><table align='center' border='1' width='80%'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>AdvanceDistance</tt> </td><td>AdvanceDistance value in points</td></tr>
+<tr><td><tt>AdvanceMedia</tt> </td><td>AdvanceMedia value (see above)</td></tr>
+<tr><td><tt>Collate</tt> </td><td>Collated copies value</td></tr>
+<tr><td><tt>CutMedia</tt> </td><td>CutMedia value (see above)</td></tr>
+<tr><td><tt>Duplex</tt> </td><td>Duplexed (double-sided) value</td></tr>
+<tr><td><tt>HWResolution[2]</tt> </td><td>Resolution in dots-per-inch</td></tr>
+<tr><td><tt>ImagingBoundingBox[4]</tt> </td><td>Pixel region that is painted (points)</td></tr>
+<tr><td><tt>InsertSheet</tt> </td><td>InsertSheet value</td></tr>
+<tr><td><tt>Jog</tt> </td><td>Jog value (see above)</td></tr>
+<tr><td><tt>LeadingEdge</tt> </td><td>LeadingEdge value (see above)</td></tr>
+<tr><td><tt>ManualFeed</tt> </td><td>ManualFeed value</td></tr>
+<tr><td><tt>Margins[2]</tt> </td><td>Lower-lefthand margins in points</td></tr>
+<tr><td><tt>MediaClass[64]</tt> </td><td>MediaClass string</td></tr>
+<tr><td><tt>MediaColor[64]</tt> </td><td>MediaColor string</td></tr>
+<tr><td><tt>MediaPosition</tt> </td><td>MediaPosition value</td></tr>
+<tr><td><tt>MediaType[64]</tt> </td><td>MediaType string</td></tr>
+<tr><td><tt>MediaWeight</tt> </td><td>MediaWeight value in grams/m^2</td></tr>
+<tr><td><tt>MirrorPrint</tt> </td><td>MirrorPrint value</td></tr>
+<tr><td><tt>NegativePrint</tt> </td><td>NegativePrint value</td></tr>
+<tr><td><tt>NumCopies</tt> </td><td>Number of copies to produce</td></tr>
+<tr><td><tt>Orientation</tt> </td><td>Orientation value (see above)</td></tr>
+<tr><td><tt>OutputFaceUp</tt> </td><td>OutputFaceUp value</td></tr>
+<tr><td><tt>OutputType[64]</tt> </td><td>OutputType string</td></tr>
+<tr><td><tt>PageSize[2]</tt> </td><td>Width and length of page in points</td></tr>
+<tr><td><tt>Separations</tt> </td><td>Separations value</td></tr>
+<tr><td><tt>TraySwitch</tt> </td><td>TraySwitch value</td></tr>
+<tr><td><tt>Tumble</tt> </td><td>Tumble value</td></tr>
+<tr><td><tt>cupsBitsPerColor</tt> </td><td>Number of bits for each color</td></tr>
+<tr><td><tt>cupsBitsPerPixel</tt> </td><td>Number of bits for each pixel</td></tr>
+<tr><td><tt>cupsBorderlessScalingFactor</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Scaling that was applied to page data </td></tr>
+<tr><td><tt>cupsBytesPerLine</tt> </td><td>Number of bytes per line</td></tr>
+<tr><td><tt>cupsColorOrder</tt> </td><td>Order of colors</td></tr>
+<tr><td><tt>cupsColorSpace</tt> </td><td>True colorspace</td></tr>
+<tr><td><tt>cupsCompression</tt> </td><td>Device compression to use</td></tr>
+<tr><td><tt>cupsHeight</tt> </td><td>Height of page image in pixels</td></tr>
+<tr><td><tt>cupsImagingBBox[4]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Floating point ImagingBoundingBox *
+(scaling factor not applied) </td></tr>
+<tr><td><tt>cupsInteger[16]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>User-defined integer values </td></tr>
+<tr><td><tt>cupsMarkerType[64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Ink/toner type </td></tr>
+<tr><td><tt>cupsMediaType</tt> </td><td>Media type code</td></tr>
+<tr><td><tt>cupsNumColors</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Number of colors </td></tr>
+<tr><td><tt>cupsPageSizeName[64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>PageSize name </td></tr>
+<tr><td><tt>cupsPageSize[2]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Floating point PageSize (scaling *
+factor not applied) </td></tr>
+<tr><td><tt>cupsReal[16]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>User-defined floating-point values </td></tr>
+<tr><td><tt>cupsRenderingIntent[64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Color rendering intent </td></tr>
+<tr><td><tt>cupsRowCount</tt> </td><td>Rows per band</td></tr>
+<tr><td><tt>cupsRowFeed</tt> </td><td>Feed between bands</td></tr>
+<tr><td><tt>cupsRowStep</tt> </td><td>Spacing between lines</td></tr>
+<tr><td><tt>cupsString[16][64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>User-defined string values </td></tr>
+<tr><td><tt>cupsWidth</tt> </td><td>Width of page image in pixels</td></tr>
+</tbody></table></div>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cups_page_header_s'>cups_page_header_s</a></h3>
+<h4>Description</h4>
+<p>Version 1 Page Header</p>
+<h4>Definition</h4>
+<pre>
+struct cups_page_header_s
+{
+  unsigned AdvanceDistance;
+  cups_adv_t AdvanceMedia;
+  cups_bool_t Collate;
+  cups_cut_t CutMedia;
+  cups_bool_t Duplex;
+  unsigned HWResolution[2];
+  unsigned ImagingBoundingBox[4];
+  cups_bool_t InsertSheet;
+  cups_jog_t Jog;
+  cups_edge_t LeadingEdge;
+  cups_bool_t ManualFeed;
+  unsigned Margins[2];
+  char MediaClass[64];
+  char MediaColor[64];
+  unsigned MediaPosition;
+  char MediaType[64];
+  unsigned MediaWeight;
+  cups_bool_t MirrorPrint;
+  cups_bool_t NegativePrint;
+  unsigned NumCopies;
+  cups_orient_t Orientation;
+  cups_bool_t OutputFaceUp;
+  char OutputType[64];
+  unsigned PageSize[2];
+  cups_bool_t Separations;
+  cups_bool_t TraySwitch;
+  cups_bool_t Tumble;
+  unsigned cupsBitsPerColor;
+  unsigned cupsBitsPerPixel;
+  unsigned cupsBytesPerLine;
+  cups_order_t cupsColorOrder;
+  cups_cspace_t cupsColorSpace;
+  unsigned cupsCompression;
+  unsigned cupsHeight;
+  unsigned cupsMediaType;
+  unsigned cupsRowCount;
+  unsigned cupsRowFeed;
+  unsigned cupsRowStep;
+  unsigned cupsWidth;
+};
+</pre>
+<h4>Members</h4>
+<div class='table'><table align='center' border='1' width='80%'>
+<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<tbody>
+<tr><td><tt>AdvanceDistance</tt> </td><td>AdvanceDistance value in points</td></tr>
+<tr><td><tt>AdvanceMedia</tt> </td><td>AdvanceMedia value (see above)</td></tr>
+<tr><td><tt>Collate</tt> </td><td>Collated copies value</td></tr>
+<tr><td><tt>CutMedia</tt> </td><td>CutMedia value (see above)</td></tr>
+<tr><td><tt>Duplex</tt> </td><td>Duplexed (double-sided) value</td></tr>
+<tr><td><tt>HWResolution[2]</tt> </td><td>Resolution in dots-per-inch</td></tr>
+<tr><td><tt>ImagingBoundingBox[4]</tt> </td><td>Pixel region that is painted (points)</td></tr>
+<tr><td><tt>InsertSheet</tt> </td><td>InsertSheet value</td></tr>
+<tr><td><tt>Jog</tt> </td><td>Jog value (see above)</td></tr>
+<tr><td><tt>LeadingEdge</tt> </td><td>LeadingEdge value (see above)</td></tr>
+<tr><td><tt>ManualFeed</tt> </td><td>ManualFeed value</td></tr>
+<tr><td><tt>Margins[2]</tt> </td><td>Lower-lefthand margins in points</td></tr>
+<tr><td><tt>MediaClass[64]</tt> </td><td>MediaClass string</td></tr>
+<tr><td><tt>MediaColor[64]</tt> </td><td>MediaColor string</td></tr>
+<tr><td><tt>MediaPosition</tt> </td><td>MediaPosition value</td></tr>
+<tr><td><tt>MediaType[64]</tt> </td><td>MediaType string</td></tr>
+<tr><td><tt>MediaWeight</tt> </td><td>MediaWeight value in grams/m^2</td></tr>
+<tr><td><tt>MirrorPrint</tt> </td><td>MirrorPrint value</td></tr>
+<tr><td><tt>NegativePrint</tt> </td><td>NegativePrint value</td></tr>
+<tr><td><tt>NumCopies</tt> </td><td>Number of copies to produce</td></tr>
+<tr><td><tt>Orientation</tt> </td><td>Orientation value (see above)</td></tr>
+<tr><td><tt>OutputFaceUp</tt> </td><td>OutputFaceUp value</td></tr>
+<tr><td><tt>OutputType[64]</tt> </td><td>OutputType string</td></tr>
+<tr><td><tt>PageSize[2]</tt> </td><td>Width and length of page in points</td></tr>
+<tr><td><tt>Separations</tt> </td><td>Separations value</td></tr>
+<tr><td><tt>TraySwitch</tt> </td><td>TraySwitch value</td></tr>
+<tr><td><tt>Tumble</tt> </td><td>Tumble value</td></tr>
+<tr><td><tt>cupsBitsPerColor</tt> </td><td>Number of bits for each color</td></tr>
+<tr><td><tt>cupsBitsPerPixel</tt> </td><td>Number of bits for each pixel</td></tr>
+<tr><td><tt>cupsBytesPerLine</tt> </td><td>Number of bytes per line</td></tr>
+<tr><td><tt>cupsColorOrder</tt> </td><td>Order of colors</td></tr>
+<tr><td><tt>cupsColorSpace</tt> </td><td>True colorspace</td></tr>
+<tr><td><tt>cupsCompression</tt> </td><td>Device compression to use</td></tr>
+<tr><td><tt>cupsHeight</tt> </td><td>Height of page image in pixels</td></tr>
+<tr><td><tt>cupsMediaType</tt> </td><td>Media type code</td></tr>
+<tr><td><tt>cupsRowCount</tt> </td><td>Rows per band</td></tr>
+<tr><td><tt>cupsRowFeed</tt> </td><td>Feed between bands</td></tr>
+<tr><td><tt>cupsRowStep</tt> </td><td>Spacing between lines</td></tr>
+<tr><td><tt>cupsWidth</tt> </td><td>Width of page image in pixels</td></tr>
+</tbody></table></div>
+<!-- NEW PAGE -->
+<h2 class='title'><a name='TYPES'>Types</a></h2>
+<ul>
+       <li><a href='#cups_page_header2_t'><tt>cups_page_header2_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
+       <li><a href='#cups_page_header_t'><tt>cups_page_header_t</tt></a> </li>
+       <li><a href='#cups_raster_t'><tt>cups_raster_t</tt></a> </li>
+</ul>
+<!-- NEW PAGE -->
+<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cups_page_header2_t'>cups_page_header2_t</a></h3>
+<h4>Description</h4>
+<p>Version 2 Page Header </p>
+<h4>Definition</h4>
+<pre>
+typedef struct <a href='#cups_page_header2_s'>cups_page_header2_s</a> cups_page_header2_t;
+</pre>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cups_page_header_t'>cups_page_header_t</a></h3>
+<h4>Description</h4>
+<p>Version 1 Page Header</p>
+<h4>Definition</h4>
+<pre>
+typedef struct <a href='#cups_page_header_s'>cups_page_header_s</a> cups_page_header_t;
+</pre>
+<!-- NEW PAGE -->
+<h3 class='title'><a name='cups_raster_t'>cups_raster_t</a></h3>
+<h4>Description</h4>
+<p>Raster stream data</p>
+<h4>Definition</h4>
+<pre>
+typedef struct _cups_raster_s cups_raster_t;
+</pre>
+</body>
+</html>
index a36626aff510f1fc8b285f25670190c533d3f46a..ee69c1c05e9d958cd155b8c55ea5b95be12b3e66 100644 (file)
@@ -7,6 +7,10 @@
 
 <!-- MISSING:
 
+BrowseLDAPBindDN
+BrowseLDAPDN
+BrowseLDAPPassword
+BrowseLDAPServer
 BrowseLocalProtocols
 BrowseRemoteProtocols
 DefaultAuthType
diff --git a/doc/help/spec-command.html b/doc/help/spec-command.html
new file mode 100644 (file)
index 0000000..a9f74f0
--- /dev/null
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<!-- SECTION: Programming -->
+<head>
+       <title>CUPS Command File Format</title>
+       <meta name='keywords' content='Programming, CUPS Command File Format'>
+       <link rel='stylesheet' type='text/css' href='../cups.css'>
+</head>
+<body>
+<!--
+  "$Id$"
+
+  CUPS command file format specification for the Common UNIX Printing
+  System (CUPS).
+
+  Copyright 1997-2006 by Easy Software Products.
+
+  These coded instructions, statements, and computer programs are the
+  property of Easy Software Products 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 missing or damaged please contact Easy Software Products
+  at:
+
+      Attn: CUPS Licensing Information
+      Easy Software Products
+      44141 Airport View Drive, Suite 204
+      Hollywood, Maryland 20636 USA
+
+      Voice: (301) 373-9600
+      EMail: cups-info@cups.org
+        WWW: http://www.cups.org
+-->
+
+<h2 class='title'><a name='INTRODUCTION'>Introduction</a></h2>
+
+<p>This specification describes the CUPS command file format
+(application/vnd.cups-command) which is used to send printer
+maintenance commands to a printer in a device-independent way.
+The current specification supports basic maintenance functions
+such as head cleaning and self-test pages.</p>
+
+<p>Printer drivers advertise support for the CUPS command file
+format by providing a filter for the
+<var>application/vnd.cups-command</var> file type. Applications
+can determine if a printer supports printing of CUPS command
+files by checking the <code>printer-type</code> attribute for the
+<code>CUPS_PRINTER_COMMANDS</code> capability bit.</p>
+
+<h2 class='title'><a name='SYNTAX'>File Syntax</a></h2>
+
+<p>CUPS command files are ASCII text files.  The first line of a
+CUPS command file MUST contain:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+</pre>
+
+<p>After that, each line is either a command or a comment.
+Comments begin with the # character, e.g.:</p>
+
+<pre class='command'>
+# This is a comment
+</pre>
+
+<p>The printer commands are described below. Printer commands are
+case-insensitive, so "PRINTSELFTESTPAGE", "printselftestpage",
+and "PrintSelfTestPage" are equivalent. Commands that accept
+arguments have their arguments on the same line separated by
+whitespace.</p>
+
+<h2 class='title'><a name='COMMANDS'>Commands</a></h2>
+
+<h3>Clean</h3>
+
+<p class='summary'>Clean colorname</p>
+
+<p>Does a standard print head cleaning.  If a printer does not
+support cleaning of individual colors or cartridges, then all
+print heads are cleaned. Command filters MUST support the "all"
+colorname. Other standard color names include "black", "color",
+"photo", "cyan", "magenta", "yellow", "light-cyan",
+"light-magenta", "light-black", "light-gray", and
+"dark-gray".</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+Clean all
+</pre>
+
+<h3>PrintSelfTestPage</h3>
+
+<p class='summary'>PrintSelfTestPage</p>
+
+<p>Print a self-test page on the printer. Typically this page
+shows if all jets on a print head are functioning properly.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+PrintSelfTestPage
+</pre>
+
+</body>
+</html>
index 6dc27cb6b6513e1131f9f220e2f9e9d7770e58cb..51c35b925fa5654addf91358124875d0bdc93ac4 100644 (file)
@@ -8,7 +8,7 @@
 </head>
 <body>
 <!--
-  "$Id: spec-ppd.html 5138 2006-02-21 10:49:06Z mike $"
+  "$Id: spec-ppd.html 5190 2006-02-27 02:42:07Z mike $"
 
   CUPS PPD extensions specification for the Common UNIX Printing System (CUPS).
 
@@ -224,6 +224,31 @@ PPD file extensions was used. Currently it must be the string
 *cupsVersion: "1.2"
 </pre>
 
+<h3>ippReason</h3>
+
+<p class='summary'>*ippReason reason/Reason Text: "optional URL"</p>
+
+<p>This optional attribute maps custom
+<code>printer-state-reasons</code> keywords that are generated by
+the driver to human readable text. The optional URL string is a
+CUPS server absolute path to a help file under the scheduler's
+<code>DocumentRoot</code> directory or a full URL
+("http://www.domain.com/path/to/help/page.html") which directs
+the user at additional information concerning the condition that
+is being reported.</p>
+
+<p>Examples:</p>
+
+<pre class='command'>
+<em>*% Map com.vendor-error to text but no page</em>
+*ippReason com.vendor-error/A serious error occurred: ""
+
+<em>*% Map com.vendor-error to text and a local page</em>
+*ippReason com.vendor-error/A serious error occurred: "/help/com.vendor/error.html"
+
+<em>*% Map com.vendor-error to text and a remote page</em>
+*ippReason com.vendor-error/A serious error occurred: "http://www.vendor.com/help"
+</pre>
 
 <h2 class='title'><a name='OPTIONS'>Custom Options</a></h2>
 
@@ -255,14 +280,6 @@ PostScript command string is
 option value is "2.0" then CUPS will output the string
 "2.0 &lt;&lt;/cupsReal1 2 1 roll&gt;&gt;setpagedevice".</p>
 
-<blockquote><b>Note:</b> Currently only CustomPageSize supports
-more than 1 parameter. This restriction is due to value encoding
-issues, since the "Custom.value" format does not allow for
-specification of named parameters. We anticipate supporting the
-collection value format "{Name1=foo Name2=bar}" for the final
-CUPS 1.2 release. In addition, the collection value format will
-allow string values to contain spaces.</blockquote>
-
 <p>The "type" is one of the following keywords:</p>
 
 <ul>
@@ -530,6 +547,11 @@ in the PPD file for a given locale.</blockquote>
 *fr_FR.Translation ModelName/La Foobar Laser 9999: ""
 *de_DE.Translation ModelName/Foobar LaserDrucken 9999: ""
 
+*ippReason com.vendor-error/A serious error occurred: "/help/com.vendor/error.html"
+<em>*% Localize printer-state-reason for French and German</em>
+*fr_FR.ippReason com.vendor-error/Une erreur s&egrave;rieuse s'est produite: "/help/com.vendor/error.html"
+*de_DE.ippReason com.vendor-error/Eine ernste St&ouml;rung trat: "/help/com.vendor/error.html"
+
 ...
 
 *OpenUI *InputSlot/Paper Source: PickOne
@@ -568,6 +590,8 @@ in the PPD file for a given locale.</blockquote>
 
        <li>Added <tt>cupsPortMonitor</tt> attribute</li>
 
+       <li>Added <tt>ippReason</tt> attribute</li>
+
        <li>Removed <tt>cupsProtocol</tt> attribute</li>
 
 </ul>
diff --git a/doc/images/clean-print-heads.gif b/doc/images/clean-print-heads.gif
new file mode 100644 (file)
index 0000000..94d42c1
Binary files /dev/null and b/doc/images/clean-print-heads.gif differ
diff --git a/doc/images/print-self-test-page.gif b/doc/images/print-self-test-page.gif
new file mode 100644 (file)
index 0000000..28363ad
Binary files /dev/null and b/doc/images/print-self-test-page.gif differ
index c181b3f3e8af4262faf06a023f641c82d65d2f1b..06a31d5e165e9dbfd9ae1231b1f4739b7e472a16 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5089 2006-02-08 04:05:01Z mike $"
+# "$Id: Makefile 5192 2006-02-27 03:08:47Z mike $"
 #
 #   Filter makefile for the Common UNIX Printing System (CUPS).
 #
@@ -103,6 +103,17 @@ installhdrs:
        $(INSTALL_DATA) raster.h $(INCLUDEDIR)/cups
 
 
+#
+# Automatic API help files...
+#
+
+apihelp:
+       echo Generating CUPS API help files...
+       mxmldoc --section "Programming" --title "Raster API" \
+               --intro api-raster.shtml \
+               raster.h interpret.c raster.c >../doc/help/api-raster.html
+
+
 #
 # formtops
 #
@@ -284,5 +295,5 @@ include Dependencies
 
 
 #
-# End of "$Id: Makefile 5089 2006-02-08 04:05:01Z mike $".
+# End of "$Id: Makefile 5192 2006-02-27 03:08:47Z mike $".
 #
diff --git a/filter/api-raster.shtml b/filter/api-raster.shtml
new file mode 100644 (file)
index 0000000..13c5044
--- /dev/null
@@ -0,0 +1,60 @@
+<!--
+  "$Id$"
+
+  Raster API introduction for the Common UNIX Printing System (CUPS).
+
+  Copyright 1997-2006 by Easy Software Products.
+
+  These coded instructions, statements, and computer programs are the
+  property of Easy Software Products 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 missing or damaged please contact Easy Software Products
+  at:
+
+      Attn: CUPS Licensing Information
+      Easy Software Products
+      44141 Airport View Drive, Suite 204
+      Hollywood, Maryland 20636 USA
+
+      Voice: (301) 373-9600
+      EMail: cups-info@cups.org
+       WWW: http://www.cups.org
+-->
+
+<h2 class='title'>Introduction</h2>
+
+<p>The CUPS raster API provides a standard interface for reading
+and writing CUPS raster streams which are used for printing to
+raster printers. Because the raster format is updated from time
+to time, it is important to use this API to avoid
+incompatibilities with newer versions of CUPS.</p>
+
+<h2 class='title'>General Usage</h2>
+
+<p>The <var>&lt;cups/raster.h&gt;</var> header file must be
+included to use the <tt>cupsRaster</tt> functions.</p>
+
+<p>Programs using these functions must be linked to the CUPS
+imaging library: <var>libcupsimage.a</var>,
+<var>libcupsimage.so.2</var>, <var>libcupsimage.2.dylib</var>,
+<var>libcupsimage_s.a</var>, or <var>libcupsimage2.lib</var>
+depending on the platform. The following command compiles
+<var>myprogram.c</var> using GCC and the CUPS imaging
+library:</p>
+
+<pre class='command'>
+<kbd>gcc -o myprogram myprogram.c -lcupsimage</kbd>
+</pre>
+
+<h2 class='title'>Compatibility</h2>
+
+<p>Unless otherwise specified, the raster API functions require
+CUPS 1.1 or higher.</p>
+
+<h2 class='title'>Licensing</h2>
+
+<p>The CUPS raster API is provided under the terms of the GNU
+General Public License, with exceptions for MacOS X-based
+programs. Please see the CUPS license agreement for more
+information.</p>
index d6363e6fb2596bc72b87f2e4f882762bbb1616f1..abfb633104ebe3f33d0e50b1aff3f10d90c83153 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: hpgl-input.c 4494 2005-02-18 02:18:11Z mike $"
+ * "$Id: hpgl-input.c 5150 2006-02-22 19:21:50Z mike $"
  *
  *   HP-GL/2 input processing for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1993-2005 by Easy Software Products.
+ *   Copyright 1993-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
@@ -125,6 +125,9 @@ ParseCommand(FILE    *fp,   /* I - File to read from */
 
         default : /* HP RTL/PCL control */
             while ((i = getc(fp)) != EOF && !isupper(i & 255));
+
+           if (i == EOF)
+             return (-1);
             break;
       }
   } while (ch < ' ');
@@ -133,7 +136,19 @@ ParseCommand(FILE    *fp,  /* I - File to read from */
   name[1] = getc(fp);
   name[2] = '\0';
 
-  if (strcasecmp(name, "LB") == 0)
+  if (name[1] < ' ')
+  {
+   /*
+    * If we get here, then more than likely we are faced with a raw PCL
+    * file which we can't handle - abort!
+    */
+
+    fputs("ERROR: Invalid HP-GL/2 command seen, unable to print file!\n",
+          stderr);
+    return (-1);
+  }
+
+  if (!strcasecmp(name, "LB"))
   {
     bufptr = buf;
     while ((ch = getc(fp)) != StringTerminator)
@@ -145,7 +160,7 @@ ParseCommand(FILE    *fp,   /* I - File to read from */
     p[num_params].value.string = strdup(buf);
     num_params ++;
   }
-  else if (strcasecmp(name, "SM") == 0)
+  else if (!strcasecmp(name, "SM"))
   {
     buf[0] = getc(fp);
     buf[1] = '\0';
@@ -153,7 +168,7 @@ ParseCommand(FILE    *fp,   /* I - File to read from */
     p[num_params].value.string = strdup(buf);
     num_params ++;
   }
-  else if (strcasecmp(name, "DT") == 0)
+  else if (!strcasecmp(name, "DT"))
   {
     if ((buf[0] = getc(fp)) != ';')
     {
@@ -163,7 +178,7 @@ ParseCommand(FILE    *fp,   /* I - File to read from */
       num_params ++;
     }
   }
-  else if (strcasecmp(name, "PE") == 0)
+  else if (!strcasecmp(name, "PE"))
   {
     bufptr = buf;
     while ((ch = getc(fp)) != ';')
@@ -254,5 +269,5 @@ FreeParameters(int     num_params,  /* I - Number of parameters */
 
 
 /*
- * End of "$Id: hpgl-input.c 4494 2005-02-18 02:18:11Z mike $".
+ * End of "$Id: hpgl-input.c 5150 2006-02-22 19:21:50Z mike $".
  */
index f87c41b4f66c1ed4e3ac4c578a508fd2127e28ad..df7bed281f27a5539b1ed48425bee1ca97517d38 100644 (file)
@@ -1,10 +1,10 @@
 /*
- * "$Id: image-private.h 4742 2005-10-02 23:01:43Z mike $"
+ * "$Id: image-private.h 5191 2006-02-27 02:47:56Z mike $"
  *
  *   Private image library definitions for the Common UNIX Printing
  *   System (CUPS).
  *
- *   Copyright 1993-2005 by Easy Software Products.
+ *   Copyright 1993-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
  * Types and structures...
  */
 
+typedef enum cups_iztype_e             /**** Image zoom type ****/
+{
+  CUPS_IZOOM_FAST,                     /* Use nearest-neighbor sampling */
+  CUPS_IZOOM_NORMAL,                   /* Use bilinear interpolation */
+  CUPS_IZOOM_BEST                      /* Use bicubic interpolation */
+} cups_iztype_t;
+
 struct cups_ic_s;
 
 typedef struct cups_itile_s            /**** Image tile ****/
@@ -199,10 +206,16 @@ extern int                _cupsImageReadTIFF(cups_image_t *img, FILE *fp,
                                           cups_icspace_t secondary,
                                           int saturation, int hue,
                                           const cups_ib_t *lut);
+extern void            _cupsImageZoomDelete(cups_izoom_t *z);
+extern void            _cupsImageZoomFill(cups_izoom_t *z, int iy);
+extern cups_izoom_t    *_cupsImageZoomNew(cups_image_t *img, int xc0, int yc0,
+                                          int xc1, int yc1, int xsize,
+                                          int ysize, int rotated,
+                                          cups_iztype_t type);
 
 
 #endif /* !_CUPS_IMAGE_PRIVATE_H_ */
 
 /*
- * End of "$Id: image-private.h 4742 2005-10-02 23:01:43Z mike $".
+ * End of "$Id: image-private.h 5191 2006-02-27 02:47:56Z mike $".
  */
index 42cc478ad89a10afaa89d677b0fa98476cea7f35..8dc67ec1e636c614463a809baf2a9f865d01810d 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: image-zoom.c 5086 2006-02-07 02:45:26Z mike $"
+ * "$Id: image-zoom.c 5191 2006-02-27 02:47:56Z mike $"
  *
  *   cupsImage zoom routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1993-2005 by Easy Software Products.
+ *   Copyright 1993-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
  *
  * Contents:
  *
- *   cupsImageZoomDelete() - Free a zoom record...
- *   cupsImageZoomFill()   - Fill a zoom record...
- *   cupsImageZoomNew()    - Allocate a pixel zoom record...
- *   zoom_bilinear()       - Fill a zoom record with image data utilizing
- *                           bilinear interpolation.
- *   zoom_nearest()        - Fill a zoom record quickly using nearest-neighbor
- *                           sampling.
+ *   _cupsImageZoomDelete() - Free a zoom record...
+ *   _cupsImageZoomFill()   - Fill a zoom record...
+ *   _cupsImageZoomNew()    - Allocate a pixel zoom record...
+ *   zoom_bilinear()        - Fill a zoom record with image data utilizing
+ *                            bilinear interpolation.
+ *   zoom_nearest()         - Fill a zoom record quickly using nearest-neighbor
+ *                            sampling.
  */
 
 /*
@@ -50,11 +50,11 @@ static void zoom_nearest(cups_izoom_t *z, int iy);
 
 
 /*
- * 'cupsImageZoomDelete()' - Free a zoom record...
+ * '_cupsImageZoomDelete()' - Free a zoom record...
  */
 
 void
-cupsImageZoomDelete(cups_izoom_t *z)   /* I - Zoom record to free */
+_cupsImageZoomDelete(cups_izoom_t *z)  /* I - Zoom record to free */
 {
   free(z->rows[0]);
   free(z->rows[1]);
@@ -64,13 +64,13 @@ cupsImageZoomDelete(cups_izoom_t *z)        /* I - Zoom record to free */
 
 
 /*
- * 'cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear
+ * '_cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear
  *                         interpolation.
  */
 
 void
-cupsImageZoomFill(cups_izoom_t *z,     /* I - Zoom record to fill */
-              int     iy)      /* I - Zoom image row */
+_cupsImageZoomFill(cups_izoom_t *z,    /* I - Zoom record to fill */
+                   int     iy)         /* I - Zoom image row */
 {
   switch (z->type)
   {
@@ -86,11 +86,11 @@ cupsImageZoomFill(cups_izoom_t *z,  /* I - Zoom record to fill */
 
 
 /*
- * 'cupsImageZoomNew()' - Allocate a pixel zoom record...
+ * '_cupsImageZoomNew()' - Allocate a pixel zoom record...
  */
 
 cups_izoom_t *
-cupsImageZoomNew(
+_cupsImageZoomNew(
     cups_image_t  *img,                        /* I - cupsImage to zoom */
     int           xc0,                 /* I - Upper-lefthand corner */
     int           yc0,                 /* I - ... */
@@ -366,5 +366,5 @@ zoom_nearest(cups_izoom_t *z,               /* I - Zoom record to fill */
 
 
 /*
- * End of "$Id: image-zoom.c 5086 2006-02-07 02:45:26Z mike $".
+ * End of "$Id: image-zoom.c 5191 2006-02-27 02:47:56Z mike $".
  */
index ae90b94fc7eb18710f7a8275a6ff9d56e5f2f6fa..b77e6ddc3f69caff25b5198dd00d4e58828233f3 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: image.h 4741 2005-10-02 04:25:52Z mike $"
+ * "$Id: image.h 5191 2006-02-27 02:47:56Z mike $"
  *
  *   Image library definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1993-2005 by Easy Software Products.
+ *   Copyright 1993-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
@@ -52,13 +52,6 @@ typedef enum cups_icspace_e          /**** Image colorspaces ****/
   CUPS_IMAGE_RGB_CMYK = 4              /* Use RGB or CMYK */
 } cups_icspace_t;
 
-typedef enum cups_iztype_e             /**** Image zoom type ****/
-{
-  CUPS_IZOOM_FAST,                     /* Use nearest-neighbor sampling */
-  CUPS_IZOOM_NORMAL,                   /* Use bilinear interpolation */
-  CUPS_IZOOM_BEST                      /* Use bicubic interpolation */
-} cups_iztype_t;
-
 
 /*
  * Types and structures...
@@ -133,11 +126,6 @@ extern void                cupsImageWhiteToRGB(const cups_ib_t *in,
                                            cups_ib_t *out, int count);
 extern void            cupsImageWhiteToWhite(const cups_ib_t *in,
                                              cups_ib_t *out, int count);
-extern void            cupsImageZoomDelete(cups_izoom_t *z);
-extern void            cupsImageZoomFill(cups_izoom_t *z, int iy);
-extern cups_izoom_t    *cupsImageZoomNew(cups_image_t *img, int x0, int y0,
-                                         int x1, int y1, int xsize, int ysize,
-                                         int rotated, cups_iztype_t type);
 
 
 #  ifdef __cplusplus
@@ -147,5 +135,5 @@ extern cups_izoom_t *cupsImageZoomNew(cups_image_t *img, int x0, int y0,
 #endif /* !_CUPS_IMAGE_H_ */
 
 /*
- * End of "$Id: image.h 4741 2005-10-02 04:25:52Z mike $".
+ * End of "$Id: image.h 5191 2006-02-27 02:47:56Z mike $".
  */
index f0dce921c3a9116370f958bf04043df7dc002a2d..affac6c0a50df5bf6d24d973af500b2030234ce4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: imagetoraster.c 5099 2006-02-13 02:46:10Z mike $"
+ * "$Id: imagetoraster.c 5191 2006-02-27 02:47:56Z mike $"
  *
  *   Image file to raster filter for the Common UNIX Printing System (CUPS).
  *
@@ -1286,10 +1286,10 @@ main(int  argc,                         /* I - Number of command-line arguments */
          */
 
           if (Flip)
-           z = cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
+           z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
                                 Orientation & 1, zoom_type);
           else
-           z = cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
+           z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
                                 Orientation & 1, zoom_type);
 
          /*
@@ -1327,9 +1327,9 @@ main(int  argc,                           /* I - Number of command-line arguments */
            if (iy != last_iy)
            {
              if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1)
-               cupsImageZoomFill(z, iy);
+               _cupsImageZoomFill(z, iy);
 
-              cupsImageZoomFill(z, iy + z->yincr);
+              _cupsImageZoomFill(z, iy + z->yincr);
 
               last_iy = iy;
            }
@@ -1449,7 +1449,7 @@ main(int  argc,                           /* I - Number of command-line arguments */
          * Free memory used for the "zoom" engine...
          */
 
-          cupsImageZoomDelete(z);
+          _cupsImageZoomDelete(z);
         }
       }
 
@@ -4611,5 +4611,5 @@ make_lut(cups_ib_t  *lut,         /* I - Lookup table */
 
 
 /*
- * End of "$Id: imagetoraster.c 5099 2006-02-13 02:46:10Z mike $".
+ * End of "$Id: imagetoraster.c 5191 2006-02-27 02:47:56Z mike $".
  */
index 10d235012b2217c7c56c094eea5fbf572886bb84..607deb1a6adc03004112eb5de2af5c06c779aedf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: raster.c 4981 2006-01-25 21:34:00Z mike $"
+ * "$Id: raster.c 5192 2006-02-27 03:08:47Z mike $"
  *
  *   Raster file routines for the Common UNIX Printing System (CUPS).
  *
  *
  *   cupsRasterClose()        - Close a raster stream.
  *   cupsRasterOpen()         - Open a raster stream.
- *   cupsRasterReadHeader()   - Read a V1 raster page header.
- *   cupsRasterReadHeader2()  - Read a V2 raster page header.
+ *   cupsRasterReadHeader()   - Read a raster page header and store it in a
+ *                              V1 page header structure.
+ *   cupsRasterReadHeader2()  - Read a raster page header and store it in a
+ *                              V2 page header structure.
  *   cupsRasterReadPixels()   - Read raster pixels.
- *   cupsRasterWriteHeader()  - Write a V1 raster page header.
- *   cupsRasterWriteHeader2() - Write a V2 raster page header.
+ *   cupsRasterWriteHeader()  - Write a raster page header from a V1 page
+ *                              header structure.
+ *   cupsRasterWriteHeader2() - Write a raster page header from a V2 page
+ *                              header structure.
  *   cupsRasterWritePixels()  - Write raster pixels.
  *   cups_raster_update()     - Update the raster header and row count for the
  *                              current page.
@@ -153,7 +157,8 @@ cupsRasterOpen(int         fd,              /* I - File descriptor */
 
 
 /*
- * 'cupsRasterReadHeader()' - Read a V1 raster page header.
+ * 'cupsRasterReadHeader()' - Read a raster page header and store it in a
+ *                            V1 page header structure.
  */
 
 unsigned                               /* O - 1 on success, 0 on fail */
@@ -179,7 +184,8 @@ cupsRasterReadHeader(
 
 
 /*
- * 'cupsRasterReadHeader2()' - Read a V2 raster page header.
+ * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a
+ *                             V2 page header structure.
  *
  * @since CUPS 1.2@
  */
@@ -395,7 +401,8 @@ cupsRasterReadPixels(cups_raster_t *r,      /* I - Raster stream */
 
 
 /*
- * 'cupsRasterWriteHeader()' - Write a V2 raster page header.
+ * 'cupsRasterWriteHeader()' - Write a raster page header from a V1 page
+ *                             header structure.
  */
  
 unsigned                               /* O - 1 on success, 0 on failure */
@@ -426,7 +433,8 @@ cupsRasterWriteHeader(
 
 
 /*
- * 'cupsRasterWriteHeader2()' - Write a V2 raster page header.
+ * 'cupsRasterWriteHeader2()' - Write a raster page header from a V2 page
+ *                              header structure.
  *
  * @since CUPS 1.2@
  */
@@ -888,5 +896,5 @@ cups_write(int                 fd,  /* I - File descriptor */
 
 
 /*
- * End of "$Id: raster.c 4981 2006-01-25 21:34:00Z mike $".
+ * End of "$Id: raster.c 5192 2006-02-27 03:08:47Z mike $".
  */
index 541e6ebf8a2a563e3ea9815ef65b6bc440010a15..f970f557869e9f94fd3a7680789c1fb1dd2831be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: raster.h 4998 2006-01-26 21:59:54Z mike $"
+ * "$Id: raster.h 5192 2006-02-27 03:08:47Z mike $"
  *
  *   Raster file definitions for the Common UNIX Printing System (CUPS).
  *
@@ -290,7 +290,7 @@ typedef struct cups_page_header2_s  /**** Version 2 Page Header @since CUPS 1.2@
   /**** Version 2 Dictionary Values ****/
   unsigned     cupsNumColors;          /* Number of colors @since CUPS 1.2@ */
   float                cupsBorderlessScalingFactor;
-                                       /* Scaling that was applied to page data */
+                                       /* Scaling that was applied to page data @since CUPS 1.2@ */
   float                cupsPageSize[2];        /* Floating point PageSize (scaling *
                                         * factor not applied) @since CUPS 1.2@ */
   float                cupsImagingBBox[4];     /* Floating point ImagingBoundingBox *
@@ -350,5 +350,5 @@ extern unsigned             cupsRasterWriteHeader2(cups_raster_t *r,
 #endif /* !_CUPS_RASTER_H_ */
 
 /*
- * End of "$Id: raster.h 4998 2006-01-26 21:59:54Z mike $".
+ * End of "$Id: raster.h 5192 2006-02-27 03:08:47Z mike $".
  */
index de9d14e7d0a2becbfddfb91b4bfef514a5f035d1..eb0a3d6978f78f94e369eb4aab97fefee074e1f2 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5114 2006-02-16 12:28:29Z mike $"
+# "$Id: Makefile 5193 2006-02-27 20:27:07Z mike $"
 #
 #   Locale file makefile for the Common UNIX Printing System (CUPS).
 #
@@ -28,7 +28,7 @@ include ../Makedefs
 # Locales...
 #
 
-LOCALES        =       fr ja
+LOCALES        =       ja
 
 
 #
@@ -102,5 +102,5 @@ translate.o:        ../cups/http.h ../cups/i18n.h ../cups/language.h ../cups/string.h
 
 
 #
-# End of "$Id: Makefile 5114 2006-02-16 12:28:29Z mike $".
+# End of "$Id: Makefile 5193 2006-02-27 20:27:07Z mike $".
 #
index d1a0aeb8f05e30f8d078e34b6df7bd16d73391c4..9697db30e54f53cb67f91ae54fa8db029ba4eaab 100644 (file)
@@ -29,7 +29,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: CUPS 1.2\n"
 "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n"
-"POT-Creation-Date: 2006-02-15 19:50-0500\n"
+"POT-Creation-Date: 2006-02-26 20:42-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -54,27 +54,32 @@ msgid "Extra"
 msgstr ""
 
 #: cups/ppd.c:656 cups/ppd.c:881 cups/ppd.c:1047 cups/ppd.c:662 cups/ppd.c:996
-#: cups/ppd.c:1169
+#: cups/ppd.c:1169 cups/ppd.c:651 cups/ppd.c:983 cups/ppd.c:1148
 msgid "General"
 msgstr ""
 
 #: cups/ppd.c:704 cups/ppd.c:1105 cups/ppd.c:710 cups/ppd.c:1224
+#: cups/ppd.c:697 cups/ppd.c:1201
 msgid "Media Size"
 msgstr ""
 
 #: cups/ppd.c:706 cups/ppd.c:1107 cups/ppd.c:712 cups/ppd.c:1226
+#: cups/ppd.c:699 cups/ppd.c:1203
 msgid "Media Type"
 msgstr ""
 
 #: cups/ppd.c:708 cups/ppd.c:1109 cups/ppd.c:714 cups/ppd.c:1228
+#: cups/ppd.c:701 cups/ppd.c:1205
 msgid "Media Source"
 msgstr ""
 
 #: cups/ppd.c:710 cups/ppd.c:1111 cups/ppd.c:716 cups/ppd.c:1230
+#: cups/ppd.c:703 cups/ppd.c:1207
 msgid "Output Mode"
 msgstr ""
 
 #: cups/ppd.c:712 cups/ppd.c:1113 cups/ppd.c:718 cups/ppd.c:1232
+#: cups/ppd.c:705 cups/ppd.c:1209
 msgid "Resolution"
 msgstr ""
 
@@ -82,11 +87,11 @@ msgstr ""
 msgid "Variable"
 msgstr ""
 
-#: cups/ppd.c:1535 cups/ppd.c:1650
+#: cups/ppd.c:1535 cups/ppd.c:1650 cups/ppd.c:1627
 msgid "Yes"
 msgstr ""
 
-#: cups/ppd.c:1537 cups/ppd.c:1652
+#: cups/ppd.c:1537 cups/ppd.c:1652 cups/ppd.c:1629
 msgid "No"
 msgstr ""
 
@@ -95,32 +100,39 @@ msgid "Auto"
 msgstr ""
 
 #: scheduler/client.c:2247 scheduler/client.c:2251 scheduler/client.c:2274
+#: scheduler/client.c:2308
 msgid "Enter your username and password or the root username and password to access this page."
 msgstr ""
 
 #: scheduler/client.c:2252 scheduler/client.c:2256 scheduler/client.c:2279
+#: scheduler/client.c:2313
 msgid "You must use a https: URL to access this page."
 msgstr ""
 
 #: scheduler/ipp.c:236 scheduler/ipp.c:244 scheduler/ipp.c:246
+#: scheduler/ipp.c:260
 #, c-format
 msgid "Bad request version number %d.%d!"
 msgstr ""
 
 #: scheduler/ipp.c:246 scheduler/ipp.c:254 scheduler/ipp.c:256
+#: scheduler/ipp.c:270
 msgid "No attributes in request!"
 msgstr ""
 
 #: scheduler/ipp.c:269 scheduler/ipp.c:277 scheduler/ipp.c:279
+#: scheduler/ipp.c:293
 #, c-format
 msgid "Attribute groups are out of order (%x < %x)!"
 msgstr ""
 
 #: scheduler/ipp.c:379 scheduler/ipp.c:389 scheduler/ipp.c:391
+#: scheduler/ipp.c:405
 msgid "Missing required attributes!"
 msgstr ""
 
 #: scheduler/ipp.c:575 scheduler/ipp.c:585 scheduler/ipp.c:591
+#: scheduler/ipp.c:605
 #, c-format
 msgid "%s not supported!"
 msgstr ""
@@ -142,26 +154,36 @@ msgstr ""
 #: scheduler/ipp.c:5357 scheduler/ipp.c:5769 scheduler/ipp.c:6077
 #: scheduler/ipp.c:6368 scheduler/ipp.c:6410 scheduler/ipp.c:6916
 #: scheduler/ipp.c:7626 scheduler/ipp.c:8589 scheduler/ipp.c:9003
-#: scheduler/ipp.c:9084 scheduler/ipp.c:9259
+#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 scheduler/ipp.c:716
+#: scheduler/ipp.c:1003 scheduler/ipp.c:1174 scheduler/ipp.c:2812
+#: scheduler/ipp.c:2927 scheduler/ipp.c:4699 scheduler/ipp.c:4942
+#: scheduler/ipp.c:5326 scheduler/ipp.c:5738 scheduler/ipp.c:6046
+#: scheduler/ipp.c:6337 scheduler/ipp.c:6379 scheduler/ipp.c:7116
+#: scheduler/ipp.c:8081 scheduler/ipp.c:8745 scheduler/ipp.c:8826
+#: scheduler/ipp.c:9001
 msgid "The printer or class was not found."
 msgstr ""
 
 #: scheduler/ipp.c:762 scheduler/ipp.c:777 scheduler/ipp.c:784
+#: scheduler/ipp.c:799
 msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"."
 msgstr ""
 
 #: scheduler/ipp.c:778 scheduler/ipp.c:1454 scheduler/ipp.c:793
 #: scheduler/ipp.c:1482 scheduler/ipp.c:800 scheduler/ipp.c:1515
+#: scheduler/ipp.c:815 scheduler/ipp.c:2031
 #, c-format
 msgid "The printer-uri \"%s\" contains invalid characters."
 msgstr ""
 
 #: scheduler/ipp.c:811 scheduler/ipp.c:826 scheduler/ipp.c:833
+#: scheduler/ipp.c:848
 #, c-format
 msgid "A printer named \"%s\" already exists!"
 msgstr ""
 
 #: scheduler/ipp.c:904 scheduler/ipp.c:924 scheduler/ipp.c:933
+#: scheduler/ipp.c:944
 #, c-format
 msgid "Attempt to set %s printer-state to bad value %d!"
 msgstr ""
@@ -177,81 +199,97 @@ msgid "add_class: Unknown printer-error-policy \"%s\"."
 msgstr ""
 
 #: scheduler/ipp.c:1144 scheduler/ipp.c:1168 scheduler/ipp.c:1200
+#: scheduler/ipp.c:1112
 msgid "Unable to allocate memory for file types!"
 msgstr ""
 
 #: scheduler/ipp.c:1290 scheduler/ipp.c:4501 scheduler/ipp.c:1316
 #: scheduler/ipp.c:4705 scheduler/ipp.c:1348 scheduler/ipp.c:4804
+#: scheduler/ipp.c:1810 scheduler/ipp.c:4773
 #, c-format
 msgid "Character set \"%s\" not supported!"
 msgstr ""
 
 #: scheduler/ipp.c:1299 scheduler/ipp.c:4510 scheduler/ipp.c:1325
 #: scheduler/ipp.c:4714 scheduler/ipp.c:1357 scheduler/ipp.c:4813
+#: scheduler/ipp.c:1819 scheduler/ipp.c:4782
 #, c-format
 msgid "Language \"%s\" not supported!"
 msgstr ""
 
 #: scheduler/ipp.c:1309 scheduler/ipp.c:4520 scheduler/ipp.c:1335
 #: scheduler/ipp.c:4724 scheduler/ipp.c:1367 scheduler/ipp.c:4823
+#: scheduler/ipp.c:1829 scheduler/ipp.c:4792
 #, c-format
 msgid "The notify-user-data value is too large (%d > 63 octets)!"
 msgstr ""
 
 #: scheduler/ipp.c:1326 scheduler/ipp.c:1352 scheduler/ipp.c:1384
+#: scheduler/ipp.c:1846
 msgid "The notify-lease-duration attribute cannot be used with job subscriptions."
 msgstr ""
 
 #: scheduler/ipp.c:1438 scheduler/ipp.c:1466 scheduler/ipp.c:1499
+#: scheduler/ipp.c:2015
 msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"."
 msgstr ""
 
 #: scheduler/ipp.c:1487 scheduler/ipp.c:1515 scheduler/ipp.c:1548
+#: scheduler/ipp.c:2064
 #, c-format
 msgid "A class named \"%s\" already exists!"
 msgstr ""
 
 #: scheduler/ipp.c:1575 scheduler/ipp.c:1607 scheduler/ipp.c:1644
+#: scheduler/ipp.c:2157
 #, c-format
 msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"."
 msgstr ""
 
 #: scheduler/ipp.c:1595 scheduler/ipp.c:1627 scheduler/ipp.c:1664
+#: scheduler/ipp.c:2177
 #, c-format
 msgid "Bad device-uri \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:1626 scheduler/ipp.c:1659 scheduler/ipp.c:1698
+#: scheduler/ipp.c:2211
 #, c-format
 msgid "Bad port-monitor \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:1669 scheduler/ipp.c:1705 scheduler/ipp.c:1744
+#: scheduler/ipp.c:2257
 #, c-format
 msgid "Bad printer-state value %d!"
 msgstr ""
 
 #: scheduler/ipp.c:1762 scheduler/ipp.c:1800 scheduler/ipp.c:1842
+#: scheduler/ipp.c:8585
 #, c-format
 msgid "Unknown printer-op-policy \"%s\"."
 msgstr ""
 
 #: scheduler/ipp.c:1775 scheduler/ipp.c:1813 scheduler/ipp.c:1855
+#: scheduler/ipp.c:8600
 #, c-format
 msgid "Unknown printer-error-policy \"%s\"."
 msgstr ""
 
 #: scheduler/ipp.c:1837 scheduler/ipp.c:1875 scheduler/ipp.c:1919
+#: scheduler/ipp.c:2336
 #, c-format
 msgid "Unable to copy interface script - %s!"
 msgstr ""
 
 #: scheduler/ipp.c:1862 scheduler/ipp.c:1900 scheduler/ipp.c:1944
+#: scheduler/ipp.c:2361
 #, c-format
 msgid "Unable to copy PPD file - %s!"
 msgstr ""
 
 #: scheduler/ipp.c:1915 scheduler/ipp.c:1954 scheduler/ipp.c:2000
+#: scheduler/ipp.c:2417
 msgid "Unable to copy PPD file!"
 msgstr ""
 
@@ -263,7 +301,9 @@ msgstr ""
 #: scheduler/ipp.c:7839 scheduler/ipp.c:8334 scheduler/ipp.c:2158
 #: scheduler/ipp.c:2451 scheduler/ipp.c:5220 scheduler/ipp.c:6210
 #: scheduler/ipp.c:7713 scheduler/ipp.c:7928 scheduler/ipp.c:8167
-#: scheduler/ipp.c:8672
+#: scheduler/ipp.c:8672 scheduler/ipp.c:2613 scheduler/ipp.c:2906
+#: scheduler/ipp.c:5189 scheduler/ipp.c:6179 scheduler/ipp.c:7203
+#: scheduler/ipp.c:7418 scheduler/ipp.c:7657 scheduler/ipp.c:8164
 msgid "Got a printer-uri attribute but no job-id!"
 msgstr ""
 
@@ -276,6 +316,9 @@ msgstr ""
 #: scheduler/ipp.c:2180 scheduler/ipp.c:2523 scheduler/ipp.c:5243
 #: scheduler/ipp.c:6233 scheduler/ipp.c:6456 scheduler/ipp.c:7736
 #: scheduler/ipp.c:7951 scheduler/ipp.c:8190 scheduler/ipp.c:8695
+#: scheduler/ipp.c:2635 scheduler/ipp.c:2978 scheduler/ipp.c:5212
+#: scheduler/ipp.c:6202 scheduler/ipp.c:6425 scheduler/ipp.c:7226
+#: scheduler/ipp.c:7441 scheduler/ipp.c:7680 scheduler/ipp.c:8187
 #, c-format
 msgid "Bad job-uri attribute \"%s\"!"
 msgstr ""
@@ -288,6 +331,7 @@ msgid "Job #%d doesn't exist!"
 msgstr ""
 
 #: scheduler/ipp.c:2131 scheduler/ipp.c:2172 scheduler/ipp.c:2214
+#: scheduler/ipp.c:2669
 #, c-format
 msgid "Job #%d is not held for authentication!"
 msgstr ""
@@ -298,19 +342,23 @@ msgid "You are not authorized to authenticate job #%d owned by \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:2221 scheduler/ipp.c:2264 scheduler/ipp.c:2303
+#: scheduler/ipp.c:2758
 msgid "The printer-uri attribute is required!"
 msgstr ""
 
 #: scheduler/ipp.c:2238 scheduler/ipp.c:2283 scheduler/ipp.c:2322
+#: scheduler/ipp.c:2777
 msgid "Missing requesting-user-name attribute!"
 msgstr ""
 
 #: scheduler/ipp.c:2277 scheduler/ipp.c:2324 scheduler/ipp.c:2363
+#: scheduler/ipp.c:2818
 #, c-format
 msgid "The printer-uri \"%s\" is not valid."
 msgstr ""
 
 #: scheduler/ipp.c:2410 scheduler/ipp.c:2460 scheduler/ipp.c:2499
+#: scheduler/ipp.c:2954
 #, c-format
 msgid "No active jobs on %s!"
 msgstr ""
@@ -321,83 +369,101 @@ msgid "You are not authorized to delete job #%d owned by \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:2476 scheduler/ipp.c:2527 scheduler/ipp.c:2563
+#: scheduler/ipp.c:3018
 #, c-format
 msgid "Job #%d is already %s - can't cancel."
 msgstr ""
 
 #: scheduler/ipp.c:3720 scheduler/ipp.c:3914 scheduler/ipp.c:4006
+#: scheduler/ipp.c:1190
 msgid "The printer or class is not shared!"
 msgstr ""
 
 #: scheduler/ipp.c:3746 scheduler/ipp.c:6647 scheduler/ipp.c:3940
 #: scheduler/ipp.c:6695 scheduler/ipp.c:4032 scheduler/ipp.c:6954
+#: scheduler/ipp.c:1216
 #, c-format
 msgid "Destination \"%s\" is not accepting jobs."
 msgstr ""
 
 #: scheduler/ipp.c:3759 scheduler/ipp.c:6443 scheduler/ipp.c:3954
 #: scheduler/ipp.c:6487 scheduler/ipp.c:4046 scheduler/ipp.c:6739
+#: scheduler/ipp.c:1230
 #, c-format
 msgid "Bad copies value %d."
 msgstr ""
 
 #: scheduler/ipp.c:3775 scheduler/ipp.c:6459 scheduler/ipp.c:3971
 #: scheduler/ipp.c:6504 scheduler/ipp.c:4063 scheduler/ipp.c:6756
+#: scheduler/ipp.c:1247
 #, c-format
 msgid "Bad page-ranges values %d-%d."
 msgstr ""
 
 #: scheduler/ipp.c:3795 scheduler/ipp.c:3991 scheduler/ipp.c:4083
+#: scheduler/ipp.c:1267
 msgid "Too many active jobs."
 msgstr ""
 
 #: scheduler/ipp.c:3801 scheduler/ipp.c:6668 scheduler/ipp.c:3997
 #: scheduler/ipp.c:6716 scheduler/ipp.c:4089 scheduler/ipp.c:6975
+#: scheduler/ipp.c:1273
 msgid "Quota limit reached."
 msgstr ""
 
 #: scheduler/ipp.c:3824 scheduler/ipp.c:6691 scheduler/ipp.c:4022
 #: scheduler/ipp.c:6741 scheduler/ipp.c:4114 scheduler/ipp.c:7000
+#: scheduler/ipp.c:1306
 #, c-format
 msgid "Unable to add job for destination \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:4469 scheduler/ipp.c:4673 scheduler/ipp.c:4770
+#: scheduler/ipp.c:4739
 msgid "No subscription attributes in request!"
 msgstr ""
 
 #: scheduler/ipp.c:4559 scheduler/ipp.c:4763 scheduler/ipp.c:4869
+#: scheduler/ipp.c:4838
 msgid "notify-events not specified!"
 msgstr ""
 
 #: scheduler/ipp.c:4577 scheduler/ipp.c:4781 scheduler/ipp.c:4887
+#: scheduler/ipp.c:4856
 #, c-format
 msgid "Job %d not found!"
 msgstr ""
 
 #: scheduler/ipp.c:4827 scheduler/ipp.c:4957 scheduler/ipp.c:5075
+#: scheduler/ipp.c:5044
 msgid "No default printer"
 msgstr ""
 
 #: scheduler/ipp.c:4930 scheduler/ipp.c:5060 scheduler/ipp.c:5178
+#: scheduler/ipp.c:5147
 msgid "cups-deviced failed to execute."
 msgstr ""
 
 #: scheduler/ipp.c:5393 scheduler/ipp.c:5479 scheduler/ipp.c:5722
+#: scheduler/ipp.c:5691
 msgid "cups-driverd failed to execute."
 msgstr ""
 
 #: scheduler/ipp.c:5571 scheduler/ipp.c:5594 scheduler/ipp.c:5837
+#: scheduler/ipp.c:5806
 msgid "No destinations added."
 msgstr ""
 
 #: scheduler/ipp.c:5794 scheduler/ipp.c:5736 scheduler/ipp.c:2615
 #: scheduler/ipp.c:5530 scheduler/ipp.c:5979 scheduler/ipp.c:7840
+#: scheduler/ipp.c:3070 scheduler/ipp.c:5499 scheduler/ipp.c:5948
+#: scheduler/ipp.c:7330
 #, c-format
 msgid "notify-subscription-id %d no good!"
 msgstr ""
 
 #: scheduler/ipp.c:5878 scheduler/ipp.c:5822 scheduler/ipp.c:6065
+#: scheduler/ipp.c:6034
 #, c-format
 msgid "Job #%s does not exist!"
 msgstr ""
@@ -412,12 +478,17 @@ msgstr ""
 #: scheduler/ipp.c:2199 scheduler/ipp.c:2541 scheduler/ipp.c:5261
 #: scheduler/ipp.c:6087 scheduler/ipp.c:6251 scheduler/ipp.c:6429
 #: scheduler/ipp.c:6474 scheduler/ipp.c:7754 scheduler/ipp.c:7969
-#: scheduler/ipp.c:8208 scheduler/ipp.c:8713
+#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 scheduler/ipp.c:2654
+#: scheduler/ipp.c:2996 scheduler/ipp.c:5230 scheduler/ipp.c:6056
+#: scheduler/ipp.c:6220 scheduler/ipp.c:6398 scheduler/ipp.c:6443
+#: scheduler/ipp.c:7244 scheduler/ipp.c:7459 scheduler/ipp.c:7698
+#: scheduler/ipp.c:8205
 #, c-format
 msgid "Job #%d does not exist!"
 msgstr ""
 
 #: scheduler/ipp.c:5969 scheduler/ipp.c:5915 scheduler/ipp.c:6150
+#: scheduler/ipp.c:6119
 msgid "No subscriptions found."
 msgstr ""
 
@@ -428,6 +499,7 @@ msgstr ""
 
 #: scheduler/ipp.c:6203 scheduler/ipp.c:8315 scheduler/ipp.c:6250
 #: scheduler/ipp.c:8390 scheduler/ipp.c:6505 scheduler/ipp.c:8728
+#: scheduler/ipp.c:6474 scheduler/ipp.c:8220
 #, c-format
 msgid "Job #%d is finished and cannot be altered!"
 msgstr ""
@@ -438,27 +510,32 @@ msgid "You are not authorized to move job #%d owned by \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:6228 scheduler/ipp.c:6098 scheduler/ipp.c:6353
+#: scheduler/ipp.c:6322
 msgid "job-printer-uri attribute missing!"
 msgstr ""
 
 #: scheduler/ipp.c:6485 scheduler/ipp.c:7847 scheduler/ipp.c:6531
 #: scheduler/ipp.c:7913 scheduler/ipp.c:6783 scheduler/ipp.c:8238
+#: scheduler/ipp.c:6703 scheduler/ipp.c:7728
 #, c-format
 msgid "Unsupported compression \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:6504 scheduler/ipp.c:7866 scheduler/ipp.c:6550
 #: scheduler/ipp.c:7932 scheduler/ipp.c:6802 scheduler/ipp.c:8257
+#: scheduler/ipp.c:6722 scheduler/ipp.c:7747
 msgid "No file!?!"
 msgstr ""
 
 #: scheduler/ipp.c:6522 scheduler/ipp.c:6568 scheduler/ipp.c:6820
+#: scheduler/ipp.c:6740
 #, c-format
 msgid "Could not scan type \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:6574 scheduler/ipp.c:7936 scheduler/ipp.c:6620
 #: scheduler/ipp.c:8001 scheduler/ipp.c:6879 scheduler/ipp.c:8332
+#: scheduler/ipp.c:6799 scheduler/ipp.c:7822
 #, c-format
 msgid "Unsupported format '%s/%s'!"
 msgstr ""
@@ -473,6 +550,7 @@ msgid "Too many jobs - %d jobs, max jobs is %d."
 msgstr ""
 
 #: scheduler/ipp.c:7448 scheduler/ipp.c:7507 scheduler/ipp.c:7768
+#: scheduler/ipp.c:7258
 #, c-format
 msgid "Job #%d is not held!"
 msgstr ""
@@ -483,11 +561,13 @@ msgid "You are not authorized to release job id %d owned by \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:7592 scheduler/ipp.c:7654 scheduler/ipp.c:7983
+#: scheduler/ipp.c:7473
 #, c-format
 msgid "Job #%d is not complete!"
 msgstr ""
 
 #: scheduler/ipp.c:7608 scheduler/ipp.c:7670 scheduler/ipp.c:8001
+#: scheduler/ipp.c:7491
 #, c-format
 msgid "Job #%d cannot be restarted - no files!"
 msgstr ""
@@ -504,6 +584,7 @@ msgstr ""
 
 #: scheduler/ipp.c:7883 scheduler/ipp.c:8803 scheduler/ipp.c:7949
 #: scheduler/ipp.c:8883 scheduler/ipp.c:8274 scheduler/ipp.c:9225
+#: scheduler/ipp.c:7764 scheduler/ipp.c:8967
 #, c-format
 msgid "Bad document-format \"%s\"!"
 msgstr ""
@@ -514,34 +595,41 @@ msgid "You are not authorized to alter job id %d owned by \"%s\"!"
 msgstr ""
 
 #: scheduler/ipp.c:8371 scheduler/ipp.c:8446 scheduler/ipp.c:8783
+#: scheduler/ipp.c:8275
 #, c-format
 msgid "%s cannot be changed."
 msgstr ""
 
 #: scheduler/ipp.c:8387 scheduler/ipp.c:8462 scheduler/ipp.c:8799
+#: scheduler/ipp.c:8291
 msgid "Bad job-priority value!"
 msgstr ""
 
 #: scheduler/ipp.c:8395 scheduler/ipp.c:8470 scheduler/ipp.c:8807
+#: scheduler/ipp.c:8299
 msgid "Job is completed and cannot be changed."
 msgstr ""
 
 #: scheduler/ipp.c:8409 scheduler/ipp.c:8484 scheduler/ipp.c:8821
+#: scheduler/ipp.c:8313
 msgid "Bad job-state value!"
 msgstr ""
 
 #: scheduler/ipp.c:8423 scheduler/ipp.c:8435 scheduler/ipp.c:8446
 #: scheduler/ipp.c:8498 scheduler/ipp.c:8510 scheduler/ipp.c:8521
 #: scheduler/ipp.c:8835 scheduler/ipp.c:8850 scheduler/ipp.c:8861
+#: scheduler/ipp.c:8327 scheduler/ipp.c:8342 scheduler/ipp.c:8353
 msgid "Job state cannot be changed."
 msgstr ""
 
 #: scheduler/ipp.c:8787 scheduler/ipp.c:8867 scheduler/ipp.c:9209
+#: scheduler/ipp.c:8951
 #, c-format
 msgid "Unsupported compression attribute %s!"
 msgstr ""
 
 #: scheduler/ipp.c:8815 scheduler/ipp.c:8894 scheduler/ipp.c:9236
+#: scheduler/ipp.c:8978
 #, c-format
 msgid "Unsupported format \"%s\"!"
 msgstr ""
@@ -1028,6 +1116,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:307 systemv/cupstestppd.c:326
+#: systemv/cupstestppd.c:325
 #, c-format
 msgid "        WARN    %s has no corresponding options!\n"
 msgstr ""
@@ -1062,17 +1151,37 @@ msgstr ""
 #: systemv/cupstestppd.c:800 systemv/cupstestppd.c:820
 #: systemv/cupstestppd.c:851 systemv/cupstestppd.c:873
 #: systemv/cupstestppd.c:921 systemv/cupstestppd.c:950
-#: systemv/cupstestppd.c:971
+#: systemv/cupstestppd.c:971 systemv/cupstestppd.c:343
+#: systemv/cupstestppd.c:361 systemv/cupstestppd.c:376
+#: systemv/cupstestppd.c:412 systemv/cupstestppd.c:440
+#: systemv/cupstestppd.c:460 systemv/cupstestppd.c:482
+#: systemv/cupstestppd.c:502 systemv/cupstestppd.c:522
+#: systemv/cupstestppd.c:542 systemv/cupstestppd.c:560
+#: systemv/cupstestppd.c:578 systemv/cupstestppd.c:599
+#: systemv/cupstestppd.c:618 systemv/cupstestppd.c:638
+#: systemv/cupstestppd.c:658 systemv/cupstestppd.c:678
+#: systemv/cupstestppd.c:698 systemv/cupstestppd.c:716
+#: systemv/cupstestppd.c:733 systemv/cupstestppd.c:755
+#: systemv/cupstestppd.c:773 systemv/cupstestppd.c:790
+#: systemv/cupstestppd.c:808 systemv/cupstestppd.c:824
+#: systemv/cupstestppd.c:844 systemv/cupstestppd.c:875
+#: systemv/cupstestppd.c:897 systemv/cupstestppd.c:945
+#: systemv/cupstestppd.c:974 systemv/cupstestppd.c:995
+#: systemv/cupstestppd.c:1050 systemv/cupstestppd.c:1075
+#: systemv/cupstestppd.c:1095 systemv/cupstestppd.c:1116
+#: systemv/cupstestppd.c:1138 systemv/cupstestppd.c:1172
 msgid " FAIL\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:321 systemv/cupstestppd.c:340
+#: systemv/cupstestppd.c:364
 msgid ""
 "      **FAIL**  REQUIRED DefaultImageableArea\n"
 "                REF: Page 102, section 5.15.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:336 systemv/cupstestppd.c:355
+#: systemv/cupstestppd.c:379
 #, c-format
 msgid ""
 "      **FAIL**  BAD DefaultImageableArea %s!\n"
@@ -1080,16 +1189,19 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:346 systemv/cupstestppd.c:365
+#: systemv/cupstestppd.c:389
 msgid "        PASS    DefaultImageableArea\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:357 systemv/cupstestppd.c:376
+#: systemv/cupstestppd.c:400
 msgid ""
 "      **FAIL**  REQUIRED DefaultPaperDimension\n"
 "                REF: Page 103, section 5.15.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:372 systemv/cupstestppd.c:391
+#: systemv/cupstestppd.c:415
 #, c-format
 msgid ""
 "      **FAIL**  BAD DefaultPaperDimension %s!\n"
@@ -1097,10 +1209,12 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:380 systemv/cupstestppd.c:399
+#: systemv/cupstestppd.c:423
 msgid "        PASS    DefaultPaperDimension\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:400 systemv/cupstestppd.c:419
+#: systemv/cupstestppd.c:443
 #, c-format
 msgid ""
 "      **FAIL**  BAD Default%s %s\n"
@@ -1108,11 +1222,13 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:409 systemv/cupstestppd.c:428
+#: systemv/cupstestppd.c:452
 #, c-format
 msgid "        PASS    Default%s\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:420 systemv/cupstestppd.c:439
+#: systemv/cupstestppd.c:463
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED Default%s\n"
@@ -1120,62 +1236,74 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:432 systemv/cupstestppd.c:451
+#: systemv/cupstestppd.c:475
 msgid "        PASS    FileVersion\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:442 systemv/cupstestppd.c:461
+#: systemv/cupstestppd.c:485
 msgid ""
 "      **FAIL**  REQUIRED FileVersion\n"
 "                REF: Page 56, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:452 systemv/cupstestppd.c:471
+#: systemv/cupstestppd.c:495
 msgid "        PASS    FormatVersion\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:462 systemv/cupstestppd.c:481
+#: systemv/cupstestppd.c:505
 msgid ""
 "      **FAIL**  REQUIRED FormatVersion\n"
 "                REF: Page 56, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:472 systemv/cupstestppd.c:491
+#: systemv/cupstestppd.c:515
 msgid "        PASS    LanguageEncoding\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:482 systemv/cupstestppd.c:501
+#: systemv/cupstestppd.c:525
 msgid ""
 "      **FAIL**  REQUIRED LanguageEncoding\n"
 "                REF: Pages 56-57, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:492 systemv/cupstestppd.c:511
+#: systemv/cupstestppd.c:535
 msgid "        PASS    LanguageVersion\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:502 systemv/cupstestppd.c:521
+#: systemv/cupstestppd.c:545
 msgid ""
 "      **FAIL**  REQUIRED LanguageVersion\n"
 "                REF: Pages 57-58, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:520 systemv/cupstestppd.c:539
+#: systemv/cupstestppd.c:563
 msgid ""
 "      **FAIL**  BAD Manufacturer (should be \"HP\")\n"
 "                REF: Page 211, table D.1.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:528 systemv/cupstestppd.c:547
+#: systemv/cupstestppd.c:571
 msgid "        PASS    Manufacturer\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:538 systemv/cupstestppd.c:557
+#: systemv/cupstestppd.c:581
 msgid ""
 "      **FAIL**  REQUIRED Manufacturer\n"
 "                REF: Pages 58-59, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:559 systemv/cupstestppd.c:578
+#: systemv/cupstestppd.c:602
 #, c-format
 msgid ""
 "      **FAIL**  BAD ModelName - \"%c\" not allowed in string.\n"
@@ -1183,110 +1311,131 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:568 systemv/cupstestppd.c:587
+#: systemv/cupstestppd.c:611
 msgid "        PASS    ModelName\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:578 systemv/cupstestppd.c:597
+#: systemv/cupstestppd.c:621
 msgid ""
 "      **FAIL**  REQUIRED ModelName\n"
 "                REF: Pages 59-60, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:588 systemv/cupstestppd.c:607
+#: systemv/cupstestppd.c:631
 msgid "        PASS    NickName\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:598 systemv/cupstestppd.c:617
+#: systemv/cupstestppd.c:641
 msgid ""
 "      **FAIL**  REQUIRED NickName\n"
 "                REF: Page 60, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:608 systemv/cupstestppd.c:627
+#: systemv/cupstestppd.c:651
 msgid "        PASS    PageSize\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:618 systemv/cupstestppd.c:637
+#: systemv/cupstestppd.c:661
 msgid ""
 "      **FAIL**  REQUIRED PageSize\n"
 "                REF: Pages 99-100, section 5.14.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:628 systemv/cupstestppd.c:647
+#: systemv/cupstestppd.c:671
 msgid "        PASS    PageRegion\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:638 systemv/cupstestppd.c:657
+#: systemv/cupstestppd.c:681
 msgid ""
 "      **FAIL**  REQUIRED PageRegion\n"
 "                REF: Page 100, section 5.14.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:648 systemv/cupstestppd.c:667
+#: systemv/cupstestppd.c:691
 msgid "        PASS    PCFileName\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:658 systemv/cupstestppd.c:677
+#: systemv/cupstestppd.c:701
 msgid ""
 "      **FAIL**  REQUIRED PCFileName\n"
 "                REF: Pages 61-62, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:676 systemv/cupstestppd.c:695
+#: systemv/cupstestppd.c:719
 msgid ""
 "      **FAIL**  BAD Product - not \"(string)\".\n"
 "                REF: Page 62, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:683 systemv/cupstestppd.c:702
+#: systemv/cupstestppd.c:726
 msgid "        PASS    Product\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:693 systemv/cupstestppd.c:712
+#: systemv/cupstestppd.c:736
 msgid ""
 "      **FAIL**  REQUIRED Product\n"
 "                REF: Page 62, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:715 systemv/cupstestppd.c:734
+#: systemv/cupstestppd.c:758
 msgid ""
 "      **FAIL**  BAD PSVersion - not \"(string) int\".\n"
 "                REF: Pages 62-64, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:723 systemv/cupstestppd.c:742
+#: systemv/cupstestppd.c:766
 msgid "        PASS    PSVersion\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:733 systemv/cupstestppd.c:752
+#: systemv/cupstestppd.c:776
 msgid ""
 "      **FAIL**  REQUIRED PSVersion\n"
 "                REF: Pages 62-64, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:750 systemv/cupstestppd.c:769
+#: systemv/cupstestppd.c:793
 msgid ""
 "      **FAIL**  BAD ShortNickName - longer than 31 chars.\n"
 "                REF: Pages 64-65, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:758 systemv/cupstestppd.c:777
+#: systemv/cupstestppd.c:801
 msgid "        PASS    ShortNickName\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:768 systemv/cupstestppd.c:787
+#: systemv/cupstestppd.c:811
 msgid ""
 "      **FAIL**  REQUIRED ShortNickName\n"
 "                REF: Page 64-65, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:784 systemv/cupstestppd.c:803
+#: systemv/cupstestppd.c:827
 msgid ""
 "      **FAIL**  BAD JobPatchFile attribute in file\n"
 "                REF: Page 24, section 3.4.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:804 systemv/cupstestppd.c:823
+#: systemv/cupstestppd.c:847
 msgid ""
 "      **FAIL**  REQUIRED PageSize\n"
 "                REF: Page 41, section 5.\n"
@@ -1294,6 +1443,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:835 systemv/cupstestppd.c:854
+#: systemv/cupstestppd.c:878
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED ImageableArea for PageSize %s\n"
@@ -1302,6 +1452,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:857 systemv/cupstestppd.c:876
+#: systemv/cupstestppd.c:900
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED PaperDimension for PageSize %s\n"
@@ -1310,6 +1461,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:905 systemv/cupstestppd.c:924
+#: systemv/cupstestppd.c:948
 #, c-format
 msgid ""
 "      **FAIL**  Bad %s choice %s!\n"
@@ -1317,6 +1469,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:934 systemv/cupstestppd.c:953
+#: systemv/cupstestppd.c:977
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED %s does not define choice None!\n"
@@ -1324,6 +1477,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:955 systemv/cupstestppd.c:974
+#: systemv/cupstestppd.c:998
 #, c-format
 msgid ""
 "      **FAIL**  Bad %s choice %s!\n"
@@ -1331,10 +1485,12 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:967 systemv/cupstestppd.c:986
+#: systemv/cupstestppd.c:1186
 msgid " PASS\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:976 systemv/cupstestppd.c:997
+#: systemv/cupstestppd.c:1197
 #, c-format
 msgid ""
 "        WARN    Duplex option keyword %s should be named Duplex or JCLDuplex!\n"
@@ -1342,10 +1498,12 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:986 systemv/cupstestppd.c:1007
+#: systemv/cupstestppd.c:1207
 msgid "        WARN    Default choices conflicting!\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:994 systemv/cupstestppd.c:1015
+#: systemv/cupstestppd.c:1215
 #, c-format
 msgid ""
 "        WARN    Obsolete PPD version %.1f!\n"
@@ -1353,42 +1511,49 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:1002 systemv/cupstestppd.c:1023
+#: systemv/cupstestppd.c:1223
 msgid ""
 "        WARN    LanguageEncoding required by PPD 4.3 spec.\n"
 "                REF: Pages 56-57, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1010 systemv/cupstestppd.c:1031
+#: systemv/cupstestppd.c:1231
 msgid ""
 "        WARN    Manufacturer required by PPD 4.3 spec.\n"
 "                REF: Pages 58-59, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1023 systemv/cupstestppd.c:1044
+#: systemv/cupstestppd.c:1244
 msgid ""
 "        WARN    PCFileName longer than 8.3 in violation of PPD spec.\n"
 "                REF: Pages 61-62, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1031 systemv/cupstestppd.c:1052
+#: systemv/cupstestppd.c:1252
 msgid ""
 "        WARN    ShortNickName required by PPD 4.3 spec.\n"
 "                REF: Pages 64-65, section 5.3.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1069
+#: systemv/cupstestppd.c:1269
 msgid ""
 "        WARN    Protocols contains both PJL and BCP; expected TBCP.\n"
 "                REF: Pages 78-79, section 5.7.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1057 systemv/cupstestppd.c:1078
+#: systemv/cupstestppd.c:1278
 msgid ""
 "        WARN    Protocols contains PJL but JCL attributes are not set.\n"
 "                REF: Pages 78-79, section 5.7.\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1085 systemv/cupstestppd.c:1106
+#: systemv/cupstestppd.c:1306
 #, c-format
 msgid ""
 "        WARN    %s shares a common prefix with %s\n"
@@ -1396,15 +1561,18 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:1097 systemv/cupstestppd.c:1118
+#: systemv/cupstestppd.c:1318
 #, c-format
 msgid "    %d ERROR%s FOUND\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1100 systemv/cupstestppd.c:1121
+#: systemv/cupstestppd.c:1321
 msgid "    NO ERRORS FOUND\n"
 msgstr ""
 
 #: systemv/cupstestppd.c:1360 systemv/cupstestppd.c:1465
+#: systemv/cupstestppd.c:1665
 #, c-format
 msgid ""
 "        WARN    \"%s %s\" conflicts with \"%s %s\"\n"
@@ -1412,6 +1580,7 @@ msgid ""
 msgstr ""
 
 #: systemv/cupstestppd.c:1376 systemv/cupstestppd.c:1481
+#: systemv/cupstestppd.c:1681
 msgid ""
 "Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n"
 "       program | cupstestppd [-q] [-r] [-v[v]] -\n"
@@ -1942,12 +2111,12 @@ msgstr ""
 msgid "lpadmin: add-printer (set location) failed: %s\n"
 msgstr ""
 
-#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814
+#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 systemv/lpadmin.c:1831
 #, c-format
 msgid "lpadmin: Unable to create temporary file - %s\n"
 msgstr ""
 
-#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824
+#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 systemv/lpadmin.c:1841
 #, c-format
 msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n"
 msgstr ""
@@ -2439,7 +2608,7 @@ msgid "Edit Configuration File"
 msgstr ""
 
 #: cgi-bin/admin.c:2135 cgi-bin/admin.c:2147 cgi-bin/admin.c:2179
-#: cgi-bin/admin.c:2191
+#: cgi-bin/admin.c:2191 cgi-bin/printers.c:219
 msgid "Unable to create temporary file:"
 msgstr ""
 
@@ -2562,15 +2731,16 @@ msgstr ""
 msgid "Unable to change printer-is-shared attribute:"
 msgstr ""
 
-#: cgi-bin/classes.c:161 cgi-bin/classes.c:208
+#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 cgi-bin/classes.c:159
+#: cgi-bin/classes.c:206
 msgid "Classes"
 msgstr ""
 
-#: cgi-bin/classes.c:355 cgi-bin/classes.c:356
+#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 cgi-bin/classes.c:354
 msgid "Unable to get class list:"
 msgstr ""
 
-#: cgi-bin/classes.c:454 cgi-bin/classes.c:455
+#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 cgi-bin/classes.c:453
 msgid "Unable to get class status:"
 msgstr ""
 
@@ -2612,114 +2782,115 @@ msgid "Job operation failed:"
 msgstr ""
 
 #: cgi-bin/printers.c:161 cgi-bin/printers.c:208 cgi-bin/printers.c:211
+#: cgi-bin/printers.c:166 cgi-bin/printers.c:335
 msgid "Printers"
 msgstr ""
 
-#: cgi-bin/printers.c:362 cgi-bin/printers.c:366
+#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 cgi-bin/printers.c:518
 msgid "Unable to get printer list:"
 msgstr ""
 
-#: cgi-bin/printers.c:461 cgi-bin/printers.c:468
+#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 cgi-bin/printers.c:628
 msgid "Unable to get printer status:"
 msgstr ""
 
-#: cups/ppd.c:319
+#: cups/ppd.c:319 cups/ppd.c:302
 msgid "OK"
 msgstr ""
 
-#: cups/ppd.c:320
+#: cups/ppd.c:320 cups/ppd.c:303
 msgid "Unable to open PPD file"
 msgstr ""
 
-#: cups/ppd.c:321
+#: cups/ppd.c:321 cups/ppd.c:304
 msgid "NULL PPD file pointer"
 msgstr ""
 
-#: cups/ppd.c:322
+#: cups/ppd.c:322 cups/ppd.c:305
 msgid "Memory allocation error"
 msgstr ""
 
-#: cups/ppd.c:323
+#: cups/ppd.c:323 cups/ppd.c:306
 msgid "Missing PPD-Adobe-4.x header"
 msgstr ""
 
-#: cups/ppd.c:324
+#: cups/ppd.c:324 cups/ppd.c:307
 msgid "Missing value string"
 msgstr ""
 
-#: cups/ppd.c:325
+#: cups/ppd.c:325 cups/ppd.c:308
 msgid "Internal error"
 msgstr ""
 
-#: cups/ppd.c:326
+#: cups/ppd.c:326 cups/ppd.c:309
 msgid "Bad OpenGroup"
 msgstr ""
 
-#: cups/ppd.c:327
+#: cups/ppd.c:327 cups/ppd.c:310
 msgid "OpenGroup without a CloseGroup first"
 msgstr ""
 
-#: cups/ppd.c:328
+#: cups/ppd.c:328 cups/ppd.c:311
 msgid "Bad OpenUI/JCLOpenUI"
 msgstr ""
 
-#: cups/ppd.c:329
+#: cups/ppd.c:329 cups/ppd.c:312
 msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first"
 msgstr ""
 
-#: cups/ppd.c:330
+#: cups/ppd.c:330 cups/ppd.c:313
 msgid "Bad OrderDependency"
 msgstr ""
 
-#: cups/ppd.c:331
+#: cups/ppd.c:331 cups/ppd.c:314
 msgid "Bad UIConstraints"
 msgstr ""
 
-#: cups/ppd.c:332
+#: cups/ppd.c:332 cups/ppd.c:315
 msgid "Missing asterisk in column 1"
 msgstr ""
 
-#: cups/ppd.c:333
+#: cups/ppd.c:333 cups/ppd.c:316
 msgid "Line longer than the maximum allowed (255 characters)"
 msgstr ""
 
-#: cups/ppd.c:334
+#: cups/ppd.c:334 cups/ppd.c:317
 msgid "Illegal control character"
 msgstr ""
 
-#: cups/ppd.c:335
+#: cups/ppd.c:335 cups/ppd.c:318
 msgid "Illegal main keyword string"
 msgstr ""
 
-#: cups/ppd.c:336
+#: cups/ppd.c:336 cups/ppd.c:319
 msgid "Illegal option keyword string"
 msgstr ""
 
-#: cups/ppd.c:337
+#: cups/ppd.c:337 cups/ppd.c:320
 msgid "Illegal translation string"
 msgstr ""
 
-#: cups/ppd.c:338
+#: cups/ppd.c:338 cups/ppd.c:321
 msgid "Illegal whitespace character"
 msgstr ""
 
-#: cups/ppd.c:339
+#: cups/ppd.c:339 cups/ppd.c:322
 msgid "Bad custom parameter"
 msgstr ""
 
-#: cups/ppd.c:344
+#: cups/ppd.c:344 cups/ppd.c:327
 msgid "Unknown"
 msgstr ""
 
-#: cups/ppd.c:1033
+#: cups/ppd.c:1033 cups/ppd.c:1020
 msgid "Custom"
 msgstr ""
 
-#: cups/ppd.c:1259
+#: cups/ppd.c:1259 cups/ppd.c:1236
 msgid "JCL"
 msgstr ""
 
-#: scheduler/ipp.c:2184 scheduler/ipp.c:2226
+#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 scheduler/ipp.c:2681
 msgid "No authentication information provided!"
 msgstr ""
 
@@ -3133,11 +3304,11 @@ msgstr ""
 msgid "idle"
 msgstr ""
 
-#: scheduler/ipp.c:5513
+#: scheduler/ipp.c:5513 scheduler/ipp.c:5482
 msgid "Missing notify-subscription-ids attribute!"
 msgstr ""
 
-#: scheduler/ipp.c:7851
+#: scheduler/ipp.c:7851 scheduler/ipp.c:7341
 msgid "Job subscriptions cannot be renewed!"
 msgstr ""
 
@@ -3159,7 +3330,7 @@ msgstr ""
 msgid "cupsd: Unknown argument \"%s\" - aborting!\n"
 msgstr ""
 
-#: scheduler/main.c:2315
+#: scheduler/main.c:2315 scheduler/main.c:2329
 msgid ""
 "Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n"
 "\n"
@@ -3170,19 +3341,67 @@ msgid ""
 "-l                  Run cupsd from launchd(8)\n"
 msgstr ""
 
-#: systemv/cupstestppd.c:1343
+#: systemv/cupstestppd.c:1343 systemv/cupstestppd.c:1543
 #, c-format
 msgid "        WARN    Line %d only contains whitespace!\n"
 msgstr ""
 
-#: systemv/cupstestppd.c:1361
+#: systemv/cupstestppd.c:1361 systemv/cupstestppd.c:1561
 msgid "        WARN    File contains a mix of CR, LF, and CR LF line endings!\n"
 msgstr ""
 
-#: systemv/cupstestppd.c:1366
+#: systemv/cupstestppd.c:1366 systemv/cupstestppd.c:1566
 msgid "        WARN    Non-Windows PPD files should use lines ending with only LF, not CR LF!\n"
 msgstr ""
 
+#: cgi-bin/printers.c:218 cgi-bin/printers.c:289
+msgid "Printer Maintenance"
+msgstr ""
+
+#: cgi-bin/printers.c:292
+msgid "Unable to send maintenance job:"
+msgstr ""
+
+#: systemv/cupsaddsmb.c:566
+#, c-format
+msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:346
+#, c-format
+msgid "      **FAIL**  %s %s does not exist!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1053
+#, c-format
+msgid "      **FAIL**  Bad language \"%s\"!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1078
+#, c-format
+msgid "      **FAIL**  Missing \"%s\" translation string for option %s!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1098
+#, c-format
+msgid "      **FAIL**  Default translation string for option %s contains 8-bit characters!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1119
+#, c-format
+msgid "      **FAIL**  Missing \"%s\" translation string for option %s, choice %s!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1141
+#, c-format
+msgid "      **FAIL**  Default translation string for option %s choice %s contains 8-bit characters!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1175
+#, c-format
+msgid "      **FAIL**  Bad cupsFilter value \"%s\"!\n"
+msgstr ""
+
 
 #
 # End of "$Id$".
diff --git a/locale/cups_fr.po b/locale/cups_fr.po
deleted file mode 100644 (file)
index c5a5e6c..0000000
+++ /dev/null
@@ -1,3245 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: CUPS 1.2\n"
-"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n"
-"POT-Creation-Date: 2006-02-15 19:50-0500\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: cgi-bin/admin.c:1276 cgi-bin/admin.c:1154 cgi-bin/admin.c:1195
-msgid "Options Installed"
-msgstr "Options Installées"
-
-#: cgi-bin/classes.c:103
-msgid "Class"
-msgstr "Classe"
-
-#: cgi-bin/printers.c:104
-msgid "Printer"
-msgstr "Imprimeur"
-
-#: cups/ppd.c:654 cups/ppd.c:1045 cups/ppd.c:660 cups/ppd.c:1167
-msgid "Extra"
-msgstr "Supplémentaire"
-
-#: cups/ppd.c:656 cups/ppd.c:881 cups/ppd.c:1047 cups/ppd.c:662 cups/ppd.c:996
-#: cups/ppd.c:1169
-msgid "General"
-msgstr "Généralités"
-
-#: cups/ppd.c:704 cups/ppd.c:1105 cups/ppd.c:710 cups/ppd.c:1224
-msgid "Media Size"
-msgstr "Taille De Médias"
-
-#: cups/ppd.c:706 cups/ppd.c:1107 cups/ppd.c:712 cups/ppd.c:1226
-msgid "Media Type"
-msgstr "Type De Supports"
-
-#: cups/ppd.c:708 cups/ppd.c:1109 cups/ppd.c:714 cups/ppd.c:1228
-msgid "Media Source"
-msgstr "Source De Médias"
-
-#: cups/ppd.c:710 cups/ppd.c:1111 cups/ppd.c:716 cups/ppd.c:1230
-msgid "Output Mode"
-msgstr "Mode De Rendement"
-
-#: cups/ppd.c:712 cups/ppd.c:1113 cups/ppd.c:718 cups/ppd.c:1232
-msgid "Resolution"
-msgstr "Résolution"
-
-#: cups/ppd.c:907
-msgid "Variable"
-msgstr "Variable"
-
-#: cups/ppd.c:1535 cups/ppd.c:1650
-msgid "Yes"
-msgstr "Oui"
-
-#: cups/ppd.c:1537 cups/ppd.c:1652
-msgid "No"
-msgstr "Non"
-
-#: cups/ppd.c:1824
-msgid "Auto"
-msgstr "Automobile"
-
-#: scheduler/client.c:2247 scheduler/client.c:2251 scheduler/client.c:2274
-msgid ""
-"Enter your username and password or the root username and password to access "
-"this page."
-msgstr ""
-"Entrez votre username et mot de passe ou le username de racine et le mot de "
-"passe pour accéder à cette page."
-
-#: scheduler/client.c:2252 scheduler/client.c:2256 scheduler/client.c:2279
-msgid "You must use a https: URL to access this page."
-msgstr "Vous devez employer des https:  URL pour accéder à cette page."
-
-#: scheduler/ipp.c:236 scheduler/ipp.c:244 scheduler/ipp.c:246
-#, c-format
-msgid "Bad request version number %d.%d!"
-msgstr "Mauvais nombre de version de demande %d.%d!"
-
-#: scheduler/ipp.c:246 scheduler/ipp.c:254 scheduler/ipp.c:256
-msgid "No attributes in request!"
-msgstr "Aucuns attributs dans la demande!"
-
-#: scheduler/ipp.c:269 scheduler/ipp.c:277 scheduler/ipp.c:279
-#, c-format
-msgid "Attribute groups are out of order (%x < %x)!"
-msgstr "Les groupes d'attribut sont en panne (%x < %x)!"
-
-#: scheduler/ipp.c:379 scheduler/ipp.c:389 scheduler/ipp.c:391
-msgid "Missing required attributes!"
-msgstr "Attributs requis manquants!"
-
-#: scheduler/ipp.c:575 scheduler/ipp.c:585 scheduler/ipp.c:591
-#, c-format
-msgid "%s not supported!"
-msgstr "%s non soutenu!"
-
-#: scheduler/ipp.c:684 scheduler/ipp.c:1055 scheduler/ipp.c:2271
-#: scheduler/ipp.c:2383 scheduler/ipp.c:3707 scheduler/ipp.c:4417
-#: scheduler/ipp.c:4649 scheduler/ipp.c:5002 scheduler/ipp.c:5445
-#: scheduler/ipp.c:5890 scheduler/ipp.c:6245 scheduler/ipp.c:6609
-#: scheduler/ipp.c:7308 scheduler/ipp.c:8179 scheduler/ipp.c:8585
-#: scheduler/ipp.c:8663 scheduler/ipp.c:8836 scheduler/ipp.c:696
-#: scheduler/ipp.c:1079 scheduler/ipp.c:2318 scheduler/ipp.c:2433
-#: scheduler/ipp.c:3901 scheduler/ipp.c:4621 scheduler/ipp.c:4855
-#: scheduler/ipp.c:5237 scheduler/ipp.c:5526 scheduler/ipp.c:5834
-#: scheduler/ipp.c:6113 scheduler/ipp.c:6155 scheduler/ipp.c:6657
-#: scheduler/ipp.c:7365 scheduler/ipp.c:8251 scheduler/ipp.c:8662
-#: scheduler/ipp.c:8742 scheduler/ipp.c:8917 scheduler/ipp.c:702
-#: scheduler/ipp.c:1093 scheduler/ipp.c:2357 scheduler/ipp.c:2472
-#: scheduler/ipp.c:3993 scheduler/ipp.c:4730 scheduler/ipp.c:4973
-#: scheduler/ipp.c:5357 scheduler/ipp.c:5769 scheduler/ipp.c:6077
-#: scheduler/ipp.c:6368 scheduler/ipp.c:6410 scheduler/ipp.c:6916
-#: scheduler/ipp.c:7626 scheduler/ipp.c:8589 scheduler/ipp.c:9003
-#: scheduler/ipp.c:9084 scheduler/ipp.c:9259
-msgid "The printer or class was not found."
-msgstr "L'imprimeur ou la classe n'a pas été trouvé."
-
-#: scheduler/ipp.c:762 scheduler/ipp.c:777 scheduler/ipp.c:784
-msgid ""
-"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"."
-msgstr ""
-"L'printer-uri doit être de la forme \"ipp://HOSTNAME/classes/CLASSNAME\"."
-
-#: scheduler/ipp.c:778 scheduler/ipp.c:1454 scheduler/ipp.c:793
-#: scheduler/ipp.c:1482 scheduler/ipp.c:800 scheduler/ipp.c:1515
-#, c-format
-msgid "The printer-uri \"%s\" contains invalid characters."
-msgstr "L'printer-uri \"%s\" contient les caractères inadmissibles."
-
-#: scheduler/ipp.c:811 scheduler/ipp.c:826 scheduler/ipp.c:833
-#, c-format
-msgid "A printer named \"%s\" already exists!"
-msgstr "Un imprimeur appelé \"%s\" existe déjà!"
-
-#: scheduler/ipp.c:904 scheduler/ipp.c:924 scheduler/ipp.c:933
-#, c-format
-msgid "Attempt to set %s printer-state to bad value %d!"
-msgstr "Essayez de placer l'imprimeur-état de %s à la mauvaise valeur %d!"
-
-#: scheduler/ipp.c:1000 scheduler/ipp.c:1022 scheduler/ipp.c:1034
-#, c-format
-msgid "add_class: Unknown printer-op-policy \"%s\"."
-msgstr "add_class:  printer-op-policy inconnue \"%s\"."
-
-#: scheduler/ipp.c:1013 scheduler/ipp.c:1035 scheduler/ipp.c:1047
-#, c-format
-msgid "add_class: Unknown printer-error-policy \"%s\"."
-msgstr "add_class:  printer-error-policy inconnue \"%s\"."
-
-#: scheduler/ipp.c:1144 scheduler/ipp.c:1168 scheduler/ipp.c:1200
-msgid "Unable to allocate memory for file types!"
-msgstr "Incapable d'assigner la mémoire pour des types de dossier!"
-
-#: scheduler/ipp.c:1290 scheduler/ipp.c:4501 scheduler/ipp.c:1316
-#: scheduler/ipp.c:4705 scheduler/ipp.c:1348 scheduler/ipp.c:4804
-#, c-format
-msgid "Character set \"%s\" not supported!"
-msgstr "Jeu de caractères \"%s\" non soutenu!"
-
-#: scheduler/ipp.c:1299 scheduler/ipp.c:4510 scheduler/ipp.c:1325
-#: scheduler/ipp.c:4714 scheduler/ipp.c:1357 scheduler/ipp.c:4813
-#, c-format
-msgid "Language \"%s\" not supported!"
-msgstr "Langue \"%s\" non soutenue!"
-
-#: scheduler/ipp.c:1309 scheduler/ipp.c:4520 scheduler/ipp.c:1335
-#: scheduler/ipp.c:4724 scheduler/ipp.c:1367 scheduler/ipp.c:4823
-#, c-format
-msgid "The notify-user-data value is too large (%d > 63 octets)!"
-msgstr "La valeur de notify-user-data est trop grande (%d > 63 octets)!"
-
-#: scheduler/ipp.c:1326 scheduler/ipp.c:1352 scheduler/ipp.c:1384
-msgid ""
-"The notify-lease-duration attribute cannot be used with job subscriptions."
-msgstr ""
-"L'attribut de notify-lease-duration ne peut pas être employé avec des "
-"abonnements du travail."
-
-#: scheduler/ipp.c:1438 scheduler/ipp.c:1466 scheduler/ipp.c:1499
-msgid ""
-"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"."
-msgstr ""
-"L'printer-uri doit être de la forme \"ipp://HOSTNAME/printers/PRINTERNAME\"."
-
-#: scheduler/ipp.c:1487 scheduler/ipp.c:1515 scheduler/ipp.c:1548
-#, c-format
-msgid "A class named \"%s\" already exists!"
-msgstr "Une classe appelée \"%s\" existe déjà!"
-
-#: scheduler/ipp.c:1575 scheduler/ipp.c:1607 scheduler/ipp.c:1644
-#, c-format
-msgid ""
-"File device URIs have been disabled! To enable, see the FileDevice directive "
-"in \"%s/cupsd.conf\"."
-msgstr ""
-"Le dispositif URIs de dossier ont été neutralisés!  Pour permettre, voyez la "
-"directive de FileDevice dans \"%s/cupsd.conf\"."
-
-#: scheduler/ipp.c:1595 scheduler/ipp.c:1627 scheduler/ipp.c:1664
-#, c-format
-msgid "Bad device-uri \"%s\"!"
-msgstr "Mauvais device-uri \"%s\"!"
-
-#: scheduler/ipp.c:1626 scheduler/ipp.c:1659 scheduler/ipp.c:1698
-#, c-format
-msgid "Bad port-monitor \"%s\"!"
-msgstr "Mauvais port-monitor \"%s\"!"
-
-#: scheduler/ipp.c:1669 scheduler/ipp.c:1705 scheduler/ipp.c:1744
-#, c-format
-msgid "Bad printer-state value %d!"
-msgstr "Mauvaise valeur %d de printer-state!"
-
-#: scheduler/ipp.c:1762 scheduler/ipp.c:1800 scheduler/ipp.c:1842
-#, c-format
-msgid "Unknown printer-op-policy \"%s\"."
-msgstr "printer-op-policy inconnue \"%s\"."
-
-#: scheduler/ipp.c:1775 scheduler/ipp.c:1813 scheduler/ipp.c:1855
-#, c-format
-msgid "Unknown printer-error-policy \"%s\"."
-msgstr "printer-error-policy inconnue \"%s\"."
-
-#: scheduler/ipp.c:1837 scheduler/ipp.c:1875 scheduler/ipp.c:1919
-#, c-format
-msgid "Unable to copy interface script - %s!"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: scheduler/ipp.c:1862 scheduler/ipp.c:1900 scheduler/ipp.c:1944
-#, c-format
-msgid "Unable to copy PPD file - %s!"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: scheduler/ipp.c:1915 scheduler/ipp.c:1954 scheduler/ipp.c:2000
-msgid "Unable to copy PPD file!"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: scheduler/ipp.c:2076 scheduler/ipp.c:2364 scheduler/ipp.c:5188
-#: scheduler/ipp.c:6008 scheduler/ipp.c:6147 scheduler/ipp.c:7394
-#: scheduler/ipp.c:7538 scheduler/ipp.c:7776 scheduler/ipp.c:8261
-#: scheduler/ipp.c:2116 scheduler/ipp.c:2412 scheduler/ipp.c:5102
-#: scheduler/ipp.c:5955 scheduler/ipp.c:7452 scheduler/ipp.c:7599
-#: scheduler/ipp.c:7839 scheduler/ipp.c:8334 scheduler/ipp.c:2158
-#: scheduler/ipp.c:2451 scheduler/ipp.c:5220 scheduler/ipp.c:6210
-#: scheduler/ipp.c:7713 scheduler/ipp.c:7928 scheduler/ipp.c:8167
-#: scheduler/ipp.c:8672
-msgid "Got a printer-uri attribute but no job-id!"
-msgstr "N'a obtenu un attribut de printer-uri mais aucune job-id!"
-
-#: scheduler/ipp.c:2097 scheduler/ipp.c:2433 scheduler/ipp.c:5210
-#: scheduler/ipp.c:6029 scheduler/ipp.c:6169 scheduler/ipp.c:7416
-#: scheduler/ipp.c:7560 scheduler/ipp.c:7797 scheduler/ipp.c:8282
-#: scheduler/ipp.c:2138 scheduler/ipp.c:2484 scheduler/ipp.c:5125
-#: scheduler/ipp.c:5978 scheduler/ipp.c:6201 scheduler/ipp.c:7475
-#: scheduler/ipp.c:7622 scheduler/ipp.c:7862 scheduler/ipp.c:8357
-#: scheduler/ipp.c:2180 scheduler/ipp.c:2523 scheduler/ipp.c:5243
-#: scheduler/ipp.c:6233 scheduler/ipp.c:6456 scheduler/ipp.c:7736
-#: scheduler/ipp.c:7951 scheduler/ipp.c:8190 scheduler/ipp.c:8695
-#, c-format
-msgid "Bad job-uri attribute \"%s\"!"
-msgstr "Mauvais attribut \"%s\" de job-uri!"
-
-#: scheduler/ipp.c:2116 scheduler/ipp.c:2451 scheduler/ipp.c:5228
-#: scheduler/ipp.c:6047 scheduler/ipp.c:6188 scheduler/ipp.c:7434
-#: scheduler/ipp.c:7578 scheduler/ipp.c:7815 scheduler/ipp.c:8300
-#, c-format
-msgid "Job #%d doesn't exist!"
-msgstr "Le travail # %d n'existe pas!"
-
-#: scheduler/ipp.c:2131 scheduler/ipp.c:2172 scheduler/ipp.c:2214
-#, c-format
-msgid "Job #%d is not held for authentication!"
-msgstr "Le travail # %d n'est pas tenu pour l'authentification!"
-
-#: scheduler/ipp.c:2153 scheduler/ipp.c:2195
-#, c-format
-msgid "You are not authorized to authenticate job #%d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à authentifier le travail # %d possédés par \"%s\"!"
-
-#: scheduler/ipp.c:2221 scheduler/ipp.c:2264 scheduler/ipp.c:2303
-msgid "The printer-uri attribute is required!"
-msgstr "L'attribut de printer-uri est exigé!"
-
-#: scheduler/ipp.c:2238 scheduler/ipp.c:2283 scheduler/ipp.c:2322
-msgid "Missing requesting-user-name attribute!"
-msgstr "Attribut absent de requesting-user-name!"
-
-#: scheduler/ipp.c:2277 scheduler/ipp.c:2324 scheduler/ipp.c:2363
-#, c-format
-msgid "The printer-uri \"%s\" is not valid."
-msgstr "L'printer-uri \"%s\" est inadmissible."
-
-#: scheduler/ipp.c:2410 scheduler/ipp.c:2460 scheduler/ipp.c:2499
-#, c-format
-msgid "No active jobs on %s!"
-msgstr "Aucuns JOBS actifs sur %s!"
-
-#: scheduler/ipp.c:2462 scheduler/ipp.c:2513
-#, c-format
-msgid "You are not authorized to delete job #%d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à supprimer le travail # %d possédés par \"%s\"!"
-
-#: scheduler/ipp.c:2476 scheduler/ipp.c:2527 scheduler/ipp.c:2563
-#, c-format
-msgid "Job #%d is already %s - can't cancel."
-msgstr "Le travail # %d est déjà %s - ne peut pas décommander."
-
-#: scheduler/ipp.c:3720 scheduler/ipp.c:3914 scheduler/ipp.c:4006
-msgid "The printer or class is not shared!"
-msgstr "L'imprimeur ou la classe n'est pas partagé!"
-
-#: scheduler/ipp.c:3746 scheduler/ipp.c:6647 scheduler/ipp.c:3940
-#: scheduler/ipp.c:6695 scheduler/ipp.c:4032 scheduler/ipp.c:6954
-#, c-format
-msgid "Destination \"%s\" is not accepting jobs."
-msgstr "La destination \"%s\" n'accepte pas les travaux."
-
-#: scheduler/ipp.c:3759 scheduler/ipp.c:6443 scheduler/ipp.c:3954
-#: scheduler/ipp.c:6487 scheduler/ipp.c:4046 scheduler/ipp.c:6739
-#, c-format
-msgid "Bad copies value %d."
-msgstr "Mauvaise valeur %d de copies."
-
-#: scheduler/ipp.c:3775 scheduler/ipp.c:6459 scheduler/ipp.c:3971
-#: scheduler/ipp.c:6504 scheduler/ipp.c:4063 scheduler/ipp.c:6756
-#, c-format
-msgid "Bad page-ranges values %d-%d."
-msgstr "Mauvaises valeurs %d-%d de page-ranges."
-
-#: scheduler/ipp.c:3795 scheduler/ipp.c:3991 scheduler/ipp.c:4083
-msgid "Too many active jobs."
-msgstr "Trop de JOBS actifs."
-
-#: scheduler/ipp.c:3801 scheduler/ipp.c:6668 scheduler/ipp.c:3997
-#: scheduler/ipp.c:6716 scheduler/ipp.c:4089 scheduler/ipp.c:6975
-msgid "Quota limit reached."
-msgstr "La limite de quote-part a atteint."
-
-#: scheduler/ipp.c:3824 scheduler/ipp.c:6691 scheduler/ipp.c:4022
-#: scheduler/ipp.c:6741 scheduler/ipp.c:4114 scheduler/ipp.c:7000
-#, c-format
-msgid "Unable to add job for destination \"%s\"!"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: scheduler/ipp.c:4469 scheduler/ipp.c:4673 scheduler/ipp.c:4770
-msgid "No subscription attributes in request!"
-msgstr "Aucuns attributs d'abonnement dans la demande!"
-
-#: scheduler/ipp.c:4559 scheduler/ipp.c:4763 scheduler/ipp.c:4869
-msgid "notify-events not specified!"
-msgstr "notify-events non indiqués!"
-
-#: scheduler/ipp.c:4577 scheduler/ipp.c:4781 scheduler/ipp.c:4887
-#, c-format
-msgid "Job %d not found!"
-msgstr "Le travail %d non trouvé!"
-
-#: scheduler/ipp.c:4827 scheduler/ipp.c:4957 scheduler/ipp.c:5075
-msgid "No default printer"
-msgstr "Aucun imprimeur de défaut"
-
-#: scheduler/ipp.c:4930 scheduler/ipp.c:5060 scheduler/ipp.c:5178
-msgid "cups-deviced failed to execute."
-msgstr "les cups-deviced ne se sont pas exécutées."
-
-#: scheduler/ipp.c:5393 scheduler/ipp.c:5479 scheduler/ipp.c:5722
-msgid "cups-driverd failed to execute."
-msgstr "les cups-driverd ne se sont pas exécutées."
-
-#: scheduler/ipp.c:5571 scheduler/ipp.c:5594 scheduler/ipp.c:5837
-msgid "No destinations added."
-msgstr "Aucunes destinations supplémentaires."
-
-#: scheduler/ipp.c:5794 scheduler/ipp.c:5736 scheduler/ipp.c:2615
-#: scheduler/ipp.c:5530 scheduler/ipp.c:5979 scheduler/ipp.c:7840
-#, c-format
-msgid "notify-subscription-id %d no good!"
-msgstr "notify-subscription-id %d aucun bon!"
-
-#: scheduler/ipp.c:5878 scheduler/ipp.c:5822 scheduler/ipp.c:6065
-#, c-format
-msgid "Job #%s does not exist!"
-msgstr "Le travail # %s n'existe pas!"
-
-#: scheduler/ipp.c:5900 scheduler/ipp.c:2116 scheduler/ipp.c:2451
-#: scheduler/ipp.c:5228 scheduler/ipp.c:6047 scheduler/ipp.c:6188
-#: scheduler/ipp.c:7434 scheduler/ipp.c:7578 scheduler/ipp.c:7815
-#: scheduler/ipp.c:8300 scheduler/ipp.c:2157 scheduler/ipp.c:2502
-#: scheduler/ipp.c:5143 scheduler/ipp.c:5844 scheduler/ipp.c:5996
-#: scheduler/ipp.c:6174 scheduler/ipp.c:6219 scheduler/ipp.c:7493
-#: scheduler/ipp.c:7640 scheduler/ipp.c:7880 scheduler/ipp.c:8375
-#: scheduler/ipp.c:2199 scheduler/ipp.c:2541 scheduler/ipp.c:5261
-#: scheduler/ipp.c:6087 scheduler/ipp.c:6251 scheduler/ipp.c:6429
-#: scheduler/ipp.c:6474 scheduler/ipp.c:7754 scheduler/ipp.c:7969
-#: scheduler/ipp.c:8208 scheduler/ipp.c:8713
-#, c-format
-msgid "Job #%d does not exist!"
-msgstr "Le travail # %d n'existe pas!"
-
-#: scheduler/ipp.c:5969 scheduler/ipp.c:5915 scheduler/ipp.c:6150
-msgid "No subscriptions found."
-msgstr "Abonnement n'a pas trouvé."
-
-#: scheduler/ipp.c:6058 scheduler/ipp.c:6007
-#, c-format
-msgid "Not authorized to hold job #%d owned by \"%s\"!"
-msgstr "Non autorisé à juger le travail # %d possédés par \"%s\"!"
-
-#: scheduler/ipp.c:6203 scheduler/ipp.c:8315 scheduler/ipp.c:6250
-#: scheduler/ipp.c:8390 scheduler/ipp.c:6505 scheduler/ipp.c:8728
-#, c-format
-msgid "Job #%d is finished and cannot be altered!"
-msgstr "Le travail # %d est fini et ne peut pas être changé!"
-
-#: scheduler/ipp.c:6215 scheduler/ipp.c:6262
-#, c-format
-msgid "You are not authorized to move job #%d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à déplacer le travail # %d possédés par \"%s\"!"
-
-#: scheduler/ipp.c:6228 scheduler/ipp.c:6098 scheduler/ipp.c:6353
-msgid "job-printer-uri attribute missing!"
-msgstr "disparus d'attribut de job-printer-uri!"
-
-#: scheduler/ipp.c:6485 scheduler/ipp.c:7847 scheduler/ipp.c:6531
-#: scheduler/ipp.c:7913 scheduler/ipp.c:6783 scheduler/ipp.c:8238
-#, c-format
-msgid "Unsupported compression \"%s\"!"
-msgstr "Compression non soutenue \"%s\"!"
-
-#: scheduler/ipp.c:6504 scheduler/ipp.c:7866 scheduler/ipp.c:6550
-#: scheduler/ipp.c:7932 scheduler/ipp.c:6802 scheduler/ipp.c:8257
-msgid "No file!?!"
-msgstr "Aucun dossier!?!"
-
-#: scheduler/ipp.c:6522 scheduler/ipp.c:6568 scheduler/ipp.c:6820
-#, c-format
-msgid "Could not scan type \"%s\"!"
-msgstr "N'a pas pu balayer le type \"%s\"!"
-
-#: scheduler/ipp.c:6574 scheduler/ipp.c:7936 scheduler/ipp.c:6620
-#: scheduler/ipp.c:8001 scheduler/ipp.c:6879 scheduler/ipp.c:8332
-#, c-format
-msgid "Unsupported format '%s/%s'!"
-msgstr "Format non soutenu '%s/%s '!"
-
-#: scheduler/ipp.c:6621 scheduler/ipp.c:6669 scheduler/ipp.c:6928
-msgid "Printer not shared!"
-msgstr "Imprimeur non partagé!"
-
-#: scheduler/ipp.c:6661 scheduler/ipp.c:6709 scheduler/ipp.c:6968
-#, c-format
-msgid "Too many jobs - %d jobs, max jobs is %d."
-msgstr "Trop de travaux - les travaux de %d, les travaux maximum est %d."
-
-#: scheduler/ipp.c:7448 scheduler/ipp.c:7507 scheduler/ipp.c:7768
-#, c-format
-msgid "Job #%d is not held!"
-msgstr "Le travail # %d n'est pas tenu!"
-
-#: scheduler/ipp.c:7459 scheduler/ipp.c:7518
-#, c-format
-msgid "You are not authorized to release job id %d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à libérer l'identification de travail %d possédée "
-"par \"%s\"!"
-
-#: scheduler/ipp.c:7592 scheduler/ipp.c:7654 scheduler/ipp.c:7983
-#, c-format
-msgid "Job #%d is not complete!"
-msgstr "Le travail # %d n'est pas complet!"
-
-#: scheduler/ipp.c:7608 scheduler/ipp.c:7670 scheduler/ipp.c:8001
-#, c-format
-msgid "Job #%d cannot be restarted - no files!"
-msgstr "Le travail # %d ne peuvent pas être remis en marche - aucuns dossiers!"
-
-#: scheduler/ipp.c:7619 scheduler/ipp.c:7681
-#, c-format
-msgid "You are not authorized to restart job id %d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à remettre en marche l'identification de travail %"
-"d possédée par \"%s\"!"
-
-#: scheduler/ipp.c:7826 scheduler/ipp.c:7891
-#, c-format
-msgid "You are not authorized to send document for job #%d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à envoyer le document pour le travail # %d "
-"possédés par \"%s\"!"
-
-#: scheduler/ipp.c:7883 scheduler/ipp.c:8803 scheduler/ipp.c:7949
-#: scheduler/ipp.c:8883 scheduler/ipp.c:8274 scheduler/ipp.c:9225
-#, c-format
-msgid "Bad document-format \"%s\"!"
-msgstr "Mauvais document-format \"%s\"!"
-
-#: scheduler/ipp.c:8326 scheduler/ipp.c:8401
-#, c-format
-msgid "You are not authorized to alter job id %d owned by \"%s\"!"
-msgstr ""
-"Vous n'êtes pas autorisés à changer l'identification de travail %d possédée "
-"par \"%s\"!"
-
-#: scheduler/ipp.c:8371 scheduler/ipp.c:8446 scheduler/ipp.c:8783
-#, c-format
-msgid "%s cannot be changed."
-msgstr "%s ne peut pas être changé."
-
-#: scheduler/ipp.c:8387 scheduler/ipp.c:8462 scheduler/ipp.c:8799
-msgid "Bad job-priority value!"
-msgstr "Mauvaise valeur de job-priority!"
-
-#: scheduler/ipp.c:8395 scheduler/ipp.c:8470 scheduler/ipp.c:8807
-msgid "Job is completed and cannot be changed."
-msgstr "Le travail est accompli et ne peut pas être changé."
-
-#: scheduler/ipp.c:8409 scheduler/ipp.c:8484 scheduler/ipp.c:8821
-msgid "Bad job-state value!"
-msgstr "Mauvaise valeur de job-state!"
-
-#: scheduler/ipp.c:8423 scheduler/ipp.c:8435 scheduler/ipp.c:8446
-#: scheduler/ipp.c:8498 scheduler/ipp.c:8510 scheduler/ipp.c:8521
-#: scheduler/ipp.c:8835 scheduler/ipp.c:8850 scheduler/ipp.c:8861
-msgid "Job state cannot be changed."
-msgstr "L'état du travail ne peut pas être changé."
-
-#: scheduler/ipp.c:8787 scheduler/ipp.c:8867 scheduler/ipp.c:9209
-#, c-format
-msgid "Unsupported compression attribute %s!"
-msgstr "Attribut non soutenu %s de compression!"
-
-#: scheduler/ipp.c:8815 scheduler/ipp.c:8894 scheduler/ipp.c:9236
-#, c-format
-msgid "Unsupported format \"%s\"!"
-msgstr "Format non soutenu \"%s\"!"
-
-#: berkeley/lpc.c:201
-#, c-format
-msgid "%s is not implemented by the CUPS version of lpc.\n"
-msgstr ""
-
-#: berkeley/lpc.c:216
-msgid ""
-"Commands may be abbreviated.  Commands are:\n"
-"\n"
-"exit    help    quit    status  ?\n"
-msgstr ""
-
-#: berkeley/lpc.c:222 berkeley/lpc.c:221
-msgid "help\t\tget help on commands\n"
-msgstr ""
-
-#: berkeley/lpc.c:225 berkeley/lpc.c:223
-msgid "status\t\tshow status of daemon and queue\n"
-msgstr ""
-
-#: berkeley/lpc.c:228 berkeley/lpc.c:225
-msgid "?Invalid help command unknown\n"
-msgstr ""
-
-#: berkeley/lpc.c:478 berkeley/lpc.c:490 berkeley/lpc.c:475 berkeley/lpc.c:487
-#: berkeley/lpc.c:476 berkeley/lpc.c:488
-#, c-format
-msgid "\tprinter is on device '%s' speed -1\n"
-msgstr ""
-
-#: berkeley/lpc.c:496 berkeley/lpc.c:493 berkeley/lpc.c:494
-msgid "\tqueuing is enabled\n"
-msgstr ""
-
-#: berkeley/lpc.c:498 berkeley/lpc.c:495 berkeley/lpc.c:496
-msgid "\tqueuing is disabled\n"
-msgstr ""
-
-#: berkeley/lpc.c:501 berkeley/lpc.c:498 berkeley/lpc.c:499
-msgid "\tprinting is enabled\n"
-msgstr ""
-
-#: berkeley/lpc.c:503 berkeley/lpc.c:500 berkeley/lpc.c:501
-msgid "\tprinting is disabled\n"
-msgstr ""
-
-#: berkeley/lpc.c:506 berkeley/lpc.c:503 berkeley/lpc.c:504
-msgid "\tno entries\n"
-msgstr ""
-
-#: berkeley/lpc.c:508 berkeley/lpc.c:505 berkeley/lpc.c:506
-#, c-format
-msgid "\t%d entries\n"
-msgstr ""
-
-#: berkeley/lpc.c:510 berkeley/lpc.c:507 berkeley/lpc.c:508
-msgid "\tdaemon present\n"
-msgstr ""
-
-#: berkeley/lpq.c:94
-msgid "lpq: Unable to contact server!\n"
-msgstr ""
-
-#: berkeley/lpq.c:125 berkeley/lpr.c:114 berkeley/lprm.c:107
-#: systemv/accept.c:108 systemv/cancel.c:95 systemv/lpstat.c:115
-#: systemv/lpadmin.c:284 systemv/lp.c:135 systemv/lpinfo.c:80
-#: systemv/lpmove.c:84 systemv/accept.c:106 systemv/cancel.c:93
-#: systemv/lpmove.c:89 berkeley/lpq.c:124 systemv/lp.c:136
-#: systemv/lpstat.c:116 berkeley/lpr.c:116 systemv/lp.c:140
-#, c-format
-msgid "%s: Sorry, no encryption support compiled in!\n"
-msgstr ""
-
-#: berkeley/lpq.c:155
-#, c-format
-msgid "lpq: Unknown destination \"%s/%s\"!\n"
-msgstr ""
-
-#: berkeley/lpq.c:159
-#, fuzzy, c-format
-msgid "lpq: Unknown destination \"%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: berkeley/lpq.c:211 systemv/lp.c:564
-#, c-format
-msgid ""
-"lp: error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr ""
-
-#: berkeley/lpq.c:216
-msgid "lpq: error - no default destination available.\n"
-msgstr ""
-
-#: berkeley/lpq.c:363 berkeley/lpq.c:523
-#, c-format
-msgid "lpq: get-jobs failed: %s\n"
-msgstr ""
-
-#: berkeley/lpq.c:457 berkeley/lpq.c:444 berkeley/lpq.c:488
-msgid ""
-"Rank   Owner      Pri  Job        Files                       Total Size\n"
-msgstr ""
-
-#: berkeley/lpq.c:461 berkeley/lpq.c:448 berkeley/lpq.c:492
-msgid "Rank    Owner   Job     File(s)                         Total Size\n"
-msgstr ""
-
-#: berkeley/lpq.c:498 berkeley/lpq.c:485 berkeley/lpq.c:529
-#, c-format
-msgid "%s: %-33.33s [job %d localhost]\n"
-msgstr ""
-
-#: berkeley/lpq.c:500 berkeley/lpq.c:487 berkeley/lpq.c:531
-#, c-format
-msgid "        %-39.39s %.0f bytes\n"
-msgstr ""
-
-#: berkeley/lpq.c:506 berkeley/lpq.c:493 berkeley/lpq.c:537
-#, c-format
-msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n"
-msgstr ""
-
-#: berkeley/lpq.c:511 berkeley/lpq.c:498 berkeley/lpq.c:542
-#, c-format
-msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n"
-msgstr ""
-
-#: berkeley/lpq.c:529 berkeley/lpq.c:515 berkeley/lpq.c:559
-msgid "no entries\n"
-msgstr ""
-
-#: berkeley/lpq.c:591 berkeley/lpq.c:620
-#, c-format
-msgid "lpq: get-printer-attributes failed: %s\n"
-msgstr ""
-
-#: berkeley/lpq.c:605 berkeley/lpq.c:576 berkeley/lpq.c:621
-#, c-format
-msgid "%s is ready\n"
-msgstr ""
-
-#: berkeley/lpq.c:608 berkeley/lpq.c:579 berkeley/lpq.c:624
-#, c-format
-msgid "%s is ready and printing\n"
-msgstr ""
-
-#: berkeley/lpq.c:612 berkeley/lpq.c:583 berkeley/lpq.c:628
-#, fuzzy, c-format
-msgid "%s is not ready\n"
-msgstr "Le travail # %d n'est pas tenu!"
-
-#: berkeley/lpq.c:633 berkeley/lpq.c:601
-msgid "Usage: lpq [-P dest] [-l] [+interval]\n"
-msgstr ""
-
-#: berkeley/lpr.c:132
-#, c-format
-msgid "lpr: error - expected value after -%c option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:146
-#, c-format
-msgid ""
-"lpr: warning - '%c' format modifier not supported - output may not be "
-"correct!\n"
-msgstr ""
-
-#: berkeley/lpr.c:159
-msgid "lpr: error - expected option=value after -o option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:185
-msgid "lpr: warning - email notification is not currently supported!\n"
-msgstr ""
-
-#: berkeley/lpr.c:207
-msgid "lpr: error - expected destination after -P option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:240
-msgid "lpr: error - expected copy count after -# option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:263
-#, c-format
-msgid "lpr: error - expected name after -%c option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:281
-msgid "lpr: error - expected username after -U option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:292
-#, c-format
-msgid "lpr: error - unknown option '%c'!\n"
-msgstr ""
-
-#: berkeley/lpr.c:305
-#, c-format
-msgid "lpr: error - unable to access \"%s\" - %s\n"
-msgstr ""
-
-#: berkeley/lpr.c:323
-#, c-format
-msgid "lpr: error - too many files - \"%s\"\n"
-msgstr ""
-
-#: berkeley/lpr.c:364
-#, c-format
-msgid ""
-"lpr: error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr ""
-
-#: berkeley/lpr.c:369
-msgid "lpr: error - no default destination available.\n"
-msgstr ""
-
-#: berkeley/lpr.c:372
-msgid "lpr: error - scheduler not responding!\n"
-msgstr ""
-
-#: berkeley/lpr.c:421
-#, c-format
-msgid "lpr: error - unable to create temporary file \"%s\" - %s\n"
-msgstr ""
-
-#: berkeley/lpr.c:431
-#, c-format
-msgid "lpr: error - unable to write to temporary file \"%s\" - %s\n"
-msgstr ""
-
-#: berkeley/lpr.c:445
-msgid "lpr: error - stdin is empty, so no job has been sent.\n"
-msgstr ""
-
-#: berkeley/lpr.c:461 berkeley/lpr.c:460
-#, c-format
-msgid "lpr: error - unable to print file: %s\n"
-msgstr ""
-
-#: berkeley/lprm.c:87
-msgid "lprm: Unable to contact server!\n"
-msgstr ""
-
-#: berkeley/lprm.c:127
-#, c-format
-msgid "lprm: Unknown destination \"%s\"!\n"
-msgstr ""
-
-#: berkeley/lprm.c:136
-#, c-format
-msgid "lprm: Unknown option '%c'!\n"
-msgstr ""
-
-#: berkeley/lprm.c:223
-#, fuzzy
-msgid "lprm: Job or printer not found!\n"
-msgstr "Le travail %d non trouvé!"
-
-#: berkeley/lprm.c:227
-#, fuzzy
-msgid "lprm: Not authorized to lprm job(s)!\n"
-msgstr "Non autorisé à juger le travail # %d possédés par \"%s\"!"
-
-#: berkeley/lprm.c:231
-#, c-format
-msgid "lprm: You don't own job ID %d!\n"
-msgstr ""
-
-#: berkeley/lprm.c:236
-msgid "lprm: Unable to lprm job(s)!\n"
-msgstr ""
-
-#: berkeley/lprm.c:253 berkeley/lprm.c:269
-msgid "lprm: Unable to cancel job(s)!\n"
-msgstr ""
-
-#: systemv/accept.c:84 systemv/accept.c:82
-#, c-format
-msgid "%s: Don't know what to do!\n"
-msgstr ""
-
-#: systemv/accept.c:129 systemv/accept.c:127
-#, c-format
-msgid "%s: Expected server name after -h!\n"
-msgstr ""
-
-#: systemv/accept.c:147 systemv/accept.c:145
-#, c-format
-msgid "%s: Expected reason text after -r!\n"
-msgstr ""
-
-#: systemv/accept.c:157 systemv/accept.c:155
-#, c-format
-msgid "%s: Unknown option '%c'!\n"
-msgstr ""
-
-#: systemv/accept.c:173 systemv/accept.c:171 systemv/accept.c:192
-#, c-format
-msgid "%s: Unable to connect to server: %s\n"
-msgstr ""
-
-#: systemv/accept.c:217 systemv/accept.c:227 systemv/accept.c:268
-#: systemv/accept.c:278 systemv/accept.c:206 systemv/accept.c:230
-#, c-format
-msgid "%s: Operation failed: %s\n"
-msgstr ""
-
-#: systemv/cancel.c:118 systemv/cancel.c:116
-msgid "cancel: Error - expected hostname after '-h' option!\n"
-msgstr ""
-
-#: systemv/cancel.c:139 systemv/cancel.c:137
-msgid "cancel: Error - expected username after '-u' option!\n"
-msgstr ""
-
-#: systemv/cancel.c:150 systemv/cancel.c:148
-#, c-format
-msgid "cancel: Unknown option '%c'!\n"
-msgstr ""
-
-#: systemv/cancel.c:207 systemv/cancel.c:205
-#, fuzzy, c-format
-msgid "cancel: Unknown destination \"%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/cancel.c:229 systemv/cancel.c:319 systemv/cancel.c:227
-#: systemv/cancel.c:308
-msgid "cancel: Unable to contact server!\n"
-msgstr ""
-
-#: systemv/cancel.c:295 systemv/cancel.c:370 systemv/cancel.c:284
-#: systemv/cancel.c:348
-#, c-format
-msgid "cancel: %s failed: %s\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:290 systemv/cupsaddsmb.c:311
-#, c-format
-msgid "cupsaddsmb: Missing value on line %d!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:301 systemv/cupsaddsmb.c:322
-#, c-format
-msgid "cupsaddsmb: Missing double quote on line %d!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:313 systemv/cupsaddsmb.c:334
-#, c-format
-msgid "cupsaddsmb: Bad option + choice on line %d!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:496 systemv/cupsaddsmb.c:553
-#, c-format
-msgid "cupsaddsmb: Unable to connect to server \"%s\" for %s - %s\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:509 systemv/cupsaddsmb.c:566
-#, c-format
-msgid "cupsaddsmb: No PPD file for printer \"%s\" - skipping!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:548 systemv/cupsaddsmb.c:562
-#, c-format
-msgid "cupsaddsmb: get-printer-attributes failed for \"%s\": %s\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:578 systemv/cupsaddsmb.c:620
-#, fuzzy, c-format
-msgid "cupsaddsmb: Unable to convert PPD file for %s - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/cupsaddsmb.c:633 systemv/cupsaddsmb.c:677
-#, c-format
-msgid "cupsaddsmb: Unable to copy Windows 2000 printer driver files (%d)!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:660 systemv/cupsaddsmb.c:704
-#, c-format
-msgid "cupsaddsmb: Unable to copy CUPS printer driver files (%d)!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:697 systemv/cupsaddsmb.c:739
-#, c-format
-msgid "cupsaddsmb: Unable to install Windows 2000 printer driver files (%d)!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:727 systemv/cupsaddsmb.c:771
-#, c-format
-msgid "cupsaddsmb: Unable to copy Windows 9x printer driver files (%d)!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:750 systemv/cupsaddsmb.c:792
-#, c-format
-msgid "cupsaddsmb: Unable to install Windows 9x printer driver files (%d)!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:771 systemv/cupsaddsmb.c:822
-#, c-format
-msgid "cupsaddsmb: Unable to set Windows printer driver (%d)!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:854 systemv/cupsaddsmb.c:905
-msgid ""
-"Usage: cupsaddsmb [options] printer1 ... printerN\n"
-"       cupsaddsmb [options] -a\n"
-"\n"
-"Options:\n"
-"  -H samba-server  Use the named SAMBA server\n"
-"  -U samba-user    Authenticate using the named SAMBA user\n"
-"  -a               Export all printers\n"
-"  -h cups-server   Use the named CUPS server\n"
-"  -v               Be verbose (show commands)\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:120 systemv/cupstestppd.c:137
-msgid "cupstestppd: The -q option is incompatible with the -v option.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:136 systemv/cupstestppd.c:153
-msgid "cupstestppd: The -v option is incompatible with the -q option.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:193 systemv/cupstestppd.c:210
-#, fuzzy, c-format
-msgid ""
-" FAIL\n"
-"      **FAIL**  Unable to open PPD file - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/cupstestppd.c:204 systemv/cupstestppd.c:221
-#, c-format
-msgid ""
-" FAIL\n"
-"      **FAIL**  Unable to open PPD file - %s on line %d.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:213 systemv/cupstestppd.c:230
-msgid "                REF: Page 42, section 5.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:217 systemv/cupstestppd.c:234
-msgid "                REF: Page 20, section 3.4.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:222 systemv/cupstestppd.c:239
-msgid "                REF: Pages 45-46, section 5.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:227 systemv/cupstestppd.c:244
-msgid "                REF: Pages 42-45, section 5.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:231 systemv/cupstestppd.c:248
-msgid "                REF: Pages 48-49, section 5.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:235 systemv/cupstestppd.c:252
-msgid "                REF: Pages 52-54, section 5.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:239 systemv/cupstestppd.c:256
-msgid "                REF: Page 15, section 3.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:243 systemv/cupstestppd.c:247
-#: systemv/cupstestppd.c:260 systemv/cupstestppd.c:264
-msgid "                REF: Page 15, section 3.1.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:251 systemv/cupstestppd.c:268
-msgid "                REF: Pages 16-17, section 3.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:255 systemv/cupstestppd.c:272
-msgid "                REF: Page 19, section 3.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:259 systemv/cupstestppd.c:276
-msgid "                REF: Page 27, section 3.5.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:280 systemv/cupstestppd.c:299
-msgid ""
-"\n"
-"    DETAILED CONFORMANCE TEST RESULTS\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:307 systemv/cupstestppd.c:326
-#, c-format
-msgid "        WARN    %s has no corresponding options!\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:318 systemv/cupstestppd.c:333
-#: systemv/cupstestppd.c:354 systemv/cupstestppd.c:369
-#: systemv/cupstestppd.c:397 systemv/cupstestppd.c:417
-#: systemv/cupstestppd.c:439 systemv/cupstestppd.c:459
-#: systemv/cupstestppd.c:479 systemv/cupstestppd.c:499
-#: systemv/cupstestppd.c:517 systemv/cupstestppd.c:535
-#: systemv/cupstestppd.c:556 systemv/cupstestppd.c:575
-#: systemv/cupstestppd.c:595 systemv/cupstestppd.c:615
-#: systemv/cupstestppd.c:635 systemv/cupstestppd.c:655
-#: systemv/cupstestppd.c:673 systemv/cupstestppd.c:690
-#: systemv/cupstestppd.c:712 systemv/cupstestppd.c:730
-#: systemv/cupstestppd.c:747 systemv/cupstestppd.c:765
-#: systemv/cupstestppd.c:781 systemv/cupstestppd.c:801
-#: systemv/cupstestppd.c:832 systemv/cupstestppd.c:854
-#: systemv/cupstestppd.c:902 systemv/cupstestppd.c:931
-#: systemv/cupstestppd.c:952 systemv/cupstestppd.c:337
-#: systemv/cupstestppd.c:352 systemv/cupstestppd.c:373
-#: systemv/cupstestppd.c:388 systemv/cupstestppd.c:416
-#: systemv/cupstestppd.c:436 systemv/cupstestppd.c:458
-#: systemv/cupstestppd.c:478 systemv/cupstestppd.c:498
-#: systemv/cupstestppd.c:518 systemv/cupstestppd.c:536
-#: systemv/cupstestppd.c:554 systemv/cupstestppd.c:594
-#: systemv/cupstestppd.c:614 systemv/cupstestppd.c:634
-#: systemv/cupstestppd.c:654 systemv/cupstestppd.c:674
-#: systemv/cupstestppd.c:692 systemv/cupstestppd.c:709
-#: systemv/cupstestppd.c:731 systemv/cupstestppd.c:749
-#: systemv/cupstestppd.c:766 systemv/cupstestppd.c:784
-#: systemv/cupstestppd.c:800 systemv/cupstestppd.c:820
-#: systemv/cupstestppd.c:851 systemv/cupstestppd.c:873
-#: systemv/cupstestppd.c:921 systemv/cupstestppd.c:950
-#: systemv/cupstestppd.c:971
-msgid " FAIL\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:321 systemv/cupstestppd.c:340
-msgid ""
-"      **FAIL**  REQUIRED DefaultImageableArea\n"
-"                REF: Page 102, section 5.15.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:336 systemv/cupstestppd.c:355
-#, c-format
-msgid ""
-"      **FAIL**  BAD DefaultImageableArea %s!\n"
-"                REF: Page 102, section 5.15.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:346 systemv/cupstestppd.c:365
-msgid "        PASS    DefaultImageableArea\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:357 systemv/cupstestppd.c:376
-msgid ""
-"      **FAIL**  REQUIRED DefaultPaperDimension\n"
-"                REF: Page 103, section 5.15.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:372 systemv/cupstestppd.c:391
-#, c-format
-msgid ""
-"      **FAIL**  BAD DefaultPaperDimension %s!\n"
-"                REF: Page 103, section 5.15.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:380 systemv/cupstestppd.c:399
-msgid "        PASS    DefaultPaperDimension\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:400 systemv/cupstestppd.c:419
-#, c-format
-msgid ""
-"      **FAIL**  BAD Default%s %s\n"
-"                REF: Page 40, section 4.5.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:409 systemv/cupstestppd.c:428
-#, c-format
-msgid "        PASS    Default%s\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:420 systemv/cupstestppd.c:439
-#, c-format
-msgid ""
-"      **FAIL**  REQUIRED Default%s\n"
-"                REF: Page 40, section 4.5.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:432 systemv/cupstestppd.c:451
-msgid "        PASS    FileVersion\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:442 systemv/cupstestppd.c:461
-msgid ""
-"      **FAIL**  REQUIRED FileVersion\n"
-"                REF: Page 56, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:452 systemv/cupstestppd.c:471
-msgid "        PASS    FormatVersion\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:462 systemv/cupstestppd.c:481
-msgid ""
-"      **FAIL**  REQUIRED FormatVersion\n"
-"                REF: Page 56, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:472 systemv/cupstestppd.c:491
-msgid "        PASS    LanguageEncoding\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:482 systemv/cupstestppd.c:501
-msgid ""
-"      **FAIL**  REQUIRED LanguageEncoding\n"
-"                REF: Pages 56-57, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:492 systemv/cupstestppd.c:511
-msgid "        PASS    LanguageVersion\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:502 systemv/cupstestppd.c:521
-msgid ""
-"      **FAIL**  REQUIRED LanguageVersion\n"
-"                REF: Pages 57-58, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:520 systemv/cupstestppd.c:539
-msgid ""
-"      **FAIL**  BAD Manufacturer (should be \"HP\")\n"
-"                REF: Page 211, table D.1.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:528 systemv/cupstestppd.c:547
-msgid "        PASS    Manufacturer\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:538 systemv/cupstestppd.c:557
-msgid ""
-"      **FAIL**  REQUIRED Manufacturer\n"
-"                REF: Pages 58-59, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:559 systemv/cupstestppd.c:578
-#, c-format
-msgid ""
-"      **FAIL**  BAD ModelName - \"%c\" not allowed in string.\n"
-"                REF: Pages 59-60, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:568 systemv/cupstestppd.c:587
-msgid "        PASS    ModelName\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:578 systemv/cupstestppd.c:597
-msgid ""
-"      **FAIL**  REQUIRED ModelName\n"
-"                REF: Pages 59-60, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:588 systemv/cupstestppd.c:607
-msgid "        PASS    NickName\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:598 systemv/cupstestppd.c:617
-msgid ""
-"      **FAIL**  REQUIRED NickName\n"
-"                REF: Page 60, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:608 systemv/cupstestppd.c:627
-msgid "        PASS    PageSize\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:618 systemv/cupstestppd.c:637
-msgid ""
-"      **FAIL**  REQUIRED PageSize\n"
-"                REF: Pages 99-100, section 5.14.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:628 systemv/cupstestppd.c:647
-msgid "        PASS    PageRegion\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:638 systemv/cupstestppd.c:657
-msgid ""
-"      **FAIL**  REQUIRED PageRegion\n"
-"                REF: Page 100, section 5.14.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:648 systemv/cupstestppd.c:667
-msgid "        PASS    PCFileName\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:658 systemv/cupstestppd.c:677
-msgid ""
-"      **FAIL**  REQUIRED PCFileName\n"
-"                REF: Pages 61-62, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:676 systemv/cupstestppd.c:695
-msgid ""
-"      **FAIL**  BAD Product - not \"(string)\".\n"
-"                REF: Page 62, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:683 systemv/cupstestppd.c:702
-msgid "        PASS    Product\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:693 systemv/cupstestppd.c:712
-msgid ""
-"      **FAIL**  REQUIRED Product\n"
-"                REF: Page 62, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:715 systemv/cupstestppd.c:734
-msgid ""
-"      **FAIL**  BAD PSVersion - not \"(string) int\".\n"
-"                REF: Pages 62-64, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:723 systemv/cupstestppd.c:742
-msgid "        PASS    PSVersion\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:733 systemv/cupstestppd.c:752
-msgid ""
-"      **FAIL**  REQUIRED PSVersion\n"
-"                REF: Pages 62-64, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:750 systemv/cupstestppd.c:769
-msgid ""
-"      **FAIL**  BAD ShortNickName - longer than 31 chars.\n"
-"                REF: Pages 64-65, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:758 systemv/cupstestppd.c:777
-msgid "        PASS    ShortNickName\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:768 systemv/cupstestppd.c:787
-msgid ""
-"      **FAIL**  REQUIRED ShortNickName\n"
-"                REF: Page 64-65, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:784 systemv/cupstestppd.c:803
-msgid ""
-"      **FAIL**  BAD JobPatchFile attribute in file\n"
-"                REF: Page 24, section 3.4.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:804 systemv/cupstestppd.c:823
-msgid ""
-"      **FAIL**  REQUIRED PageSize\n"
-"                REF: Page 41, section 5.\n"
-"                REF: Page 99, section 5.14.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:835 systemv/cupstestppd.c:854
-#, c-format
-msgid ""
-"      **FAIL**  REQUIRED ImageableArea for PageSize %s\n"
-"                REF: Page 41, section 5.\n"
-"                REF: Page 102, section 5.15.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:857 systemv/cupstestppd.c:876
-#, c-format
-msgid ""
-"      **FAIL**  REQUIRED PaperDimension for PageSize %s\n"
-"                REF: Page 41, section 5.\n"
-"                REF: Page 103, section 5.15.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:905 systemv/cupstestppd.c:924
-#, c-format
-msgid ""
-"      **FAIL**  Bad %s choice %s!\n"
-"                REF: Page 84, section 5.9\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:934 systemv/cupstestppd.c:953
-#, c-format
-msgid ""
-"      **FAIL**  REQUIRED %s does not define choice None!\n"
-"                REF: Page 122, section 5.17\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:955 systemv/cupstestppd.c:974
-#, c-format
-msgid ""
-"      **FAIL**  Bad %s choice %s!\n"
-"                REF: Page 122, section 5.17\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:967 systemv/cupstestppd.c:986
-msgid " PASS\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:976 systemv/cupstestppd.c:997
-#, c-format
-msgid ""
-"        WARN    Duplex option keyword %s should be named Duplex or "
-"JCLDuplex!\n"
-"                REF: Page 122, section 5.17\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:986 systemv/cupstestppd.c:1007
-msgid "        WARN    Default choices conflicting!\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:994 systemv/cupstestppd.c:1015
-#, c-format
-msgid ""
-"        WARN    Obsolete PPD version %.1f!\n"
-"                REF: Page 42, section 5.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1002 systemv/cupstestppd.c:1023
-msgid ""
-"        WARN    LanguageEncoding required by PPD 4.3 spec.\n"
-"                REF: Pages 56-57, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1010 systemv/cupstestppd.c:1031
-msgid ""
-"        WARN    Manufacturer required by PPD 4.3 spec.\n"
-"                REF: Pages 58-59, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1023 systemv/cupstestppd.c:1044
-msgid ""
-"        WARN    PCFileName longer than 8.3 in violation of PPD spec.\n"
-"                REF: Pages 61-62, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1031 systemv/cupstestppd.c:1052
-msgid ""
-"        WARN    ShortNickName required by PPD 4.3 spec.\n"
-"                REF: Pages 64-65, section 5.3.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1069
-msgid ""
-"        WARN    Protocols contains both PJL and BCP; expected TBCP.\n"
-"                REF: Pages 78-79, section 5.7.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1057 systemv/cupstestppd.c:1078
-msgid ""
-"        WARN    Protocols contains PJL but JCL attributes are not set.\n"
-"                REF: Pages 78-79, section 5.7.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1085 systemv/cupstestppd.c:1106
-#, c-format
-msgid ""
-"        WARN    %s shares a common prefix with %s\n"
-"                REF: Page 15, section 3.2.\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1097 systemv/cupstestppd.c:1118
-#, c-format
-msgid "    %d ERROR%s FOUND\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1100 systemv/cupstestppd.c:1121
-msgid "    NO ERRORS FOUND\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1360 systemv/cupstestppd.c:1465
-#, c-format
-msgid ""
-"        WARN    \"%s %s\" conflicts with \"%s %s\"\n"
-"                (constraint=\"%s %s %s %s\")\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1376 systemv/cupstestppd.c:1481
-msgid ""
-"Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[."
-"gz]]\n"
-"       program | cupstestppd [-q] [-r] [-v[v]] -\n"
-msgstr ""
-
-#: systemv/lpstat.c:144 systemv/lpstat.c:155
-msgid "lpstat: Need \"completed\" or \"not-completed\" after -W!\n"
-msgstr ""
-
-#: systemv/lpstat.c:212 systemv/lpstat.c:213
-msgid "lpstat: The -b option requires a destination argument.\n"
-msgstr ""
-
-#: systemv/lpstat.c:274 systemv/lpinfo.c:143 systemv/lpmove.c:105
-#: systemv/lpmove.c:110 systemv/lpstat.c:275
-msgid "Error: need hostname after '-h' option!\n"
-msgstr ""
-
-#: systemv/lpstat.c:433 systemv/lpstat.c:434
-#, c-format
-msgid "lpstat: Unknown option '%c'!\n"
-msgstr ""
-
-#: systemv/lpstat.c:504 systemv/lpstat.c:505
-#, c-format
-msgid "lpstat: Invalid destination name in list \"%s\"!\n"
-msgstr ""
-
-#: systemv/lpstat.c:519 systemv/lpstat.c:520
-#, fuzzy, c-format
-msgid "lpstat: Unknown destination \"%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpstat.c:541 systemv/lpstat.c:542
-#, c-format
-msgid "lpstat: Unable to connect to server %s on port %d: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:625 systemv/lpstat.c:773 systemv/lpstat.c:1187
-#: systemv/lpstat.c:1379 systemv/lpstat.c:1809 systemv/lpstat.c:2262
-#, c-format
-msgid "lpstat: get-printers failed: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:741
-#, c-format
-msgid "%s accepting requests since Jan 01 00:00\n"
-msgstr ""
-
-#: systemv/lpstat.c:745
-#, c-format
-msgid ""
-"%s not accepting requests since Jan 01 00:00 -\n"
-"\t%s\n"
-msgstr ""
-
-#: systemv/lpstat.c:754
-#, c-format
-msgid "%s/%s accepting requests since Jan 01 00:00\n"
-msgstr ""
-
-#: systemv/lpstat.c:758
-#, c-format
-msgid ""
-"%s/%s not accepting requests since Jan 01 00:00 -\n"
-"\t%s\n"
-msgstr ""
-
-#: systemv/lpstat.c:861 systemv/lpstat.c:1056
-#, c-format
-msgid "lpstat: get-classes failed: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1033 systemv/lpstat.c:1011 systemv/lpstat.c:1039
-#, c-format
-msgid "members of class %s:\n"
-msgstr ""
-
-#: systemv/lpstat.c:1080 systemv/lpstat.c:1057 systemv/lpstat.c:1085
-#, c-format
-msgid "system default destination: %s/%s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1083 systemv/lpstat.c:1060 systemv/lpstat.c:1088
-#, c-format
-msgid "system default destination: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1105 systemv/lpstat.c:1082 systemv/lpstat.c:1110
-#, c-format
-msgid ""
-"lpstat: error - %s environment variable names non-existent destination \"%s"
-"\"!\n"
-msgstr ""
-
-#: systemv/lpstat.c:1109 systemv/lpstat.c:1086 systemv/lpstat.c:1114
-msgid "no system default destination\n"
-msgstr ""
-
-#: systemv/lpstat.c:1313 systemv/lpstat.c:1281 systemv/lpstat.c:1309
-#: systemv/lpstat.c:1311
-#, c-format
-msgid "Output for printer %s is sent to remote printer %s on %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1319 systemv/lpstat.c:1323 systemv/lpstat.c:1287
-#: systemv/lpstat.c:1291 systemv/lpstat.c:1315 systemv/lpstat.c:1317
-#: systemv/lpstat.c:1321
-#, c-format
-msgid "Output for printer %s is sent to %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1331 systemv/lpstat.c:1299 systemv/lpstat.c:1327
-#: systemv/lpstat.c:1329
-#, c-format
-msgid "Output for printer %s/%s is sent to remote printer %s on %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1337 systemv/lpstat.c:1341 systemv/lpstat.c:1305
-#: systemv/lpstat.c:1309 systemv/lpstat.c:1333 systemv/lpstat.c:1335
-#: systemv/lpstat.c:1339
-#, c-format
-msgid "Output for printer %s/%s is sent to %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1346 systemv/lpstat.c:1349 systemv/lpstat.c:1352
-#: systemv/lpstat.c:1314 systemv/lpstat.c:1317 systemv/lpstat.c:1320
-#: systemv/lpstat.c:1342 systemv/lpstat.c:1345 systemv/lpstat.c:1348
-#: systemv/lpstat.c:1344 systemv/lpstat.c:1347 systemv/lpstat.c:1350
-#, c-format
-msgid "device for %s: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1359 systemv/lpstat.c:1362 systemv/lpstat.c:1365
-#: systemv/lpstat.c:1327 systemv/lpstat.c:1330 systemv/lpstat.c:1333
-#: systemv/lpstat.c:1355 systemv/lpstat.c:1358 systemv/lpstat.c:1361
-#: systemv/lpstat.c:1357 systemv/lpstat.c:1360 systemv/lpstat.c:1363
-#, c-format
-msgid "device for %s/%s: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1481 systemv/lpstat.c:1693
-#, c-format
-msgid "lpstat: get-jobs failed: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:1681 systemv/lpstat.c:1635 systemv/lpstat.c:1663
-#: systemv/lpstat.c:1665
-#, c-format
-msgid "\tqueued for %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2037 systemv/lpstat.c:1971 systemv/lpstat.c:1999
-#: systemv/lpstat.c:2001
-#, c-format
-msgid "printer %s is idle.  enabled since %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2042 systemv/lpstat.c:1976 systemv/lpstat.c:2004
-#: systemv/lpstat.c:2006
-#, c-format
-msgid "printer %s now printing %s-%d.  enabled since %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2048 systemv/lpstat.c:1982 systemv/lpstat.c:2010
-#: systemv/lpstat.c:2012
-#, c-format
-msgid "printer %s disabled since %s -\n"
-msgstr ""
-
-#: systemv/lpstat.c:2056 systemv/lpstat.c:2169 systemv/lpstat.c:1990
-#: systemv/lpstat.c:2103 systemv/lpstat.c:2018 systemv/lpstat.c:2131
-#: systemv/lpstat.c:2020 systemv/lpstat.c:2133
-msgid "\treason unknown\n"
-msgstr ""
-
-#: systemv/lpstat.c:2063 systemv/lpstat.c:2176 systemv/lpstat.c:1997
-#: systemv/lpstat.c:2110 systemv/lpstat.c:2025 systemv/lpstat.c:2138
-#: systemv/lpstat.c:2027 systemv/lpstat.c:2140
-msgid ""
-"\tForm mounted:\n"
-"\tContent types: any\n"
-"\tPrinter types: unknown\n"
-msgstr ""
-
-#: systemv/lpstat.c:2069 systemv/lpstat.c:2182 systemv/lpstat.c:2003
-#: systemv/lpstat.c:2116 systemv/lpstat.c:2031 systemv/lpstat.c:2144
-#: systemv/lpstat.c:2033 systemv/lpstat.c:2146
-#, c-format
-msgid "\tDescription: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2074 systemv/lpstat.c:2187 systemv/lpstat.c:2008
-#: systemv/lpstat.c:2121 systemv/lpstat.c:2036 systemv/lpstat.c:2149
-#: systemv/lpstat.c:2038 systemv/lpstat.c:2151
-msgid "\tAlerts:"
-msgstr ""
-
-#: systemv/lpstat.c:2083 systemv/lpstat.c:2196 systemv/lpstat.c:2017
-#: systemv/lpstat.c:2130 systemv/lpstat.c:2045 systemv/lpstat.c:2158
-#: systemv/lpstat.c:2047 systemv/lpstat.c:2160
-#, c-format
-msgid "\tLocation: %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2088 systemv/lpstat.c:2201 systemv/lpstat.c:2022
-#: systemv/lpstat.c:2135 systemv/lpstat.c:2050 systemv/lpstat.c:2163
-#: systemv/lpstat.c:2052 systemv/lpstat.c:2165
-msgid "\tConnection: remote\n"
-msgstr ""
-
-#: systemv/lpstat.c:2092 systemv/lpstat.c:2205 systemv/lpstat.c:2026
-#: systemv/lpstat.c:2139 systemv/lpstat.c:2054 systemv/lpstat.c:2167
-#: systemv/lpstat.c:2056 systemv/lpstat.c:2169
-#, c-format
-msgid "\tInterface: %s.ppd\n"
-msgstr ""
-
-#: systemv/lpstat.c:2097 systemv/lpstat.c:2210 systemv/lpstat.c:2031
-#: systemv/lpstat.c:2144 systemv/lpstat.c:2059 systemv/lpstat.c:2172
-#: systemv/lpstat.c:2061 systemv/lpstat.c:2174
-msgid "\tConnection: direct\n"
-msgstr ""
-
-#: systemv/lpstat.c:2101 systemv/lpstat.c:2214 systemv/lpstat.c:2035
-#: systemv/lpstat.c:2148 systemv/lpstat.c:2063 systemv/lpstat.c:2176
-#: systemv/lpstat.c:2065 systemv/lpstat.c:2178
-#, c-format
-msgid "\tInterface: %s/interfaces/%s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2105 systemv/lpstat.c:2218 systemv/lpstat.c:2039
-#: systemv/lpstat.c:2152 systemv/lpstat.c:2067 systemv/lpstat.c:2180
-#: systemv/lpstat.c:2069 systemv/lpstat.c:2182
-#, c-format
-msgid "\tInterface: %s/ppd/%s.ppd\n"
-msgstr ""
-
-#: systemv/lpstat.c:2107 systemv/lpstat.c:2220 systemv/lpstat.c:2041
-#: systemv/lpstat.c:2154 systemv/lpstat.c:2069 systemv/lpstat.c:2182
-#: systemv/lpstat.c:2071 systemv/lpstat.c:2184
-msgid "\tOn fault: no alert\n"
-msgstr ""
-
-#: systemv/lpstat.c:2108 systemv/lpstat.c:2221 systemv/lpstat.c:2042
-#: systemv/lpstat.c:2155 systemv/lpstat.c:2070 systemv/lpstat.c:2183
-#: systemv/lpstat.c:2072 systemv/lpstat.c:2185
-msgid "\tAfter fault: continue\n"
-msgstr ""
-
-#: systemv/lpstat.c:2112 systemv/lpstat.c:2126 systemv/lpstat.c:2225
-#: systemv/lpstat.c:2239 systemv/lpstat.c:2046 systemv/lpstat.c:2060
-#: systemv/lpstat.c:2159 systemv/lpstat.c:2173 systemv/lpstat.c:2074
-#: systemv/lpstat.c:2088 systemv/lpstat.c:2187 systemv/lpstat.c:2201
-#: systemv/lpstat.c:2076 systemv/lpstat.c:2090 systemv/lpstat.c:2189
-#: systemv/lpstat.c:2203
-msgid "\tUsers allowed:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2119 systemv/lpstat.c:2232 systemv/lpstat.c:2053
-#: systemv/lpstat.c:2166 systemv/lpstat.c:2081 systemv/lpstat.c:2194
-#: systemv/lpstat.c:2083 systemv/lpstat.c:2196
-msgid "\tUsers denied:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2127 systemv/lpstat.c:2240 systemv/lpstat.c:2061
-#: systemv/lpstat.c:2174 systemv/lpstat.c:2089 systemv/lpstat.c:2202
-#: systemv/lpstat.c:2091 systemv/lpstat.c:2204
-msgid "\t\t(all)\n"
-msgstr ""
-
-#: systemv/lpstat.c:2129 systemv/lpstat.c:2242 systemv/lpstat.c:2063
-#: systemv/lpstat.c:2176 systemv/lpstat.c:2091 systemv/lpstat.c:2204
-#: systemv/lpstat.c:2093 systemv/lpstat.c:2206
-msgid "\tForms allowed:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2130 systemv/lpstat.c:2133 systemv/lpstat.c:2243
-#: systemv/lpstat.c:2246 systemv/lpstat.c:2064 systemv/lpstat.c:2067
-#: systemv/lpstat.c:2177 systemv/lpstat.c:2180 systemv/lpstat.c:2092
-#: systemv/lpstat.c:2095 systemv/lpstat.c:2205 systemv/lpstat.c:2208
-#: systemv/lpstat.c:2094 systemv/lpstat.c:2097 systemv/lpstat.c:2207
-#: systemv/lpstat.c:2210
-msgid "\t\t(none)\n"
-msgstr ""
-
-#: systemv/lpstat.c:2131 systemv/lpstat.c:2244 systemv/lpstat.c:2065
-#: systemv/lpstat.c:2178 systemv/lpstat.c:2093 systemv/lpstat.c:2206
-#: systemv/lpstat.c:2095 systemv/lpstat.c:2208
-msgid "\tBanner required\n"
-msgstr ""
-
-#: systemv/lpstat.c:2132 systemv/lpstat.c:2245 systemv/lpstat.c:2066
-#: systemv/lpstat.c:2179 systemv/lpstat.c:2094 systemv/lpstat.c:2207
-#: systemv/lpstat.c:2096 systemv/lpstat.c:2209
-msgid "\tCharset sets:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2134 systemv/lpstat.c:2247 systemv/lpstat.c:2068
-#: systemv/lpstat.c:2181 systemv/lpstat.c:2096 systemv/lpstat.c:2209
-#: systemv/lpstat.c:2098 systemv/lpstat.c:2211
-msgid "\tDefault pitch:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2135 systemv/lpstat.c:2248 systemv/lpstat.c:2069
-#: systemv/lpstat.c:2182 systemv/lpstat.c:2097 systemv/lpstat.c:2210
-#: systemv/lpstat.c:2099 systemv/lpstat.c:2212
-msgid "\tDefault page size:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2136 systemv/lpstat.c:2249 systemv/lpstat.c:2070
-#: systemv/lpstat.c:2183 systemv/lpstat.c:2098 systemv/lpstat.c:2211
-#: systemv/lpstat.c:2100 systemv/lpstat.c:2213
-msgid "\tDefault port settings:\n"
-msgstr ""
-
-#: systemv/lpstat.c:2146 systemv/lpstat.c:2080 systemv/lpstat.c:2108
-#: systemv/lpstat.c:2110
-#, c-format
-msgid "printer %s/%s is idle.  enabled since %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2153 systemv/lpstat.c:2087 systemv/lpstat.c:2115
-#: systemv/lpstat.c:2117
-#, c-format
-msgid "printer %s/%s now printing %s-%d.  enabled since %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:2160 systemv/lpstat.c:2094 systemv/lpstat.c:2122
-#: systemv/lpstat.c:2124
-#, c-format
-msgid "printer %s/%s disabled since %s -\n"
-msgstr ""
-
-#: systemv/lpstat.c:2279 systemv/lpstat.c:2212 systemv/lpstat.c:2240
-#: systemv/lpstat.c:2242
-msgid "scheduler is running\n"
-msgstr ""
-
-#: systemv/lpstat.c:2281 systemv/lpstat.c:2214 systemv/lpstat.c:2242
-#: systemv/lpstat.c:2244
-msgid "scheduler is not running\n"
-msgstr ""
-
-#: systemv/lpadmin.c:113 systemv/lpadmin.c:166 systemv/lpadmin.c:237
-#: systemv/lpadmin.c:298 systemv/lpadmin.c:317 systemv/lpadmin.c:383
-#: systemv/lpadmin.c:424 systemv/lpadmin.c:511 systemv/lpadmin.c:557
-#: systemv/lpadmin.c:603 systemv/lpadmin.c:665 systemv/lpadmin.c:711
-#: systemv/lpadmin.c:772
-#, fuzzy, c-format
-msgid "lpadmin: Unable to connect to server: %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lpadmin.c:122
-msgid ""
-"lpadmin: Unable to add a printer to the class:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:137
-msgid "lpadmin: Expected class name after '-c' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:148 systemv/lpadmin.c:460
-msgid "lpadmin: Class name can only contain printable characters!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:181
-msgid "lpadmin: Expected printer name after '-d' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:192 systemv/lpadmin.c:409 systemv/lpadmin.c:583
-msgid "lpadmin: Printer name can only contain printable characters!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:219
-msgid "lpadmin: Expected hostname after '-h' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:246
-msgid ""
-"lpadmin: Unable to set the interface script:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:264
-msgid "lpadmin: Expected interface after '-i' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:326
-msgid ""
-"lpadmin: Unable to set the interface script or PPD file:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:345
-msgid "lpadmin: Expected model after '-m' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:365
-msgid "lpadmin: Expected name=value after '-o' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:398
-msgid "lpadmin: Expected printer after '-p' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:433
-msgid ""
-"lpadmin: Unable to remove a printer from the class:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:449
-msgid "lpadmin: Expected class after '-r' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:479
-msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:496
-#, fuzzy, c-format
-msgid "lpadmin: Unknown allow/deny option \"%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpadmin.c:520
-msgid ""
-"lpadmin: Unable to set the device URI:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:538
-msgid "lpadmin: Expected device URI after '-v' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:572
-msgid "lpadmin: Expected printer or class after '-x' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:612
-msgid ""
-"lpadmin: Unable to set the printer description:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:631
-msgid "lpadmin: Expected description after '-D' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:647
-msgid "lpadmin: Expected file type(s) after '-I' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:653
-msgid "lpadmin: Warning - content type list ignored!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:674
-msgid ""
-"lpadmin: Unable to set the printer location:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:692
-msgid "lpadmin: Expected location after '-L' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:720
-msgid ""
-"lpadmin: Unable to set the PPD file:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:738
-msgid "lpadmin: Expected PPD after '-P' option!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:749
-#, fuzzy, c-format
-msgid "lpadmin: Unknown option '%c'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpadmin.c:754
-#, fuzzy, c-format
-msgid "lpadmin: Unknown argument '%s'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpadmin.c:781
-msgid ""
-"lpadmin: Unable to set the printer options:\n"
-"         You must specify a printer name first!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:793
-msgid ""
-"Usage:\n"
-"\n"
-"    lpadmin [-h server] -d destination\n"
-"    lpadmin [-h server] -x destination\n"
-"    lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n"
-"                       [-r remove-class] [-v device] [-D description]\n"
-"                       [-P ppd-file] [-o name=value]\n"
-"                       [-u allow:user,user] [-u deny:user,user]\n"
-"\n"
-msgstr ""
-
-#: systemv/lpadmin.c:1554 systemv/lpadmin.c:1440
-#, fuzzy, c-format
-msgid "lpadmin: Unable to create temporary file: %s\n"
-msgstr "Incapable d'assigner la mémoire pour des types de dossier!"
-
-#: systemv/lpadmin.c:1562 systemv/lpadmin.c:1448
-#, fuzzy, c-format
-msgid "lpadmin: Unable to open file \"%s\": %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lpadmin.c:1631 systemv/lpadmin.c:1862 systemv/lpadmin.c:1870
-#, c-format
-msgid "lpadmin: add-printer (set model) failed: %s\n"
-msgstr ""
-
-#: systemv/lpadmin.c:1701 systemv/lpadmin.c:1708
-#, c-format
-msgid "lpadmin: add-printer (set description) failed: %s\n"
-msgstr ""
-
-#: systemv/lpadmin.c:1784 systemv/lpadmin.c:1792
-#, c-format
-msgid "lpadmin: add-printer (set location) failed: %s\n"
-msgstr ""
-
-#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814
-#, fuzzy, c-format
-msgid "lpadmin: Unable to create temporary file - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824
-#, fuzzy, c-format
-msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lpadmin.c:2117 systemv/lpadmin.c:2125
-#, c-format
-msgid "lpadmin: %s failed: %s\n"
-msgstr ""
-
-#: systemv/lp.c:153
-msgid "lp: Expected destination after -d option!\n"
-msgstr ""
-
-#: systemv/lp.c:184
-msgid "lp: Expected form after -f option!\n"
-msgstr ""
-
-#: systemv/lp.c:202
-msgid "lp: Expected hostname after -h option!\n"
-msgstr ""
-
-#: systemv/lp.c:220
-msgid "lp: Expected job ID after -i option!\n"
-msgstr ""
-
-#: systemv/lp.c:230
-msgid "lp: Error - cannot print files and alter jobs simultaneously!\n"
-msgstr ""
-
-#: systemv/lp.c:242
-msgid "lp: Error - bad job ID!\n"
-msgstr ""
-
-#: systemv/lp.c:264
-msgid "lp: Expected copies after -n option!\n"
-msgstr ""
-
-#: systemv/lp.c:285
-msgid "lp: Expected option string after -o option!\n"
-msgstr ""
-
-#: systemv/lp.c:304
-#, c-format
-msgid "lp: Expected priority after -%c option!\n"
-msgstr ""
-
-#: systemv/lp.c:326
-msgid "lp: Priority must be between 1 and 100.\n"
-msgstr ""
-
-#: systemv/lp.c:348
-msgid "lp: Expected title after -t option!\n"
-msgstr ""
-
-#: systemv/lp.c:364
-msgid "lp: Expected mode list after -y option!\n"
-msgstr ""
-
-#: systemv/lp.c:370
-msgid "lp: Warning - mode option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:383
-msgid "lp: Expected hold name after -H option!\n"
-msgstr ""
-
-#: systemv/lp.c:405
-msgid "lp: Need job ID (-i) before \"-H restart\"!\n"
-msgstr ""
-
-#: systemv/lp.c:427
-msgid "lp: Expected page list after -P option!\n"
-msgstr ""
-
-#: systemv/lp.c:446
-msgid "lp: Expected character set after -S option!\n"
-msgstr ""
-
-#: systemv/lp.c:452
-msgid "lp: Warning - character set option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:463
-msgid "lp: Expected content type after -T option!\n"
-msgstr ""
-
-#: systemv/lp.c:469
-msgid "lp: Warning - content type option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:473
-#, fuzzy, c-format
-msgid "lp: Unknown option '%c'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lp.c:482
-msgid ""
-"lp: Error - cannot print from stdin if files or a job ID are provided!\n"
-msgstr ""
-
-#: systemv/lp.c:497
-#, c-format
-msgid "lp: Unable to access \"%s\" - %s\n"
-msgstr ""
-
-#: systemv/lp.c:514
-#, c-format
-msgid "lp: Too many files - \"%s\"\n"
-msgstr ""
-
-#: systemv/lp.c:569
-msgid "lp: error - no default destination available.\n"
-msgstr ""
-
-#: systemv/lp.c:572
-msgid "lp: error - scheduler not responding!\n"
-msgstr ""
-
-#: systemv/lp.c:611
-#, fuzzy, c-format
-msgid "lp: unable to create temporary file \"%s\" - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lp.c:620
-#, c-format
-msgid "lp: error - unable to write to temporary file \"%s\" - %s\n"
-msgstr ""
-
-#: systemv/lp.c:634
-msgid "lp: stdin is empty, so no job has been sent.\n"
-msgstr ""
-
-#: systemv/lp.c:650
-#, fuzzy, c-format
-msgid "lp: unable to print file: %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lp.c:656 systemv/lp.c:653 systemv/lp.c:713 systemv/lp.c:729
-#, c-format
-msgid "request id is %s-%d (%d file(s))\n"
-msgstr ""
-
-#: systemv/lp.c:703 systemv/lp.c:713
-#, c-format
-msgid "lp: restart-job failed: %s\n"
-msgstr ""
-
-#: systemv/lp.c:769 systemv/lp.c:779
-#, c-format
-msgid "lp: set-job-attributes failed: %s\n"
-msgstr ""
-
-#: systemv/lpinfo.c:98 systemv/lpinfo.c:117
-#, c-format
-msgid "lpinfo: Unable to connect to server: %s\n"
-msgstr ""
-
-#: systemv/lpinfo.c:152
-#, fuzzy, c-format
-msgid "lpinfo: Unknown option '%c'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpinfo.c:158
-#, fuzzy, c-format
-msgid "lpinfo: Unknown argument '%s'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpinfo.c:225 systemv/lpinfo.c:310
-#, c-format
-msgid "lpinfo: cups-get-devices failed: %s\n"
-msgstr ""
-
-#: systemv/lpinfo.c:293
-#, c-format
-msgid ""
-"Device: uri = %s\n"
-"        class = %s\n"
-"        info = %s\n"
-"        make-and-model = %s\n"
-msgstr ""
-
-#: systemv/lpinfo.c:376 systemv/lpinfo.c:454
-#, c-format
-msgid "lpinfo: cups-get-ppds failed: %s\n"
-msgstr ""
-
-#: systemv/lpinfo.c:438
-#, c-format
-msgid ""
-"Model:  name = %s\n"
-"        natural_language = %s\n"
-"        make-and-model = %s\n"
-msgstr ""
-
-#: systemv/lpmove.c:114 systemv/lpmove.c:119
-#, fuzzy, c-format
-msgid "lpmove: Unknown option '%c'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpmove.c:133 systemv/lpmove.c:138
-#, fuzzy, c-format
-msgid "lpmove: Unknown argument '%s'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/lpmove.c:140
-msgid "Usage: lpmove job dest\n"
-msgstr ""
-
-#: systemv/lpmove.c:151 systemv/lpmove.c:156
-#, c-format
-msgid "lpmove: Unable to connect to server: %s\n"
-msgstr ""
-
-#: systemv/lpmove.c:225 systemv/lpmove.c:234
-#, c-format
-msgid "lpmove: move-job failed: %s\n"
-msgstr ""
-
-#: systemv/lpoptions.c:109
-msgid "lpoptions: Unknown printer or class!\n"
-msgstr ""
-
-#: systemv/lpoptions.c:159
-msgid "lpoptions: No printers!?!\n"
-msgstr ""
-
-#: systemv/lpoptions.c:207
-#, c-format
-msgid "lpoptions: Unable to add printer or instance: %s\n"
-msgstr ""
-
-#: systemv/lpoptions.c:411
-#, c-format
-msgid "lpoptions: Destination %s has no PPD file!\n"
-msgstr ""
-
-#: systemv/lpoptions.c:420
-#, fuzzy, c-format
-msgid "lpoptions: Unable to open PPD file for %s!\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/lpoptions.c:444
-msgid ""
-"Usage: lpoptions [-h server] [-E] -d printer\n"
-"       lpoptions [-h server] [-E] [-p printer] -l\n"
-"       lpoptions [-h server] [-E] -p printer -o option[=value] ...\n"
-"       lpoptions [-h server] [-E] -x printer\n"
-msgstr ""
-
-#: systemv/lppasswd.c:192
-msgid "lppasswd: Only root can add or delete passwords!\n"
-msgstr ""
-
-#: systemv/lppasswd.c:212
-msgid "Enter old password:"
-msgstr ""
-
-#: systemv/lppasswd.c:218 systemv/lppasswd.c:236
-#, c-format
-msgid "lppasswd: Unable to copy password string: %s\n"
-msgstr ""
-
-#: systemv/lppasswd.c:230
-msgid "Enter password:"
-msgstr ""
-
-#: systemv/lppasswd.c:241
-msgid "Enter password again:"
-msgstr ""
-
-#: systemv/lppasswd.c:247
-msgid "lppasswd: Sorry, passwords don't match!\n"
-msgstr ""
-
-#: systemv/lppasswd.c:271
-msgid ""
-"lppasswd: Sorry, password rejected.\n"
-"Your password must be at least 6 characters long, cannot contain\n"
-"your username, and must contain at least one letter and number.\n"
-msgstr ""
-
-#: systemv/lppasswd.c:321
-msgid "lppasswd: Password file busy!\n"
-msgstr ""
-
-#: systemv/lppasswd.c:324 systemv/lppasswd.c:333 systemv/lppasswd.c:351
-#, c-format
-msgid "lppasswd: Unable to open password file: %s\n"
-msgstr ""
-
-#: systemv/lppasswd.c:386 systemv/lppasswd.c:399 systemv/lppasswd.c:431
-#, c-format
-msgid "lppasswd: Unable to write to password file: %s\n"
-msgstr ""
-
-#: systemv/lppasswd.c:411
-#, c-format
-msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n"
-msgstr ""
-
-#: systemv/lppasswd.c:421
-msgid "lppasswd: Sorry, password doesn't match!\n"
-msgstr ""
-
-#: systemv/lppasswd.c:454
-msgid "lppasswd: Password file not updated!\n"
-msgstr ""
-
-#: systemv/lppasswd.c:469
-#, c-format
-msgid "lppasswd: failed to backup old password file: %s\n"
-msgstr ""
-
-#: systemv/lppasswd.c:482
-#, c-format
-msgid "lppasswd: failed to rename password file: %s\n"
-msgstr ""
-
-#: systemv/lppasswd.c:501 systemv/lppasswd.c:500
-msgid "Usage: lppasswd [-g groupname]\n"
-msgstr ""
-
-#: systemv/lppasswd.c:506 systemv/lppasswd.c:503
-msgid ""
-"Usage: lppasswd [-g groupname] [username]\n"
-"       lppasswd [-g groupname] -a [username]\n"
-"       lppasswd [-g groupname] -x [username]\n"
-msgstr ""
-
-#: cgi-bin/admin.c:125 cgi-bin/admin.c:142
-#, fuzzy
-msgid "Start Printer"
-msgstr "Imprimeur"
-
-#: cgi-bin/admin.c:127 cgi-bin/admin.c:144
-#, fuzzy
-msgid "Stop Printer"
-msgstr "Imprimeur"
-
-#: cgi-bin/admin.c:129 cgi-bin/admin.c:146
-#, fuzzy
-msgid "Start Class"
-msgstr "Classe"
-
-#: cgi-bin/admin.c:131 cgi-bin/admin.c:148
-#, fuzzy
-msgid "Stop Class"
-msgstr "Classe"
-
-#: cgi-bin/admin.c:133 cgi-bin/admin.c:150
-msgid "Accept Jobs"
-msgstr ""
-
-#: cgi-bin/admin.c:135 cgi-bin/admin.c:152
-msgid "Reject Jobs"
-msgstr ""
-
-#: cgi-bin/admin.c:137 cgi-bin/admin.c:154
-msgid "Purge Jobs"
-msgstr ""
-
-#: cgi-bin/admin.c:141 cgi-bin/admin.c:158
-msgid "Set As Default"
-msgstr ""
-
-#: cgi-bin/admin.c:168 cgi-bin/admin.c:179 cgi-bin/admin.c:2690
-#: cgi-bin/admin.c:185 cgi-bin/admin.c:196 cgi-bin/admin.c:2734
-msgid "Administration"
-msgstr ""
-
-#: cgi-bin/admin.c:224 cgi-bin/admin.c:241
-msgid "Modify Class"
-msgstr ""
-
-#: cgi-bin/admin.c:224 cgi-bin/admin.c:241
-#, fuzzy
-msgid "Add Class"
-msgstr "Classe"
-
-#: cgi-bin/admin.c:385 cgi-bin/admin.c:402
-msgid ""
-"The class name may only contain up to 127 printable characters and may not "
-"contain spaces, slashes (/), or the pound sign (#)."
-msgstr ""
-
-#: cgi-bin/admin.c:444 cgi-bin/admin.c:462
-msgid "Unable to modify class:"
-msgstr ""
-
-#: cgi-bin/admin.c:445 cgi-bin/admin.c:463
-msgid "Unable to add class:"
-msgstr ""
-
-#: cgi-bin/admin.c:514 cgi-bin/admin.c:532
-#, fuzzy
-msgid "Modify Printer"
-msgstr "Imprimeur"
-
-#: cgi-bin/admin.c:514 cgi-bin/admin.c:532
-#, fuzzy
-msgid "Add Printer"
-msgstr "Imprimeur"
-
-#: cgi-bin/admin.c:583 cgi-bin/admin.c:602
-msgid ""
-"The printer name may only contain up to 127 printable characters and may not "
-"contain spaces, slashes (/), or the pound sign (#)."
-msgstr ""
-
-#: cgi-bin/admin.c:900 cgi-bin/admin.c:930
-msgid "Unable to get list of printer drivers:"
-msgstr ""
-
-#: cgi-bin/admin.c:983 cgi-bin/admin.c:1014
-#, fuzzy
-msgid "Unable to modify printer:"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: cgi-bin/admin.c:984 cgi-bin/admin.c:1015
-#, fuzzy
-msgid "Unable to add printer:"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: cgi-bin/admin.c:1051 cgi-bin/admin.c:1082
-msgid "Set Printer Options"
-msgstr ""
-
-#: cgi-bin/admin.c:1062 cgi-bin/admin.c:2330 cgi-bin/admin.c:2391
-#: cgi-bin/admin.c:3112 cgi-bin/admin.c:3213 cgi-bin/admin.c:3449
-#: cgi-bin/admin.c:1095 cgi-bin/admin.c:2374 cgi-bin/admin.c:2435
-#: cgi-bin/admin.c:3156 cgi-bin/admin.c:3258 cgi-bin/admin.c:3496
-#, fuzzy
-msgid "Missing form variable!"
-msgstr "Attributs requis manquants!"
-
-#: cgi-bin/admin.c:1076 cgi-bin/admin.c:1113
-#, fuzzy
-msgid "Unable to get PPD file!"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: cgi-bin/admin.c:1084 cgi-bin/admin.c:1123
-#, fuzzy
-msgid "Unable to open PPD file:"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: cgi-bin/admin.c:1241 cgi-bin/admin.c:1282
-msgid "Banners"
-msgstr ""
-
-#: cgi-bin/admin.c:1255 cgi-bin/admin.c:1296
-msgid "Starting Banner"
-msgstr ""
-
-#: cgi-bin/admin.c:1262 cgi-bin/admin.c:1303
-msgid "Ending Banner"
-msgstr ""
-
-#: cgi-bin/admin.c:1280 cgi-bin/admin.c:1321
-msgid "Policies"
-msgstr ""
-
-#: cgi-bin/admin.c:1304 cgi-bin/admin.c:1345
-msgid "Error Policy"
-msgstr ""
-
-#: cgi-bin/admin.c:1331 cgi-bin/admin.c:1372
-msgid "Operation Policy"
-msgstr ""
-
-#: cgi-bin/admin.c:1352 cgi-bin/admin.c:1372 cgi-bin/admin.c:1393
-#: cgi-bin/admin.c:1413
-msgid "PS Binary Protocol"
-msgstr ""
-
-#: cgi-bin/admin.c:1358 cgi-bin/admin.c:1399
-#, fuzzy
-msgid "None"
-msgstr "Non"
-
-#: cgi-bin/admin.c:1490 cgi-bin/admin.c:1534
-msgid "Unable to set options:"
-msgstr ""
-
-#: cgi-bin/admin.c:1591 cgi-bin/admin.c:1607 cgi-bin/admin.c:1620
-#: cgi-bin/admin.c:2099 cgi-bin/admin.c:2106 cgi-bin/admin.c:1635
-#: cgi-bin/admin.c:1651 cgi-bin/admin.c:1664 cgi-bin/admin.c:2143
-#: cgi-bin/admin.c:2150
-msgid "Change Settings"
-msgstr ""
-
-#: cgi-bin/admin.c:1592 cgi-bin/admin.c:1608 cgi-bin/admin.c:1621
-#: cgi-bin/admin.c:1636 cgi-bin/admin.c:1652 cgi-bin/admin.c:1665
-msgid "Unable to change server settings:"
-msgstr ""
-
-#: cgi-bin/admin.c:2097 cgi-bin/admin.c:2190 cgi-bin/admin.c:2141
-#: cgi-bin/admin.c:2234
-msgid "Unable to upload cupsd.conf file:"
-msgstr ""
-
-#: cgi-bin/admin.c:2134 cgi-bin/admin.c:2146 cgi-bin/admin.c:2193
-#: cgi-bin/admin.c:2200 cgi-bin/admin.c:2232 cgi-bin/admin.c:2244
-#: cgi-bin/admin.c:2267 cgi-bin/admin.c:2178 cgi-bin/admin.c:2190
-#: cgi-bin/admin.c:2237 cgi-bin/admin.c:2276 cgi-bin/admin.c:2288
-#: cgi-bin/admin.c:2311
-msgid "Edit Configuration File"
-msgstr ""
-
-#: cgi-bin/admin.c:2135 cgi-bin/admin.c:2147 cgi-bin/admin.c:2179
-#: cgi-bin/admin.c:2191
-#, fuzzy
-msgid "Unable to create temporary file:"
-msgstr "Incapable d'assigner la mémoire pour des types de dossier!"
-
-#: cgi-bin/admin.c:2233 cgi-bin/admin.c:2245 cgi-bin/admin.c:2268
-#: cgi-bin/admin.c:2277 cgi-bin/admin.c:2289 cgi-bin/admin.c:2312
-msgid "Unable to access cupsd.conf file:"
-msgstr ""
-
-#: cgi-bin/admin.c:2247 cgi-bin/admin.c:2291
-msgid "Unable to edit cupsd.conf files larger than 1MB!"
-msgstr ""
-
-#: cgi-bin/admin.c:2316 cgi-bin/admin.c:2360
-msgid "Delete Class"
-msgstr ""
-
-#: cgi-bin/admin.c:2357 cgi-bin/admin.c:2401
-msgid "Unable to delete class:"
-msgstr ""
-
-#: cgi-bin/admin.c:2377 cgi-bin/admin.c:2421
-#, fuzzy
-msgid "Delete Printer"
-msgstr "Imprimeur"
-
-#: cgi-bin/admin.c:2418 cgi-bin/admin.c:2462
-#, fuzzy
-msgid "Unable to delete printer:"
-msgstr "Aucun imprimeur de défaut"
-
-#: cgi-bin/admin.c:2447 cgi-bin/admin.c:2491
-msgid "Export Printers to Samba"
-msgstr ""
-
-#: cgi-bin/admin.c:2515 cgi-bin/admin.c:2559
-#, fuzzy
-msgid "Unable to fork process!"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: cgi-bin/admin.c:2534 cgi-bin/admin.c:2578
-#, fuzzy
-msgid "Unable to connect to server!"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: cgi-bin/admin.c:2538 cgi-bin/admin.c:2582
-#, fuzzy
-msgid "Unable to get printer attributes!"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: cgi-bin/admin.c:2543 cgi-bin/admin.c:2587
-#, fuzzy
-msgid "Unable to convert PPD file!"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: cgi-bin/admin.c:2547 cgi-bin/admin.c:2591
-#, fuzzy
-msgid "Unable to copy Windows 2000 printer driver files!"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: cgi-bin/admin.c:2552 cgi-bin/admin.c:2596
-msgid "Unable to install Windows 2000 printer driver files!"
-msgstr ""
-
-#: cgi-bin/admin.c:2557 cgi-bin/admin.c:2601
-#, fuzzy
-msgid "Unable to copy Windows 9x printer driver files!"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: cgi-bin/admin.c:2562 cgi-bin/admin.c:2606
-msgid "Unable to install Windows 9x printer driver files!"
-msgstr ""
-
-#: cgi-bin/admin.c:2567 cgi-bin/admin.c:2611
-msgid "Unable to set Windows printer driver!"
-msgstr ""
-
-#: cgi-bin/admin.c:2572 cgi-bin/admin.c:2616
-msgid "No printer drivers found!"
-msgstr ""
-
-#: cgi-bin/admin.c:2576 cgi-bin/admin.c:2620
-msgid "Unable to execute cupsaddsmb command!"
-msgstr ""
-
-#: cgi-bin/admin.c:2582 cgi-bin/admin.c:2626
-#, c-format
-msgid "cupsaddsmb failed with status %d"
-msgstr ""
-
-#: cgi-bin/admin.c:2592 cgi-bin/admin.c:2636
-#, c-format
-msgid "cupsaddsmb crashed on signal %d"
-msgstr ""
-
-#: cgi-bin/admin.c:2608 cgi-bin/admin.c:2652
-msgid "A Samba username is required to export printer drivers!"
-msgstr ""
-
-#: cgi-bin/admin.c:2612 cgi-bin/admin.c:2656
-msgid "A Samba password is required to export printer drivers!"
-msgstr ""
-
-#: cgi-bin/admin.c:2704 cgi-bin/admin.c:2748
-#, fuzzy
-msgid "Unable to open cupsd.conf file:"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: cgi-bin/admin.c:3144 cgi-bin/admin.c:3400 cgi-bin/admin.c:3189
-#: cgi-bin/admin.c:3447
-msgid "Unable to change printer:"
-msgstr ""
-
-#: cgi-bin/admin.c:3214 cgi-bin/admin.c:3259 cgi-bin/admin.c:3399
-#: cgi-bin/admin.c:3417 cgi-bin/admin.c:3305 cgi-bin/admin.c:3446
-#: cgi-bin/admin.c:3464
-msgid "Set Allowed Users"
-msgstr ""
-
-#: cgi-bin/admin.c:3262 cgi-bin/admin.c:3308
-#, fuzzy
-msgid "Unable to get printer attributes:"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: cgi-bin/admin.c:3450 cgi-bin/admin.c:3488 cgi-bin/admin.c:3506
-#: cgi-bin/admin.c:3497 cgi-bin/admin.c:3536 cgi-bin/admin.c:3554
-msgid "Set Publishing"
-msgstr ""
-
-#: cgi-bin/admin.c:3489 cgi-bin/admin.c:3537
-msgid "Unable to change printer-is-shared attribute:"
-msgstr ""
-
-#: cgi-bin/classes.c:161 cgi-bin/classes.c:208
-#, fuzzy
-msgid "Classes"
-msgstr "Classe"
-
-#: cgi-bin/classes.c:355 cgi-bin/classes.c:356
-msgid "Unable to get class list:"
-msgstr ""
-
-#: cgi-bin/classes.c:454 cgi-bin/classes.c:455
-msgid "Unable to get class status:"
-msgstr ""
-
-#: cgi-bin/ipp-var.c:366 cgi-bin/ipp-var.c:419 cgi-bin/ipp-var.c:489
-#: cgi-bin/ipp-var.c:490
-msgid "Move Job"
-msgstr ""
-
-#: cgi-bin/ipp-var.c:367
-#, fuzzy
-msgid "Unable to find destination for job!"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: cgi-bin/ipp-var.c:421 cgi-bin/ipp-var.c:491 cgi-bin/ipp-var.c:492
-msgid "Move All Jobs"
-msgstr ""
-
-#: cgi-bin/ipp-var.c:496 cgi-bin/ipp-var.c:497
-msgid "Unable to move job"
-msgstr ""
-
-#: cgi-bin/ipp-var.c:498 cgi-bin/ipp-var.c:499
-msgid "Unable to move jobs"
-msgstr ""
-
-#: cgi-bin/ipp-var.c:603 cgi-bin/ipp-var.c:605
-msgid "Print Test Page"
-msgstr ""
-
-#: cgi-bin/ipp-var.c:606 cgi-bin/ipp-var.c:608
-#, fuzzy
-msgid "Unable to print test page:"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: cgi-bin/jobs.c:111 cgi-bin/jobs.c:122 cgi-bin/jobs.c:184
-msgid "Jobs"
-msgstr ""
-
-#: cgi-bin/jobs.c:187
-msgid "Job operation failed:"
-msgstr ""
-
-#: cgi-bin/printers.c:161 cgi-bin/printers.c:208 cgi-bin/printers.c:211
-#, fuzzy
-msgid "Printers"
-msgstr "Imprimeur"
-
-#: cgi-bin/printers.c:362 cgi-bin/printers.c:366
-#, fuzzy
-msgid "Unable to get printer list:"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: cgi-bin/printers.c:461 cgi-bin/printers.c:468
-#, fuzzy
-msgid "Unable to get printer status:"
-msgstr "Incapable de copier le manuscrit d'interface - %s!"
-
-#: cups/ppd.c:319
-msgid "OK"
-msgstr ""
-
-#: cups/ppd.c:320
-#, fuzzy
-msgid "Unable to open PPD file"
-msgstr "Incapable de copier le dossier de PPD!"
-
-#: cups/ppd.c:321
-msgid "NULL PPD file pointer"
-msgstr ""
-
-#: cups/ppd.c:322
-msgid "Memory allocation error"
-msgstr ""
-
-#: cups/ppd.c:323
-msgid "Missing PPD-Adobe-4.x header"
-msgstr ""
-
-#: cups/ppd.c:324
-msgid "Missing value string"
-msgstr ""
-
-#: cups/ppd.c:325
-msgid "Internal error"
-msgstr ""
-
-#: cups/ppd.c:326
-msgid "Bad OpenGroup"
-msgstr ""
-
-#: cups/ppd.c:327
-msgid "OpenGroup without a CloseGroup first"
-msgstr ""
-
-#: cups/ppd.c:328
-msgid "Bad OpenUI/JCLOpenUI"
-msgstr ""
-
-#: cups/ppd.c:329
-msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first"
-msgstr ""
-
-#: cups/ppd.c:330
-msgid "Bad OrderDependency"
-msgstr ""
-
-#: cups/ppd.c:331
-msgid "Bad UIConstraints"
-msgstr ""
-
-#: cups/ppd.c:332
-msgid "Missing asterisk in column 1"
-msgstr ""
-
-#: cups/ppd.c:333
-msgid "Line longer than the maximum allowed (255 characters)"
-msgstr ""
-
-#: cups/ppd.c:334
-msgid "Illegal control character"
-msgstr ""
-
-#: cups/ppd.c:335
-msgid "Illegal main keyword string"
-msgstr ""
-
-#: cups/ppd.c:336
-msgid "Illegal option keyword string"
-msgstr ""
-
-#: cups/ppd.c:337
-msgid "Illegal translation string"
-msgstr ""
-
-#: cups/ppd.c:338
-msgid "Illegal whitespace character"
-msgstr ""
-
-#: cups/ppd.c:339
-msgid "Bad custom parameter"
-msgstr ""
-
-#: cups/ppd.c:344
-msgid "Unknown"
-msgstr ""
-
-#: cups/ppd.c:1033
-#, fuzzy
-msgid "Custom"
-msgstr "Automobile"
-
-#: cups/ppd.c:1259
-msgid "JCL"
-msgstr ""
-
-#: scheduler/ipp.c:2184 scheduler/ipp.c:2226
-msgid "No authentication information provided!"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:440
-#, c-format
-msgid "Password for %s required to access %s via SAMBA: "
-msgstr ""
-
-#: systemv/cupsaddsmb.c:451
-#, c-format
-msgid "Running command: %s %s -N -U '%s%%%s' -c '%s'\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:479
-#, fuzzy, c-format
-msgid "cupsaddsmb: Unable to run \"%s\": %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: systemv/cupsaddsmb.c:805
-msgid "cupsaddsmb: No Windows printer drivers are installed!\n"
-msgstr ""
-
-#: systemv/cupsaddsmb.c:810
-msgid "cupsaddsmb: Warning, no Windows 2000 printer drivers are installed!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:881
-#, c-format
-msgid "lpadmin: Printer %s is already a member of class %s.\n"
-msgstr ""
-
-#: systemv/lpadmin.c:1115
-msgid "lpadmin: No member names were seen!\n"
-msgstr ""
-
-#: systemv/lpadmin.c:1129
-#, c-format
-msgid "lpadmin: Printer %s is not a member of class %s.\n"
-msgstr ""
-
-#: systemv/lpinfo.c:278
-#, c-format
-msgid ""
-"Device: uri = %s\n"
-"        class = %s\n"
-"        info = %s\n"
-"        make-and-model = %s\n"
-"        device-id = %s\n"
-msgstr ""
-
-#: systemv/lpinfo.c:410
-#, c-format
-msgid ""
-"Model:  name = %s\n"
-"        natural_language = %s\n"
-"        make-and-model = %s\n"
-"        device-id = %s\n"
-msgstr ""
-
-#: systemv/lpmove.c:145
-msgid "Usage: lpmove job/src dest\n"
-msgstr ""
-
-#: systemv/lpstat.c:144 systemv/lpstat.c:156
-msgid "lpstat: Need \"completed\", \"not-completed\", or \"all\" after -W!\n"
-msgstr ""
-
-#: systemv/lpstat.c:740 systemv/lpstat.c:768
-#, c-format
-msgid "%s accepting requests since %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:743 systemv/lpstat.c:771
-#, c-format
-msgid ""
-"%s not accepting requests since %s -\n"
-"\t%s\n"
-msgstr ""
-
-#: systemv/lpstat.c:752 systemv/lpstat.c:780
-#, c-format
-msgid "%s/%s accepting requests since %s\n"
-msgstr ""
-
-#: systemv/lpstat.c:755 systemv/lpstat.c:783
-#, c-format
-msgid ""
-"%s/%s not accepting requests since %s -\n"
-"\t%s\n"
-msgstr ""
-
-#: berkeley/lpc.c:88 berkeley/lpc.c:116 berkeley/lpc.c:152
-msgid "lpc> "
-msgstr ""
-
-#: berkeley/lpq.c:93 systemv/cancel.c:250 systemv/cancel.c:332
-#: systemv/cancel.c:331
-#, fuzzy, c-format
-msgid "%s: Unable to contact server!\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: berkeley/lpq.c:138 berkeley/lpr.c:128 berkeley/lprm.c:144
-#: systemv/accept.c:120 systemv/cancel.c:107 systemv/lp.c:150
-#: systemv/lpstat.c:144 berkeley/lpr.c:130 systemv/lp.c:154
-#, c-format
-msgid "%s: Error - expected username after '-U' option!\n"
-msgstr ""
-
-#: berkeley/lpq.c:173
-#, fuzzy, c-format
-msgid "%s: Error - unknown destination \"%s/%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: berkeley/lpq.c:177 systemv/lpstat.c:549
-#, fuzzy, c-format
-msgid "%s: Unknown destination \"%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: berkeley/lpq.c:201 berkeley/lprm.c:167 systemv/accept.c:146
-#: systemv/cancel.c:135 systemv/lp.c:227 systemv/lpstat.c:300 systemv/lp.c:231
-#, c-format
-msgid "%s: Error - expected hostname after '-h' option!\n"
-msgstr ""
-
-#: berkeley/lpq.c:253
-#, c-format
-msgid ""
-"%s: error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr ""
-
-#: berkeley/lpq.c:258
-#, c-format
-msgid "%s: error - no default destination available.\n"
-msgstr ""
-
-#: berkeley/lpq.c:647
-msgid ""
-"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n"
-msgstr ""
-
-#: berkeley/lpr.c:148 berkeley/lpr.c:150
-#, c-format
-msgid "%s: Error - expected hostname after '-H' option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:171 berkeley/lpr.c:173
-#, c-format
-msgid "%s: Error - expected value after '-%c' option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:185 berkeley/lpr.c:187
-#, c-format
-msgid ""
-"%s: Warning - '%c' format modifier not supported - output may not be "
-"correct!\n"
-msgstr ""
-
-#: berkeley/lpr.c:199 berkeley/lpr.c:201
-#, c-format
-msgid "%s: error - expected option=value after '-o' option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:250 berkeley/lpr.c:258
-#, c-format
-msgid "%s: Error - expected destination after '-P' option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:285 berkeley/lpr.c:293
-#, c-format
-msgid "%s: Error - expected copy count after '-#' option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:309 berkeley/lpr.c:317
-#, c-format
-msgid "%s: Error - expected name after '-%c' option!\n"
-msgstr ""
-
-#: berkeley/lpr.c:320 berkeley/lprm.c:179 systemv/accept.c:176
-#: systemv/cancel.c:169 systemv/lp.c:529 systemv/lpstat.c:461
-#: berkeley/lpr.c:328 systemv/lp.c:545
-#, fuzzy, c-format
-msgid "%s: Error - unknown option '%c'!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: berkeley/lpr.c:333 systemv/lp.c:554 berkeley/lpr.c:341 systemv/lp.c:570
-#, c-format
-msgid "%s: Error - unable to access \"%s\" - %s\n"
-msgstr ""
-
-#: berkeley/lpr.c:351 systemv/lp.c:571 berkeley/lpr.c:359 systemv/lp.c:587
-#, c-format
-msgid "%s: Error - too many files - \"%s\"\n"
-msgstr ""
-
-#: berkeley/lpr.c:393 systemv/lp.c:621 berkeley/lpr.c:401 systemv/lp.c:637
-#, c-format
-msgid ""
-"%s: Error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr ""
-
-#: berkeley/lpr.c:398 systemv/lp.c:626 berkeley/lpr.c:406 systemv/lp.c:642
-#, c-format
-msgid "%s: Error - no default destination available.\n"
-msgstr ""
-
-#: berkeley/lpr.c:402 systemv/lp.c:630 berkeley/lpr.c:410 systemv/lp.c:646
-#, c-format
-msgid "%s: Error - scheduler not responding!\n"
-msgstr ""
-
-#: berkeley/lpr.c:452 systemv/lp.c:670 berkeley/lpr.c:460 systemv/lp.c:686
-#, fuzzy, c-format
-msgid "%s: Error - unable to create temporary file \"%s\" - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: berkeley/lpr.c:462 systemv/lp.c:679 berkeley/lpr.c:470 systemv/lp.c:695
-#, fuzzy, c-format
-msgid "%s: Error - unable to write to temporary file \"%s\" - %s\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: berkeley/lpr.c:476 systemv/lp.c:693 berkeley/lpr.c:484 systemv/lp.c:709
-#, c-format
-msgid "%s: Error - stdin is empty, so no job has been sent.\n"
-msgstr ""
-
-#: berkeley/lprm.c:127 systemv/cancel.c:227
-#, fuzzy, c-format
-msgid "%s: Error - unknown destination \"%s\"!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: systemv/accept.c:165
-#, c-format
-msgid "%s: Error - expected reason text after '-r' option!\n"
-msgstr ""
-
-#: systemv/cancel.c:157
-#, c-format
-msgid "%s: Error - expected username after '-u' option!\n"
-msgstr ""
-
-#: systemv/cancel.c:308 systemv/cancel.c:373 systemv/cancel.c:372
-#, c-format
-msgid "%s: %s failed: %s\n"
-msgstr ""
-
-#: systemv/lp.c:173 systemv/lp.c:177
-#, c-format
-msgid "%s: Error - expected destination after '-d' option!\n"
-msgstr ""
-
-#: systemv/lp.c:206 systemv/lp.c:210
-#, c-format
-msgid "%s: Error - expected form after '-f' option!\n"
-msgstr ""
-
-#: systemv/lp.c:213 systemv/lp.c:217
-#, c-format
-msgid "%s: Warning - form option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:247 systemv/lp.c:251
-#, c-format
-msgid "%s: Expected job ID after '-i' option!\n"
-msgstr ""
-
-#: systemv/lp.c:258 systemv/lp.c:262
-#, c-format
-msgid "%s: Error - cannot print files and alter jobs simultaneously!\n"
-msgstr ""
-
-#: systemv/lp.c:271 systemv/lp.c:275
-#, c-format
-msgid "%s: Error - bad job ID!\n"
-msgstr ""
-
-#: systemv/lp.c:296 systemv/lp.c:308
-#, c-format
-msgid "%s: Error - expected copies after '-n' option!\n"
-msgstr ""
-
-#: systemv/lp.c:319 systemv/lp.c:331
-#, c-format
-msgid "%s: Error - expected option string after '-o' option!\n"
-msgstr ""
-
-#: systemv/lp.c:340 systemv/lp.c:352
-#, c-format
-msgid "%s: Error - expected priority after '-%c' option!\n"
-msgstr ""
-
-#: systemv/lp.c:363 systemv/lp.c:375
-#, c-format
-msgid "%s: Error - priority must be between 1 and 100.\n"
-msgstr ""
-
-#: systemv/lp.c:387 systemv/lp.c:399
-#, c-format
-msgid "%s: Error - expected title after '-t' option!\n"
-msgstr ""
-
-#: systemv/lp.c:405 systemv/lp.c:417
-#, c-format
-msgid "%s: Error - expected mode list after '-y' option!\n"
-msgstr ""
-
-#: systemv/lp.c:413 systemv/lp.c:425
-#, c-format
-msgid "%s: Warning - mode option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:427 systemv/lp.c:439
-#, c-format
-msgid "%s: Error - expected hold name after '-H' option!\n"
-msgstr ""
-
-#: systemv/lp.c:451 systemv/lp.c:463
-#, c-format
-msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n"
-msgstr ""
-
-#: systemv/lp.c:475 systemv/lp.c:487
-#, c-format
-msgid "%s: Error - expected page list after '-P' option!\n"
-msgstr ""
-
-#: systemv/lp.c:496 systemv/lp.c:508
-#, c-format
-msgid "%s: Error - expected character set after '-S' option!\n"
-msgstr ""
-
-#: systemv/lp.c:504 systemv/lp.c:516
-#, c-format
-msgid "%s: Warning - character set option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:516 systemv/lp.c:528
-#, c-format
-msgid "%s: Error - expected content type after '-T' option!\n"
-msgstr ""
-
-#: systemv/lp.c:524 systemv/lp.c:536
-#, c-format
-msgid "%s: Warning - content type option ignored!\n"
-msgstr ""
-
-#: systemv/lp.c:538 systemv/lp.c:554
-#, c-format
-msgid ""
-"%s: Error - cannot print from stdin if files or a job ID are provided!\n"
-msgstr ""
-
-#: systemv/lpstat.c:164 systemv/lpstat.c:178
-#, c-format
-msgid ""
-"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' "
-"option!\n"
-msgstr ""
-
-#: systemv/lpstat.c:237
-#, c-format
-msgid "%s: Error - expected destination after '-b' option!\n"
-msgstr ""
-
-#: systemv/lpstat.c:534
-#, c-format
-msgid "%s: Invalid destination name in list \"%s\"!\n"
-msgstr ""
-
-#: systemv/lpstat.c:571
-#, fuzzy, c-format
-msgid "%s: Unable to connect to server\n"
-msgstr "Incapable de copier le dossier de PPD - %s!"
-
-#: cups/notify.c:91
-msgid "Print Job:"
-msgstr ""
-
-#: cups/notify.c:96
-msgid "pending"
-msgstr ""
-
-#: cups/notify.c:99
-msgid "held"
-msgstr ""
-
-#: cups/notify.c:102 cups/notify.c:143
-msgid "processing"
-msgstr ""
-
-#: cups/notify.c:105 cups/notify.c:146
-msgid "stopped"
-msgstr ""
-
-#: cups/notify.c:108
-msgid "canceled"
-msgstr ""
-
-#: cups/notify.c:111
-msgid "aborted"
-msgstr ""
-
-#: cups/notify.c:114
-msgid "completed"
-msgstr ""
-
-#: cups/notify.c:117 cups/notify.c:149
-msgid "unknown"
-msgstr ""
-
-#: cups/notify.c:126
-msgid "untitled"
-msgstr ""
-
-#: cups/notify.c:135
-#, fuzzy
-msgid "Printer:"
-msgstr "Imprimeur"
-
-#: cups/notify.c:140
-msgid "idle"
-msgstr ""
-
-#: scheduler/ipp.c:5513
-#, fuzzy
-msgid "Missing notify-subscription-ids attribute!"
-msgstr "Attribut absent de requesting-user-name!"
-
-#: scheduler/ipp.c:7851
-#, fuzzy
-msgid "Job subscriptions cannot be renewed!"
-msgstr "Aucuns attributs d'abonnement dans la demande!"
-
-#: scheduler/main.c:163
-msgid "cupsd: Expected config filename after \"-c\" option!\n"
-msgstr ""
-
-#: scheduler/main.c:218
-msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n"
-msgstr ""
-
-#: scheduler/main.c:225
-#, fuzzy, c-format
-msgid "cupsd: Unknown option \"%c\" - aborting!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: scheduler/main.c:232
-#, fuzzy, c-format
-msgid "cupsd: Unknown argument \"%s\" - aborting!\n"
-msgstr "Incapable d'ajouter le travail pour la destination \"%s\"!"
-
-#: scheduler/main.c:2315
-msgid ""
-"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n"
-"\n"
-"-c config-file      Load alternate configuration file\n"
-"-f                  Run in the foreground\n"
-"-F                  Run in the foreground but detach\n"
-"-h                  Show this usage message\n"
-"-l                  Run cupsd from launchd(8)\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1343
-#, c-format
-msgid "        WARN    Line %d only contains whitespace!\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1361
-msgid ""
-"        WARN    File contains a mix of CR, LF, and CR LF line endings!\n"
-msgstr ""
-
-#: systemv/cupstestppd.c:1366
-msgid ""
-"        WARN    Non-Windows PPD files should use lines ending with only LF, "
-"not CR LF!\n"
-msgstr ""
index b05ac29665738e692ce1977644d6a0dff508d0cb..cf0517f09d81b840517d6d9c7f2f7f5577b43bbe 100644 (file)
@@ -25,7 +25,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: CUPS 1.2\n"
 "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n"
-"POT-Creation-Date: 2006-02-15 19:50-0500\n"
+"POT-Creation-Date: 2006-02-26 20:42-0500\n"
 "PO-Revision-Date: 2006-02-17 11:17+0900\n"
 "Last-Translator: Kenshi Muto <kmuto@debian.org>\n"
 "Language-Team: Japanese <LL@li.org>\n"
@@ -50,27 +50,32 @@ msgid "Extra"
 msgstr "補助"
 
 #: cups/ppd.c:656 cups/ppd.c:881 cups/ppd.c:1047 cups/ppd.c:662 cups/ppd.c:996
-#: cups/ppd.c:1169
+#: cups/ppd.c:1169 cups/ppd.c:651 cups/ppd.c:983 cups/ppd.c:1148
 msgid "General"
 msgstr "一般"
 
 #: cups/ppd.c:704 cups/ppd.c:1105 cups/ppd.c:710 cups/ppd.c:1224
+#: cups/ppd.c:697 cups/ppd.c:1201
 msgid "Media Size"
 msgstr "用紙サイズ"
 
 #: cups/ppd.c:706 cups/ppd.c:1107 cups/ppd.c:712 cups/ppd.c:1226
+#: cups/ppd.c:699 cups/ppd.c:1203
 msgid "Media Type"
 msgstr "用紙形式"
 
 #: cups/ppd.c:708 cups/ppd.c:1109 cups/ppd.c:714 cups/ppd.c:1228
+#: cups/ppd.c:701 cups/ppd.c:1205
 msgid "Media Source"
 msgstr "給紙"
 
 #: cups/ppd.c:710 cups/ppd.c:1111 cups/ppd.c:716 cups/ppd.c:1230
+#: cups/ppd.c:703 cups/ppd.c:1207
 msgid "Output Mode"
 msgstr "出力モード"
 
 #: cups/ppd.c:712 cups/ppd.c:1113 cups/ppd.c:718 cups/ppd.c:1232
+#: cups/ppd.c:705 cups/ppd.c:1209
 msgid "Resolution"
 msgstr "解像度"
 
@@ -78,11 +83,11 @@ msgstr "解像度"
 msgid "Variable"
 msgstr "可変"
 
-#: cups/ppd.c:1535 cups/ppd.c:1650
+#: cups/ppd.c:1535 cups/ppd.c:1650 cups/ppd.c:1627
 msgid "Yes"
 msgstr "はい"
 
-#: cups/ppd.c:1537 cups/ppd.c:1652
+#: cups/ppd.c:1537 cups/ppd.c:1652 cups/ppd.c:1629
 msgid "No"
 msgstr "いいえ"
 
@@ -91,6 +96,7 @@ msgid "Auto"
 msgstr "自動"
 
 #: scheduler/client.c:2247 scheduler/client.c:2251 scheduler/client.c:2274
+#: scheduler/client.c:2308
 msgid ""
 "Enter your username and password or the root username and password to access "
 "this page."
@@ -99,28 +105,34 @@ msgstr ""
 "のユーザ名とパスワードを入力してください。"
 
 #: scheduler/client.c:2252 scheduler/client.c:2256 scheduler/client.c:2279
+#: scheduler/client.c:2313
 msgid "You must use a https: URL to access this page."
 msgstr "このページにアクセスするためには、https: URL を使う必要があります。"
 
 #: scheduler/ipp.c:236 scheduler/ipp.c:244 scheduler/ipp.c:246
+#: scheduler/ipp.c:260
 #, c-format
 msgid "Bad request version number %d.%d!"
 msgstr "バージョン番号 %d.%d は無効なリクエストです!"
 
 #: scheduler/ipp.c:246 scheduler/ipp.c:254 scheduler/ipp.c:256
+#: scheduler/ipp.c:270
 msgid "No attributes in request!"
 msgstr "リクエストに属性がありません!"
 
 #: scheduler/ipp.c:269 scheduler/ipp.c:277 scheduler/ipp.c:279
+#: scheduler/ipp.c:293
 #, c-format
 msgid "Attribute groups are out of order (%x < %x)!"
 msgstr "属性グループは範囲外です (%x < %x)!"
 
 #: scheduler/ipp.c:379 scheduler/ipp.c:389 scheduler/ipp.c:391
+#: scheduler/ipp.c:405
 msgid "Missing required attributes!"
 msgstr "必須の属性が設定されていません!"
 
 #: scheduler/ipp.c:575 scheduler/ipp.c:585 scheduler/ipp.c:591
+#: scheduler/ipp.c:605
 #, c-format
 msgid "%s not supported!"
 msgstr "%s はサポートされていません!"
@@ -142,11 +154,18 @@ msgstr "%s はサポートされていません!"
 #: scheduler/ipp.c:5357 scheduler/ipp.c:5769 scheduler/ipp.c:6077
 #: scheduler/ipp.c:6368 scheduler/ipp.c:6410 scheduler/ipp.c:6916
 #: scheduler/ipp.c:7626 scheduler/ipp.c:8589 scheduler/ipp.c:9003
-#: scheduler/ipp.c:9084 scheduler/ipp.c:9259
+#: scheduler/ipp.c:9084 scheduler/ipp.c:9259 scheduler/ipp.c:716
+#: scheduler/ipp.c:1003 scheduler/ipp.c:1174 scheduler/ipp.c:2812
+#: scheduler/ipp.c:2927 scheduler/ipp.c:4699 scheduler/ipp.c:4942
+#: scheduler/ipp.c:5326 scheduler/ipp.c:5738 scheduler/ipp.c:6046
+#: scheduler/ipp.c:6337 scheduler/ipp.c:6379 scheduler/ipp.c:7116
+#: scheduler/ipp.c:8081 scheduler/ipp.c:8745 scheduler/ipp.c:8826
+#: scheduler/ipp.c:9001
 msgid "The printer or class was not found."
 msgstr "プリンタまたはクラスが見つかりませんでした。"
 
 #: scheduler/ipp.c:762 scheduler/ipp.c:777 scheduler/ipp.c:784
+#: scheduler/ipp.c:799
 msgid ""
 "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"."
 msgstr ""
@@ -155,16 +174,19 @@ msgstr ""
 
 #: scheduler/ipp.c:778 scheduler/ipp.c:1454 scheduler/ipp.c:793
 #: scheduler/ipp.c:1482 scheduler/ipp.c:800 scheduler/ipp.c:1515
+#: scheduler/ipp.c:815 scheduler/ipp.c:2031
 #, c-format
 msgid "The printer-uri \"%s\" contains invalid characters."
 msgstr "printer-uri \"%s\" には、無効な文字が含まれています。"
 
 #: scheduler/ipp.c:811 scheduler/ipp.c:826 scheduler/ipp.c:833
+#: scheduler/ipp.c:848
 #, c-format
 msgid "A printer named \"%s\" already exists!"
 msgstr "プリンタ名 \"%s\" はすでに存在します!"
 
 #: scheduler/ipp.c:904 scheduler/ipp.c:924 scheduler/ipp.c:933
+#: scheduler/ipp.c:944
 #, c-format
 msgid "Attempt to set %s printer-state to bad value %d!"
 msgstr "%s printer-state に 不正な値 %d を設定しようとしています!"
@@ -180,28 +202,33 @@ msgid "add_class: Unknown printer-error-policy \"%s\"."
 msgstr "add_class: \"%s\" は未知の printer-error-policy です。"
 
 #: scheduler/ipp.c:1144 scheduler/ipp.c:1168 scheduler/ipp.c:1200
+#: scheduler/ipp.c:1112
 msgid "Unable to allocate memory for file types!"
 msgstr "ファイルタイプ用にメモリを割り当てられません!"
 
 #: scheduler/ipp.c:1290 scheduler/ipp.c:4501 scheduler/ipp.c:1316
 #: scheduler/ipp.c:4705 scheduler/ipp.c:1348 scheduler/ipp.c:4804
+#: scheduler/ipp.c:1810 scheduler/ipp.c:4773
 #, c-format
 msgid "Character set \"%s\" not supported!"
 msgstr "文字セット \"%s\" はサポートされていません!"
 
 #: scheduler/ipp.c:1299 scheduler/ipp.c:4510 scheduler/ipp.c:1325
 #: scheduler/ipp.c:4714 scheduler/ipp.c:1357 scheduler/ipp.c:4813
+#: scheduler/ipp.c:1819 scheduler/ipp.c:4782
 #, c-format
 msgid "Language \"%s\" not supported!"
 msgstr "言語 \"%s\" はサポートされていません!"
 
 #: scheduler/ipp.c:1309 scheduler/ipp.c:4520 scheduler/ipp.c:1335
 #: scheduler/ipp.c:4724 scheduler/ipp.c:1367 scheduler/ipp.c:4823
+#: scheduler/ipp.c:1829 scheduler/ipp.c:4792
 #, c-format
 msgid "The notify-user-data value is too large (%d > 63 octets)!"
 msgstr "notify-user-data 値が大きすぎます (%d > 63 オクテット)!"
 
 #: scheduler/ipp.c:1326 scheduler/ipp.c:1352 scheduler/ipp.c:1384
+#: scheduler/ipp.c:1846
 msgid ""
 "The notify-lease-duration attribute cannot be used with job subscriptions."
 msgstr ""
@@ -209,6 +236,7 @@ msgstr ""
 "ません。"
 
 #: scheduler/ipp.c:1438 scheduler/ipp.c:1466 scheduler/ipp.c:1499
+#: scheduler/ipp.c:2015
 msgid ""
 "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"."
 msgstr ""
@@ -216,11 +244,13 @@ msgstr ""
 "ん。"
 
 #: scheduler/ipp.c:1487 scheduler/ipp.c:1515 scheduler/ipp.c:1548
+#: scheduler/ipp.c:2064
 #, c-format
 msgid "A class named \"%s\" already exists!"
 msgstr "クラス名 \"%s\" はすでに存在します!"
 
 #: scheduler/ipp.c:1575 scheduler/ipp.c:1607 scheduler/ipp.c:1644
+#: scheduler/ipp.c:2157
 #, c-format
 msgid ""
 "File device URIs have been disabled! To enable, see the FileDevice directive "
@@ -230,41 +260,49 @@ msgstr ""
 "\" の FileDevice ディレクティブを確認してください。"
 
 #: scheduler/ipp.c:1595 scheduler/ipp.c:1627 scheduler/ipp.c:1664
+#: scheduler/ipp.c:2177
 #, c-format
 msgid "Bad device-uri \"%s\"!"
 msgstr "\"%s\" は無効な device-uri です!"
 
 #: scheduler/ipp.c:1626 scheduler/ipp.c:1659 scheduler/ipp.c:1698
+#: scheduler/ipp.c:2211
 #, c-format
 msgid "Bad port-monitor \"%s\"!"
 msgstr "\"%s\" は無効な port-monitor です!"
 
 #: scheduler/ipp.c:1669 scheduler/ipp.c:1705 scheduler/ipp.c:1744
+#: scheduler/ipp.c:2257
 #, c-format
 msgid "Bad printer-state value %d!"
 msgstr "%d は無効な printer-state 値です!"
 
 #: scheduler/ipp.c:1762 scheduler/ipp.c:1800 scheduler/ipp.c:1842
+#: scheduler/ipp.c:8585
 #, c-format
 msgid "Unknown printer-op-policy \"%s\"."
 msgstr "\"%s\" は未知の printer-op-policy です。"
 
 #: scheduler/ipp.c:1775 scheduler/ipp.c:1813 scheduler/ipp.c:1855
+#: scheduler/ipp.c:8600
 #, c-format
 msgid "Unknown printer-error-policy \"%s\"."
 msgstr "\"%s\" は未知の printer-error-policy です。"
 
 #: scheduler/ipp.c:1837 scheduler/ipp.c:1875 scheduler/ipp.c:1919
+#: scheduler/ipp.c:2336
 #, c-format
 msgid "Unable to copy interface script - %s!"
 msgstr "インターフェイススクリプトをコピーできません - %s!"
 
 #: scheduler/ipp.c:1862 scheduler/ipp.c:1900 scheduler/ipp.c:1944
+#: scheduler/ipp.c:2361
 #, c-format
 msgid "Unable to copy PPD file - %s!"
 msgstr " PPD ファイルをコピーできません - %s!"
 
 #: scheduler/ipp.c:1915 scheduler/ipp.c:1954 scheduler/ipp.c:2000
+#: scheduler/ipp.c:2417
 msgid "Unable to copy PPD file!"
 msgstr "PPD ファイルをコピーできません!"
 
@@ -276,7 +314,9 @@ msgstr "PPD ファイルをコピーできません!"
 #: scheduler/ipp.c:7839 scheduler/ipp.c:8334 scheduler/ipp.c:2158
 #: scheduler/ipp.c:2451 scheduler/ipp.c:5220 scheduler/ipp.c:6210
 #: scheduler/ipp.c:7713 scheduler/ipp.c:7928 scheduler/ipp.c:8167
-#: scheduler/ipp.c:8672
+#: scheduler/ipp.c:8672 scheduler/ipp.c:2613 scheduler/ipp.c:2906
+#: scheduler/ipp.c:5189 scheduler/ipp.c:6179 scheduler/ipp.c:7203
+#: scheduler/ipp.c:7418 scheduler/ipp.c:7657 scheduler/ipp.c:8164
 msgid "Got a printer-uri attribute but no job-id!"
 msgstr "printer-uri 属性を取得しましたが、job-id を取得できませんでした!"
 
@@ -289,6 +329,9 @@ msgstr "printer-uri 属性を取得しましたが、job-id を取得できま
 #: scheduler/ipp.c:2180 scheduler/ipp.c:2523 scheduler/ipp.c:5243
 #: scheduler/ipp.c:6233 scheduler/ipp.c:6456 scheduler/ipp.c:7736
 #: scheduler/ipp.c:7951 scheduler/ipp.c:8190 scheduler/ipp.c:8695
+#: scheduler/ipp.c:2635 scheduler/ipp.c:2978 scheduler/ipp.c:5212
+#: scheduler/ipp.c:6202 scheduler/ipp.c:6425 scheduler/ipp.c:7226
+#: scheduler/ipp.c:7441 scheduler/ipp.c:7680 scheduler/ipp.c:8187
 #, c-format
 msgid "Bad job-uri attribute \"%s\"!"
 msgstr "\"%s\" は無効な job-uri 属性です!"
@@ -301,6 +344,7 @@ msgid "Job #%d doesn't exist!"
 msgstr "ジョブ #%d は存在しません!"
 
 #: scheduler/ipp.c:2131 scheduler/ipp.c:2172 scheduler/ipp.c:2214
+#: scheduler/ipp.c:2669
 #, c-format
 msgid "Job #%d is not held for authentication!"
 msgstr "ジョブ #%d は認証が行われていません!"
@@ -313,19 +357,23 @@ msgstr ""
 "ん!"
 
 #: scheduler/ipp.c:2221 scheduler/ipp.c:2264 scheduler/ipp.c:2303
+#: scheduler/ipp.c:2758
 msgid "The printer-uri attribute is required!"
 msgstr "printer-uri 属性は必須です!"
 
 #: scheduler/ipp.c:2238 scheduler/ipp.c:2283 scheduler/ipp.c:2322
+#: scheduler/ipp.c:2777
 msgid "Missing requesting-user-name attribute!"
 msgstr "requesting-user-name 属性が設定されていません!"
 
 #: scheduler/ipp.c:2277 scheduler/ipp.c:2324 scheduler/ipp.c:2363
+#: scheduler/ipp.c:2818
 #, c-format
 msgid "The printer-uri \"%s\" is not valid."
 msgstr "printer-uri \"%s\" は有効ではありません。"
 
 #: scheduler/ipp.c:2410 scheduler/ipp.c:2460 scheduler/ipp.c:2499
+#: scheduler/ipp.c:2954
 #, c-format
 msgid "No active jobs on %s!"
 msgstr "%s にはアクティブなジョブはありません!"
@@ -338,83 +386,101 @@ msgstr ""
 "ん!"
 
 #: scheduler/ipp.c:2476 scheduler/ipp.c:2527 scheduler/ipp.c:2563
+#: scheduler/ipp.c:3018
 #, c-format
 msgid "Job #%d is already %s - can't cancel."
 msgstr "ジョブ #%d はすでに %s です - キャンセルできません。"
 
 #: scheduler/ipp.c:3720 scheduler/ipp.c:3914 scheduler/ipp.c:4006
+#: scheduler/ipp.c:1190
 msgid "The printer or class is not shared!"
 msgstr "プリンタまたはクラスは共有できません!"
 
 #: scheduler/ipp.c:3746 scheduler/ipp.c:6647 scheduler/ipp.c:3940
 #: scheduler/ipp.c:6695 scheduler/ipp.c:4032 scheduler/ipp.c:6954
+#: scheduler/ipp.c:1216
 #, c-format
 msgid "Destination \"%s\" is not accepting jobs."
 msgstr "宛先 \"%s\" はジョブを受け付けていません。"
 
 #: scheduler/ipp.c:3759 scheduler/ipp.c:6443 scheduler/ipp.c:3954
 #: scheduler/ipp.c:6487 scheduler/ipp.c:4046 scheduler/ipp.c:6739
+#: scheduler/ipp.c:1230
 #, c-format
 msgid "Bad copies value %d."
 msgstr "%d は不正なコピー値です。"
 
 #: scheduler/ipp.c:3775 scheduler/ipp.c:6459 scheduler/ipp.c:3971
 #: scheduler/ipp.c:6504 scheduler/ipp.c:4063 scheduler/ipp.c:6756
+#: scheduler/ipp.c:1247
 #, c-format
 msgid "Bad page-ranges values %d-%d."
 msgstr "%d-%d は不正な page-ranges 値です。"
 
 #: scheduler/ipp.c:3795 scheduler/ipp.c:3991 scheduler/ipp.c:4083
+#: scheduler/ipp.c:1267
 msgid "Too many active jobs."
 msgstr "アクティブなジョブが多すぎます。"
 
 #: scheduler/ipp.c:3801 scheduler/ipp.c:6668 scheduler/ipp.c:3997
 #: scheduler/ipp.c:6716 scheduler/ipp.c:4089 scheduler/ipp.c:6975
+#: scheduler/ipp.c:1273
 msgid "Quota limit reached."
 msgstr "Quota の制限に達しました。"
 
 #: scheduler/ipp.c:3824 scheduler/ipp.c:6691 scheduler/ipp.c:4022
 #: scheduler/ipp.c:6741 scheduler/ipp.c:4114 scheduler/ipp.c:7000
+#: scheduler/ipp.c:1306
 #, c-format
 msgid "Unable to add job for destination \"%s\"!"
 msgstr "宛先 \"%s\" にジョブを追加できません!"
 
 #: scheduler/ipp.c:4469 scheduler/ipp.c:4673 scheduler/ipp.c:4770
+#: scheduler/ipp.c:4739
 msgid "No subscription attributes in request!"
 msgstr "リクエストにサブスクリプション属性がありません!"
 
 #: scheduler/ipp.c:4559 scheduler/ipp.c:4763 scheduler/ipp.c:4869
+#: scheduler/ipp.c:4838
 msgid "notify-events not specified!"
 msgstr "notify-events が指定されていません!"
 
 #: scheduler/ipp.c:4577 scheduler/ipp.c:4781 scheduler/ipp.c:4887
+#: scheduler/ipp.c:4856
 #, c-format
 msgid "Job %d not found!"
 msgstr "ジョブ %d は見つかりません!"
 
 #: scheduler/ipp.c:4827 scheduler/ipp.c:4957 scheduler/ipp.c:5075
+#: scheduler/ipp.c:5044
 msgid "No default printer"
 msgstr "デフォルトプリンタはありません"
 
 #: scheduler/ipp.c:4930 scheduler/ipp.c:5060 scheduler/ipp.c:5178
+#: scheduler/ipp.c:5147
 msgid "cups-deviced failed to execute."
 msgstr "cups-deviced の実行に失敗しました。"
 
 #: scheduler/ipp.c:5393 scheduler/ipp.c:5479 scheduler/ipp.c:5722
+#: scheduler/ipp.c:5691
 msgid "cups-driverd failed to execute."
 msgstr "cups-driverd の実行に失敗しました。"
 
 #: scheduler/ipp.c:5571 scheduler/ipp.c:5594 scheduler/ipp.c:5837
+#: scheduler/ipp.c:5806
 msgid "No destinations added."
 msgstr "追加された宛先はありません。"
 
 #: scheduler/ipp.c:5794 scheduler/ipp.c:5736 scheduler/ipp.c:2615
 #: scheduler/ipp.c:5530 scheduler/ipp.c:5979 scheduler/ipp.c:7840
+#: scheduler/ipp.c:3070 scheduler/ipp.c:5499 scheduler/ipp.c:5948
+#: scheduler/ipp.c:7330
 #, c-format
 msgid "notify-subscription-id %d no good!"
 msgstr "notify-subscription-id %d は良くありません!"
 
 #: scheduler/ipp.c:5878 scheduler/ipp.c:5822 scheduler/ipp.c:6065
+#: scheduler/ipp.c:6034
 #, c-format
 msgid "Job #%s does not exist!"
 msgstr "ジョブ #%s は存在しません!"
@@ -429,12 +495,17 @@ msgstr "ジョブ #%s は存在しません!"
 #: scheduler/ipp.c:2199 scheduler/ipp.c:2541 scheduler/ipp.c:5261
 #: scheduler/ipp.c:6087 scheduler/ipp.c:6251 scheduler/ipp.c:6429
 #: scheduler/ipp.c:6474 scheduler/ipp.c:7754 scheduler/ipp.c:7969
-#: scheduler/ipp.c:8208 scheduler/ipp.c:8713
+#: scheduler/ipp.c:8208 scheduler/ipp.c:8713 scheduler/ipp.c:2654
+#: scheduler/ipp.c:2996 scheduler/ipp.c:5230 scheduler/ipp.c:6056
+#: scheduler/ipp.c:6220 scheduler/ipp.c:6398 scheduler/ipp.c:6443
+#: scheduler/ipp.c:7244 scheduler/ipp.c:7459 scheduler/ipp.c:7698
+#: scheduler/ipp.c:8205
 #, c-format
 msgid "Job #%d does not exist!"
 msgstr "ジョブ #%d は存在しません!"
 
 #: scheduler/ipp.c:5969 scheduler/ipp.c:5915 scheduler/ipp.c:6150
+#: scheduler/ipp.c:6119
 msgid "No subscriptions found."
 msgstr "サブスクリプションが見つかりません。"
 
@@ -446,6 +517,7 @@ msgstr ""
 
 #: scheduler/ipp.c:6203 scheduler/ipp.c:8315 scheduler/ipp.c:6250
 #: scheduler/ipp.c:8390 scheduler/ipp.c:6505 scheduler/ipp.c:8728
+#: scheduler/ipp.c:6474 scheduler/ipp.c:8220
 #, c-format
 msgid "Job #%d is finished and cannot be altered!"
 msgstr "ジョブ #%d は完了し、変更することはできません!"
@@ -458,27 +530,32 @@ msgstr ""
 "ん!"
 
 #: scheduler/ipp.c:6228 scheduler/ipp.c:6098 scheduler/ipp.c:6353
+#: scheduler/ipp.c:6322
 msgid "job-printer-uri attribute missing!"
 msgstr "job-printer-uri 属性がありません!"
 
 #: scheduler/ipp.c:6485 scheduler/ipp.c:7847 scheduler/ipp.c:6531
 #: scheduler/ipp.c:7913 scheduler/ipp.c:6783 scheduler/ipp.c:8238
+#: scheduler/ipp.c:6703 scheduler/ipp.c:7728
 #, c-format
 msgid "Unsupported compression \"%s\"!"
 msgstr "\"%s\" はサポートされていない圧縮です!"
 
 #: scheduler/ipp.c:6504 scheduler/ipp.c:7866 scheduler/ipp.c:6550
 #: scheduler/ipp.c:7932 scheduler/ipp.c:6802 scheduler/ipp.c:8257
+#: scheduler/ipp.c:6722 scheduler/ipp.c:7747
 msgid "No file!?!"
 msgstr "ファイルがありません!?!"
 
 #: scheduler/ipp.c:6522 scheduler/ipp.c:6568 scheduler/ipp.c:6820
+#: scheduler/ipp.c:6740
 #, c-format
 msgid "Could not scan type \"%s\"!"
 msgstr "タイプ \"%s\" を検査できませんでした!"
 
 #: scheduler/ipp.c:6574 scheduler/ipp.c:7936 scheduler/ipp.c:6620
 #: scheduler/ipp.c:8001 scheduler/ipp.c:6879 scheduler/ipp.c:8332
+#: scheduler/ipp.c:6799 scheduler/ipp.c:7822
 #, c-format
 msgid "Unsupported format '%s/%s'!"
 msgstr "'%s/%s' はサポートされていない形式です!"
@@ -493,6 +570,7 @@ msgid "Too many jobs - %d jobs, max jobs is %d."
 msgstr "ジョブが多すぎます - %d ジョブ。最大ジョブ数は %d です。"
 
 #: scheduler/ipp.c:7448 scheduler/ipp.c:7507 scheduler/ipp.c:7768
+#: scheduler/ipp.c:7258
 #, c-format
 msgid "Job #%d is not held!"
 msgstr "ジョブ #%d はホールドされていません!"
@@ -505,11 +583,13 @@ msgstr ""
 "せん!"
 
 #: scheduler/ipp.c:7592 scheduler/ipp.c:7654 scheduler/ipp.c:7983
+#: scheduler/ipp.c:7473
 #, c-format
 msgid "Job #%d is not complete!"
 msgstr "ジョブ #%d は完結していません!"
 
 #: scheduler/ipp.c:7608 scheduler/ipp.c:7670 scheduler/ipp.c:8001
+#: scheduler/ipp.c:7491
 #, c-format
 msgid "Job #%d cannot be restarted - no files!"
 msgstr "ジョブ #%d は再起動できません - ファイルがありません!"
@@ -530,6 +610,7 @@ msgstr ""
 
 #: scheduler/ipp.c:7883 scheduler/ipp.c:8803 scheduler/ipp.c:7949
 #: scheduler/ipp.c:8883 scheduler/ipp.c:8274 scheduler/ipp.c:9225
+#: scheduler/ipp.c:7764 scheduler/ipp.c:8967
 #, c-format
 msgid "Bad document-format \"%s\"!"
 msgstr "\"%s\" は不正な document-format です!"
@@ -542,34 +623,41 @@ msgstr ""
 "せん!"
 
 #: scheduler/ipp.c:8371 scheduler/ipp.c:8446 scheduler/ipp.c:8783
+#: scheduler/ipp.c:8275
 #, c-format
 msgid "%s cannot be changed."
 msgstr "%s は変更できません。"
 
 #: scheduler/ipp.c:8387 scheduler/ipp.c:8462 scheduler/ipp.c:8799
+#: scheduler/ipp.c:8291
 msgid "Bad job-priority value!"
 msgstr "不正な job-priority 値です!"
 
 #: scheduler/ipp.c:8395 scheduler/ipp.c:8470 scheduler/ipp.c:8807
+#: scheduler/ipp.c:8299
 msgid "Job is completed and cannot be changed."
 msgstr "ジョブは完結し、変更できません。"
 
 #: scheduler/ipp.c:8409 scheduler/ipp.c:8484 scheduler/ipp.c:8821
+#: scheduler/ipp.c:8313
 msgid "Bad job-state value!"
 msgstr "不正な job-state 値です!"
 
 #: scheduler/ipp.c:8423 scheduler/ipp.c:8435 scheduler/ipp.c:8446
 #: scheduler/ipp.c:8498 scheduler/ipp.c:8510 scheduler/ipp.c:8521
 #: scheduler/ipp.c:8835 scheduler/ipp.c:8850 scheduler/ipp.c:8861
+#: scheduler/ipp.c:8327 scheduler/ipp.c:8342 scheduler/ipp.c:8353
 msgid "Job state cannot be changed."
 msgstr "ジョブの状態を変更できません。"
 
 #: scheduler/ipp.c:8787 scheduler/ipp.c:8867 scheduler/ipp.c:9209
+#: scheduler/ipp.c:8951
 #, c-format
 msgid "Unsupported compression attribute %s!"
 msgstr "%s はサポートされていない圧縮属性です!"
 
 #: scheduler/ipp.c:8815 scheduler/ipp.c:8894 scheduler/ipp.c:9236
+#: scheduler/ipp.c:8978
 #, c-format
 msgid "Unsupported format \"%s\"!"
 msgstr "\"%s\" はサポートされていない形式です!"
@@ -1091,6 +1179,7 @@ msgstr ""
 "    適合テスト結果詳細\n"
 
 #: systemv/cupstestppd.c:307 systemv/cupstestppd.c:326
+#: systemv/cupstestppd.c:325
 #, c-format
 msgid "        WARN    %s has no corresponding options!\n"
 msgstr "        警告    %s は相当するオプションがありません!\n"
@@ -1125,11 +1214,30 @@ msgstr "        警告    %s は相当するオプションがありません!\n
 #: systemv/cupstestppd.c:800 systemv/cupstestppd.c:820
 #: systemv/cupstestppd.c:851 systemv/cupstestppd.c:873
 #: systemv/cupstestppd.c:921 systemv/cupstestppd.c:950
-#: systemv/cupstestppd.c:971
+#: systemv/cupstestppd.c:971 systemv/cupstestppd.c:343
+#: systemv/cupstestppd.c:361 systemv/cupstestppd.c:376
+#: systemv/cupstestppd.c:412 systemv/cupstestppd.c:440
+#: systemv/cupstestppd.c:460 systemv/cupstestppd.c:482
+#: systemv/cupstestppd.c:502 systemv/cupstestppd.c:522
+#: systemv/cupstestppd.c:542 systemv/cupstestppd.c:560
+#: systemv/cupstestppd.c:578 systemv/cupstestppd.c:599
+#: systemv/cupstestppd.c:618 systemv/cupstestppd.c:638
+#: systemv/cupstestppd.c:658 systemv/cupstestppd.c:678
+#: systemv/cupstestppd.c:698 systemv/cupstestppd.c:716
+#: systemv/cupstestppd.c:733 systemv/cupstestppd.c:755
+#: systemv/cupstestppd.c:773 systemv/cupstestppd.c:790
+#: systemv/cupstestppd.c:808 systemv/cupstestppd.c:824
+#: systemv/cupstestppd.c:844 systemv/cupstestppd.c:875
+#: systemv/cupstestppd.c:897 systemv/cupstestppd.c:945
+#: systemv/cupstestppd.c:974 systemv/cupstestppd.c:995
+#: systemv/cupstestppd.c:1050 systemv/cupstestppd.c:1075
+#: systemv/cupstestppd.c:1095 systemv/cupstestppd.c:1116
+#: systemv/cupstestppd.c:1138 systemv/cupstestppd.c:1172
 msgid " FAIL\n"
 msgstr " 失敗\n"
 
 #: systemv/cupstestppd.c:321 systemv/cupstestppd.c:340
+#: systemv/cupstestppd.c:364
 msgid ""
 "      **FAIL**  REQUIRED DefaultImageableArea\n"
 "                REF: Page 102, section 5.15.\n"
@@ -1138,6 +1246,7 @@ msgstr ""
 "                REF: 102 ページ、セクション 5.15。\n"
 
 #: systemv/cupstestppd.c:336 systemv/cupstestppd.c:355
+#: systemv/cupstestppd.c:379
 #, c-format
 msgid ""
 "      **FAIL**  BAD DefaultImageableArea %s!\n"
@@ -1147,10 +1256,12 @@ msgstr ""
 "                REF: 102 ページ、セクション 5.15。\n"
 
 #: systemv/cupstestppd.c:346 systemv/cupstestppd.c:365
+#: systemv/cupstestppd.c:389
 msgid "        PASS    DefaultImageableArea\n"
 msgstr "        合格    DefaultImageableArea\n"
 
 #: systemv/cupstestppd.c:357 systemv/cupstestppd.c:376
+#: systemv/cupstestppd.c:400
 msgid ""
 "      **FAIL**  REQUIRED DefaultPaperDimension\n"
 "                REF: Page 103, section 5.15.\n"
@@ -1159,6 +1270,7 @@ msgstr ""
 "                REF: 103 ページ、セクション 5.15。\n"
 
 #: systemv/cupstestppd.c:372 systemv/cupstestppd.c:391
+#: systemv/cupstestppd.c:415
 #, c-format
 msgid ""
 "      **FAIL**  BAD DefaultPaperDimension %s!\n"
@@ -1168,10 +1280,12 @@ msgstr ""
 "                REF: 103 ページ、セクション 5.15。\n"
 
 #: systemv/cupstestppd.c:380 systemv/cupstestppd.c:399
+#: systemv/cupstestppd.c:423
 msgid "        PASS    DefaultPaperDimension\n"
 msgstr "        合格    DefaultPaperDimension\n"
 
 #: systemv/cupstestppd.c:400 systemv/cupstestppd.c:419
+#: systemv/cupstestppd.c:443
 #, c-format
 msgid ""
 "      **FAIL**  BAD Default%s %s\n"
@@ -1181,11 +1295,13 @@ msgstr ""
 "                REF: 40 ページ、セクション 4.5。\n"
 
 #: systemv/cupstestppd.c:409 systemv/cupstestppd.c:428
+#: systemv/cupstestppd.c:452
 #, c-format
 msgid "        PASS    Default%s\n"
 msgstr "        合格    Default%s\n"
 
 #: systemv/cupstestppd.c:420 systemv/cupstestppd.c:439
+#: systemv/cupstestppd.c:463
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED Default%s\n"
@@ -1195,10 +1311,12 @@ msgstr ""
 "                REF: 40 ページ、セクション 4.5。\n"
 
 #: systemv/cupstestppd.c:432 systemv/cupstestppd.c:451
+#: systemv/cupstestppd.c:475
 msgid "        PASS    FileVersion\n"
 msgstr "        合格    FileVersion\n"
 
 #: systemv/cupstestppd.c:442 systemv/cupstestppd.c:461
+#: systemv/cupstestppd.c:485
 msgid ""
 "      **FAIL**  REQUIRED FileVersion\n"
 "                REF: Page 56, section 5.3.\n"
@@ -1207,10 +1325,12 @@ msgstr ""
 "                REF: 56 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:452 systemv/cupstestppd.c:471
+#: systemv/cupstestppd.c:495
 msgid "        PASS    FormatVersion\n"
 msgstr "        合格    FormatVersion\n"
 
 #: systemv/cupstestppd.c:462 systemv/cupstestppd.c:481
+#: systemv/cupstestppd.c:505
 msgid ""
 "      **FAIL**  REQUIRED FormatVersion\n"
 "                REF: Page 56, section 5.3.\n"
@@ -1219,10 +1339,12 @@ msgstr ""
 "                REF: 56 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:472 systemv/cupstestppd.c:491
+#: systemv/cupstestppd.c:515
 msgid "        PASS    LanguageEncoding\n"
 msgstr "        合格    LanguageEncoding\n"
 
 #: systemv/cupstestppd.c:482 systemv/cupstestppd.c:501
+#: systemv/cupstestppd.c:525
 msgid ""
 "      **FAIL**  REQUIRED LanguageEncoding\n"
 "                REF: Pages 56-57, section 5.3.\n"
@@ -1231,10 +1353,12 @@ msgstr ""
 "                REF: 56-57 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:492 systemv/cupstestppd.c:511
+#: systemv/cupstestppd.c:535
 msgid "        PASS    LanguageVersion\n"
 msgstr "        合格    LanguageVersion\n"
 
 #: systemv/cupstestppd.c:502 systemv/cupstestppd.c:521
+#: systemv/cupstestppd.c:545
 msgid ""
 "      **FAIL**  REQUIRED LanguageVersion\n"
 "                REF: Pages 57-58, section 5.3.\n"
@@ -1243,6 +1367,7 @@ msgstr ""
 "                REF: 57-58 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:520 systemv/cupstestppd.c:539
+#: systemv/cupstestppd.c:563
 msgid ""
 "      **FAIL**  BAD Manufacturer (should be \"HP\")\n"
 "                REF: Page 211, table D.1.\n"
@@ -1251,10 +1376,12 @@ msgstr ""
 "                REF: 211 ページ、表 D.1。\n"
 
 #: systemv/cupstestppd.c:528 systemv/cupstestppd.c:547
+#: systemv/cupstestppd.c:571
 msgid "        PASS    Manufacturer\n"
 msgstr "        合格    Manufacturer\n"
 
 #: systemv/cupstestppd.c:538 systemv/cupstestppd.c:557
+#: systemv/cupstestppd.c:581
 msgid ""
 "      **FAIL**  REQUIRED Manufacturer\n"
 "                REF: Pages 58-59, section 5.3.\n"
@@ -1263,6 +1390,7 @@ msgstr ""
 "                REF: 58-59 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:559 systemv/cupstestppd.c:578
+#: systemv/cupstestppd.c:602
 #, c-format
 msgid ""
 "      **FAIL**  BAD ModelName - \"%c\" not allowed in string.\n"
@@ -1272,10 +1400,12 @@ msgstr ""
 "                REF: 59-60 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:568 systemv/cupstestppd.c:587
+#: systemv/cupstestppd.c:611
 msgid "        PASS    ModelName\n"
 msgstr "        合格    ModelName\n"
 
 #: systemv/cupstestppd.c:578 systemv/cupstestppd.c:597
+#: systemv/cupstestppd.c:621
 msgid ""
 "      **FAIL**  REQUIRED ModelName\n"
 "                REF: Pages 59-60, section 5.3.\n"
@@ -1284,10 +1414,12 @@ msgstr ""
 "                REF: 59-60 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:588 systemv/cupstestppd.c:607
+#: systemv/cupstestppd.c:631
 msgid "        PASS    NickName\n"
 msgstr "        合格    NickName\n"
 
 #: systemv/cupstestppd.c:598 systemv/cupstestppd.c:617
+#: systemv/cupstestppd.c:641
 msgid ""
 "      **FAIL**  REQUIRED NickName\n"
 "                REF: Page 60, section 5.3.\n"
@@ -1296,10 +1428,12 @@ msgstr ""
 "                REF: 60 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:608 systemv/cupstestppd.c:627
+#: systemv/cupstestppd.c:651
 msgid "        PASS    PageSize\n"
 msgstr "        合格    PageSize\n"
 
 #: systemv/cupstestppd.c:618 systemv/cupstestppd.c:637
+#: systemv/cupstestppd.c:661
 msgid ""
 "      **FAIL**  REQUIRED PageSize\n"
 "                REF: Pages 99-100, section 5.14.\n"
@@ -1308,10 +1442,12 @@ msgstr ""
 "                REF: 99-100 ページ、セクション 5.14。\n"
 
 #: systemv/cupstestppd.c:628 systemv/cupstestppd.c:647
+#: systemv/cupstestppd.c:671
 msgid "        PASS    PageRegion\n"
 msgstr "        合格    PageRegion\n"
 
 #: systemv/cupstestppd.c:638 systemv/cupstestppd.c:657
+#: systemv/cupstestppd.c:681
 msgid ""
 "      **FAIL**  REQUIRED PageRegion\n"
 "                REF: Page 100, section 5.14.\n"
@@ -1320,10 +1456,12 @@ msgstr ""
 "                REF: 100 ページ、セクション 5.14。\n"
 
 #: systemv/cupstestppd.c:648 systemv/cupstestppd.c:667
+#: systemv/cupstestppd.c:691
 msgid "        PASS    PCFileName\n"
 msgstr "        合格    PCFileName\n"
 
 #: systemv/cupstestppd.c:658 systemv/cupstestppd.c:677
+#: systemv/cupstestppd.c:701
 msgid ""
 "      **FAIL**  REQUIRED PCFileName\n"
 "                REF: Pages 61-62, section 5.3.\n"
@@ -1332,6 +1470,7 @@ msgstr ""
 "                REF: 61-62 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:676 systemv/cupstestppd.c:695
+#: systemv/cupstestppd.c:719
 msgid ""
 "      **FAIL**  BAD Product - not \"(string)\".\n"
 "                REF: Page 62, section 5.3.\n"
@@ -1340,10 +1479,12 @@ msgstr ""
 "                REF: 62 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:683 systemv/cupstestppd.c:702
+#: systemv/cupstestppd.c:726
 msgid "        PASS    Product\n"
 msgstr "        合格    Product\n"
 
 #: systemv/cupstestppd.c:693 systemv/cupstestppd.c:712
+#: systemv/cupstestppd.c:736
 msgid ""
 "      **FAIL**  REQUIRED Product\n"
 "                REF: Page 62, section 5.3.\n"
@@ -1352,6 +1493,7 @@ msgstr ""
 "                REF: 62 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:715 systemv/cupstestppd.c:734
+#: systemv/cupstestppd.c:758
 msgid ""
 "      **FAIL**  BAD PSVersion - not \"(string) int\".\n"
 "                REF: Pages 62-64, section 5.3.\n"
@@ -1360,10 +1502,12 @@ msgstr ""
 "                REF: 62-64 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:723 systemv/cupstestppd.c:742
+#: systemv/cupstestppd.c:766
 msgid "        PASS    PSVersion\n"
 msgstr "        合格    PSVersion\n"
 
 #: systemv/cupstestppd.c:733 systemv/cupstestppd.c:752
+#: systemv/cupstestppd.c:776
 msgid ""
 "      **FAIL**  REQUIRED PSVersion\n"
 "                REF: Pages 62-64, section 5.3.\n"
@@ -1372,6 +1516,7 @@ msgstr ""
 "                REF: 62-64 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:750 systemv/cupstestppd.c:769
+#: systemv/cupstestppd.c:793
 msgid ""
 "      **FAIL**  BAD ShortNickName - longer than 31 chars.\n"
 "                REF: Pages 64-65, section 5.3.\n"
@@ -1380,10 +1525,12 @@ msgstr ""
 "                REF: 64-65 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:758 systemv/cupstestppd.c:777
+#: systemv/cupstestppd.c:801
 msgid "        PASS    ShortNickName\n"
 msgstr "        合格    ShortNickName\n"
 
 #: systemv/cupstestppd.c:768 systemv/cupstestppd.c:787
+#: systemv/cupstestppd.c:811
 msgid ""
 "      **FAIL**  REQUIRED ShortNickName\n"
 "                REF: Page 64-65, section 5.3.\n"
@@ -1392,6 +1539,7 @@ msgstr ""
 "                REF: 64-65 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:784 systemv/cupstestppd.c:803
+#: systemv/cupstestppd.c:827
 msgid ""
 "      **FAIL**  BAD JobPatchFile attribute in file\n"
 "                REF: Page 24, section 3.4.\n"
@@ -1400,6 +1548,7 @@ msgstr ""
 "                REF: 24 ページ、セクション 3.4。\n"
 
 #: systemv/cupstestppd.c:804 systemv/cupstestppd.c:823
+#: systemv/cupstestppd.c:847
 msgid ""
 "      **FAIL**  REQUIRED PageSize\n"
 "                REF: Page 41, section 5.\n"
@@ -1410,6 +1559,7 @@ msgstr ""
 "                REF: 99 ページ、セクション 5.14。\n"
 
 #: systemv/cupstestppd.c:835 systemv/cupstestppd.c:854
+#: systemv/cupstestppd.c:878
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED ImageableArea for PageSize %s\n"
@@ -1421,6 +1571,7 @@ msgstr ""
 "                REF: 102 ページ、セクション 5.15。\n"
 
 #: systemv/cupstestppd.c:857 systemv/cupstestppd.c:876
+#: systemv/cupstestppd.c:900
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED PaperDimension for PageSize %s\n"
@@ -1432,6 +1583,7 @@ msgstr ""
 "                REF: 103 ページ、セクション 5.15。\n"
 
 #: systemv/cupstestppd.c:905 systemv/cupstestppd.c:924
+#: systemv/cupstestppd.c:948
 #, c-format
 msgid ""
 "      **FAIL**  Bad %s choice %s!\n"
@@ -1441,6 +1593,7 @@ msgstr ""
 "                REF: 84 ページ、セクション 5.9\n"
 
 #: systemv/cupstestppd.c:934 systemv/cupstestppd.c:953
+#: systemv/cupstestppd.c:977
 #, c-format
 msgid ""
 "      **FAIL**  REQUIRED %s does not define choice None!\n"
@@ -1450,6 +1603,7 @@ msgstr ""
 "                REF: 122 ページ、セクション 5.17\n"
 
 #: systemv/cupstestppd.c:955 systemv/cupstestppd.c:974
+#: systemv/cupstestppd.c:998
 #, c-format
 msgid ""
 "      **FAIL**  Bad %s choice %s!\n"
@@ -1459,10 +1613,12 @@ msgstr ""
 "                REF: 122 ページ、セクション 5.17\n"
 
 #: systemv/cupstestppd.c:967 systemv/cupstestppd.c:986
+#: systemv/cupstestppd.c:1186
 msgid " PASS\n"
 msgstr " 合格\n"
 
 #: systemv/cupstestppd.c:976 systemv/cupstestppd.c:997
+#: systemv/cupstestppd.c:1197
 #, c-format
 msgid ""
 "        WARN    Duplex option keyword %s should be named Duplex or "
@@ -1474,10 +1630,12 @@ msgstr ""
 "                REF: 122 ページ、セクション 5.17\n"
 
 #: systemv/cupstestppd.c:986 systemv/cupstestppd.c:1007
+#: systemv/cupstestppd.c:1207
 msgid "        WARN    Default choices conflicting!\n"
 msgstr "        警告    デフォルトの選択肢が衝突しています!\n"
 
 #: systemv/cupstestppd.c:994 systemv/cupstestppd.c:1015
+#: systemv/cupstestppd.c:1215
 #, c-format
 msgid ""
 "        WARN    Obsolete PPD version %.1f!\n"
@@ -1487,6 +1645,7 @@ msgstr ""
 "                REF: 42 ページ、セクション 5.2。\n"
 
 #: systemv/cupstestppd.c:1002 systemv/cupstestppd.c:1023
+#: systemv/cupstestppd.c:1223
 msgid ""
 "        WARN    LanguageEncoding required by PPD 4.3 spec.\n"
 "                REF: Pages 56-57, section 5.3.\n"
@@ -1495,6 +1654,7 @@ msgstr ""
 "                REF: 56-57 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:1010 systemv/cupstestppd.c:1031
+#: systemv/cupstestppd.c:1231
 msgid ""
 "        WARN    Manufacturer required by PPD 4.3 spec.\n"
 "                REF: Pages 58-59, section 5.3.\n"
@@ -1503,6 +1663,7 @@ msgstr ""
 "                REF: 58-59 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:1023 systemv/cupstestppd.c:1044
+#: systemv/cupstestppd.c:1244
 msgid ""
 "        WARN    PCFileName longer than 8.3 in violation of PPD spec.\n"
 "                REF: Pages 61-62, section 5.3.\n"
@@ -1511,6 +1672,7 @@ msgstr ""
 "                REF: 61-62 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:1031 systemv/cupstestppd.c:1052
+#: systemv/cupstestppd.c:1252
 msgid ""
 "        WARN    ShortNickName required by PPD 4.3 spec.\n"
 "                REF: Pages 64-65, section 5.3.\n"
@@ -1519,6 +1681,7 @@ msgstr ""
 "                REF: 64-65 ページ、セクション 5.3。\n"
 
 #: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1069
+#: systemv/cupstestppd.c:1269
 msgid ""
 "        WARN    Protocols contains both PJL and BCP; expected TBCP.\n"
 "                REF: Pages 78-79, section 5.7.\n"
@@ -1528,6 +1691,7 @@ msgstr ""
 "                REF: 78-79 ページ、セクション 5.7。\n"
 
 #: systemv/cupstestppd.c:1057 systemv/cupstestppd.c:1078
+#: systemv/cupstestppd.c:1278
 msgid ""
 "        WARN    Protocols contains PJL but JCL attributes are not set.\n"
 "                REF: Pages 78-79, section 5.7.\n"
@@ -1537,6 +1701,7 @@ msgstr ""
 "                REF: 78-79 ページ、セクション 5.7。\n"
 
 #: systemv/cupstestppd.c:1085 systemv/cupstestppd.c:1106
+#: systemv/cupstestppd.c:1306
 #, c-format
 msgid ""
 "        WARN    %s shares a common prefix with %s\n"
@@ -1546,15 +1711,18 @@ msgstr ""
 "                REF: 15 ページ、セクション 3.2。\n"
 
 #: systemv/cupstestppd.c:1097 systemv/cupstestppd.c:1118
+#: systemv/cupstestppd.c:1318
 #, c-format
 msgid "    %d ERROR%s FOUND\n"
 msgstr "    %d 個のエラー%s が見つかりました\n"
 
 #: systemv/cupstestppd.c:1100 systemv/cupstestppd.c:1121
+#: systemv/cupstestppd.c:1321
 msgid "    NO ERRORS FOUND\n"
 msgstr "    エラーは見つかりませんでした\n"
 
 #: systemv/cupstestppd.c:1360 systemv/cupstestppd.c:1465
+#: systemv/cupstestppd.c:1665
 #, c-format
 msgid ""
 "        WARN    \"%s %s\" conflicts with \"%s %s\"\n"
@@ -1564,6 +1732,7 @@ msgstr ""
 "                (constraint=\"%s %s %s %s\")\n"
 
 #: systemv/cupstestppd.c:1376 systemv/cupstestppd.c:1481
+#: systemv/cupstestppd.c:1681
 msgid ""
 "Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[."
 "gz]]\n"
@@ -2139,12 +2308,12 @@ msgstr "lpadmin: add-printer (説明の設定) に失敗しました: %s\n"
 msgid "lpadmin: add-printer (set location) failed: %s\n"
 msgstr "lpadmin: add-printer (場所の設定) に失敗しました: %s\n"
 
-#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814
+#: systemv/lpadmin.c:2021 systemv/lpadmin.c:1814 systemv/lpadmin.c:1831
 #, c-format
 msgid "lpadmin: Unable to create temporary file - %s\n"
 msgstr "lpadmin: テンポラリファイルを作成できません - %s\n"
 
-#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824
+#: systemv/lpadmin.c:2031 systemv/lpadmin.c:1824 systemv/lpadmin.c:1841
 #, c-format
 msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n"
 msgstr "lpadmin: PPD ファイル \"%s\" を開くことができません - %s\n"
@@ -2666,7 +2835,7 @@ msgid "Edit Configuration File"
 msgstr "設定ファイルの編集"
 
 #: cgi-bin/admin.c:2135 cgi-bin/admin.c:2147 cgi-bin/admin.c:2179
-#: cgi-bin/admin.c:2191
+#: cgi-bin/admin.c:2191 cgi-bin/printers.c:219
 msgid "Unable to create temporary file:"
 msgstr "テンポラリファイルを作成できません:"
 
@@ -2789,15 +2958,16 @@ msgstr "公開の設定"
 msgid "Unable to change printer-is-shared attribute:"
 msgstr "printer-is-shared 属性を変更できません:"
 
-#: cgi-bin/classes.c:161 cgi-bin/classes.c:208
+#: cgi-bin/classes.c:161 cgi-bin/classes.c:208 cgi-bin/classes.c:159
+#: cgi-bin/classes.c:206
 msgid "Classes"
 msgstr "クラス"
 
-#: cgi-bin/classes.c:355 cgi-bin/classes.c:356
+#: cgi-bin/classes.c:355 cgi-bin/classes.c:356 cgi-bin/classes.c:354
 msgid "Unable to get class list:"
 msgstr "クラスリストを取得できません:"
 
-#: cgi-bin/classes.c:454 cgi-bin/classes.c:455
+#: cgi-bin/classes.c:454 cgi-bin/classes.c:455 cgi-bin/classes.c:453
 msgid "Unable to get class status:"
 msgstr "クラスの状態を取得できません:"
 
@@ -2839,114 +3009,115 @@ msgid "Job operation failed:"
 msgstr "ジョブ操作に失敗しました:"
 
 #: cgi-bin/printers.c:161 cgi-bin/printers.c:208 cgi-bin/printers.c:211
+#: cgi-bin/printers.c:166 cgi-bin/printers.c:335
 msgid "Printers"
 msgstr "プリンタ"
 
-#: cgi-bin/printers.c:362 cgi-bin/printers.c:366
+#: cgi-bin/printers.c:362 cgi-bin/printers.c:366 cgi-bin/printers.c:518
 msgid "Unable to get printer list:"
 msgstr "プリンタリストを取得できません:"
 
-#: cgi-bin/printers.c:461 cgi-bin/printers.c:468
+#: cgi-bin/printers.c:461 cgi-bin/printers.c:468 cgi-bin/printers.c:628
 msgid "Unable to get printer status:"
 msgstr "プリンタの状態を取得できません:"
 
-#: cups/ppd.c:319
+#: cups/ppd.c:319 cups/ppd.c:302
 msgid "OK"
 msgstr "OK"
 
-#: cups/ppd.c:320
+#: cups/ppd.c:320 cups/ppd.c:303
 msgid "Unable to open PPD file"
 msgstr "PPD ファイルを開くことができません"
 
-#: cups/ppd.c:321
+#: cups/ppd.c:321 cups/ppd.c:304
 msgid "NULL PPD file pointer"
 msgstr "NULL PPD ファイルポインタ"
 
-#: cups/ppd.c:322
+#: cups/ppd.c:322 cups/ppd.c:305
 msgid "Memory allocation error"
 msgstr "メモリ割り当てエラー"
 
-#: cups/ppd.c:323
+#: cups/ppd.c:323 cups/ppd.c:306
 msgid "Missing PPD-Adobe-4.x header"
 msgstr "PPD-Adobe-4.x ヘッダがありません"
 
-#: cups/ppd.c:324
+#: cups/ppd.c:324 cups/ppd.c:307
 msgid "Missing value string"
 msgstr "値文字列がありません"
 
-#: cups/ppd.c:325
+#: cups/ppd.c:325 cups/ppd.c:308
 msgid "Internal error"
 msgstr "内部エラー"
 
-#: cups/ppd.c:326
+#: cups/ppd.c:326 cups/ppd.c:309
 msgid "Bad OpenGroup"
 msgstr "不正な OpenGroup"
 
-#: cups/ppd.c:327
+#: cups/ppd.c:327 cups/ppd.c:310
 msgid "OpenGroup without a CloseGroup first"
 msgstr "最初の CloseGroup なしの OpenGroup"
 
-#: cups/ppd.c:328
+#: cups/ppd.c:328 cups/ppd.c:311
 msgid "Bad OpenUI/JCLOpenUI"
 msgstr "不正な OpenUI/JCLOpenUI"
 
-#: cups/ppd.c:329
+#: cups/ppd.c:329 cups/ppd.c:312
 msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first"
 msgstr "最初の CloseUI/JCLCloseUI なしの OpenUI/JCLOpenUI"
 
-#: cups/ppd.c:330
+#: cups/ppd.c:330 cups/ppd.c:313
 msgid "Bad OrderDependency"
 msgstr "不正な OrderDependency"
 
-#: cups/ppd.c:331
+#: cups/ppd.c:331 cups/ppd.c:314
 msgid "Bad UIConstraints"
 msgstr "不正な UIConstraints"
 
-#: cups/ppd.c:332
+#: cups/ppd.c:332 cups/ppd.c:315
 msgid "Missing asterisk in column 1"
 msgstr "1 列目にアスタリスクがありません"
 
-#: cups/ppd.c:333
+#: cups/ppd.c:333 cups/ppd.c:316
 msgid "Line longer than the maximum allowed (255 characters)"
 msgstr "1 行が最大許可値 (255 文字) を超えています"
 
-#: cups/ppd.c:334
+#: cups/ppd.c:334 cups/ppd.c:317
 msgid "Illegal control character"
 msgstr "不正な制御文字"
 
-#: cups/ppd.c:335
+#: cups/ppd.c:335 cups/ppd.c:318
 msgid "Illegal main keyword string"
 msgstr "不正なメインキーワード文字列"
 
-#: cups/ppd.c:336
+#: cups/ppd.c:336 cups/ppd.c:319
 msgid "Illegal option keyword string"
 msgstr "不正なオプションキーワード文字列"
 
-#: cups/ppd.c:337
+#: cups/ppd.c:337 cups/ppd.c:320
 msgid "Illegal translation string"
 msgstr "不正な翻訳文字列"
 
-#: cups/ppd.c:338
+#: cups/ppd.c:338 cups/ppd.c:321
 msgid "Illegal whitespace character"
 msgstr "不正な空白文字"
 
-#: cups/ppd.c:339
+#: cups/ppd.c:339 cups/ppd.c:322
 msgid "Bad custom parameter"
 msgstr "不正なカスタムパラメータ"
 
-#: cups/ppd.c:344
+#: cups/ppd.c:344 cups/ppd.c:327
 msgid "Unknown"
 msgstr "未知"
 
-#: cups/ppd.c:1033
+#: cups/ppd.c:1033 cups/ppd.c:1020
 msgid "Custom"
 msgstr "カスタム"
 
-#: cups/ppd.c:1259
+#: cups/ppd.c:1259 cups/ppd.c:1236
 msgid "JCL"
 msgstr "JCL"
 
-#: scheduler/ipp.c:2184 scheduler/ipp.c:2226
+#: scheduler/ipp.c:2184 scheduler/ipp.c:2226 scheduler/ipp.c:2681
 msgid "No authentication information provided!"
 msgstr "認証情報が提供されていません!"
 
@@ -3394,11 +3565,11 @@ msgstr "プリンタ:"
 msgid "idle"
 msgstr "待機中"
 
-#: scheduler/ipp.c:5513
+#: scheduler/ipp.c:5513 scheduler/ipp.c:5482
 msgid "Missing notify-subscription-ids attribute!"
 msgstr "notify-subscription-ids 属性がありません!"
 
-#: scheduler/ipp.c:7851
+#: scheduler/ipp.c:7851 scheduler/ipp.c:7341
 msgid "Job subscriptions cannot be renewed!"
 msgstr "ジョブサブスクリプションが更新されていません!"
 
@@ -3408,7 +3579,9 @@ msgstr "cupsd: -c オプションのあとには設定ファイル名が必要
 
 #: scheduler/main.c:218
 msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n"
-msgstr "cupsd: launchd(8) サポートがコンパイルされていないので、通常モードで動作します。\n"
+msgstr ""
+"cupsd: launchd(8) サポートがコンパイルされていないので、通常モードで動作しま"
+"す。\n"
 
 #: scheduler/main.c:225
 #, c-format
@@ -3420,7 +3593,7 @@ msgstr "cupsd: \"%c\" は未知のオプションです - 停止します!\n"
 msgid "cupsd: Unknown argument \"%s\" - aborting!\n"
 msgstr "cupsd: \"%s\" は未知の引数です - 停止します!\n"
 
-#: scheduler/main.c:2315
+#: scheduler/main.c:2315 scheduler/main.c:2329
 msgid ""
 "Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n"
 "\n"
@@ -3438,18 +3611,77 @@ msgstr ""
 "-h                  この使用例を表示する\n"
 "-l                  launchd(8) から cupsd を実行する\n"
 
-#: systemv/cupstestppd.c:1343
+#: systemv/cupstestppd.c:1343 systemv/cupstestppd.c:1543
 #, c-format
 msgid "        WARN    Line %d only contains whitespace!\n"
 msgstr "        警告    %d 行が空白だけです!\n"
 
-#: systemv/cupstestppd.c:1361
+#: systemv/cupstestppd.c:1361 systemv/cupstestppd.c:1561
 msgid ""
 "        WARN    File contains a mix of CR, LF, and CR LF line endings!\n"
-msgstr "        警告    ファイルが CR、LF、CR LF の行末を混在して含んでいます!\n"
+msgstr ""
+"        警告    ファイルが CR、LF、CR LF の行末を混在して含んでいます!\n"
 
-#: systemv/cupstestppd.c:1366
+#: systemv/cupstestppd.c:1366 systemv/cupstestppd.c:1566
 msgid ""
 "        WARN    Non-Windows PPD files should use lines ending with only LF, "
 "not CR LF!\n"
-msgstr "        警告    非 Windows PPD ファイルは、CR LF でなく LF のみを行末に使うべきです!\n"
+msgstr ""
+"        警告    非 Windows PPD ファイルは、CR LF でなく LF のみを行末に使うべ"
+"きです!\n"
+
+#: cgi-bin/printers.c:218 cgi-bin/printers.c:289
+#, fuzzy
+msgid "Printer Maintenance"
+msgstr "プリンタは共有されていません!"
+
+#: cgi-bin/printers.c:292
+#, fuzzy
+msgid "Unable to send maintenance job:"
+msgstr "ジョブを移動できません"
+
+#: systemv/cupsaddsmb.c:566
+#, fuzzy, c-format
+msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n"
+msgstr ""
+"cupsaddsmb: プリンタ \"%s\" の PPD ファイルがありません - スキップします!\n"
+
+#: systemv/cupstestppd.c:346
+#, fuzzy, c-format
+msgid "      **FAIL**  %s %s does not exist!\n"
+msgstr "ジョブ #%s は存在しません!"
+
+#: systemv/cupstestppd.c:1053
+#, c-format
+msgid "      **FAIL**  Bad language \"%s\"!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1078
+#, c-format
+msgid "      **FAIL**  Missing \"%s\" translation string for option %s!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1098
+#, c-format
+msgid ""
+"      **FAIL**  Default translation string for option %s contains 8-bit "
+"characters!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1119
+#, c-format
+msgid ""
+"      **FAIL**  Missing \"%s\" translation string for option %s, choice %s!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1141
+#, c-format
+msgid ""
+"      **FAIL**  Default translation string for option %s choice %s contains "
+"8-bit characters!\n"
+msgstr ""
+
+#: systemv/cupstestppd.c:1175
+#, c-format
+msgid "      **FAIL**  Bad cupsFilter value \"%s\"!\n"
+msgstr ""
index c64f3b6660ece3ed79b9e5570a3767254daab432..62e551da827f6fc027769383b89fdb6f2e1f2225 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5099 2006-02-13 02:46:10Z mike $"
+# "$Id: Makefile 5182 2006-02-26 04:10:27Z mike $"
 #
 #   Man page makefile for the Common UNIX Printing System (CUPS).
 #
@@ -40,6 +40,7 @@ MAN1  =       cancel.$(MAN1EXT) \
                lpr.$(MAN1EXT) \
                lpstat.$(MAN1EXT)
 MAN5   =       classes.conf.$(MAN5EXT) \
+               client.conf.$(MAN5EXT) \
                cupsd.conf.$(MAN5EXT) \
                mime.convs.$(MAN5EXT) \
                mime.types.$(MAN5EXT) \
@@ -154,5 +155,5 @@ mantohtml:  mantohtml.o
 
 
 #
-# End of "$Id: Makefile 5099 2006-02-13 02:46:10Z mike $".
+# End of "$Id: Makefile 5182 2006-02-26 04:10:27Z mike $".
 #
diff --git a/man/client.conf.man.in b/man/client.conf.man.in
new file mode 100644 (file)
index 0000000..55b4c8e
--- /dev/null
@@ -0,0 +1,58 @@
+.\"
+.\" "$Id: client.conf.man.in 5182 2006-02-26 04:10:27Z mike $"
+.\"
+.\"   client.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\"   Copyright 2006 by Easy Software Products.
+.\"
+.\"   These coded instructions, statements, and computer programs are the
+.\"   property of Easy Software Products 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 missing or damaged please contact Easy Software Products
+.\"   at:
+.\"
+.\"       Attn: CUPS Licensing Information
+.\"       Easy Software Products
+.\"       44141 Airport View Drive, Suite 204
+.\"       Hollywood, Maryland 20636 USA
+.\"
+.\"       Voice: (301) 373-9600
+.\"       EMail: cups-info@cups.org
+.\"         WWW: http://www.cups.org
+.\"
+.TH client.conf 5 "Common UNIX Printing System" "25 February 2006" "Easy Software Products"
+.SH NAME
+client.conf \- client configuration file for cups
+.SH DESCRIPTION
+The \fIclient.conf\fR file configures the CUPS client and is 
+normally located in the \fI@CUPS_SERVERROOT@\fR or \fI~/.cups\fR
+directory. Each line in the file can be a configuration
+directive, a blank line, or a comment. Comment lines start with
+the # character.
+.SH DIRECTIVES
+The following directives are understood by the client. Consult the
+on-line help for detailed descriptions:
+.TP 5
+Encryption IfRequested
+.TP 5
+Encryption Never
+.TP 5
+Encryption Required
+.br
+Specifies the level of encryption that is required for a particular
+location.
+.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
+.SH SEE ALSO
+http://localhost:631/help
+.SH COPYRIGHT
+Copyright 2006 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: client.conf.man.in 5182 2006-02-26 04:10:27Z mike $".
+.\"
similarity index 92%
rename from man/lpoptions.man
rename to man/lpoptions.man.in
index 08e012bdd9adb2b0cd54a1e3a20d5ac66320caf1..1f6f3f0e02bf2bff75d4435390aba41ef272b1b1 100644 (file)
@@ -1,5 +1,5 @@
 .\"
-.\" "$Id: lpoptions.man 5099 2006-02-13 02:46:10Z mike $"
+.\" "$Id: lpoptions.man.in 5182 2006-02-26 04:10:27Z mike $"
 .\"
 .\"   lpoptions man page for the Common UNIX Printing System (CUPS).
 .\"
@@ -128,11 +128,11 @@ options and instances for \fIall users\fR in the
 .SH COMPATIBILITY
 The \fIlpoptions\fR command is unique to CUPS.
 .SH FILES
-~/.lpoptions - user defaults and instances created by non-root
+~/.cups/lpoptions - user defaults and instances created by non-root
 users.
 .br
-/etc/cups/lpoptions - system-wide defaults and instances created
-by the root user.
+@CUPS_SERVERROOT@/lpoptions - system-wide defaults and instances
+created by the root user.
 .SH SEE ALSO
 \fIcancel(1)\fR, \fIlp(1)\fR, \fIlpr(1)\fR,
 .br
@@ -140,5 +140,5 @@ http://localhost:631/help
 .SH COPYRIGHT
 Copyright 1997-2006 by Easy Software Products, All Rights Reserved.
 .\"
-.\" End of "$Id: lpoptions.man 5099 2006-02-13 02:46:10Z mike $".
+.\" End of "$Id: lpoptions.man.in 5182 2006-02-26 04:10:27Z mike $".
 .\"
index c2721216f04f02a5088daf5543a685dd43e1a247..2f19c85ba7b1e72255a548cf6fe20d04c042d8c2 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: cups.list.in 5116 2006-02-16 12:52:32Z mike $"
+# "$Id: cups.list.in 5193 2006-02-27 20:27:07Z mike $"
 #
 #   ESP Package Manager (EPM) file list for the Common UNIX Printing
 #   System (CUPS).
@@ -294,8 +294,6 @@ d 0755 root $CUPS_GROUP $STATEDIR -
 d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs -
 
 # Data files
-f 0644 root sys $LOCALEDIR/fr/cups_fr.po locale/cups_fr.po
-
 %subpackage ja
 f 0644 root sys $LOCALEDIR/ja/cups_ja.po locale/cups_ja.po
 %subpackage
@@ -462,5 +460,5 @@ f 0644 root sys $AMANDIR/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.$MAN8EXT
 i 0755 root sys cups init/cups.sh
 
 #
-# End of "$Id: cups.list.in 5116 2006-02-16 12:52:32Z mike $".
+# End of "$Id: cups.list.in 5193 2006-02-27 20:27:07Z mike $".
 #
index da7ca0794580130453c380e4a807fe38647436c7..1cdee77514b6dc083011dfbc0a919ede3d67829a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: cups.spec.in 5146 2006-02-22 14:03:50Z mike $"
+# "$Id: cups.spec.in 5193 2006-02-27 20:27:07Z mike $"
 #
 #   RPM "spec" file for the Common UNIX Printing System (CUPS).
 #
 # Conditional build options (--with name/--without name):
 #
 #   dbus     - Enable/disable DBUS support (default = enable)
+#   php      - Enable/disable PHP support (default = enable)
 
 %{!?_with_dbus: %{!?_without_dbus: %define _with_dbus --with-dbus}}
 %{?_with_dbus: %define _dbus --enable-dbus}
 %{!?_with_dbus: %define _dbus --disable-dbus}
 
+%{!?_with_php: %{!?_without_php: %define _with_php --with-php}}
+
 Summary: Common UNIX Printing System
 Name: cups
 Version: @CUPS_VERSION@
@@ -72,6 +75,13 @@ Summary: Common UNIX Printing System - Japanese support
 Group: System Environment/Daemons
 Requires: %{name} = %{epoch}:%{version}
 
+%if %{?_with_php:1}%{!?_with_php:0}
+%package php
+Summary: Common UNIX Printing System - PHP support
+Group: Development/Languages
+Requires: %{name}-libs = %{epoch}:%{version}
+%endif
+
 %description
 The Common UNIX Printing System provides a portable printing layer for 
 UNIX® operating systems. It has been developed by Easy Software Products 
@@ -95,11 +105,17 @@ UNIX
 The Common UNIX Printing System provides a portable printing layer for 
 UNIX® operating systems. This package provides Japanese support.
 
+%if %{?_with_php:1}%{!?_with_php:0}
+%description php
+The Common UNIX Printing System provides a portable printing layer for 
+UNIX® operating systems. This package provides PHP support.
+%endif
+
 %prep
 %setup
 
 %build
-CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure %{_dbus}
+CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure %{_dbus} %{_without_php}
 
 # If we got this far, all prerequisite libraries must be here.
 make
@@ -224,7 +240,6 @@ rm -rf $RPM_BUILD_ROOT
 /usr/share/doc/cups/help/whatsnew.html
 %dir /usr/share/doc/cups/images
 /usr/share/doc/cups/images/*
-/usr/share/locale/fr/cups_fr.po
 
 %dir /usr/share/man/man1
 /usr/share/man/man1/cancel.1.gz
@@ -300,6 +315,13 @@ rm -rf $RPM_BUILD_ROOT
 /usr/share/cups/templates/ja/*
 /usr/share/locale/ja/cups_ja.po
 
+%if %{?_with_php:1}%{!?_with_php:0}
+%files php
+# PHP
+/usr/lib/php*
+%endif
+
+
 #
-# End of "$Id: cups.spec.in 5146 2006-02-22 14:03:50Z mike $".
+# End of "$Id: cups.spec.in 5193 2006-02-27 20:27:07Z mike $".
 #
index adbebbf54aba0600edba8c4a1994f4db67d2e07a..de9cecfbb7af36dfffb95ae0d0b27e7b0eff4942 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5116 2006-02-16 12:52:32Z mike $"
+# "$Id: Makefile 5157 2006-02-23 20:58:57Z mike $"
 #
 #   Scheduler Makefile for the Common UNIX Printing System (CUPS).
 #
@@ -155,14 +155,15 @@ install:  all
 cupsd: $(CUPSDOBJS) libmime.a ../cups/$(LIBCUPS)
        echo Linking $@...
        $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) libmime.a \
-               $(LIBZ) $(SSLLIBS) $(LIBSLP) $(PAMLIBS) \
+               $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
                $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS) $(LIBS)
 
 cupsd-static:  $(CUPSDOBJS) libmime.a ../cups/libcups.a
        echo Linking $@...
        $(CC) $(LDFLAGS) -o cupsd-static $(CUPSDOBJS) libmime.a \
-               $(LIBZ) $(SSLLIBS) $(LIBSLP) $(PAMLIBS) ../cups/libcups.a \
-               $(COMMONLIBS) $(LIBZ) $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS)
+               $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
+               ../cups/libcups.a $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \
+               $(LIBMALLOC) $(CUPSDLIBS)
 
 
 #
@@ -248,5 +249,5 @@ include Dependencies
 
 
 #
-# End of "$Id: Makefile 5116 2006-02-16 12:52:32Z mike $".
+# End of "$Id: Makefile 5157 2006-02-23 20:58:57Z mike $".
 #
index 89011f7db89ab0e2ef1cc58fd89f6190a6da9959..bee2ad395cb0b77732475d47be3e5c3c73ca53b5 100644 (file)
@@ -1,5 +1,5 @@
-;/*
- * "$Id: auth.c 5083 2006-02-06 02:57:43Z mike $"
+/*
+ * "$Id: auth.c 5197 2006-02-27 21:30:20Z mike $"
  *
  *   Authorization routines for the Common UNIX Printing System (CUPS).
  *
@@ -116,7 +116,7 @@ typedef struct cupsd_authdata_s             /**** Authentication data ****/
  */
 
 #if defined(__hpux) && defined(HAVE_LIBPAM)
-static cupsd_authdata_t        *auth_datat;    /* Current client being authenticated */
+static cupsd_authdata_t        *auth_data    /* Current client being authenticated */
 #endif /* __hpux && HAVE_LIBPAM */
 
 
@@ -2156,5 +2156,5 @@ to64(char          *s,                    /* O - Output string */
 
 
 /*
- * End of "$Id: auth.c 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: auth.c 5197 2006-02-27 21:30:20Z mike $".
  */
index fe36555d81412cc3a2efd302b802dfd8eb75569e..749a1bda01bdefd08c21d1df86791b7ef3878bdb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: classes.c 5083 2006-02-06 02:57:43Z mike $"
+ * "$Id: classes.c 5151 2006-02-22 22:43:17Z mike $"
  *
  *   Printer class routines for the Common UNIX Printing System (CUPS).
  *
@@ -410,6 +410,25 @@ cupsdLoadAllClasses(void)
       if (value)
         cupsdSetString(&p->location, value);
     }
+    else if (!strcasecmp(line, "Option") && value)
+    {
+     /*
+      * Option name value
+      */
+
+      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
+
+      if (!*valueptr)
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of classes.conf.", linenum);
+      else
+      {
+        for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
+
+        p->num_options = cupsAddOption(value, valueptr, p->num_options,
+                                      &(p->options));
+      }
+    }
     else if (!strcasecmp(line, "Printer"))
     {
       if (!value)
@@ -683,6 +702,7 @@ cupsdSaveAllClasses(void)
   int                  i;              /* Looping var */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
+  cups_option_t                *option;        /* Current option */
 
 
  /*
@@ -801,6 +821,11 @@ cupsdSaveAllClasses(void)
     if (pclass->error_policy)
       cupsFilePrintf(fp, "ErrorPolicy %s\n", pclass->error_policy);
 
+    for (i = pclass->num_options, option = pclass->options;
+         i > 0;
+        i --, option ++)
+      cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+
     cupsFilePuts(fp, "</Class>\n");
   }
 
@@ -839,5 +864,5 @@ cupsdUpdateImplicitClasses(void)
 
 
 /*
- * End of "$Id: classes.c 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: classes.c 5151 2006-02-22 22:43:17Z mike $".
  */
index b35ed9ba9c3599a0ad7e88b20b557d3426921219..c9ae16f010900f9ab98bcc4728f5aed635735d61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: client.c 5083 2006-02-06 02:57:43Z mike $"
+ * "$Id: client.c 5200 2006-02-28 00:10:32Z mike $"
  *
  *   Client routines for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -515,7 +515,9 @@ cupsdCloseClient(cupsd_client_t *con)       /* I - Client to close */
     free(conn);
 
 #  elif defined(HAVE_CDSASSL)
-    SSLClose((SSLContextRef)con->http.tls);
+    while (SSLClose((SSLContextRef)con->http.tls) == errSSLWouldBlock)
+      usleep(1000);
+
     SSLDisposeContext((SSLContextRef)con->http.tls);
 #  endif /* HAVE_LIBSSL */
 
@@ -755,6 +757,7 @@ cupsdEncryptClient(cupsd_client_t *con)     /* I - Client to encrypt */
 #elif defined(HAVE_CDSASSL)
   OSStatus     error;                  /* Error info */
   SSLContextRef        conn;                   /* New connection */
+  CFArrayRef   certificatesArray;      /* Array containing certificates */
   int          allowExpired;           /* Allow expired certificates? */
   int          allowAnyRoot;           /* Allow any root certificate? */
 
@@ -764,10 +767,9 @@ cupsdEncryptClient(cupsd_client_t *con)    /* I - Client to encrypt */
   allowExpired = 1;
   allowAnyRoot = 1;
 
-  if (!ServerCertificatesArray)
-    ServerCertificatesArray = get_cdsa_server_certs();
+  certificatesArray = get_cdsa_server_certs();
 
-  if (!ServerCertificatesArray)
+  if (!certificatesArray)
   {
     cupsdLogMessage(CUPSD_LOG_ERROR,
                    "EncryptClient: Could not find signing key in keychain "
@@ -794,22 +796,23 @@ cupsdEncryptClient(cupsd_client_t *con)   /* I - Client to encrypt */
   if (!error && allowAnyRoot)
     error = SSLSetAllowsAnyRoot(conn, true);
 
-  if (!error && ServerCertificatesArray)
+  if (!error)
+    error = SSLSetCertificate(conn, certificatesArray);
+
+  if (certificatesArray)
   {
-    error = SSLSetCertificate(conn, ServerCertificatesArray);
+    CFRelease(certificatesArray);
+    certificatesArray = NULL;
+  }
 
+  if (!error)
+  {
    /*
     * Perform SSL/TLS handshake
     */
-  
-    if (!error)
-    {
-      do
-      {
-       error = SSLHandshake(conn);
-      }
-      while (error == errSSLWouldBlock);
-    }
+
+    while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+      usleep(1000);
   }
 
   if (error)
@@ -889,10 +892,7 @@ cupsdIsCGI(cupsd_client_t *con,            /* I - Client connection */
 
     filename = strrchr(filename, '/') + 1; /* Filename always absolute */
 
-    if (options)
-      cupsdSetStringf(&con->options, "%s %s", filename, options);
-    else
-      cupsdSetStringf(&con->options, "%s", filename);
+    cupsdSetString(&con->options, options);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -910,9 +910,9 @@ cupsdIsCGI(cupsd_client_t *con,             /* I - Client connection */
     cupsdSetString(&con->command, CUPS_JAVA);
 
     if (options)
-      cupsdSetStringf(&con->options, "java %s %s", filename, options);
+      cupsdSetStringf(&con->options, "%s %s", filename, options);
     else
-      cupsdSetStringf(&con->options, "java %s", filename);
+      cupsdSetString(&con->options, filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -931,9 +931,9 @@ cupsdIsCGI(cupsd_client_t *con,             /* I - Client connection */
     cupsdSetString(&con->command, CUPS_PERL);
 
     if (options)
-      cupsdSetStringf(&con->options, "perl %s %s", filename, options);
+      cupsdSetStringf(&con->options, "%s %s", filename, options);
     else
-      cupsdSetStringf(&con->options, "perl %s", filename);
+      cupsdSetString(&con->options, filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -952,9 +952,9 @@ cupsdIsCGI(cupsd_client_t *con,             /* I - Client connection */
     cupsdSetString(&con->command, CUPS_PHP);
 
     if (options)
-      cupsdSetStringf(&con->options, "php %s %s", filename, options);
+      cupsdSetStringf(&con->options, "%s %s", filename, options);
     else
-      cupsdSetStringf(&con->options, "php %s", filename);
+      cupsdSetString(&con->options, filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -973,9 +973,9 @@ cupsdIsCGI(cupsd_client_t *con,             /* I - Client connection */
     cupsdSetString(&con->command, CUPS_PYTHON);
 
     if (options)
-      cupsdSetStringf(&con->options, "python %s %s", filename, options);
+      cupsdSetStringf(&con->options, "%s %s", filename, options);
     else
-      cupsdSetStringf(&con->options, "python %s", filename);
+      cupsdSetString(&con->options, filename);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2,
                     "cupsdIsCGI: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -1346,11 +1346,6 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
 #endif /* HAVE_SSL */
       }
 
-      if (con->http.expect)
-      {
-        /**** TODO: send expected header ****/
-      }
-
       if (!cupsdSendHeader(con, HTTP_OK, NULL))
        return (cupsdCloseClient(con));
 
@@ -1401,9 +1396,30 @@ cupsdReadClient(cupsd_client_t *con)     /* I - Client to read from */
        return (cupsdCloseClient(con));
       }
 
-      if (con->http.expect)
+      if (con->http.expect &&
+          (con->operation == HTTP_POST || con->operation == HTTP_PUT))
       {
-        /**** TODO: send expected header ****/
+        if (con->http.expect == HTTP_CONTINUE)
+       {
+        /*
+         * Send 100-continue header...
+         */
+
+         if (!cupsdSendHeader(con, HTTP_CONTINUE, NULL))
+           return (cupsdCloseClient(con));
+       }
+       else
+       {
+        /*
+         * Send 417-expectation-failed header...
+         */
+
+         if (!cupsdSendHeader(con, HTTP_EXPECTATION_FAILED, NULL))
+           return (cupsdCloseClient(con));
+
+         httpPrintf(HTTP(con), "Content-Length: 0\r\n");
+         httpPrintf(HTTP(con), "\r\n");
+       }
       }
 
       switch (con->http.state)
@@ -1447,38 +1463,48 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
                cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi",
                                ServerBin);
 
-               if ((ptr = strchr(con->uri + 6, '?')) != NULL)
-                 cupsdSetStringf(&con->options, "admin%s", ptr);
-               else
-                 cupsdSetString(&con->options, "admin");
+               cupsdSetString(&con->options, strchr(con->uri + 6, '?'));
              }
               else if (!strncmp(con->uri, "/printers", 9))
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi",
                                ServerBin);
-               cupsdSetString(&con->options, con->uri + 9);
+
+                if (con->uri[9] && con->uri[10])
+                 cupsdSetString(&con->options, con->uri + 9);
+               else
+                 cupsdSetString(&con->options, NULL);
              }
              else if (!strncmp(con->uri, "/classes", 8))
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi",
                                ServerBin);
-               cupsdSetString(&con->options, con->uri + 8);
+
+                if (con->uri[8] && con->uri[9])
+                 cupsdSetString(&con->options, con->uri + 8);
+               else
+                 cupsdSetString(&con->options, NULL);
              }
              else if (!strncmp(con->uri, "/jobs", 5))
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi",
                                ServerBin);
-                cupsdSetString(&con->options, con->uri + 5);
+
+                if (con->uri[5] && con->uri[6])
+                 cupsdSetString(&con->options, con->uri + 5);
+               else
+                 cupsdSetString(&con->options, NULL);
              }
              else
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi",
                                ServerBin);
-                cupsdSetString(&con->options, con->uri + 5);
-             }
 
-              if (con->options[0] == '/')
-               _cups_strcpy(con->options, con->options + 1);
+                if (con->uri[5] && con->uri[6])
+                 cupsdSetString(&con->options, con->uri + 5);
+               else
+                 cupsdSetString(&con->options, NULL);
+             }
 
               if (!cupsdSendCommand(con, con->command, con->options, 0))
              {
@@ -1623,41 +1649,52 @@ cupsdReadClient(cupsd_client_t *con)    /* I - Client to read from */
                cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi",
                                ServerBin);
 
-               if ((ptr = strchr(con->uri + 6, '?')) != NULL)
-                 cupsdSetStringf(&con->options, "admin%s", ptr);
-               else
-                 cupsdSetString(&con->options, "admin");
+               cupsdSetString(&con->options, strchr(con->uri + 6, '?'));
              }
               else if (!strncmp(con->uri, "/printers", 9))
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi",
                                ServerBin);
-               cupsdSetString(&con->options, con->uri + 9);
+
+                if (con->uri[9] && con->uri[10])
+                 cupsdSetString(&con->options, con->uri + 9);
+               else
+                 cupsdSetString(&con->options, NULL);
              }
              else if (!strncmp(con->uri, "/classes", 8))
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi",
                                ServerBin);
-               cupsdSetString(&con->options, con->uri + 8);
+
+                if (con->uri[8] && con->uri[9])
+                 cupsdSetString(&con->options, con->uri + 8);
+               else
+                 cupsdSetString(&con->options, NULL);
              }
              else if (!strncmp(con->uri, "/jobs", 5))
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi",
                                ServerBin);
-               cupsdSetString(&con->options, con->uri + 5);
+
+                if (con->uri[5] && con->uri[6])
+                 cupsdSetString(&con->options, con->uri + 5);
+               else
+                 cupsdSetString(&con->options, NULL);
              }
              else
              {
                cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi",
                                ServerBin);
-               cupsdSetString(&con->options, con->uri + 5);
-             }
 
-             if (con->options[0] == '/')
-               _cups_strcpy(con->options, con->options + 1);
+                if (con->uri[5] && con->uri[6])
+                 cupsdSetString(&con->options, con->uri + 5);
+               else
+                 cupsdSetString(&con->options, NULL);
+             }
 
               cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                             "cupsdReadClient: %d command=\"%s\", options = \"%s\"",
+                             "cupsdReadClient: %d command=\"%s\", "
+                             "options = \"%s\"",
                              con->http.fd, con->command, con->options);
 
              if (con->http.version <= HTTP_1_0)
@@ -2382,6 +2419,15 @@ cupsdSendHeader(cupsd_client_t *con,     /* I - Client to send to */
   if (httpPrintf(HTTP(con), "HTTP/%d.%d %d %s\r\n", con->http.version / 100,
                  con->http.version % 100, code, httpStatus(code)) < 0)
     return (0);
+
+  if (code == HTTP_CONTINUE)
+  {
+    if (httpPrintf(HTTP(con), "\r\n") < 0)
+      return (0);
+    else
+      return (1);
+  }
+
   if (httpPrintf(HTTP(con), "Date: %s\r\n", httpGetDateString(time(NULL))) < 0)
     return (0);
   if (ServerHeader)
@@ -2792,7 +2838,7 @@ check_if_modified(
  * To create a self-signed certificate for testing use the certtool.
  * Executing the following as root will do it:
  *
- *     certtool c c v k=CUPS
+ *     certtool c k=/Library/Keychains/System.keychain
  */
 
 static CFArrayRef                      /* O - Array of certificates */
@@ -2848,19 +2894,19 @@ get_cdsa_server_certs(void)
          * to array as well.
          */
 
-         ca = CFArrayCreate(NULL, (const void **)&identity, 1, NULL);
+         ca = CFArrayCreate(NULL, (const void **)&identity, 1, &kCFTypeArrayCallBacks);
 
          if (ca == nil)
            cupsdLogMessage(CUPSD_LOG_ERROR, "CFArrayCreate error");
        }
 
-       /*CFRelease(identity);*/
+       CFRelease(identity);
       }
 
-      /*CFRelease(srchRef);*/
+      CFRelease(srchRef);
     }
 
-    /*CFRelease(kcRef);*/
+    CFRelease(kcRef);
   }
 
   return (ca);
@@ -3215,19 +3261,21 @@ pipe_command(cupsd_client_t *con,       /* I - Client connection */
 {
   int          i;                      /* Looping var */
   int          pid;                    /* Process ID */
-  char         *commptr;               /* Command string pointer */
+  char         *commptr,               /* Command string pointer */
+               commch;                 /* Command string character */
   char         *uriptr;                /* URI string pointer */
   int          fds[2];                 /* Pipe FDs */
   int          argc;                   /* Number of arguments */
   int          envc;                   /* Number of environment variables */
   char         argbuf[10240],          /* Argument buffer */
                *argv[100],             /* Argument strings */
-               *envp[MAX_ENV + 16];    /* Environment variables */
+               *envp[MAX_ENV + 17];    /* Environment variables */
   char         content_length[1024],   /* CONTENT_LENGTH environment variable */
                content_type[1024],     /* CONTENT_TYPE environment variable */
                http_cookie[32768],     /* HTTP_COOKIE environment variable */
                http_user_agent[1024],  /* HTTP_USER_AGENT environment variable */
                lang[1024],             /* LANG environment variable */
+               path_info[1024],        /* PATH_INFO environment variable */
                *query_string,          /* QUERY_STRING env variable */
                remote_addr[1024],      /* REMOTE_ADDR environment variable */
                remote_host[1024],      /* REMOTE_HOST environment variable */
@@ -3240,10 +3288,12 @@ pipe_command(cupsd_client_t *con,       /* I - Client connection */
  /*
   * Parse a copy of the options string, which is of the form:
   *
-  *     name argument+argument+argument
-  *     name?argument+argument+argument
-  *     name param=value&param=value
-  *     name?param=value&param=value
+  *     argument+argument+argument
+  *     ?argument+argument+argument
+  *     param=value&param=value
+  *     ?param=value&param=value
+  *     /name?argument+argument+argument
+  *     /name?param=value&param=value
   *
   * If the string contains an "=" character after the initial name,
   * then we treat it as a HTTP GET form request and make a copy of
@@ -3257,87 +3307,100 @@ pipe_command(cupsd_client_t *con,      /* I - Client connection */
                   "pipe_command: command=\"%s\", options=\"%s\"",
                   command, options);
 
-  strlcpy(argbuf, options, sizeof(argbuf));
-
-  argv[0]      = argbuf;
+  argv[0]      = command;
   query_string = NULL;
 
-  for (commptr = argbuf, argc = 1; *commptr != '\0' && argc < 99; commptr ++)
+  if (options)
+    strlcpy(argbuf, options, sizeof(argbuf));
+  else
+    argbuf[0] = '\0';
+
+  if (argbuf[0] == '/')
   {
    /*
-    * Break arguments whenever we see a + or space...
+    * Found some trailing path information, set PATH_INFO...
     */
 
-    if (*commptr == ' ' || *commptr == '+' || (*commptr == '?' && argc == 1))
-    {
-     /*
-      * Terminate the current string and skip trailing whitespace...
-      */
+    if ((commptr = strchr(argbuf, '?')) == NULL)
+      commptr = argbuf + strlen(argbuf);
 
-      *commptr++ = '\0';
+    commch   = *commptr;
+    *commptr = '\0';
+    snprintf(path_info, sizeof(path_info), "PATH_INFO=%s", argbuf);
+    *commptr = commch;
+  }
+  else
+  {
+    commptr      = argbuf;
+    path_info[0] = '\0';
+  }
 
-      while (*commptr == ' ')
-        commptr ++;
+  if (*commptr == '?' && con->operation == HTTP_GET)
+  {
+    commptr ++;
+    cupsdSetStringf(&query_string, "QUERY_STRING=%s", commptr);
+  }
 
-     /*
-      * If we don't have a blank string, save it as another argument...
-      */
+  argc = 1;
 
-      if (*commptr)
-      {
-        argv[argc] = commptr;
-       argc ++;
-      }
-      else
-        break;
+  if (*commptr)
+  {
+    argv[argc ++] = commptr;
 
+    for (; *commptr && argc < 99; commptr ++)
+    {
      /*
-      * If we see an "=" in the remaining string, make a copy of it since
-      * it will be query data...
+      * Break arguments whenever we see a + or space...
       */
 
-      if (argc == 2 && strchr(commptr, '=') && con->operation == HTTP_GET)
-       cupsdSetStringf(&query_string, "QUERY_STRING=%s", commptr);
+      if (*commptr == ' ' || *commptr == '+')
+      {
+       while (*commptr == ' ' || *commptr == '+')
+         *commptr++ = '\0';
 
-     /*
-      * Don't skip the first non-blank character...
-      */
+       /*
+       * If we don't have a blank string, save it as another argument...
+       */
 
-      commptr --;
-    }
-    else if (*commptr == '%' && isxdigit(commptr[1] & 255) &&
-             isxdigit(commptr[2] & 255))
-    {
-     /*
-      * Convert the %xx notation to the individual character.
-      */
+       if (*commptr)
+       {
+         argv[argc] = commptr;
+         argc ++;
+       }
+       else
+         break;
+      }
+      else if (*commptr == '%' && isxdigit(commptr[1] & 255) &&
+               isxdigit(commptr[2] & 255))
+      {
+       /*
+       * Convert the %xx notation to the individual character.
+       */
 
-      if (commptr[1] >= '0' && commptr[1] <= '9')
-        *commptr = (commptr[1] - '0') << 4;
-      else
-        *commptr = (tolower(commptr[1]) - 'a' + 10) << 4;
+       if (commptr[1] >= '0' && commptr[1] <= '9')
+          *commptr = (commptr[1] - '0') << 4;
+       else
+          *commptr = (tolower(commptr[1]) - 'a' + 10) << 4;
 
-      if (commptr[2] >= '0' && commptr[2] <= '9')
-        *commptr |= commptr[2] - '0';
-      else
-        *commptr |= tolower(commptr[2]) - 'a' + 10;
+       if (commptr[2] >= '0' && commptr[2] <= '9')
+          *commptr |= commptr[2] - '0';
+       else
+          *commptr |= tolower(commptr[2]) - 'a' + 10;
 
-      _cups_strcpy(commptr + 1, commptr + 3);
+       _cups_strcpy(commptr + 1, commptr + 3);
 
-     /*
-      * Check for a %00 and break if that is the case...
-      */
+       /*
+       * Check for a %00 and break if that is the case...
+       */
 
-      if (!*commptr)
-        break;
+       if (!*commptr)
+          break;
+      }
     }
   }
 
   argv[argc] = NULL;
 
-  if (argv[0][0] == '\0')
-    argv[0] = strrchr(command, '/') + 1;
-
  /*
   * Setup the environment variables as needed...
   */
@@ -3373,6 +3436,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
   envp[envc ++] = remote_host;
   envp[envc ++] = script_name;
 
+  if (path_info[0])
+    envp[envc ++] = path_info;
+
   if (con->username[0])
   {
     snprintf(remote_user, sizeof(remote_user), "REMOTE_USER=%s", con->username);
@@ -3503,5 +3569,5 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
 
 
 /*
- * End of "$Id: client.c 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: client.c 5200 2006-02-28 00:10:32Z mike $".
  */
index f76d86c91571ea39091b6f07576e17a5a9499585..cc8c782b40cd9f47c4531a2a9d36204ad062d1e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: conf.c 5116 2006-02-16 12:52:32Z mike $"
+ * "$Id: conf.c 5167 2006-02-25 02:11:44Z mike $"
  *
  *   Configuration routines for the Common UNIX Printing System (CUPS).
  *
@@ -89,6 +89,12 @@ static cupsd_var_t   variables[] =
   { "AccessLog",               &AccessLog,             CUPSD_VARTYPE_STRING },
   { "AutoPurgeJobs",           &JobAutoPurge,          CUPSD_VARTYPE_BOOLEAN },
   { "BrowseInterval",          &BrowseInterval,        CUPSD_VARTYPE_INTEGER },
+#ifdef HAVE_LDAP
+  { "BrowseLDAPBindDN",                &BrowseLDAPBindDN,      CUPSD_VARTYPE_STRING },
+  { "BrowseLDAPDN",            &BrowseLDAPDN,          CUPSD_VARTYPE_STRING },
+  { "BrowseLDAPPassword",      &BrowseLDAPPassword,    CUPSD_VARTYPE_STRING },
+  { "BrowseLDAPServer",                &BrowseLDAPServer,      CUPSD_VARTYPE_STRING },
+#endif /* HAVE_LDAP */
   { "BrowseLocalOptions",      &BrowseLocalOptions,    CUPSD_VARTYPE_STRING },
   { "BrowsePort",              &BrowsePort,            CUPSD_VARTYPE_INTEGER },
   { "BrowseRemoteOptions",     &BrowseRemoteOptions,   CUPSD_VARTYPE_STRING },
@@ -216,6 +222,9 @@ cupsdReadConfiguration(void)
   struct group *group;                 /* Default group */
   char         *old_serverroot,        /* Old ServerRoot */
                *old_requestroot;       /* Old RequestRoot */
+  const char   *tmpdir;                /* TMPDIR environment variable */
+  struct stat  tmpinfo;                /* Temporary directory info */
+
 
  /*
   * Save the old root paths...
@@ -309,10 +318,7 @@ cupsdReadConfiguration(void)
 
   cupsdSetString(&RIPCache, "8m");
 
-  if (getenv("TMPDIR") == NULL)
-    cupsdSetString(&TempDir, CUPS_REQUESTS "/tmp");
-  else
-    cupsdSetString(&TempDir, getenv("TMPDIR"));
+  cupsdSetString(&TempDir, NULL);
 
  /*
   * Find the default user...
@@ -395,6 +401,13 @@ cupsdReadConfiguration(void)
   cupsdClearString(&BrowseLocalOptions);
   cupsdClearString(&BrowseRemoteOptions);
 
+#ifdef HAVE_LDAP
+  cupsdClearString(&BrowseLDAPBindDN);
+  cupsdClearString(&BrowseLDAPDN);
+  cupsdClearString(&BrowseLDAPPassword);
+  cupsdClearString(&BrowseLDAPServer);
+#endif /* HAVE_LDAP */
+
   JobHistory          = DEFAULT_HISTORY;
   JobFiles            = DEFAULT_FILES;
   JobAutoPurge        = 0;
@@ -615,6 +628,41 @@ cupsdReadConfiguration(void)
   check_permissions(ServerRoot, "printers.conf", 0600, RunUser, Group, 0, 0);
   check_permissions(ServerRoot, "passwd.md5", 0600, User, Group, 0, 0);
 
+ /*
+  * Update TempDir to the default if it hasn't been set already...
+  */
+
+  if (!TempDir)
+  {
+    if ((tmpdir = getenv("TMPDIR")) != NULL)
+    {
+     /*
+      * TMPDIR is defined, see if it is OK for us to use...
+      */
+
+      if (stat(tmpdir, &tmpinfo))
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to access TMPDIR (%s): %s",
+                       tmpdir, strerror(errno));
+      else if (!S_ISDIR(tmpinfo.st_mode))
+        cupsdLogMessage(CUPSD_LOG_ERROR, "TMPDIR (%s) is not a directory!",
+                       tmpdir);
+      else if ((tmpinfo.st_uid != User || !(tmpinfo.st_mode & S_IWUSR)) &&
+               (tmpinfo.st_gid != Group || !(tmpinfo.st_mode & S_IWGRP)) &&
+              !(tmpinfo.st_mode & S_IWOTH))
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "TMPDIR (%s) has the wrong permissions!", tmpdir);
+      else
+        cupsdSetString(&TempDir, tmpdir);
+
+      if (!TempDir)
+        cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
+                       RequestRoot);
+    }
+
+    if (!TempDir)
+      cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
+  }
+
  /*
   * Make sure the request and temporary directories have the right
   * permissions...
@@ -3169,5 +3217,5 @@ read_policy(cups_file_t *fp,              /* I - Configuration file */
 
 
 /*
- * End of "$Id: conf.c 5116 2006-02-16 12:52:32Z mike $".
+ * End of "$Id: conf.c 5167 2006-02-25 02:11:44Z mike $".
  */
index 8e50f11351b070a23311ed45ce58c84f4f09505f..ee151148cfe01c049612878a0d5c19ac9656a482 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: conf.h 5078 2006-02-05 03:36:35Z mike $"
+ * "$Id: conf.h 5200 2006-02-28 00:10:32Z mike $"
  *
  *   Configuration file definitions for the Common UNIX Printing System (CUPS)
  *   scheduler.
@@ -186,9 +186,6 @@ VAR char            *ServerCertificate      VALUE(NULL);
 #  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
 VAR char               *ServerKey              VALUE(NULL);
                                        /* Server key file */
-#  else
-VAR CFArrayRef         ServerCertificatesArray VALUE(NULL);
-                                       /* Array containing certificates */
 #  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
 #endif /* HAVE_SSL */
 
@@ -215,5 +212,5 @@ extern int  cupsdLogPage(cupsd_job_t *job, const char *page);
 
 
 /*
- * End of "$Id: conf.h 5078 2006-02-05 03:36:35Z mike $".
+ * End of "$Id: conf.h 5200 2006-02-28 00:10:32Z mike $".
  */
index d3cd41b93a524d96999a332e6d386fce9b7e4f0f..a83c129acbe775401d791921828162fa4ab7f7c2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cups-deviced.c 5099 2006-02-13 02:46:10Z mike $"
+ * "$Id: cups-deviced.c 5194 2006-02-27 20:57:07Z mike $"
  *
  *   Device scanning mini-daemon for the Common UNIX Printing System (CUPS).
  *
 #include <cups/array.h>
 #include <cups/dir.h>
 
+#ifdef __hpux
+#  define seteuid(uid) setresuid(-1, (uid), -1)
+#endif /* __hpux */
+
 
 /*
  * Device information structure...
@@ -496,5 +500,5 @@ sigalrm_handler(int sig)            /* I - Signal number */
 
 
 /*
- * End of "$Id: cups-deviced.c 5099 2006-02-13 02:46:10Z mike $".
+ * End of "$Id: cups-deviced.c 5194 2006-02-27 20:57:07Z mike $".
  */
index 37e8974262943bad30bb2c9a8e7f4e97a10c7151..eda350c52655784d409e0cd987e242f33eee82bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cups-lpd.c 5137 2006-02-19 19:44:50Z mike $"
+ * "$Id: cups-lpd.c 5196 2006-02-27 21:23:00Z mike $"
  *
  *   Line Printer Daemon interface for the Common UNIX Printing System (CUPS).
  *
@@ -1307,7 +1307,7 @@ recv_print_job(
  * 'remove_jobs()' - Cancel one or more jobs.
  */
 
-int                                    /* O - Command status */
+static int                             /* O - Command status */
 remove_jobs(const char *dest,          /* I - Destination */
             const char *agent,         /* I - User agent */
            const char *list)           /* I - List of jobs or users */
@@ -1392,7 +1392,7 @@ remove_jobs(const char *dest,             /* I - Destination */
  * 'send_state()' - Send the queue state.
  */
 
-int                                    /* O - Command status */
+static int                             /* O - Command status */
 send_state(const char *queue,          /* I - Destination */
            const char *list,           /* I - Job or user */
           int        longstatus)       /* I - List of jobs or users */
@@ -1657,7 +1657,7 @@ send_state(const char *queue,             /* I - Destination */
  * 'smart_gets()' - Get a line of text, removing the trailing CR and/or LF.
  */
 
-char *                                 /* O - Line read or NULL */
+static char *                          /* O - Line read or NULL */
 smart_gets(char *s,                    /* I - Pointer to line buffer */
            int  len,                   /* I - Size of line buffer */
           FILE *fp)                    /* I - File to read from */
@@ -1708,5 +1708,5 @@ smart_gets(char *s,                       /* I - Pointer to line buffer */
 
 
 /*
- * End of "$Id: cups-lpd.c 5137 2006-02-19 19:44:50Z mike $".
+ * End of "$Id: cups-lpd.c 5196 2006-02-27 21:23:00Z mike $".
  */
index e543d5f94cd3dbc0dda972ee53a35920cbf27684..d33ab58005e25842e25eef17169034f12f524067 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cupsd.h 5053 2006-02-02 18:14:38Z mike $"
+ * "$Id: cupsd.h 5196 2006-02-27 21:23:00Z mike $"
  *
  *   Main header file for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -65,6 +65,9 @@
  */
 
 #ifndef HAVE_HSTRERROR
+#  ifdef hstrerror
+#    undef hstrerror
+#  endif /* hstrerror */
 #  define hstrerror cups_hstrerror
 
 extern const char *cups_hstrerror(int);
@@ -204,5 +207,5 @@ extern int  cupsdStartProcess(const char *command, char *argv[],
 
 
 /*
- * End of "$Id: cupsd.h 5053 2006-02-02 18:14:38Z mike $".
+ * End of "$Id: cupsd.h 5196 2006-02-27 21:23:00Z mike $".
  */
index 8b59c68e2fac6930b0805efbdc631dc8ab2996d3..f4c72b9ece13e81b8f24b7a092ce2835fe58fa7b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: dirsvc.c 5117 2006-02-16 14:10:43Z mike $"
+ * "$Id: dirsvc.c 5178 2006-02-26 00:24:23Z mike $"
  *
  *   Directory services routines for the Common UNIX Printing System (CUPS).
  *
  */
 
 static char    *dequote(char *d, const char *s, int dlen);
-static void    process_browse_data(const char *uri, cups_ptype_t type,
+static int     is_local_queue(const char *uri, char *host, int hostlen,
+                              char *resource, int resourcelen);
+static void    process_browse_data(const char *uri, const char *host,
+                                   const char *resource, cups_ptype_t type,
                                    ipp_pstate_t state, const char *location,
                                    const char *info, const char *make_model,
                                    int num_attrs, cups_option_t *attrs);
 static void    process_implicit_classes(void);
 
 
+#ifdef HAVE_OPENLDAP
+static const char * const ldap_attrs[] =/* CUPS LDAP attributes */
+               {
+                 "printerDescription",
+                 "printerLocation",
+                 "printerMakeAndModel",
+                 "printerType",
+                 "printerURI",
+                 NULL
+               };
+#endif /* HAVE_OPENLDAP */
+
 #ifdef HAVE_LIBSLP 
 /*
  * SLP definitions...
@@ -308,6 +323,25 @@ cupsdLoadRemoteCache(void)
        return;
       }
     }
+    else if (!strcasecmp(line, "Option") && value)
+    {
+     /*
+      * Option name value
+      */
+
+      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
+
+      if (!*valueptr)
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of remote.cache.", linenum);
+      else
+      {
+        for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
+
+        p->num_options = cupsAddOption(value, valueptr, p->num_options,
+                                      &(p->options));
+      }
+    }
     else if (!strcasecmp(line, "State"))
     {
      /*
@@ -482,6 +516,7 @@ cupsdSaveRemoteCache(void)
   cupsd_printer_t      *printer;       /* Current printer class */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
+  cups_option_t                *option;        /* Current option */
 
 
  /*
@@ -582,6 +617,11 @@ cupsdSaveRemoteCache(void)
       cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
               printer->users[i]);
 
+    for (i = printer->num_options, option = printer->options;
+         i > 0;
+        i --, option ++)
+      cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+
     if (printer->type & CUPS_PRINTER_CLASS)
       cupsFilePuts(fp, "</Class>\n");
     else
@@ -646,8 +686,8 @@ cupsdSendBrowseList(void)
   * Compute the update and timeout times...
   */
 
-  ut = time(NULL) - BrowseInterval;
-  to = time(NULL) - BrowseTimeout;
+  to = time(NULL);
+  ut = to - BrowseInterval;
 
  /*
   * Figure out how many printers need an update...
@@ -715,6 +755,11 @@ cupsdSendBrowseList(void)
        if (BrowseLocalProtocols & BROWSE_SLP)
           cupsdSendSLPBrowse(p);
 #endif /* HAVE_LIBSLP */
+
+#ifdef HAVE_LDAP
+       if (BrowseLocalProtocols & BROWSE_LDAP)
+          cupsdSendLDAPBrowse(p);
+#endif /* HAVE_LDAP */
       }
     }
 
@@ -739,7 +784,7 @@ cupsdSendBrowseList(void)
 
     if (p->type & CUPS_PRINTER_REMOTE)
     {
-      if (p->browse_time < to)
+      if (p->browse_expire < to)
       {
        cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL,
                       "%s \'%s\' deleted by directory services (timeout).",
@@ -747,7 +792,8 @@ cupsdSendBrowseList(void)
                      p->name);
 
         cupsdLogMessage(CUPSD_LOG_INFO,
-                       "Remote destination \"%s\" has timed out; deleting it...",
+                       "Remote destination \"%s\" has timed out; "
+                       "deleting it...",
                        p->name);
 
         cupsArraySave(Printers);
@@ -760,7 +806,8 @@ cupsdSendBrowseList(void)
 
 
 /*
- * 'cupsdSendCUPSBrowse()' - Send new browsing information using the CUPS protocol.
+ * 'cupsdSendCUPSBrowse()' - Send new browsing information using the CUPS
+ *                           protocol.
  */
 
 void
@@ -772,7 +819,6 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)     /* I - Printer to send */
   int                  bytes;          /* Length of packet */
   char                 packet[1453],   /* Browse data packet */
                        uri[1024],      /* Printer URI */
-                       options[1024],  /* Browse local options */
                        location[1024], /* printer-location */
                        info[1024],     /* printer-info */
                        make_model[1024];
@@ -792,15 +838,6 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)    /* I - Printer to send */
   if (p == DefaultPrinter)
     type |= CUPS_PRINTER_DEFAULT;
 
- /*
-  * Initialize the browse options...
-  */
-
-  if (BrowseLocalOptions)
-    snprintf(options, sizeof(options), " ipp-options=%s", BrowseLocalOptions);
-  else
-    options[0] = '\0';
-
  /*
   * Remove quotes from printer-info, printer-location, and
   * printer-make-and-model attributes...
@@ -847,8 +884,9 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)     /* I - Printer to send */
                           (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s%s" :
                                                            "/printers/%s",
                           p->name);
-         snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"%s\n",
-                  type, p->state, uri, location, info, make_model, options);
+         snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+                  type, p->state, uri, location, info, make_model,
+                  p->browse_attrs ? p->browse_attrs : "");
 
          bytes = strlen(packet);
 
@@ -887,8 +925,9 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)     /* I - Printer to send */
                           (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s%s" :
                                                            "/printers/%s",
                           p->name);
-         snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"%s\n",
-                  type, p->state, uri, location, info, make_model, options);
+         snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+                  type, p->state, uri, location, info, make_model,
+                  p->browse_attrs ? p->browse_attrs : "");
 
          bytes = strlen(packet);
 
@@ -911,8 +950,9 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)     /* I - Printer to send */
       * the default server name...
       */
 
-      snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"%s\n",
-                      type, p->state, p->uri, location, info, make_model, options);
+      snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+                      type, p->state, p->uri, location, info, make_model,
+              p->browse_attrs ? p->browse_attrs : "");
 
       bytes = strlen(packet);
       cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -928,11 +968,12 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)   /* I - Printer to send */
        */
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "cupsdSendBrowseList: sendto failed for browser %d - %s.",
+                       "cupsdSendBrowseList: sendto failed for browser "
+                       "%d - %s.",
                        b - Browsers + 1, strerror(errno));
 
         if (i > 1)
-         memcpy(b, b + 1, (i - 1) * sizeof(cupsd_dirsvc_addr_t));
+         memmove(b, b + 1, (i - 1) * sizeof(cupsd_dirsvc_addr_t));
 
        b --;
        NumBrowsers --;
@@ -941,6 +982,131 @@ cupsdSendCUPSBrowse(cupsd_printer_t *p)   /* I - Printer to send */
 }
 
 
+#ifdef HAVE_OPENLDAP
+/*
+ * cupsdSendLDAPBrowse()' - Send LDAP printer registrations.
+ */
+
+void 
+cupsdSendLDAPBrowse(cupsd_printer_t *p)        /* I - Printer to register */
+{
+  int          i;                      /* Looping var... */
+  LDAPMod      mods[7];                /* The 7 attributes we will be adding */
+  LDAPMod      *pmods[8];              /* Pointers to the 7 attributes + NULL */
+  LDAPMessage  *res;                   /* Search result token */
+  char         *cn_value[2],           /* Change records */
+               *uri[2],
+               *info[2],
+               *location[2],
+               *make_model[2],
+               *type[2],
+               typestring[255],        /* String to hold printer-type */
+               filter[256],            /* Search filter for possible UPDATEs */
+               dn[1024];               /* DN of the printer we are adding */
+  int          rc;                     /* LDAP status */
+  static const char * const objectClass_values[] =
+               {                       /* The 3 objectClass's we use in */
+                 "top",                /* our LDAP entries              */
+                 "device",
+                 "cupsPrinter",
+                 NULL
+               };
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSendLDAPBrowse: %s\n", p->name);
+
+ /*
+  * Everything in ldap is ** so we fudge around it...
+  */
+
+  sprintf(typestring, "%u", p->type);
+
+  cn_value[0]   = p->info;
+  cn_value[1]   = NULL;
+  info[0]       = p->info;
+  info[1]       = NULL;
+  location[0]   = p->location;
+  location[1]   = NULL;
+  make_model[0] = p->make_model;
+  make_model[1] = NULL;
+  type[0]       = typestring;
+  type[1]       = NULL;
+  uri[0]        = p->uri;
+  uri[1]        = NULL;
+
+  snprintf(filter, sizeof(filter),
+           "(&(objectclass=cupsPrinter)(printerDescription~=%s))", p->info);
+
+  ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
+                filter, (char **)ldap_attrs, 0, &res);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSendLDAPBrowse: Searching \"%s\"",
+                  filter);
+
+  mods[0].mod_type = "cn";
+  mods[0].mod_values = cn_value;
+  mods[1].mod_type = "printerDescription";
+  mods[1].mod_values = info;
+  mods[2].mod_type = "printerURI";
+  mods[2].mod_values = uri;
+  mods[3].mod_type = "printerLocation";
+  mods[3].mod_values = location;
+  mods[4].mod_type = "printerMakeAndModel";
+  mods[4].mod_values = make_model;
+  mods[5].mod_type = "printerType";
+  mods[5].mod_values = type;
+  mods[6].mod_type = "objectClass";
+  mods[6].mod_values = (char **)objectClass_values;
+
+  snprintf(dn, sizeof(dn), "cn=%s,ou=printers,%s", p->info, BrowseLDAPDN);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSendLDAPBrowse: dn=\"%s\"", dn);
+
+  if (ldap_count_entries(BrowseLDAPHandle, res) > 0)
+  {
+   /*
+    * Printer has already been registered, modify the current
+    * registration...
+    */
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                    "cupsdSendLDAPBrowse: Replacing entry...");
+
+    for (i = 0; i < 7; i ++)
+    {
+      pmods[i]         = mods + i;
+      pmods[i]->mod_op = LDAP_MOD_REPLACE;
+    }
+    pmods[i] = NULL;
+
+    if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "LDAP modify for %s failed with status %d: %s",
+                      p->name, rc, ldap_err2string(rc));
+  }
+  else 
+  {
+   /*
+    * Printer has already been registered, modify the current
+    * registration...
+    */
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                    "cupsdSendLDAPBrowse: Adding entry...");
+
+    for (i = 0; i < 7; i ++)
+    {
+      pmods[i]         = mods + i;
+      pmods[i]->mod_op = LDAP_MOD_REPLACE;
+    }
+    pmods[i] = NULL;
+
+    if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "LDAP add for %s failed with status %d: %s",
+                      p->name, rc, ldap_err2string(rc));
+  }
+}
+#endif /* HAVE_OPENLDAP */
+
+
 #ifdef HAVE_LIBSLP
 /*
  * 'cupsdSendSLPBrowse()' - Register the specified printer with SLP.
@@ -1090,6 +1256,7 @@ cupsdSendSLPBrowse(cupsd_printer_t *p)    /* I - Printer to register */
            "(printer-info=%s),"
            "(printer-more-info=%s),"
            "(printer-make-and-model=%s),"
+          "(printer-type=%d),"
           "(charset-supported=utf-8),"
           "(natural-language-configured=%s),"
           "(natural-language-supported=de,en,es,fr,it),"
@@ -1099,7 +1266,7 @@ cupsdSendSLPBrowse(cupsd_printer_t *p)    /* I - Printer to register */
           "(multiple-document-jobs-supported=true)"
           "(ipp-versions-supported=1.0,1.1)",
           p->uri, authentication->values[0].string.text, p->name, location,
-          info, p->uri, make_model, DefaultLanguage,
+          info, p->uri, make_model, p->type, DefaultLanguage,
            p->type & CUPS_PRINTER_COLOR ? "true" : "false",
            finishings,
            p->type & CUPS_PRINTER_DUPLEX ?
@@ -1243,6 +1410,79 @@ cupsdStartBrowsing(void)
     BrowseSLPRefresh = 0;
   }
 #endif /* HAVE_LIBSLP */
+
+#ifdef HAVE_OPENLDAP
+  if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP)
+  {
+    if (!BrowseLDAPDN)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Need to set BrowseLDAPDN to use LDAP browsing!");
+      BrowseLocalProtocols &= ~BROWSE_LDAP;
+      BrowseRemoteProtocols &= ~BROWSE_LDAP;
+    }
+    else
+    {
+     /* 
+      * Open LDAP handle...
+      */
+
+      int              rc;             /* LDAP API status */
+      int              version = 3;    /* LDAP version */
+      struct berval    bv = {0, ""};   /* SASL bind value */
+
+
+     /*
+      * LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
+      */
+
+      if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) 
+        rc = ldap_initialize(&BrowseLDAPHandle, "ldapi:///");
+      else     
+       rc = ldap_initialize(&BrowseLDAPHandle, BrowseLDAPServer);
+
+      if (rc != LDAP_SUCCESS)
+      {
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unable to initialize LDAP; disabling LDAP browsing!");
+       BrowseLocalProtocols &= ~BROWSE_LDAP;
+       BrowseRemoteProtocols &= ~BROWSE_LDAP;
+      }
+      else if (ldap_set_option(BrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
+                               (const void *)&version) != LDAP_SUCCESS)
+      {
+       ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL);
+       BrowseLDAPHandle = NULL;
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unable to set LDAP protocol version; "
+                       "disabling LDAP browsing!");
+       BrowseLocalProtocols &= ~BROWSE_LDAP;
+       BrowseRemoteProtocols &= ~BROWSE_LDAP;
+      }
+      else
+      {
+       if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
+         rc = ldap_sasl_bind_s(BrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
+                               NULL, NULL);
+       else
+         rc = ldap_bind_s(BrowseLDAPHandle, BrowseLDAPBindDN,
+                          BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
+
+       if (rc != LDAP_SUCCESS)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Unable to bind to LDAP server; "
+                         "disabling LDAP browsing!");
+         ldap_unbind_ext(BrowseLDAPHandle, NULL, NULL);
+         BrowseLocalProtocols &= ~BROWSE_LDAP;
+         BrowseRemoteProtocols &= ~BROWSE_LDAP;
+       }
+      }
+    }
+
+    BrowseLDAPRefresh = 0;
+  }
+#endif /* HAVE_OPENLDAP */
 }
 
 
@@ -1384,15 +1624,26 @@ cupsdStopBrowsing(void)
   }
 
 #ifdef HAVE_LIBSLP
-  if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP)
+  if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) &&
+      BrowseSLPHandle)
   {
    /* 
     * Close SLP handle...
     */
 
     SLPClose(BrowseSLPHandle);
+    BrowseSLPHandle = NULL;
   }
 #endif /* HAVE_LIBSLP */
+
+#ifdef HAVE_OPENDAP
+  if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) &&
+      BrowseLDAPHandle)
+  {
+    ldap_unbind(BrowseLDAPHandle);
+    BrowseLDAPHandle = NULL;
+  }
+#endif /* HAVE_OPENLDAP */
 }
 
 
@@ -1446,15 +1697,11 @@ cupsdUpdateCUPSBrowse(void)
   unsigned     type;                   /* Printer type */
   unsigned     state;                  /* Printer state */
   char         uri[HTTP_MAX_URI],      /* Printer URI */
-               method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
                host[HTTP_MAX_URI],     /* Host portion of URI */
                resource[HTTP_MAX_URI], /* Resource portion of URI */
                info[IPP_MAX_NAME],     /* Information string */
                location[IPP_MAX_NAME], /* Location string */
                make_model[IPP_MAX_NAME];/* Make and model string */
-  int          port;                   /* Port portion of URI */
-  cupsd_netif_t        *iface;                 /* Network interface */
   int          num_attrs;              /* Number of attributes */
   cups_option_t        *attrs;                 /* Attributes */
 
@@ -1670,33 +1917,12 @@ cupsdUpdateCUPSBrowse(void)
   * Pull the URI apart to see if this is a local or remote printer...
   */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), username,
-                  sizeof(username), host, sizeof(host), &port, resource,
-                 sizeof(resource));
-
-  DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName));
-
- /*
-  * Check for packets from the local server...
-  */
-
-  if (!strcasecmp(host, ServerName) && port == LocalPort)
+  if (is_local_queue(uri, host, sizeof(host), resource, sizeof(resource)))
   {
     cupsFreeOptions(num_attrs, attrs);
     return;
   }
 
-  cupsdNetIFUpdate();
-
-  for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
-       iface;
-       iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
-    if (!strcasecmp(host, iface->hostname) && port == iface->port)
-    {
-      cupsFreeOptions(num_attrs, attrs);
-      return;
-    }
-
  /*
   * Do relaying...
   */
@@ -1718,12 +1944,99 @@ cupsdUpdateCUPSBrowse(void)
   * Process the browse data...
   */
 
-  process_browse_data(uri, (cups_ptype_t)type, (ipp_pstate_t)state, location,
-                         info, make_model, num_attrs, attrs);
-  cupsFreeOptions(num_attrs, attrs);
+  process_browse_data(uri, host, resource, (cups_ptype_t)type,
+                      (ipp_pstate_t)state, location, info, make_model,
+                     num_attrs, attrs);
 }
 
 
+#ifdef HAVE_OPENLDAP
+/*
+ * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP...
+ */
+
+void
+cupsdUpdateLDAPBrowse(void)
+{
+  char         uri[HTTP_MAX_URI],      /* Printer URI */
+               host[HTTP_MAX_URI],     /* Hostname */
+               resource[HTTP_MAX_URI], /* Resource path */
+               location[1024],         /* Printer location */
+               info[1024],             /* Printer information */
+               make_model[1024],       /* Printer make and model */
+               **value;                /* Holds the returned data from LDAP */
+  int          type;                   /* Printer type */
+  int          rc;                     /* LDAP status */
+  int          limit;                  /* Size limit */
+  LDAPMessage  *res,                   /* LDAP search results */
+                 *e;                   /* Current entry from search */
+
+
+ /*
+  * Search for printers...
+  */
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "UpdateLDAPBrowse: %s", ServerName);
+
+  BrowseLDAPRefresh = time(NULL) + BrowseInterval;
+
+  rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
+                     "(objectclass=cupsPrinter)", (char **)ldap_attrs, 0, &res);
+  if (rc != LDAP_SUCCESS) 
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "LDAP search returned error %d: %s", rc,
+                   ldap_err2string(rc));
+    return;
+  }
+
+  limit = ldap_count_entries(BrowseLDAPHandle, res);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "LDAP search returned %d entries", limit);
+  if (limit < 1)
+    return;
+
+ /*
+  * Loop through the available printers...
+  */
+
+  if ((e = ldap_first_entry(BrowseLDAPHandle, res)) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get LDAP printer entry!");
+    return;
+  }
+
+  while (e)
+  {
+    value = ldap_get_values(BrowseLDAPHandle, e, "printerDescription");
+    strlcpy(info, *value, sizeof(info));
+    ldap_value_free(value);
+
+    value = ldap_get_values(BrowseLDAPHandle, e, "printerLocation");
+    strlcpy(location, *value, sizeof(location));
+    ldap_value_free(value);
+
+    value = ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel");
+    strlcpy(make_model, *value, sizeof(make_model));
+    ldap_value_free(value);
+
+    value = ldap_get_values(BrowseLDAPHandle, e, "printerType");
+    type = atoi(*value);
+    ldap_value_free(value);
+
+    value = ldap_get_values(BrowseLDAPHandle, e, "printerURI");
+    strlcpy(uri, *value, sizeof(uri));
+    ldap_value_free(value);
+
+    if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource)))
+      process_browse_data(uri, host, resource, type, IPP_PRINTER_IDLE,
+                          location, info, make_model, 0, NULL);
+
+    e = ldap_next_entry(BrowseLDAPHandle, e);
+  }
+}
+#endif /* HAVE_OPENLDAP */
+
+
 /*
  * 'cupsdUpdatePolling()' - Read status messages from the poll daemons.
  */
@@ -1762,22 +2075,13 @@ cupsdUpdatePolling(void)
 void
 cupsdUpdateSLPBrowse(void)
 {
-  slpsrvurl_t          *s,             /* Temporary list of service URLs */
-                       *next;          /* Next service in list */
-  cupsd_printer_t      p;              /* Printer information */
-  const char           *uri;           /* Pointer to printer URI */
-  char                 method[HTTP_MAX_URI],
-                                       /* Method portion of URI */
-                       username[HTTP_MAX_URI],
-                                       /* Username portion of URI */
-                       host[HTTP_MAX_URI],
-                                       /* Host portion of URI */
-                       resource[HTTP_MAX_URI];
-                                       /* Resource portion of URI */
-  int                  port;           /* Port portion of URI */
-
+  slpsrvurl_t  *s,                     /* Temporary list of service URLs */
+               *next;                  /* Next service in list */
+  cupsd_printer_t p;                   /* Printer information */
+  const char   *uri;                   /* Pointer to printer URI */
+  char         host[HTTP_MAX_URI],     /* Host portion of URI */
+               resource[HTTP_MAX_URI]; /* Resource portion of URI */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdUpdateSLPBrowse() Start...");
 
  /*
   * Reset the refresh time...
@@ -1824,34 +2128,21 @@ cupsdUpdateSLPBrowse(void)
       * Pull the URI apart to see if this is a local or remote printer...
       */
 
-      httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method),
-                      username, sizeof(username), host, sizeof(host), &port,
-                     resource, sizeof(resource));
-
-      if (!strcasecmp(host, ServerName))
-       continue;
-
-     /*
-      * OK, at least an IPP printer, see if it is a CUPS printer or
-      * class...
-      */
-
-      if (strstr(uri, "/printers/") != NULL)
-        process_browse_data(uri, p.type, IPP_PRINTER_IDLE, p.location,
-                         p.info, p.make_model, 0, NULL);
-      else if (strstr(uri, "/classes/") != NULL)
-        process_browse_data(uri, p.type | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE,
-                         p.location, p.info, p.make_model, 0, NULL);
+      if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource)))
+        process_browse_data(uri, host, resource, p.type, IPP_PRINTER_IDLE,
+                           p.location,  p.info, p.make_model, 0, NULL);
     }
 
    /*
     * Free this listing...
     */
 
+    cupsdClearString(&p.info);
+    cupsdClearString(&p.location);
+    cupsdClearString(&p.make_model);
+
     free(s);
   }       
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdUpdateSLPBrowse() End...");
 }
 #endif /* HAVE_LIBSLP */
 
@@ -1886,6 +2177,57 @@ dequote(char       *d,                   /* I - Destination string */
 }
 
 
+/*
+ * 'is_local_queue()' - Determine whether the URI points at a local queue.
+ */
+
+static int                             /* O - 1 = local, 0 = remote, -1 = bad URI */
+is_local_queue(const char *uri,                /* I - Printer URI */
+               char       *host,       /* O - Host string */
+              int        hostlen,      /* I - Length of host buffer */
+               char       *resource,   /* O - Resource string */
+              int        resourcelen)  /* I - Length of resource buffer */
+{
+  char         scheme[32],             /* Scheme portion of URI */
+               username[HTTP_MAX_URI]; /* Username portion of URI */
+  int          port;                   /* Port portion of URI */
+  cupsd_netif_t        *iface;                 /* Network interface */
+
+
+ /*
+  * Pull the URI apart to see if this is a local or remote printer...
+  */
+
+  if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
+                      username, sizeof(username), host, hostlen, &port,
+                     resource, resourcelen) < HTTP_URI_OK)
+    return (-1);
+
+  DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName));
+
+ /*
+  * Check for local server addresses...
+  */
+
+  if (!strcasecmp(host, ServerName) && port == LocalPort)
+    return (1);
+
+  cupsdNetIFUpdate();
+
+  for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
+       iface;
+       iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
+    if (!strcasecmp(host, iface->hostname) && port == iface->port)
+      return (1);
+
+ /*
+  * If we get here, the printer is remote...
+  */
+
+  return (0);
+}
+
+
 /*
  * 'process_browse_data()' - Process new browse data.
  */
@@ -1893,6 +2235,8 @@ dequote(char       *d,                    /* I - Destination string */
 static void
 process_browse_data(
     const char    *uri,                        /* I - URI of printer/class */
+    const char    *host,               /* I - Hostname */
+    const char    *resource,           /* I - Resource path */
     cups_ptype_t  type,                        /* I - Printer type */
     ipp_pstate_t  state,               /* I - Printer state */
     const char    *location,           /* I - Printer location */
@@ -1901,29 +2245,19 @@ process_browse_data(
     int                  num_attrs,            /* I - Number of attributes */
     cups_option_t *attrs)              /* I - Attributes */
 {
+  int          i;                      /* Looping var */
   int          update;                 /* Update printer attributes? */
   char         finaluri[HTTP_MAX_URI], /* Final URI for printer */
-               method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
-               host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI]; /* Resource portion of URI */
-  int          port;                   /* Port portion of URI */
-  char         name[IPP_MAX_NAME],     /* Name of printer */
+               name[IPP_MAX_NAME],     /* Name of printer */
+               newname[IPP_MAX_NAME],  /* New name of printer */
                *hptr,                  /* Pointer into hostname */
                *sptr;                  /* Pointer into ServerName */
   char         local_make_model[IPP_MAX_NAME];
                                        /* Local make and model */
   cupsd_printer_t *p;                  /* Printer information */
-  const char   *ipp_options;           /* ipp-options value */
-
-
- /*
-  * Pull the URI apart to see if this is a local or remote printer...
-  */
+  const char   *ipp_options,           /* ipp-options value */
+               *lease_duration;        /* lease-duration value */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), username,
-                  sizeof(username), host, sizeof(host), &port, resource,
-                 sizeof(resource));
 
  /*
   * Determine if the URI contains any illegal characters in it...
@@ -2055,10 +2389,8 @@ process_browse_data(
                          "Class \'%s\' deleted by directory services.",
                          p->name);
 
-            cupsArrayRemove(Printers, p);
-            cupsdSetStringf(&p->name, "%s@%s", p->name, p->hostname);
-           cupsdSetPrinterAttrs(p);
-           cupsArrayAdd(Printers, p);
+            snprintf(newname, sizeof(newname), "%s@%s", p->name, p->hostname);
+            cupsdRenamePrinter(p, newname);
 
            cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
                          "Class \'%s\' added by directory services.",
@@ -2160,10 +2492,8 @@ process_browse_data(
                          "Printer \'%s\' deleted by directory services.",
                          p->name);
 
-           cupsArrayRemove(Printers, p);
-           cupsdSetStringf(&p->name, "%s@%s", p->name, p->hostname);
-           cupsdSetPrinterAttrs(p);
-           cupsArrayAdd(Printers, p);
+            snprintf(newname, sizeof(newname), "%s@%s", p->name, p->hostname);
+            cupsdRenamePrinter(p, newname);
 
            cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
                          "Printer \'%s\' added by directory services.",
@@ -2241,6 +2571,23 @@ process_browse_data(
   p->state       = state;
   p->browse_time = time(NULL);
 
+  if ((lease_duration = cupsGetOption("lease-duration", num_attrs,
+                                      attrs)) != NULL)
+  {
+   /*
+    * Grab the lease-duration for the browse data; anything less then 1
+    * second or more than 1 week gets the default BrowseTimeout...
+    */
+
+    i = atoi(lease_duration);
+    if (i < 1 || i > 604800)
+      i = BrowseTimeout;
+
+    p->browse_expire = p->browse_time + i;
+  }
+  else
+    p->browse_expire = p->browse_time + BrowseTimeout;
+
   if (type & CUPS_PRINTER_REJECTING)
   {
     type &= ~CUPS_PRINTER_REJECTING;
@@ -2294,6 +2641,39 @@ process_browse_data(
     update = 1;
   }
 
+  if (p->num_options)
+  {
+    if (!update && !(type & CUPS_PRINTER_DELETE))
+    {
+     /*
+      * See if we need to update the attributes...
+      */
+
+      if (p->num_options != num_attrs)
+       update = 1;
+      else
+      {
+       for (i = 0; i < num_attrs; i ++)
+          if (strcmp(attrs[i].name, p->options[i].name) ||
+             (!attrs[i].value != !p->options[i].value) ||
+             (attrs[i].value && strcmp(attrs[i].value, p->options[i].value)))
+          {
+           update = 1;
+           break;
+          }
+      }
+    }
+
+   /*
+    * Free the old options...
+    */
+
+    cupsFreeOptions(p->num_options, p->options);
+  }
+
+  p->num_options = num_attrs;
+  p->options     = attrs;
+
   if (type & CUPS_PRINTER_DELETE)
   {
     cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL,
@@ -2312,8 +2692,8 @@ process_browse_data(
   }
 
  /*
-  * See if we have a default printer...  If not, make the first printer the
-  * default.
+  * See if we have a default printer...  If not, make the first network
+  * default printer the default.
   */
 
   if (DefaultPrinter == NULL && Printers != NULL && UseNetworkDefault)
@@ -2431,6 +2811,9 @@ process_implicit_classes(void)
 
         cupsdLogMessage(CUPSD_LOG_INFO, "Added implicit class \"%s\"...",
                        name);
+       cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
+                      "Implicit class \'%s\' added by directory services.",
+                     name);
       }
 
       if (first != NULL)
@@ -2535,15 +2918,12 @@ slp_attr_callback(
     SLPError   errcode,                        /* I - Parsing status for this attr */
     void       *cookie)                        /* I - Current printer */
 {
-  char                 *tmp = 0;
+  char                 *tmp = 0;       /* Temporary string */
   cupsd_printer_t      *p = (cupsd_printer_t*)cookie;
+                                       /* Current printer */
 
 
- /*
-  * Let the compiler know we won't be using these...
-  */
-
-  (void)hslp;
+  (void)hslp;                          /* anti-compiler-warning-code */
 
  /*
   * Bail if there was an error
@@ -2558,33 +2938,16 @@ slp_attr_callback(
 
   memset(p, 0, sizeof(cupsd_printer_t));
 
-  p->type = CUPS_PRINTER_REMOTE;
-
   if (slp_get_attr(attrlist, "(printer-location=", &(p->location)))
     return (SLP_FALSE);
   if (slp_get_attr(attrlist, "(printer-info=", &(p->info)))
     return (SLP_FALSE);
   if (slp_get_attr(attrlist, "(printer-make-and-model=", &(p->make_model)))
     return (SLP_FALSE);
-
-  if (slp_get_attr(attrlist, "(color-supported=", &tmp))
-    return (SLP_FALSE);
-  if (!strcasecmp(tmp, "true"))
-    p->type |= CUPS_PRINTER_COLOR;
-
-  if (slp_get_attr(attrlist, "(finishings-supported=", &tmp))
-    return (SLP_FALSE);
-  if (strstr(tmp, "staple"))
-    p->type |= CUPS_PRINTER_STAPLE;
-  if (strstr(tmp, "bind"))
-    p->type |= CUPS_PRINTER_BIND;
-  if (strstr(tmp, "punch"))
-    p->type |= CUPS_PRINTER_PUNCH;
-
-  if (slp_get_attr(attrlist, "(sides-supported=", &tmp))
-    return (SLP_FALSE);
-  if (strstr(tmp,"two-sided"))
-    p->type |= CUPS_PRINTER_DUPLEX;
+  if (!slp_get_attr(attrlist, "(printer-type=", &tmp))
+    p->type = atoi(tmp);
+  else
+    p->type = CUPS_PRINTER_REMOTE;
 
   cupsdClearString(&tmp);
 
@@ -2747,5 +3110,5 @@ slp_url_callback(
 
 
 /*
- * End of "$Id: dirsvc.c 5117 2006-02-16 14:10:43Z mike $".
+ * End of "$Id: dirsvc.c 5178 2006-02-26 00:24:23Z mike $".
  */
index 951407efe90044c9df63cfdcf20caab196ba91ac..ac8eccd66b427023d0ab8def02fa6eaf29c5b47e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: dirsvc.h 5031 2006-01-31 03:05:32Z mike $"
+ * "$Id: dirsvc.h 5198 2006-02-27 21:58:43Z mike $"
  *
  *   Directory services definitions for the Common UNIX Printing System
  *   (CUPS) scheduler.
 #  include <slp.h>
 #endif /* HAVE_LIBSLP */
 
+#ifdef HAVE_OPENLDAP
+#  ifdef __sun
+#    include <lber.h>
+#  endif /* __sun */
+#  include <ldap.h>
+#endif /* HAVE_OPENLDAP */
 
 /*
  * Browse protocols...
@@ -38,7 +44,7 @@
 
 #define BROWSE_CUPS    1               /* CUPS */
 #define        BROWSE_SLP      2               /* SLPv2 */
-#define BROWSE_LDAP    4               /* LDAP (not supported yet) */
+#define BROWSE_LDAP    4               /* LDAP */
 #define BROWSE_DNSSD   8               /* DNS Service Discovery aka Bonjour */
 #define BROWSE_ALL     15              /* All protocols */
 
@@ -135,6 +141,23 @@ VAR time_t         BrowseSLPRefresh VALUE(0);
                                        /* Next SLP refresh time */
 #endif /* HAVE_LIBSLP */
 
+#ifdef HAVE_LDAP
+#  ifdef HAVE_OPENLDAP
+VAR LDAP               *BrowseLDAPHandle VALUE(NULL);
+                                       /* Handle to LDAP server */
+#  endif /* HAVE_OPENLDAP */
+VAR time_t             BrowseLDAPRefresh VALUE(0);
+                                       /* Next LDAP refresh time */
+VAR char               *BrowseLDAPBindDN VALUE(NULL),
+                                       /* LDAP login DN */
+                       *BrowseLDAPDN   VALUE(NULL),
+                                       /* LDAP search DN */
+                       *BrowseLDAPPassword VALUE(NULL),
+                                       /* LDAP login password */
+                       *BrowseLDAPServer VALUE(NULL);
+                                       /* LDAP server to use */
+#endif /* HAVE_LDAP */
+
 
 /*
  * Prototypes...
@@ -145,16 +168,22 @@ extern void       cupsdSaveRemoteCache(void);
 extern void    cupsdSendBrowseDelete(cupsd_printer_t *p);
 extern void    cupsdSendBrowseList(void);
 extern void    cupsdSendCUPSBrowse(cupsd_printer_t *p);
+#ifdef HAVE_LDAP
+extern void    cupsdSendLDAPBrowse(cupsd_printer_t *p);
+#endif /* HAVE_LDAP */
 extern void    cupsdSendSLPBrowse(cupsd_printer_t *p);
 extern void    cupsdStartBrowsing(void);
 extern void    cupsdStartPolling(void);
 extern void    cupsdStopBrowsing(void);
 extern void    cupsdStopPolling(void);
 extern void    cupsdUpdateCUPSBrowse(void);
+#ifdef HAVE_LDAP
+extern void    cupsdUpdateLDAPBrowse(void);
+#endif /* HAVE_LDAP */
 extern void    cupsdUpdatePolling(void);
 extern void    cupsdUpdateSLPBrowse(void);
 
 
 /*
- * End of "$Id: dirsvc.h 5031 2006-01-31 03:05:32Z mike $".
+ * End of "$Id: dirsvc.h 5198 2006-02-27 21:58:43Z mike $".
  */
index f315910af1872cf1435d8cd9c042b27b26c50f2b..92d68f8626f0e67a0aee4be5788eead424b0b871 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: filter.c 5083 2006-02-06 02:57:43Z mike $"
+ * "$Id: filter.c 5196 2006-02-27 21:23:00Z mike $"
  *
  *   File type conversion routines for the Common UNIX Printing System (CUPS).
  *
@@ -199,7 +199,7 @@ compare_filters(mime_filter_t *f0,  /* I - First filter */
  * 'find_filters()' - Find the filters to convert from one type to another.
  */
 
-cups_array_t *                         /* O - Array of filters to run */
+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 */
             mime_type_t      *dst,     /* I - Destination file type */
@@ -360,5 +360,5 @@ lookup(mime_t      *mime,           /* I - MIME database */
 
 
 /*
- * End of "$Id: filter.c 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: filter.c 5196 2006-02-27 21:23:00Z mike $".
  */
index 7053ad0a8541a5a033815e5be98bb17ee0a5310e..3c50525df7c0537d12a0f77043687bc02c4963d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ipp.c 5131 2006-02-18 05:31:36Z mike $"
+ * "$Id: ipp.c 5164 2006-02-24 20:40:00Z mike $"
  *
  *   IPP routines for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -27,6 +27,7 @@
  *   accept_jobs()               - Accept print jobs to a printer.
  *   add_class()                 - Add a class to the system.
  *   add_file()                  - Add a file to a job.
+ *   add_job()                   - Add a job to a print queue.
  *   add_job_state_reasons()     - Add the "job-state-reasons" attribute based
  *                                 upon the job and printer state...
  *   add_job_subscriptions()     - Add any subcriptions for a job.
@@ -35,6 +36,7 @@
  *   add_printer_state_reasons() - Add the "printer-state-reasons" attribute
  *                                 based upon the printer state...
  *   add_queued_job_count()      - Add the "queued-job-count" attribute for
+ *   apply_printer_defaults()    - Apply printer default options to a job.
  *   authenticate_job()          - Set job authentication info.
  *   cancel_all_jobs()           - Cancel all print jobs.
  *   cancel_job()                - Cancel a print job.
@@ -83,6 +85,7 @@
  *   send_ipp_status()           - Send a status back to the IPP client.
  *   set_default()               - Set the default destination...
  *   set_job_attrs()             - Set job attributes.
+ *   set_printer_defaults()      - Set printer default options from a request.
  *   start_printer()             - Start a printer.
  *   stop_printer()              - Stop a printer.
  *   user_allowed()              - See if a user is allowed to print to a queue.
@@ -120,14 +123,19 @@ typedef struct
 
 static void    accept_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    add_class(cupsd_client_t *con, ipp_attribute_t *uri);
-static int     add_file(cupsd_client_t *con, cupsd_job_t *job, mime_type_t *filetype,
-                        int compression);
+static int     add_file(cupsd_client_t *con, cupsd_job_t *job,
+                        mime_type_t *filetype, int compression);
+static cupsd_job_t *add_job(cupsd_client_t *con, ipp_attribute_t *uri,
+                           cupsd_printer_t **dprinter);
 static void    add_job_state_reasons(cupsd_client_t *con, cupsd_job_t *job);
 static void    add_job_subscriptions(cupsd_client_t *con, cupsd_job_t *job);
 static void    add_job_uuid(cupsd_client_t *con, cupsd_job_t *job);
 static void    add_printer(cupsd_client_t *con, ipp_attribute_t *uri);
-static void    add_printer_state_reasons(cupsd_client_t *con, cupsd_printer_t *p);
+static void    add_printer_state_reasons(cupsd_client_t *con,
+                                         cupsd_printer_t *p);
 static void    add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p);
+static void    apply_printer_defaults(cupsd_printer_t *printer,
+                                      cupsd_job_t *job);
 static void    authenticate_job(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    cancel_all_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -137,9 +145,11 @@ static ipp_attribute_t     *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
                                        int quickcopy);
 static void    copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
                           ipp_tag_t group, int quickcopy);
-static int     copy_banner(cupsd_client_t *con, cupsd_job_t *job, const char *name);
+static int     copy_banner(cupsd_client_t *con, cupsd_job_t *job,
+                           const char *name);
 static int     copy_file(const char *from, const char *to);
-static int     copy_model(cupsd_client_t *con, const char *from, const char *to);
+static int     copy_model(cupsd_client_t *con, const char *from,
+                          const char *to);
 static void    copy_job_attrs(cupsd_client_t *con,
                               cupsd_job_t *job,
                               cups_array_t *ra);
@@ -187,6 +197,8 @@ __attribute__ ((__format__ (__printf__, 3, 4)))
 ;
 static void    set_default(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    set_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
+static void    set_printer_defaults(cupsd_client_t *con,
+                                    cupsd_printer_t *printer);
 static void    start_printer(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    stop_printer(cupsd_client_t *con, ipp_attribute_t *uri);
 static int     user_allowed(cupsd_printer_t *p, const char *username);
@@ -761,6 +773,7 @@ add_class(cupsd_client_t  *con,             /* I - Client connection */
   const char   *dest;                  /* Printer or class name */
   ipp_attribute_t *attr;               /* Printer attribute */
   int          modify;                 /* Non-zero if we just modified */
+  char         newname[IPP_MAX_NAME];  /* New class name */
   int          need_restart_job;       /* Need to restart job? */
 
 
@@ -852,9 +865,8 @@ add_class(cupsd_client_t  *con,             /* I - Client connection */
 
     if (ImplicitAnyClasses)
     {
-      cupsArrayRemove(Printers, pclass);
-      cupsdSetStringf(&pclass->name, "Any%s", resource + 9);
-      cupsArrayAdd(Printers, pclass);
+      snprintf(newname, sizeof(newname), "Any%s", resource + 9);
+      cupsdRenamePrinter(pclass, newname);
     }
     else
       cupsdDeletePrinter(pclass, 1);
@@ -872,11 +884,8 @@ add_class(cupsd_client_t  *con,            /* I - Client connection */
     * Rename the remote class to "Class"...
     */
 
-    cupsdDeletePrinterFilters(pclass);
-    cupsArrayRemove(Printers, pclass);
-    cupsdSetStringf(&pclass->name, "%s@%s", resource + 9, pclass->hostname);
-    cupsdSetPrinterAttrs(pclass);
-    cupsArrayAdd(Printers, pclass);
+    snprintf(newname, sizeof(newname), "%s@%s", resource + 9, pclass->hostname);
+    cupsdRenamePrinter(pclass, newname);
 
    /*
     * Add the class as a new local class...
@@ -955,107 +964,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
             sizeof(pclass->state_message));
     cupsdAddPrinterHistory(pclass);
   }
-  if ((attr = ippFindAttribute(con->request, "job-sheets-default",
-                               IPP_TAG_ZERO)) != NULL &&
-      !Classification)
-  {
-    cupsdSetString(&pclass->job_sheets[0], attr->values[0].string.text);
-    if (attr->num_values > 1)
-      cupsdSetString(&pclass->job_sheets[1], attr->values[1].string.text);
-    else
-      cupsdSetString(&pclass->job_sheets[1], "none");
-  }
-  if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed",
-                               IPP_TAG_ZERO)) != NULL)
-  {
-    cupsdFreePrinterUsers(pclass);
-
-    pclass->deny_users = 0;
-    if (attr->value_tag == IPP_TAG_NAME &&
-        (attr->num_values > 1 ||
-        strcmp(attr->values[0].string.text, "all")))
-      for (i = 0; i < attr->num_values; i ++)
-       cupsdAddPrinterUser(pclass, attr->values[i].string.text);
-  }
-  else if ((attr = ippFindAttribute(con->request, "requesting-user-name-denied",
-                                    IPP_TAG_ZERO)) != NULL)
-  {
-    cupsdFreePrinterUsers(pclass);
-
-    pclass->deny_users = 1;
-    if (attr->value_tag == IPP_TAG_NAME &&
-        (attr->num_values > 1 ||
-        strcmp(attr->values[0].string.text, "none")))
-      for (i = 0; i < attr->num_values; i ++)
-       cupsdAddPrinterUser(pclass, attr->values[i].string.text);
-  }
-  if ((attr = ippFindAttribute(con->request, "job-quota-period",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "add_class: Setting job-quota-period to %d...",
-                    attr->values[0].integer);
-    cupsdFreeQuotas(pclass);
-    pclass->quota_period = attr->values[0].integer;
-  }
-  if ((attr = ippFindAttribute(con->request, "job-k-limit",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "add_class: Setting job-k-limit to %d...",
-                    attr->values[0].integer);
-    cupsdFreeQuotas(pclass);
-    pclass->k_limit = attr->values[0].integer;
-  }
-  if ((attr = ippFindAttribute(con->request, "job-page-limit",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "add_class: Setting job-page-limit to %d...",
-                    attr->values[0].integer);
-    cupsdFreeQuotas(pclass);
-    pclass->page_limit = attr->values[0].integer;
-  }
-  if ((attr = ippFindAttribute(con->request, "printer-op-policy",
-                               IPP_TAG_NAME)) != NULL)
-  {
-    cupsd_policy_t *p;                 /* Policy */
-
-
-    if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "add_class: Setting printer-op-policy to \"%s\"...",
-                      attr->values[0].string.text);
-      cupsdSetString(&pclass->op_policy, attr->values[0].string.text);
-      pclass->op_policy_ptr = p;
-    }
-    else
-    {
-      send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("add_class: Unknown printer-op-policy \"%s\"."),
-                      attr->values[0].string.text);
-      return;
-    }
-  }
-  if ((attr = ippFindAttribute(con->request, "printer-error-policy",
-                               IPP_TAG_NAME)) != NULL)
-  {
-    if (strcmp(attr->values[0].string.text, "abort-job") &&
-        strcmp(attr->values[0].string.text, "retry-job") &&
-        strcmp(attr->values[0].string.text, "stop-printer"))
-    {
-      send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("add_class: Unknown printer-error-policy \"%s\"."),
-                      attr->values[0].string.text);
-      return;
-    }
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "add_class: Setting printer-error-policy to \"%s\"...",
-                    attr->values[0].string.text);
-    cupsdSetString(&pclass->error_policy, attr->values[0].string.text);
-  }
   if ((attr = ippFindAttribute(con->request, "member-uris",
                                IPP_TAG_URI)) != NULL)
   {
@@ -1104,6 +1012,8 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
     }
   }
 
+  set_printer_defaults(con, pclass);
+
  /*
   * Update the printer class attributes and return...
   */
@@ -1215,3297 +1125,3301 @@ add_file(cupsd_client_t *con,               /* I - Connection to client */
 
 
 /*
- * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based
- *                             upon the job and printer state...
+ * 'add_job()' - Add a job to a print queue.
  */
 
-static void
-add_job_state_reasons(
-    cupsd_client_t *con,               /* I - Client connection */
-    cupsd_job_t    *job)               /* I - Job info */
+static cupsd_job_t *                   /* O - Job object */
+add_job(cupsd_client_t  *con,          /* I - Client connection */
+        ipp_attribute_t *uri,          /* I - printer-uri */
+       cupsd_printer_t **dprinter)     /* I - Destination printer */
 {
-  cupsd_printer_t      *dest;          /* Destination printer */
+  http_status_t        status;                 /* Policy status */
+  ipp_attribute_t *attr;               /* Current attribute */
+  const char   *dest;                  /* Destination */
+  cups_ptype_t dtype;                  /* Destination type (printer or class) */
+  const char   *val;                   /* Default option value */
+  int          priority;               /* Job priority */
+  char         *title;                 /* Job name/title */
+  cupsd_job_t  *job;                   /* Current job */
+  char         job_uri[HTTP_MAX_URI],  /* Job URI */
+               method[HTTP_MAX_URI],   /* Method portion of URI */
+               username[HTTP_MAX_URI], /* Username portion of URI */
+               host[HTTP_MAX_URI],     /* Host portion of URI */
+               resource[HTTP_MAX_URI]; /* Resource portion of URI */
+  int          port;                   /* Port portion of URI */
+  cupsd_printer_t *printer;            /* Printer data */
+  int          kbytes;                 /* Size of print file */
+  int          i;                      /* Looping var */
+  int          lowerpagerange;         /* Page range bound */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job_state_reasons(%p[%d], %d)",
-                  con, con->http.fd, job ? job->id : 0);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
 
-  switch (job ? job->state_value : IPP_JOB_CANCELLED)
+ /*
+  * Is the destination valid?
+  */
+
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                  sizeof(method), username, sizeof(username), host,
+                 sizeof(host), &port, resource, sizeof(resource));
+
+  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
   {
-    case IPP_JOB_PENDING :
-        if (job->dtype & CUPS_PRINTER_CLASS)
-         dest = cupsdFindClass(job->dest);
-       else
-         dest = cupsdFindPrinter(job->dest);
+   /*
+    * Bad URI...
+    */
 
-        if (dest && dest->state == IPP_PRINTER_STOPPED)
-          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                      "job-state-reasons", NULL, "printer-stopped");
-        else
-          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                      "job-state-reasons", NULL, "none");
-        break;
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("The printer or class was not found."));
+    return (NULL);
+  }
 
-    case IPP_JOB_HELD :
-        if (ippFindAttribute(job->attrs, "job-hold-until",
-                            IPP_TAG_KEYWORD) != NULL ||
-           ippFindAttribute(job->attrs, "job-hold-until",
-                            IPP_TAG_NAME) != NULL)
-          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                      "job-state-reasons", NULL, "job-hold-until-specified");
-        else
-          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                      "job-state-reasons", NULL, "job-incoming");
-        break;
+  if (dprinter)
+    *dprinter = printer;
 
-    case IPP_JOB_PROCESSING :
-        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                    "job-state-reasons", NULL, "job-printing");
-        break;
+ /*
+  * Check remote printing to non-shared printer...
+  */
 
-    case IPP_JOB_STOPPED :
-        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                    "job-state-reasons", NULL, "job-stopped");
-        break;
+  if (!printer->shared &&
+      strcasecmp(con->http.hostname, "localhost") &&
+      strcasecmp(con->http.hostname, ServerName))
+  {
+    send_ipp_status(con, IPP_NOT_AUTHORIZED,
+                    _("The printer or class is not shared!"));
+    return (NULL);
+  }
 
-    case IPP_JOB_CANCELLED :
-        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                    "job-state-reasons", NULL, "job-canceled-by-user");
-        break;
+ /*
+  * Check policy...
+  */
 
-    case IPP_JOB_ABORTED :
-        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                    "job-state-reasons", NULL, "aborted-by-system");
-        break;
+  if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
+  {
+    send_http_error(con, status);
+    return (NULL);
+  }
+  else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && !con->username[0])
+  {
+    send_http_error(con, HTTP_UNAUTHORIZED);
+    return (NULL);
+  }
 
-    case IPP_JOB_COMPLETED :
-        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                    "job-state-reasons", NULL, "job-completed-successfully");
-        break;
+ /*
+  * See if the printer is accepting jobs...
+  */
+
+  if (!printer->accepting)
+  {
+    send_ipp_status(con, IPP_NOT_ACCEPTING,
+                    _("Destination \"%s\" is not accepting jobs."),
+                    dest);
+    return (NULL);
   }
-}
 
+ /*
+  * Validate job template attributes; for now just copies and page-ranges...
+  */
 
-/*
- * 'add_job_subscriptions()' - Add any subcriptions for a job.
- */
+  if ((attr = ippFindAttribute(con->request, "copies",
+                               IPP_TAG_INTEGER)) != NULL)
+  {
+    if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies)
+    {
+      send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."),
+                      attr->values[0].integer);
+      ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER,
+                   "copies", attr->values[0].integer);
+      return (NULL);
+    }
+  }
 
-static void
-add_job_subscriptions(
-    cupsd_client_t *con,               /* I - Client connection */
-    cupsd_job_t    *job)               /* I - Newly created job */
-{
-  int                  i;              /* Looping var */
-  ipp_attribute_t      *prev,          /* Previous attribute */
-                       *next,          /* Next attribute */
-                       *attr;          /* Current attribute */
-  cupsd_subscription_t *sub;           /* Subscription object */
-  const char           *recipient,     /* notify-recipient-uri */
-                       *pullmethod;    /* notify-pull-method */
-  ipp_attribute_t      *user_data;     /* notify-user-data */
-  int                  interval;       /* notify-time-interval */
-  unsigned             mask;           /* notify-events */
+  if ((attr = ippFindAttribute(con->request, "page-ranges",
+                               IPP_TAG_RANGE)) != NULL)
+  {
+    for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++)
+    {
+      if (attr->values[i].range.lower < lowerpagerange || 
+         attr->values[i].range.lower > attr->values[i].range.upper)
+      {
+       send_ipp_status(con, IPP_BAD_REQUEST,
+                       _("Bad page-ranges values %d-%d."),
+                       attr->values[i].range.lower,
+                       attr->values[i].range.upper);
+       return (NULL);
+      }
 
+      lowerpagerange = attr->values[i].range.upper + 1;
+    }
+  }
 
  /*
-  * Find the first subscription group attribute; return if we have
-  * none...
+  * Make sure we aren't over our limit...
   */
 
-  for (attr = job->attrs->attrs, prev = NULL;
-       attr;
-       prev = attr, attr = attr->next)
-    if (attr->group_tag == IPP_TAG_SUBSCRIPTION)
-      break;
+  if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs)
+    cupsdCleanJobs();
 
-  if (!attr)
-    return;
+  if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs)
+  {
+    send_ipp_status(con, IPP_NOT_POSSIBLE,
+                    _("Too many active jobs."));
+    return (NULL);
+  }
+
+  if (!check_quotas(con, printer))
+  {
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached."));
+    return (NULL);
+  }
 
  /*
-  * Process the subscription attributes in the request...
+  * Create the job and set things up...
   */
 
-  while (attr)
+  if ((attr = ippFindAttribute(con->request, "job-priority",
+                               IPP_TAG_INTEGER)) != NULL)
+    priority = attr->values[0].integer;
+  else
   {
-    recipient = NULL;
-    pullmethod = NULL;
-    user_data  = NULL;
-    interval   = 0;
-    mask       = CUPSD_EVENT_NONE;
-
-    while (attr && attr->group_tag != IPP_TAG_ZERO)
-    {
-      if (!strcmp(attr->name, "notify-recipient") &&
-          attr->value_tag == IPP_TAG_URI)
-        recipient = attr->values[0].string.text;
-      else if (!strcmp(attr->name, "notify-pull-method") &&
-               attr->value_tag == IPP_TAG_KEYWORD)
-        pullmethod = attr->values[0].string.text;
-      else if (!strcmp(attr->name, "notify-charset") &&
-               attr->value_tag == IPP_TAG_CHARSET &&
-              strcmp(attr->values[0].string.text, "us-ascii") &&
-              strcmp(attr->values[0].string.text, "utf-8"))
-      {
-        send_ipp_status(con, IPP_CHARSET,
-                       _("Character set \"%s\" not supported!"),
-                       attr->values[0].string.text);
-       return;
-      }
-      else if (!strcmp(attr->name, "notify-natural-language") &&
-               (attr->value_tag != IPP_TAG_LANGUAGE ||
-               strcmp(attr->values[0].string.text, DefaultLanguage)))
-      {
-        send_ipp_status(con, IPP_CHARSET,
-                       _("Language \"%s\" not supported!"),
-                       attr->values[0].string.text);
-       return;
-      }
-      else if (!strcmp(attr->name, "notify-user-data") &&
-               attr->value_tag == IPP_TAG_STRING)
-      {
-        if (attr->num_values > 1 || attr->values[0].unknown.length > 63)
-       {
-          send_ipp_status(con, IPP_REQUEST_VALUE,
-                         _("The notify-user-data value is too large "
-                           "(%d > 63 octets)!"),
-                         attr->values[0].unknown.length);
-         return;
-       }
-
-        user_data = attr;
-      }
-      else if (!strcmp(attr->name, "notify-events") &&
-               attr->value_tag == IPP_TAG_KEYWORD)
-      {
-        for (i = 0; i < attr->num_values; i ++)
-         mask |= cupsdEventValue(attr->values[i].string.text);
-      }
-      else if (!strcmp(attr->name, "notify-lease-duration"))
-      {
-        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("The notify-lease-duration attribute cannot be "
-                         "used with job subscriptions."));
-       return;
-      }
-      else if (!strcmp(attr->name, "notify-time-interval") &&
-               attr->value_tag == IPP_TAG_INTEGER)
-        interval = attr->values[0].integer;
-
-      attr = attr->next;
-    }
+    if ((val = cupsGetOption("job-priority", printer->num_options,
+                             printer->options)) != NULL)
+      priority = atoi(val);
+    else
+      priority = 50;
 
-    if (!recipient && !pullmethod)
-      break;
+    ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
+                  priority);
+  }
 
-    if (mask == CUPSD_EVENT_NONE)
-      mask = CUPSD_EVENT_JOB_COMPLETED;
+  if ((attr = ippFindAttribute(con->request, "job-name",
+                               IPP_TAG_NAME)) != NULL)
+    title = attr->values[0].string.text;
+  else
+    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+                 title = "Untitled");
 
-    sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, recipient,
-                               0);
+  if ((job = cupsdAddJob(priority, printer->name)) == NULL)
+  {
+    send_ipp_status(con, IPP_INTERNAL_ERROR,
+                    _("Unable to add job for destination \"%s\"!"), dest);
+    return (NULL);
+  }
 
-    sub->interval = interval;
+  job->dtype   = dtype;
+  job->attrs   = con->request;
+  con->request = NULL;
 
-    cupsdSetString(&sub->owner, job->username);
+  add_job_uuid(con, job);
+  apply_printer_defaults(printer, job);
 
-    if (user_data)
-    {
-      sub->user_data_len = user_data->values[0].unknown.length;
-      memcpy(sub->user_data, user_data->values[0].unknown.data,
-             sub->user_data_len);
-    }
+  attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME);
 
-    ippAddSeparator(con->response);
-    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
-                  "notify-subscription-id", sub->id);
+  if (con->username[0])
+  {
+    cupsdSetString(&job->username, con->username);
 
     if (attr)
-      attr = attr->next;
+      cupsdSetString(&attr->values[0].string.text, con->username);
+
+    save_auth_info(con, job);
   }
+  else if (attr)
+  {
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
+                    "add_job: requesting-user-name=\"%s\"",
+                    attr->values[0].string.text);
 
-  cupsdSaveAllSubscriptions();
+    cupsdSetString(&job->username, attr->values[0].string.text);
+  }
+  else
+    cupsdSetString(&job->username, "anonymous");
 
- /*
-  * Remove all of the subscription attributes from the job request...
-  */
+  if (!attr)
+    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
+                 "job-originating-user-name", NULL, job->username);
+  else
+  {
+    attr->group_tag = IPP_TAG_JOB;
+    _cups_sp_free(attr->name);
+    attr->name = _cups_sp_alloc("job-originating-user-name");
+  }
 
-  for (attr = job->attrs->attrs, prev = NULL; attr; attr = next)
+  if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
+                               IPP_TAG_ZERO)) != NULL)
   {
-    next = attr->next;
+   /*
+    * Request contains a job-originating-host-name attribute; validate it...
+    */
 
-    if (attr->group_tag == IPP_TAG_SUBSCRIPTION ||
-        attr->group_tag == IPP_TAG_ZERO)
+    if (attr->value_tag != IPP_TAG_NAME ||
+        attr->num_values != 1 ||
+        strcmp(con->http.hostname, "localhost"))
     {
      /*
-      * Free and remove this attribute...
+      * Can't override the value if we aren't connected via localhost.
+      * Also, we can only have 1 value and it must be a name value.
       */
 
-      _ipp_free_attr(attr);
-
-      if (prev)
-        prev->next = next;
-      else
-        job->attrs->attrs = next;
-    }
-    else
-      prev = attr;
-  }
+      switch (attr->value_tag)
+      {
+        case IPP_TAG_STRING :
+       case IPP_TAG_TEXTLANG :
+       case IPP_TAG_NAMELANG :
+       case IPP_TAG_TEXT :
+       case IPP_TAG_NAME :
+       case IPP_TAG_KEYWORD :
+       case IPP_TAG_URI :
+       case IPP_TAG_URISCHEME :
+       case IPP_TAG_CHARSET :
+       case IPP_TAG_LANGUAGE :
+       case IPP_TAG_MIMETYPE :
+          /*
+           * Free old strings...
+           */
 
-  job->attrs->last    = prev;
-  job->attrs->current = prev;
-}
+           for (i = 0; i < attr->num_values; i ++)
+           {
+             _cups_sp_free(attr->values[i].string.text);
+             attr->values[i].string.text = NULL;
+             if (attr->values[i].string.charset)
+             {
+               _cups_sp_free(attr->values[i].string.charset);
+               attr->values[i].string.charset = NULL;
+             }
+            }
 
+       default :
+            break;
+      }
 
-/*
- * 'add_job_uuid()' - Add job-uuid attribute to a job.
- *
- * See RFC 4122 for the definition of UUIDs and the format.
- */
+     /*
+      * Use the default connection hostname instead...
+      */
 
-static void
-add_job_uuid(cupsd_client_t *con,      /* I - Client connection */
-             cupsd_job_t    *job)      /* I - Job */
-{
-  char                 uuid[1024];     /* job-uuid string */
-  ipp_attribute_t      *attr;          /* job-uuid attribute */
-  _cups_md5_state_t    md5state;       /* MD5 state */
-  unsigned char                md5sum[16];     /* MD5 digest/sum */
+      attr->value_tag             = IPP_TAG_NAME;
+      attr->num_values            = 1;
+      attr->values[0].string.text = _cups_sp_alloc(con->http.hostname);
+    }
 
+    attr->group_tag = IPP_TAG_JOB;
+  }
+  else
+  {
+   /*
+    * No job-originating-host-name attribute, so use the hostname from
+    * the connection...
+    */
 
- /*
-  * First see if the job already has a job-uuid attribute; if so, return...
-  */
+    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, 
+                "job-originating-host-name", NULL, con->http.hostname);
+  }
 
-  if ((attr = ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI)) != NULL)
-    return;
+  ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation",
+                time(NULL));
+  attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+                       "time-at-processing", 0);
+  attr->value_tag = IPP_TAG_NOVALUE;
+  attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+                       "time-at-completed", 0);
+  attr->value_tag = IPP_TAG_NOVALUE;
 
  /*
-  * No job-uuid attribute, so build a version 3 UUID with the local job
-  * ID at the end; see RFC 4122 for details.  Start with the MD5 sum of
-  * the ServerName, server name and port that the client connected to,
-  * and local job ID...
+  * Add remaining job attributes...
   */
 
-  snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername,
-          con->serverport, job->id);
+  ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+  job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM,
+                             "job-state", IPP_JOB_STOPPED);
+  job->state_value = job->state->values[0].integer;
+  job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+                              "job-media-sheets-completed", 0);
+  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
+               printer->uri);
+  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+               title);
 
-  _cups_md5_init(&md5state);
-  _cups_md5_append(&md5state, (unsigned char *)uuid, strlen(uuid));
-  _cups_md5_finish(&md5state, md5sum);
+  if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
+                               IPP_TAG_INTEGER)) != NULL)
+    attr->values[0].integer = 0;
+  else
+    attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+                         "job-k-octets", 0);
 
- /*
-  * Format the UUID URI using the MD5 sum and job ID.
-  */
-
-  snprintf(uuid, sizeof(uuid),
-           "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]);
-
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid);
-}
-
-
-/*
- * 'add_printer()' - Add a printer to the system.
- */
-
-static void
-add_printer(cupsd_client_t  *con,      /* I - Client connection */
-            ipp_attribute_t *uri)      /* I - URI of printer */
-{
-  http_status_t        status;                 /* Policy status */
-  int          i;                      /* Looping var */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
-               host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI]; /* Resource portion of URI */
-  int          port;                   /* Port portion of URI */
-  cupsd_printer_t *printer;            /* Printer/class */
-  ipp_attribute_t *attr;               /* Printer attribute */
-  cups_file_t  *fp;                    /* Script/PPD file */
-  char         line[1024];             /* Line from file... */
-  char         srcfile[1024],          /* Source Script/PPD file */
-               dstfile[1024];          /* Destination Script/PPD file */
-  int          modify;                 /* Non-zero if we are modifying */
-  int          need_restart_job;       /* Need to restart job? */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con,
-                  con->http.fd, uri->values[0].string.text);
-
- /*
-  * Do we have a valid URI?
-  */
-
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
-
-  if (strncmp(resource, "/printers/", 10) || strlen(resource) == 10)
+  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
+                               IPP_TAG_KEYWORD)) == NULL)
+    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+  if (!attr)
   {
-   /*
-    * No, return an error...
-    */
+    if ((val = cupsGetOption("job-hold-until", printer->num_options,
+                             printer->options)) == NULL)
+      val = "no-hold";
 
-    send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("The printer-uri must be of the form "
-                     "\"ipp://HOSTNAME/printers/PRINTERNAME\"."));
-    return;
+    attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                        "job-hold-until", NULL, val);
   }
-
- /*
-  * Do we have a valid printer name?
-  */
-
-  if (!validate_name(resource + 10))
+  if (attr && strcmp(attr->values[0].string.text, "no-hold") &&
+      !(printer->type & CUPS_PRINTER_REMOTE))
   {
    /*
-    * No, return an error...
+    * Hold job until specified time...
     */
 
-    send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("The printer-uri \"%s\" contains invalid characters."),
-                   uri->values[0].string.text);
-    return;
+    cupsdSetJobHoldUntil(job, attr->values[0].string.text);
   }
-
- /*
-  * Check policy...
-  */
-
-  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+  else if (job->attrs->request.op.operation_id == IPP_CREATE_JOB)
   {
-    send_http_error(con, status);
-    return;
+    job->hold_until = time(NULL) + 60;
+    job->state->values[0].integer = IPP_JOB_HELD;
+    job->state_value              = IPP_JOB_HELD;
+  }
+  else
+  {
+    job->state->values[0].integer = IPP_JOB_PENDING;
+    job->state_value              = IPP_JOB_PENDING;
   }
 
- /*
-  * See if the printer already exists; if not, create a new printer...
-  */
-
-  if ((printer = cupsdFindPrinter(resource + 10)) == NULL)
+  if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
+      Classification)
   {
    /*
-    * Printer doesn't exist; see if we have a class of the same name...
+    * Add job sheets options...
     */
 
-    if ((printer = cupsdFindClass(resource + 10)) != NULL &&
-        !(printer->type & CUPS_PRINTER_REMOTE))
+    if ((attr = ippFindAttribute(job->attrs, "job-sheets",
+                                 IPP_TAG_ZERO)) == NULL)
     {
-     /*
-      * Yes, return an error...
-      */
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "Adding default job-sheets values \"%s,%s\"...",
+                      printer->job_sheets[0], printer->job_sheets[1]);
 
-      send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("A class named \"%s\" already exists!"),
-                     resource + 10);
-      return;
+      attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
+                           2, NULL, NULL);
+      attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]);
+      attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]);
     }
 
-   /*
-    * No, add the printer...
-    */
+    job->job_sheets = attr;
 
-    printer = cupsdAddPrinter(resource + 10);
-    modify  = 0;
-  }
-  else if (printer->type & CUPS_PRINTER_IMPLICIT)
-  {
    /*
-    * Rename the implicit printer to "AnyPrinter" or delete it...
+    * Enforce classification level if set...
     */
 
-    if (ImplicitAnyClasses)
+    if (Classification)
     {
-      cupsArrayRemove(Printers, printer);
-      cupsdSetStringf(&printer->name, "Any%s", resource + 10);
-      cupsArrayAdd(Printers, printer);
-    }
-    else
-      cupsdDeletePrinter(printer, 1);
-
-   /*
-    * Add the printer as a new local printer...
-    */
-
-    printer = cupsdAddPrinter(resource + 10);
-    modify  = 0;
-  }
-  else if (printer->type & CUPS_PRINTER_REMOTE)
-  {
-   /*
-    * Rename the remote printer to "Printer@server"...
-    */
-
-    cupsdDeletePrinterFilters(printer);
-    cupsArrayRemove(Printers, printer);
-    cupsdSetStringf(&printer->name, "%s@%s", resource + 10, printer->hostname);
-    cupsdSetPrinterAttrs(printer);
-    cupsArrayAdd(Printers, printer);
-
-   /*
-    * Add the printer as a new local printer...
-    */
-
-    printer = cupsdAddPrinter(resource + 10);
-    modify  = 0;
-  }
-  else
-    modify = 1;
-
- /*
-  * Look for attributes and copy them over as needed...
-  */
-
-  need_restart_job = 0;
-
-  if ((attr = ippFindAttribute(con->request, "printer-location",
-                               IPP_TAG_TEXT)) != NULL)
-    cupsdSetString(&printer->location, attr->values[0].string.text);
-
-  if ((attr = ippFindAttribute(con->request, "printer-info",
-                               IPP_TAG_TEXT)) != NULL)
-    cupsdSetString(&printer->info, attr->values[0].string.text);
+      cupsdLogMessage(CUPSD_LOG_INFO,
+                      "Classification=\"%s\", ClassifyOverride=%d",
+                      Classification ? Classification : "(null)",
+                     ClassifyOverride);
 
-  if ((attr = ippFindAttribute(con->request, "device-uri",
-                               IPP_TAG_URI)) != NULL)
-  {
-   /*
-    * Do we have a valid device URI?
-    */
+      if (ClassifyOverride)
+      {
+        if (!strcmp(attr->values[0].string.text, "none") &&
+           (attr->num_values == 1 ||
+            !strcmp(attr->values[1].string.text, "none")))
+        {
+        /*
+          * Force the leading banner to have the classification on it...
+         */
 
-    need_restart_job = 1;
+          cupsdSetString(&attr->values[0].string.text, Classification);
 
-    httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method,
-                    sizeof(method), username, sizeof(username), host,
-                   sizeof(host), &port, resource, sizeof(resource));
+         cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED "
+                                           "job-sheets=\"%s,none\", "
+                                           "job-originating-user-name=\"%s\"",
+                        job->id, Classification, job->username);
+       }
+       else if (attr->num_values == 2 &&
+                strcmp(attr->values[0].string.text,
+                       attr->values[1].string.text) &&
+                strcmp(attr->values[0].string.text, "none") &&
+                strcmp(attr->values[1].string.text, "none"))
+        {
+        /*
+         * Can't put two different security markings on the same document!
+         */
 
-    if (!strcmp(method, "file"))
-    {
-     /*
-      * See if the administrator has enabled file devices...
-      */
+          cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
 
-      if (!FileDevice && strcmp(resource, "/dev/null"))
+         cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED "
+                                           "job-sheets=\"%s,%s\", "
+                                           "job-originating-user-name=\"%s\"",
+                        job->id, attr->values[0].string.text,
+                        attr->values[1].string.text, job->username);
+       }
+       else if (strcmp(attr->values[0].string.text, Classification) &&
+                strcmp(attr->values[0].string.text, "none") &&
+                (attr->num_values == 1 ||
+                 (strcmp(attr->values[1].string.text, Classification) &&
+                  strcmp(attr->values[1].string.text, "none"))))
+        {
+         if (attr->num_values == 1)
+            cupsdLogMessage(CUPSD_LOG_NOTICE,
+                           "[Job %d] CLASSIFICATION OVERRIDDEN "
+                           "job-sheets=\"%s\", "
+                           "job-originating-user-name=\"%s\"",
+                      job->id, attr->values[0].string.text, job->username);
+          else
+            cupsdLogMessage(CUPSD_LOG_NOTICE,
+                           "[Job %d] CLASSIFICATION OVERRIDDEN "
+                           "job-sheets=\"%s,%s\",fffff "
+                           "job-originating-user-name=\"%s\"",
+                           job->id, attr->values[0].string.text,
+                           attr->values[1].string.text, job->username);
+        }
+      }
+      else if (strcmp(attr->values[0].string.text, Classification) &&
+               (attr->num_values == 1 ||
+              strcmp(attr->values[1].string.text, Classification)))
       {
        /*
-        * File devices are disabled and the URL is not file:/dev/null...
+        * Force the banner to have the classification on it...
        */
 
-       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                       _("File device URIs have been disabled! "
-                         "To enable, see the FileDevice directive in "
-                         "\"%s/cupsd.conf\"."),
-                       ServerRoot);
-       return;
-      }
-    }
-    else
-    {
-     /*
-      * See if the backend exists and is executable...
-      */
+        if (attr->num_values > 1 &&
+           !strcmp(attr->values[0].string.text, attr->values[1].string.text))
+       {
+          cupsdSetString(&(attr->values[0].string.text), Classification);
+          cupsdSetString(&(attr->values[1].string.text), Classification);
+       }
+        else
+       {
+          if (attr->num_values == 1 ||
+             strcmp(attr->values[0].string.text, "none"))
+            cupsdSetString(&(attr->values[0].string.text), Classification);
 
-      snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin, method);
-      if (access(srcfile, X_OK))
-      {
-       /*
-        * Could not find device in list!
-       */
+          if (attr->num_values > 1 &&
+             strcmp(attr->values[1].string.text, "none"))
+            cupsdSetString(&(attr->values[1].string.text), Classification);
+        }
 
-       send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"!"),
-                       attr->values[0].string.text);
-       return;
+        if (attr->num_values > 1)
+         cupsdLogMessage(CUPSD_LOG_NOTICE,
+                         "[Job %d] CLASSIFICATION FORCED "
+                         "job-sheets=\"%s,%s\", "
+                         "job-originating-user-name=\"%s\"",
+                         job->id, attr->values[0].string.text,
+                         attr->values[1].string.text, job->username);
+        else
+         cupsdLogMessage(CUPSD_LOG_NOTICE,
+                         "[Job %d] CLASSIFICATION FORCED "
+                         "job-sheets=\"%s\", "
+                         "job-originating-user-name=\"%s\"",
+                        job->id, Classification, job->username);
       }
     }
 
-    cupsdLogMessage(CUPSD_LOG_INFO,
-                    "Setting %s device-uri to \"%s\" (was \"%s\".)",
-                   printer->name,
-                   cupsdSanitizeURI(attr->values[0].string.text, line,
-                                    sizeof(line)),
-                   cupsdSanitizeURI(printer->device_uri, resource,
-                                    sizeof(resource)));
-
-    cupsdSetString(&printer->device_uri, attr->values[0].string.text);
-  }
-
-  if ((attr = ippFindAttribute(con->request, "port-monitor",
-                               IPP_TAG_KEYWORD)) != NULL)
-  {
-    ipp_attribute_t    *supported;     /* port-monitor-supported attribute */
-
-
-    need_restart_job = 1;
-
-    supported = ippFindAttribute(printer->attrs, "port-monitor-supported",
-                                 IPP_TAG_KEYWORD);
-    for (i = 0; i < supported->num_values; i ++)
-      if (!strcmp(supported->values[i].string.text,
-                  attr->values[0].string.text))
-        break;
+   /*
+    * See if we need to add the starting sheet...
+    */
 
-    if (i >= supported->num_values)
+    if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
     {
-      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"),
-                     attr->values[0].string.text);
-      return;
-    }
-
-    cupsdLogMessage(CUPSD_LOG_INFO,
-                    "Setting %s port-monitor to \"%s\" (was \"%s\".)",
-                    printer->name, attr->values[0].string.text,
-                   printer->port_monitor);
-
-    if (strcmp(attr->values[0].string.text, "none"))
-      cupsdSetString(&printer->port_monitor, attr->values[0].string.text);
-    else
-      cupsdClearString(&printer->port_monitor);
-  }
+      cupsdLogMessage(CUPSD_LOG_INFO,
+                      "Adding start banner page \"%s\" to job %d.",
+                      attr->values[0].string.text, job->id);
 
-  if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs",
-                               IPP_TAG_BOOLEAN)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_INFO,
-                    "Setting %s printer-is-accepting-jobs to %d (was %d.)",
-                    printer->name, attr->values[0].boolean, printer->accepting);
+      kbytes = copy_banner(con, job, attr->values[0].string.text);
 
-    printer->accepting = attr->values[0].boolean;
-    cupsdAddPrinterHistory(printer);
+      cupsdUpdateQuota(printer, job->username, 0, kbytes);
+    }
   }
+  else if ((attr = ippFindAttribute(job->attrs, "job-sheets",
+                                    IPP_TAG_ZERO)) != NULL)
+    job->sheets = attr;
 
-  if ((attr = ippFindAttribute(con->request, "printer-is-shared",
-                               IPP_TAG_BOOLEAN)) != NULL)
-  {
-    if (printer->shared && !attr->values[0].boolean)
-      cupsdSendBrowseDelete(printer);
-
-    cupsdLogMessage(CUPSD_LOG_INFO,
-                    "Setting %s printer-is-shared to %d (was %d.)",
-                    printer->name, attr->values[0].boolean, printer->shared);
+ /*
+  * Fill in the response info...
+  */
 
-    printer->shared = attr->values[0].boolean;
-  }
+  snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
+          LocalPort, job->id);
 
-  if ((attr = ippFindAttribute(con->request, "printer-state",
-                               IPP_TAG_ENUM)) != NULL)
-  {
-    if (attr->values[0].integer != IPP_PRINTER_IDLE &&
-        attr->values[0].integer != IPP_PRINTER_STOPPED)
-    {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d!"),
-                      attr->values[0].integer);
-      return;
-    }
+  ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
+               job_uri);
 
-    cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-state to %d (was %d.)", printer->name,
-               attr->values[0].integer, printer->state);
+  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
 
-    if (attr->values[0].integer == IPP_PRINTER_STOPPED)
-      cupsdStopPrinter(printer, 0);
-    else
-    {
-      need_restart_job = 1;
-      cupsdSetPrinterState(printer, (ipp_pstate_t)(attr->values[0].integer), 0);
-    }
-  }
-  if ((attr = ippFindAttribute(con->request, "printer-state-message",
-                               IPP_TAG_TEXT)) != NULL)
-  {
-    strlcpy(printer->state_message, attr->values[0].string.text,
-            sizeof(printer->state_message));
-    cupsdAddPrinterHistory(printer);
-  }
-  if ((attr = ippFindAttribute(con->request, "job-sheets-default",
-                               IPP_TAG_ZERO)) != NULL &&
-      !Classification)
-  {
-    cupsdSetString(&printer->job_sheets[0], attr->values[0].string.text);
-    if (attr->num_values > 1)
-      cupsdSetString(&printer->job_sheets[1], attr->values[1].string.text);
-    else
-      cupsdSetString(&printer->job_sheets[1], "none");
-  }
-  if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed",
-                               IPP_TAG_ZERO)) != NULL)
-  {
-    cupsdFreePrinterUsers(printer);
+  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
+                job->state_value);
+  add_job_state_reasons(con, job);
 
-    printer->deny_users = 0;
-    if (attr->value_tag == IPP_TAG_NAME &&
-        (attr->num_values > 1 ||
-        strcmp(attr->values[0].string.text, "all")))
-      for (i = 0; i < attr->num_values; i ++)
-       cupsdAddPrinterUser(printer, attr->values[i].string.text);
-  }
-  else if ((attr = ippFindAttribute(con->request, "requesting-user-name-denied",
-                                    IPP_TAG_ZERO)) != NULL)
-  {
-    cupsdFreePrinterUsers(printer);
+  con->response->request.status.status_code = IPP_OK;
 
-    printer->deny_users = 1;
-    if (attr->value_tag == IPP_TAG_NAME &&
-        (attr->num_values > 1 ||
-        strcmp(attr->values[0].string.text, "none")))
-      for (i = 0; i < attr->num_values; i ++)
-       cupsdAddPrinterUser(printer, attr->values[i].string.text);
-  }
-  if ((attr = ippFindAttribute(con->request, "job-quota-period",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-quota-period to %d...",
-               attr->values[0].integer);
-    cupsdFreeQuotas(printer);
-    printer->quota_period = attr->values[0].integer;
-  }
-  if ((attr = ippFindAttribute(con->request, "job-k-limit",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-k-limit to %d...",
-               attr->values[0].integer);
-    cupsdFreeQuotas(printer);
-    printer->k_limit = attr->values[0].integer;
-  }
-  if ((attr = ippFindAttribute(con->request, "job-page-limit",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-page-limit to %d...",
-               attr->values[0].integer);
-    cupsdFreeQuotas(printer);
-    printer->page_limit = attr->values[0].integer;
-  }
-  if ((attr = ippFindAttribute(con->request, "printer-op-policy",
-                               IPP_TAG_NAME)) != NULL)
-  {
-    cupsd_policy_t *p;                 /* Policy */
+ /*
+  * Add any job subscriptions...
+  */
 
+  add_job_subscriptions(con, job);
 
-    if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "Setting printer-op-policy to \"%s\"...",
-                      attr->values[0].string.text);
-      cupsdSetString(&printer->op_policy, attr->values[0].string.text);
-      printer->op_policy_ptr = p;
-    }
-    else
-    {
-      send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Unknown printer-op-policy \"%s\"."),
-                      attr->values[0].string.text);
-      return;
-    }
-  }
-  if ((attr = ippFindAttribute(con->request, "printer-error-policy",
-                               IPP_TAG_NAME)) != NULL)
-  {
-    if (strcmp(attr->values[0].string.text, "abort-job") &&
-        strcmp(attr->values[0].string.text, "retry-job") &&
-        strcmp(attr->values[0].string.text, "stop-printer"))
-    {
-      send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Unknown printer-error-policy \"%s\"."),
-                      attr->values[0].string.text);
-      return;
-    }
+ /*
+  * Set all but the first two attributes to the job attributes group...
+  */
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "Setting printer-error-policy to \"%s\"...",
-                    attr->values[0].string.text);
-    cupsdSetString(&printer->error_policy, attr->values[0].string.text);
-  }
+  for (attr = job->attrs->attrs->next->next; attr; attr = attr->next)
+    attr->group_tag = IPP_TAG_JOB;
 
  /*
-  * See if we have all required attributes...
+  * Fire the "job created" event...
   */
 
-  if (!printer->device_uri)
-    cupsdSetString(&printer->device_uri, "file:///dev/null");
+  cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created.");
 
  /*
-  * See if we have an interface script or PPD file attached to the request...
+  * Return the new job...
   */
 
-  if (con->filename)
-  {
-    need_restart_job = 1;
-
-    strlcpy(srcfile, con->filename, sizeof(srcfile));
+  return (job);
+}
 
-    if ((fp = cupsFileOpen(srcfile, "rb")))
-    {
-     /*
-      * Yes; get the first line from it...
-      */
 
-      line[0] = '\0';
-      cupsFileGets(fp, line, sizeof(line));
-      cupsFileClose(fp);
+/*
+ * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based
+ *                             upon the job and printer state...
+ */
 
-     /*
-      * Then see what kind of file it is...
-      */
+static void
+add_job_state_reasons(
+    cupsd_client_t *con,               /* I - Client connection */
+    cupsd_job_t    *job)               /* I - Job info */
+{
+  cupsd_printer_t      *dest;          /* Destination printer */
 
-      snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
-               printer->name);
 
-      if (!strncmp(line, "*PPD-Adobe", 10))
-      {
-       /*
-       * The new file is a PPD file, so remove any old interface script
-       * that might be lying around...
-       */
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job_state_reasons(%p[%d], %d)",
+                  con, con->http.fd, job ? job->id : 0);
 
-       unlink(dstfile);
-      }
-      else
-      {
-       /*
-       * This must be an interface script, so move the file over to the
-       * interfaces directory and make it executable...
-       */
-
-       if (copy_file(srcfile, dstfile))
-       {
-          send_ipp_status(con, IPP_INTERNAL_ERROR,
-                         _("Unable to copy interface script - %s!"),
-                         strerror(errno));
-         return;
-       }
-       else
-       {
-          cupsdLogMessage(CUPSD_LOG_DEBUG,
-                         "Copied interface script successfully!");
-          chmod(dstfile, 0755);
-       }
-      }
-
-      snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
-               printer->name);
-
-      if (!strncmp(line, "*PPD-Adobe", 10))
-      {
-       /*
-       * The new file is a PPD file, so move the file over to the
-       * ppd directory and make it readable by all...
-       */
-
-       if (copy_file(srcfile, dstfile))
-       {
-          send_ipp_status(con, IPP_INTERNAL_ERROR,
-                         _("Unable to copy PPD file - %s!"),
-                         strerror(errno));
-         return;
-       }
-       else
-       {
-          cupsdLogMessage(CUPSD_LOG_DEBUG,
-                         "Copied PPD file successfully!");
-          chmod(dstfile, 0644);
-       }
-      }
-      else
-      {
-       /*
-       * This must be an interface script, so remove any old PPD file that
-       * may be lying around...
-       */
-
-       unlink(dstfile);
-      }
-    }
-  }
-  else if ((attr = ippFindAttribute(con->request, "ppd-name",
-                                    IPP_TAG_NAME)) != NULL)
-  {
-    need_restart_job = 1;
-
-    if (!strcmp(attr->values[0].string.text, "raw"))
-    {
-     /*
-      * Raw driver, remove any existing PPD or interface script files.
-      */
-
-      snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
-               printer->name);
-      unlink(dstfile);
-
-      snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
-               printer->name);
-      unlink(dstfile);
-    }
-    else
-    {
-     /*
-      * PPD model file...
-      */
-
-      snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
-               printer->name);
-      unlink(dstfile);
-
-      snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
-               printer->name);
-
-      if (copy_model(con, attr->values[0].string.text, dstfile))
-      {
-        send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file!"));
-       return;
-      }
-      else
-      {
-        cupsdLogMessage(CUPSD_LOG_DEBUG,
-                       "Copied PPD file successfully!");
-        chmod(dstfile, 0644);
-      }
-    }
-  }
-
- /*
-  * Update the printer attributes and return...
-  */
-
-  cupsdSetPrinterAttrs(printer);
-  cupsdSaveAllPrinters();
-
-  if (need_restart_job && printer->job)
+  switch (job ? job->state_value : IPP_JOB_CANCELLED)
   {
-    cupsd_job_t *job;
-
-   /*
-    * Stop the current job and then restart it below...
-    */
-
-    job = (cupsd_job_t *)printer->job;
-
-    cupsdStopJob(job, 1);
+    case IPP_JOB_PENDING :
+        if (job->dtype & CUPS_PRINTER_CLASS)
+         dest = cupsdFindClass(job->dest);
+       else
+         dest = cupsdFindPrinter(job->dest);
 
-    job->state->values[0].integer = IPP_JOB_PENDING;
-    job->state_value              = IPP_JOB_PENDING;
-  }
+        if (dest && dest->state == IPP_PRINTER_STOPPED)
+          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                      "job-state-reasons", NULL, "printer-stopped");
+        else
+          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                      "job-state-reasons", NULL, "none");
+        break;
 
-  if (need_restart_job)
-    cupsdCheckJobs();
+    case IPP_JOB_HELD :
+        if (ippFindAttribute(job->attrs, "job-hold-until",
+                            IPP_TAG_KEYWORD) != NULL ||
+           ippFindAttribute(job->attrs, "job-hold-until",
+                            IPP_TAG_NAME) != NULL)
+          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                      "job-state-reasons", NULL, "job-hold-until-specified");
+        else
+          ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                      "job-state-reasons", NULL, "job-incoming");
+        break;
 
-  cupsdWritePrintcap();
+    case IPP_JOB_PROCESSING :
+        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                    "job-state-reasons", NULL, "job-printing");
+        break;
 
-  if (modify)
-  {
-    cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL,
-                  "Printer \"%s\" modified by \"%s\".", printer->name,
-                 get_username(con));
+    case IPP_JOB_STOPPED :
+        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                    "job-state-reasons", NULL, "job-stopped");
+        break;
 
-    cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" modified by \"%s\".",
-                    printer->name, get_username(con));
-  }
-  else
-  {
-    cupsdAddPrinterHistory(printer);
+    case IPP_JOB_CANCELLED :
+        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                    "job-state-reasons", NULL, "job-canceled-by-user");
+        break;
 
-    cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, printer, NULL,
-                  "New printer \"%s\" added by \"%s\".", printer->name,
-                 get_username(con));
+    case IPP_JOB_ABORTED :
+        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                    "job-state-reasons", NULL, "aborted-by-system");
+        break;
 
-    cupsdLogMessage(CUPSD_LOG_INFO, "New printer \"%s\" added by \"%s\".",
-                    printer->name, get_username(con));
+    case IPP_JOB_COMPLETED :
+        ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+                    "job-state-reasons", NULL, "job-completed-successfully");
+        break;
   }
-
-  con->response->request.status.status_code = IPP_OK;
 }
 
 
 /*
- * 'add_printer_state_reasons()' - Add the "printer-state-reasons" attribute
- *                                 based upon the printer state...
+ * 'add_job_subscriptions()' - Add any subcriptions for a job.
  */
 
 static void
-add_printer_state_reasons(
-    cupsd_client_t  *con,              /* I - Client connection */
-    cupsd_printer_t *p)                        /* I - Printer info */
+add_job_subscriptions(
+    cupsd_client_t *con,               /* I - Client connection */
+    cupsd_job_t    *job)               /* I - Newly created job */
 {
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "add_printer_state_reasons(%p[%d], %p[%s])",
-                  con, con->http.fd, p, p->name);
-
-  if (p->num_reasons == 0)
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                 "printer-state-reasons", NULL,
-                p->state == IPP_PRINTER_STOPPED ? "paused" : "none");
-  else
-    ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                  "printer-state-reasons", p->num_reasons, NULL,
-                 (const char * const *)p->reasons);
-}
-
-
-/*
- * 'add_queued_job_count()' - Add the "queued-job-count" attribute for
- *                            the specified printer or class.
- */
+  int                  i;              /* Looping var */
+  ipp_attribute_t      *prev,          /* Previous attribute */
+                       *next,          /* Next attribute */
+                       *attr;          /* Current attribute */
+  cupsd_subscription_t *sub;           /* Subscription object */
+  const char           *recipient,     /* notify-recipient-uri */
+                       *pullmethod;    /* notify-pull-method */
+  ipp_attribute_t      *user_data;     /* notify-user-data */
+  int                  interval;       /* notify-time-interval */
+  unsigned             mask;           /* notify-events */
 
-static void
-add_queued_job_count(
-    cupsd_client_t  *con,              /* I - Client connection */
-    cupsd_printer_t *p)                        /* I - Printer or class */
-{
-  int          count;                  /* Number of jobs on destination */
 
+ /*
+  * Find the first subscription group attribute; return if we have
+  * none...
+  */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])",
-                  con, con->http.fd, p, p->name);
+  for (attr = job->attrs->attrs, prev = NULL;
+       attr;
+       prev = attr, attr = attr->next)
+    if (attr->group_tag == IPP_TAG_SUBSCRIPTION)
+      break;
 
-  count = cupsdGetPrinterJobCount(p->name);
+  if (!attr)
+    return;
 
-  ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                "queued-job-count", count);
-}
+ /*
+  * Process the subscription attributes in the request...
+  */
 
+  while (attr)
+  {
+    recipient = NULL;
+    pullmethod = NULL;
+    user_data  = NULL;
+    interval   = 0;
+    mask       = CUPSD_EVENT_NONE;
 
-/*
- * 'authenticate_job()' - Set job authentication info.
- */
+    while (attr && attr->group_tag != IPP_TAG_ZERO)
+    {
+      if (!strcmp(attr->name, "notify-recipient") &&
+          attr->value_tag == IPP_TAG_URI)
+        recipient = attr->values[0].string.text;
+      else if (!strcmp(attr->name, "notify-pull-method") &&
+               attr->value_tag == IPP_TAG_KEYWORD)
+        pullmethod = attr->values[0].string.text;
+      else if (!strcmp(attr->name, "notify-charset") &&
+               attr->value_tag == IPP_TAG_CHARSET &&
+              strcmp(attr->values[0].string.text, "us-ascii") &&
+              strcmp(attr->values[0].string.text, "utf-8"))
+      {
+        send_ipp_status(con, IPP_CHARSET,
+                       _("Character set \"%s\" not supported!"),
+                       attr->values[0].string.text);
+       return;
+      }
+      else if (!strcmp(attr->name, "notify-natural-language") &&
+               (attr->value_tag != IPP_TAG_LANGUAGE ||
+               strcmp(attr->values[0].string.text, DefaultLanguage)))
+      {
+        send_ipp_status(con, IPP_CHARSET,
+                       _("Language \"%s\" not supported!"),
+                       attr->values[0].string.text);
+       return;
+      }
+      else if (!strcmp(attr->name, "notify-user-data") &&
+               attr->value_tag == IPP_TAG_STRING)
+      {
+        if (attr->num_values > 1 || attr->values[0].unknown.length > 63)
+       {
+          send_ipp_status(con, IPP_REQUEST_VALUE,
+                         _("The notify-user-data value is too large "
+                           "(%d > 63 octets)!"),
+                         attr->values[0].unknown.length);
+         return;
+       }
 
-static void
-authenticate_job(cupsd_client_t  *con, /* I - Client connection */
-                ipp_attribute_t *uri)  /* I - Job URI */
-{
-  ipp_attribute_t      *attr;          /* Job-id attribute */
-  int                  jobid;          /* Job ID */
-  cupsd_job_t          *job;           /* Current job */
-  char                 method[HTTP_MAX_URI],
-                                       /* Method portion of URI */
-                       username[HTTP_MAX_URI],
-                                       /* Username portion of URI */
-                       host[HTTP_MAX_URI],
-                                       /* Host portion of URI */
-                       resource[HTTP_MAX_URI];
-                                       /* Resource portion of URI */
-  int                  port;           /* Port portion of URI */
+        user_data = attr;
+      }
+      else if (!strcmp(attr->name, "notify-events") &&
+               attr->value_tag == IPP_TAG_KEYWORD)
+      {
+        for (i = 0; i < attr->num_values; i ++)
+         mask |= cupsdEventValue(attr->values[i].string.text);
+      }
+      else if (!strcmp(attr->name, "notify-lease-duration"))
+      {
+        send_ipp_status(con, IPP_BAD_REQUEST,
+                       _("The notify-lease-duration attribute cannot be "
+                         "used with job subscriptions."));
+       return;
+      }
+      else if (!strcmp(attr->name, "notify-time-interval") &&
+               attr->value_tag == IPP_TAG_INTEGER)
+        interval = attr->values[0].integer;
 
+      attr = attr->next;
+    }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)",
-                  con, con->http.fd, uri->values[0].string.text);
+    if (!recipient && !pullmethod)
+      break;
 
- /*
-  * Start with "everything is OK" status...
-  */
+    if (mask == CUPSD_EVENT_NONE)
+      mask = CUPSD_EVENT_JOB_COMPLETED;
 
-  con->response->request.status.status_code = IPP_OK;
+    sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, recipient,
+                               0);
 
- /*
-  * See if we have a job URI or a printer URI...
-  */
+    sub->interval = interval;
 
-  if (!strcmp(uri->name, "printer-uri"))
-  {
-   /*
-    * Got a printer URI; see if we also have a job-id attribute...
-    */
+    cupsdSetString(&sub->owner, job->username);
 
-    if ((attr = ippFindAttribute(con->request, "job-id",
-                                 IPP_TAG_INTEGER)) == NULL)
+    if (user_data)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id!"));
-      return;
+      sub->user_data_len = user_data->values[0].unknown.length;
+      memcpy(sub->user_data, user_data->values[0].unknown.data,
+             sub->user_data_len);
     }
 
-    jobid = attr->values[0].integer;
-  }
-  else
-  {
-   /*
-    * Got a job URI; parse it to get the job ID...
-    */
-
-    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                    sizeof(method), username, sizeof(username), host,
-                   sizeof(host), &port, resource, sizeof(resource));
-    if (strncmp(resource, "/jobs/", 6))
-    {
-     /*
-      * Not a valid URI!
-      */
-
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\"!"),
-                      uri->values[0].string.text);
-      return;
-    }
+    ippAddSeparator(con->response);
+    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+                  "notify-subscription-id", sub->id);
 
-    jobid = atoi(resource + 6);
+    if (attr)
+      attr = attr->next;
   }
 
+  cupsdSaveAllSubscriptions();
+
  /*
-  * See if the job exists...
+  * Remove all of the subscription attributes from the job request...
   */
 
-  if ((job = cupsdFindJob(jobid)) == NULL)
+  for (attr = job->attrs->attrs, prev = NULL; attr; attr = next)
   {
-   /*
-    * Nope - return a "not found" error...
-    */
-
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("Job #%d does not exist!"), jobid);
-    return;
-  }
+    next = attr->next;
 
- /*
-  * See if the job has been completed...
-  */
+    if (attr->group_tag == IPP_TAG_SUBSCRIPTION ||
+        attr->group_tag == IPP_TAG_ZERO)
+    {
+     /*
+      * Free and remove this attribute...
+      */
 
-  if (job->state_value != IPP_JOB_HELD)
-  {
-   /*
-    * Return a "not-possible" error...
-    */
+      _ipp_free_attr(attr);
 
-    send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d is not held for authentication!"),
-                   jobid);
-    return;
+      if (prev)
+        prev->next = next;
+      else
+        job->attrs->attrs = next;
+    }
+    else
+      prev = attr;
   }
 
- /*
-  * See if we have already authenticated...
-  */
+  job->attrs->last    = prev;
+  job->attrs->current = prev;
+}
 
-  if (!con->username[0])
-  {
-    send_ipp_status(con, IPP_NOT_AUTHORIZED,
-                    _("No authentication information provided!"));
-    return;
-  }
 
- /*
-  * See if the job is owned by the requesting user...
-  */
+/*
+ * 'add_job_uuid()' - Add job-uuid attribute to a job.
+ *
+ * See RFC 4122 for the definition of UUIDs and the format.
+ */
+
+static void
+add_job_uuid(cupsd_client_t *con,      /* I - Client connection */
+             cupsd_job_t    *job)      /* I - Job */
+{
+  char                 uuid[1024];     /* job-uuid string */
+  ipp_attribute_t      *attr;          /* job-uuid attribute */
+  _cups_md5_state_t    md5state;       /* MD5 state */
+  unsigned char                md5sum[16];     /* MD5 digest/sum */
 
-  if (!validate_user(job, con, job->username, username, sizeof(username)))
-  {
-    send_http_error(con, HTTP_UNAUTHORIZED);
-    return;
-  }
 
  /*
-  * Save the authentication information for this job...
+  * First see if the job already has a job-uuid attribute; if so, return...
   */
 
-  save_auth_info(con, job);
+  if ((attr = ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI)) != NULL)
+    return;
 
  /*
-  * Reset the job-hold-until value to "no-hold"...
+  * No job-uuid attribute, so build a version 3 UUID with the local job
+  * ID at the end; see RFC 4122 for details.  Start with the MD5 sum of
+  * the ServerName, server name and port that the client connected to,
+  * and local job ID...
   */
 
-  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
-                               IPP_TAG_KEYWORD)) == NULL)
-    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+  snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername,
+          con->serverport, job->id);
 
-  if (attr)
-  {
-    attr->value_tag = IPP_TAG_KEYWORD;
-    cupsdSetString(&(attr->values[0].string.text), "no-hold");
-  }
+  _cups_md5_init(&md5state);
+  _cups_md5_append(&md5state, (unsigned char *)uuid, strlen(uuid));
+  _cups_md5_finish(&md5state, md5sum);
 
  /*
-  * Release the job and return...
+  * Format the UUID URI using the MD5 sum and job ID.
   */
 
-  cupsdReleaseJob(job);
+  snprintf(uuid, sizeof(uuid),
+           "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]);
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was authenticated by \"%s\".", jobid,
-                  con->username);
+  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid);
 }
 
 
 /*
- * 'cancel_all_jobs()' - Cancel all print jobs.
+ * 'add_printer()' - Add a printer to the system.
  */
 
 static void
-cancel_all_jobs(cupsd_client_t  *con,  /* I - Client connection */
-               ipp_attribute_t *uri)   /* I - Job or Printer URI */
+add_printer(cupsd_client_t  *con,      /* I - Client connection */
+            ipp_attribute_t *uri)      /* I - URI of printer */
 {
   http_status_t        status;                 /* Policy status */
-  const char   *dest;                  /* Destination */
-  cups_ptype_t dtype;                  /* Destination type */
+  int          i;                      /* Looping var */
   char         method[HTTP_MAX_URI],   /* Method portion of URI */
-               userpass[HTTP_MAX_URI], /* Username portion of URI */
+               username[HTTP_MAX_URI], /* Username portion of URI */
                host[HTTP_MAX_URI],     /* Host portion of URI */
                resource[HTTP_MAX_URI]; /* Resource portion of URI */
   int          port;                   /* Port portion of URI */
-  ipp_attribute_t *attr;               /* Attribute in request */
-  const char   *username;              /* Username */
-  int          purge;                  /* Purge? */
-  cupsd_printer_t *printer;            /* Printer */
+  cupsd_printer_t *printer;            /* Printer/class */
+  ipp_attribute_t *attr;               /* Printer attribute */
+  cups_file_t  *fp;                    /* Script/PPD file */
+  char         line[1024];             /* Line from file... */
+  char         srcfile[1024],          /* Source Script/PPD file */
+               dstfile[1024];          /* Destination Script/PPD file */
+  int          modify;                 /* Non-zero if we are modifying */
+  char         newname[IPP_MAX_NAME];  /* New printer name */
+  int          need_restart_job;       /* Need to restart job? */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con,
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con,
                   con->http.fd, uri->values[0].string.text);
 
  /*
-  * See if we have a printer URI...
+  * Do we have a valid URI?
   */
 
-  if (strcmp(uri->name, "printer-uri"))
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                  sizeof(method), username, sizeof(username), host,
+                 sizeof(host), &port, resource, sizeof(resource));
+
+  if (strncmp(resource, "/printers/", 10) || strlen(resource) == 10)
   {
+   /*
+    * No, return an error...
+    */
+
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("The printer-uri attribute is required!"));
+                    _("The printer-uri must be of the form "
+                     "\"ipp://HOSTNAME/printers/PRINTERNAME\"."));
     return;
   }
 
  /*
-  * Get the username (if any) for the jobs we want to cancel (only if
-  * "my-jobs" is specified...
+  * Do we have a valid printer name?
   */
 
-  if ((attr = ippFindAttribute(con->request, "my-jobs",
-                               IPP_TAG_BOOLEAN)) != NULL &&
-      attr->values[0].boolean)
+  if (!validate_name(resource + 10))
   {
-    if ((attr = ippFindAttribute(con->request, "requesting-user-name",
-                                 IPP_TAG_NAME)) != NULL)
-      username = attr->values[0].string.text;
-    else
-    {
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Missing requesting-user-name attribute!"));
-      return;
-    }
+   /*
+    * No, return an error...
+    */
+
+    send_ipp_status(con, IPP_BAD_REQUEST,
+                    _("The printer-uri \"%s\" contains invalid characters."),
+                   uri->values[0].string.text);
+    return;
   }
-  else
-    username = NULL;
 
  /*
-  * Look for the "purge-jobs" attribute...
+  * Check policy...
   */
 
-  if ((attr = ippFindAttribute(con->request, "purge-jobs",
-                               IPP_TAG_BOOLEAN)) != NULL)
-    purge = attr->values[0].boolean;
-  else
-    purge = 1;
+  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+  {
+    send_http_error(con, status);
+    return;
+  }
 
  /*
-  * And if the destination is valid...
-  */
-
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), userpass, sizeof(userpass), host,
-                 sizeof(host), &port, resource, sizeof(resource));
+  * See if the printer already exists; if not, create a new printer...
+  */
 
-  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
+  if ((printer = cupsdFindPrinter(resource + 10)) == NULL)
   {
    /*
-    * Bad URI?
+    * Printer doesn't exist; see if we have a class of the same name...
     */
 
-    if ((!strncmp(resource, "/printers/", 10) && resource[10]) ||
-        (!strncmp(resource, "/classes/", 9) && resource[9]))
-    {
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("The printer or class was not found."));
-      return;
-    }
-    else if (strcmp(resource, "/printers/"))
+    if ((printer = cupsdFindClass(resource + 10)) != NULL &&
+        !(printer->type & CUPS_PRINTER_REMOTE))
     {
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("The printer-uri \"%s\" is not valid."),
-                     uri->values[0].string.text);
-      return;
-    }
-
-   /*
-    * Check policy...
-    */
+     /*
+      * Yes, return an error...
+      */
 
-    if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
-    {
-      send_http_error(con, status);
+      send_ipp_status(con, IPP_NOT_POSSIBLE,
+                      _("A class named \"%s\" already exists!"),
+                     resource + 10);
       return;
     }
 
    /*
-    * Cancel all jobs on all printers...
+    * No, add the printer...
     */
 
-    cupsdCancelJobs(NULL, username, purge);
-
-    cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".",
-                    purge ? "purged" : "cancelled", get_username(con));
+    printer = cupsdAddPrinter(resource + 10);
+    modify  = 0;
   }
-  else
+  else if (printer->type & CUPS_PRINTER_IMPLICIT)
   {
    /*
-    * Check policy...
+    * Rename the implicit printer to "AnyPrinter" or delete it...
     */
 
-    if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
+    if (ImplicitAnyClasses)
     {
-      send_http_error(con, status);
-      return;
+      snprintf(newname, sizeof(newname), "Any%s", resource + 10);
+      cupsdRenamePrinter(printer, newname);
     }
+    else
+      cupsdDeletePrinter(printer, 1);
 
    /*
-    * Cancel all of the jobs on the named printer...
+    * Add the printer as a new local printer...
     */
 
-    cupsdCancelJobs(dest, username, purge);
-
-    cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".",
-                    dest, purge ? "purged" : "cancelled", get_username(con));
+    printer = cupsdAddPrinter(resource + 10);
+    modify  = 0;
   }
+  else if (printer->type & CUPS_PRINTER_REMOTE)
+  {
+   /*
+    * Rename the remote printer to "Printer@server"...
+    */
 
-  con->response->request.status.status_code = IPP_OK;
-}
+    snprintf(newname, sizeof(newname), "%s@%s", resource + 10,
+             printer->hostname);
+    cupsdRenamePrinter(printer, newname);
 
+   /*
+    * Add the printer as a new local printer...
+    */
 
-/*
- * 'cancel_job()' - Cancel a print job.
- */
+    printer = cupsdAddPrinter(resource + 10);
+    modify  = 0;
+  }
+  else
+    modify = 1;
 
-static void
-cancel_job(cupsd_client_t  *con,       /* I - Client connection */
-          ipp_attribute_t *uri)        /* I - Job or Printer URI */
-{
-  ipp_attribute_t *attr;               /* Current attribute */
-  int          jobid;                  /* Job ID */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
-               host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI]; /* Resource portion of URI */
-  int          port;                   /* Port portion of URI */
-  cupsd_job_t  *job;                   /* Job information */
-  const char   *dest;                  /* Destination */
-  cups_ptype_t dtype;                  /* Destination type (printer or class) */
-  cupsd_printer_t *printer;            /* Printer data */
+ /*
+  * Look for attributes and copy them over as needed...
+  */
 
+  need_restart_job = 0;
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con,
-                  con->http.fd, uri->values[0].string.text);
+  if ((attr = ippFindAttribute(con->request, "printer-location",
+                               IPP_TAG_TEXT)) != NULL)
+    cupsdSetString(&printer->location, attr->values[0].string.text);
 
- /*
-  * See if we have a job URI or a printer URI...
-  */
+  if ((attr = ippFindAttribute(con->request, "printer-info",
+                               IPP_TAG_TEXT)) != NULL)
+    cupsdSetString(&printer->info, attr->values[0].string.text);
 
-  if (!strcmp(uri->name, "printer-uri"))
+  if ((attr = ippFindAttribute(con->request, "device-uri",
+                               IPP_TAG_URI)) != NULL)
   {
    /*
-    * Got a printer URI; see if we also have a job-id attribute...
+    * Do we have a valid device URI?
     */
 
-    if ((attr = ippFindAttribute(con->request, "job-id",
-                                 IPP_TAG_INTEGER)) == NULL)
-    {
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id!"));
-      return;
-    }
+    need_restart_job = 1;
 
-    if ((jobid = attr->values[0].integer) == 0)
+    httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method,
+                    sizeof(method), username, sizeof(username), host,
+                   sizeof(host), &port, resource, sizeof(resource));
+
+    if (!strcmp(method, "file"))
     {
      /*
-      * Find the current job on the specified printer...
+      * See if the administrator has enabled file devices...
       */
 
-      httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                      sizeof(method), username, sizeof(username), host,
-                     sizeof(host), &port, resource, sizeof(resource));
-
-      if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
+      if (!FileDevice && strcmp(resource, "/dev/null"))
       {
        /*
-       * Bad URI...
+        * File devices are disabled and the URL is not file:/dev/null...
        */
 
-       send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+       send_ipp_status(con, IPP_NOT_POSSIBLE,
+                       _("File device URIs have been disabled! "
+                         "To enable, see the FileDevice directive in "
+                         "\"%s/cupsd.conf\"."),
+                       ServerRoot);
        return;
       }
-
+    }
+    else
+    {
      /*
-      * See if the printer is currently printing a job...
+      * See if the backend exists and is executable...
       */
 
-      if (printer->job)
-        jobid = ((cupsd_job_t *)printer->job)->id;
-      else
+      snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin, method);
+      if (access(srcfile, X_OK))
       {
        /*
-        * No, see if there are any pending jobs...
+        * Could not find device in list!
        */
-        
-        for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
-            job;
-            job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
-         if (job->state_value <= IPP_JOB_PROCESSING &&
-             !strcasecmp(job->dest, dest))
-           break;
 
-       if (job)
-         jobid = job->id;
-       else
-       {
-         send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"),
-                         dest);
-         return;
-       }
+       send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"!"),
+                       attr->values[0].string.text);
+       return;
       }
     }
-  }
-  else
-  {
-   /*
-    * Got a job URI; parse it to get the job ID...
-    */
-
-    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                    sizeof(method), username, sizeof(username), host,
-                   sizeof(host), &port, resource, sizeof(resource));
-    if (strncmp(resource, "/jobs/", 6))
-    {
-     /*
-      * Not a valid URI!
-      */
-
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\"!"),
-                      uri->values[0].string.text);
-      return;
-    }
-
-    jobid = atoi(resource + 6);
-  }
-
- /*
-  * See if the job exists...
-  */
-
-  if ((job = cupsdFindJob(jobid)) == NULL)
-  {
-   /*
-    * Nope - return a "not found" error...
-    */
-
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
-    return;
-  }
 
- /*
-  * See if the job is owned by the requesting user...
-  */
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Setting %s device-uri to \"%s\" (was \"%s\".)",
+                   printer->name,
+                   cupsdSanitizeURI(attr->values[0].string.text, line,
+                                    sizeof(line)),
+                   cupsdSanitizeURI(printer->device_uri, resource,
+                                    sizeof(resource)));
 
-  if (!validate_user(job, con, job->username, username, sizeof(username)))
-  {
-    send_http_error(con, HTTP_UNAUTHORIZED);
-    return;
+    cupsdSetString(&printer->device_uri, attr->values[0].string.text);
   }
 
- /*
-  * See if the job is already completed, cancelled, or aborted; if so,
-  * we can't cancel...
-  */
-
-  if (job->state_value >= IPP_JOB_CANCELLED)
+  if ((attr = ippFindAttribute(con->request, "port-monitor",
+                               IPP_TAG_KEYWORD)) != NULL)
   {
-    send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d is already %s - can\'t cancel."), jobid,
-                   job->state_value == IPP_JOB_CANCELLED ? "cancelled" :
-                   job->state_value == IPP_JOB_ABORTED ? "aborted" :
-                   "completed");
-    return;
-  }
+    ipp_attribute_t    *supported;     /* port-monitor-supported attribute */
 
- /*
-  * Cancel the job and return...
-  */
 
-  cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job,
-                "Job cancelled by \"%s\".", username);
+    need_restart_job = 1;
 
-  cupsdCancelJob(job, 0);
-  cupsdCheckJobs();
+    supported = ippFindAttribute(printer->attrs, "port-monitor-supported",
+                                 IPP_TAG_KEYWORD);
+    for (i = 0; i < supported->num_values; i ++)
+      if (!strcmp(supported->values[i].string.text,
+                  attr->values[0].string.text))
+        break;
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was cancelled by \"%s\".", jobid,
-                  username);
+    if (i >= supported->num_values)
+    {
+      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"),
+                     attr->values[0].string.text);
+      return;
+    }
 
-  con->response->request.status.status_code = IPP_OK;
-}
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Setting %s port-monitor to \"%s\" (was \"%s\".)",
+                    printer->name, attr->values[0].string.text,
+                   printer->port_monitor);
 
+    if (strcmp(attr->values[0].string.text, "none"))
+      cupsdSetString(&printer->port_monitor, attr->values[0].string.text);
+    else
+      cupsdClearString(&printer->port_monitor);
+  }
 
-/*
- * 'cancel_subscription()' - Cancel a subscription.
- */
+  if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs",
+                               IPP_TAG_BOOLEAN)) != NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Setting %s printer-is-accepting-jobs to %d (was %d.)",
+                    printer->name, attr->values[0].boolean, printer->accepting);
 
-static void
-cancel_subscription(
-    cupsd_client_t *con,               /* I - Client connection */
-    int            sub_id)             /* I - Subscription ID */
-{
-  http_status_t                status;         /* Policy status */
-  cupsd_subscription_t *sub;           /* Subscription */
+    printer->accepting = attr->values[0].boolean;
+    cupsdAddPrinterHistory(printer);
+  }
 
+  if ((attr = ippFindAttribute(con->request, "printer-is-shared",
+                               IPP_TAG_BOOLEAN)) != NULL)
+  {
+    if (printer->shared && !attr->values[0].boolean)
+      cupsdSendBrowseDelete(printer);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "cancel_subscription(con=%p[%d], sub_id=%d)",
-                  con, con->http.fd, sub_id);
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Setting %s printer-is-shared to %d (was %d.)",
+                    printer->name, attr->values[0].boolean, printer->shared);
 
- /*
-  * Is the subscription ID valid?
-  */
+    printer->shared = attr->values[0].boolean;
+  }
 
-  if ((sub = cupsdFindSubscription(sub_id)) == NULL)
+  if ((attr = ippFindAttribute(con->request, "printer-state",
+                               IPP_TAG_ENUM)) != NULL)
   {
-   /*
-    * Bad subscription ID...
-    */
+    if (attr->values[0].integer != IPP_PRINTER_IDLE &&
+        attr->values[0].integer != IPP_PRINTER_STOPPED)
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d!"),
+                      attr->values[0].integer);
+      return;
+    }
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good!"), sub_id);
-    return;
+    cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-state to %d (was %d.)", printer->name,
+               attr->values[0].integer, printer->state);
+
+    if (attr->values[0].integer == IPP_PRINTER_STOPPED)
+      cupsdStopPrinter(printer, 0);
+    else
+    {
+      need_restart_job = 1;
+      cupsdSetPrinterState(printer, (ipp_pstate_t)(attr->values[0].integer), 0);
+    }
+  }
+  if ((attr = ippFindAttribute(con->request, "printer-state-message",
+                               IPP_TAG_TEXT)) != NULL)
+  {
+    strlcpy(printer->state_message, attr->values[0].string.text,
+            sizeof(printer->state_message));
+    cupsdAddPrinterHistory(printer);
   }
 
+  set_printer_defaults(con, printer);
+
  /*
-  * Check policy...
+  * See if we have all required attributes...
   */
 
-  if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr :
-                                             DefaultPolicyPtr,
-                                 con, sub->owner)) != HTTP_OK)
-  {
-    send_http_error(con, status);
-    return;
-  }
+  if (!printer->device_uri)
+    cupsdSetString(&printer->device_uri, "file:///dev/null");
 
  /*
-  * Cancel the subscription...
+  * See if we have an interface script or PPD file attached to the request...
   */
 
-  cupsdDeleteSubscription(sub, 1);
+  if (con->filename)
+  {
+    need_restart_job = 1;
 
-  con->response->request.status.status_code = IPP_OK;
-}
+    strlcpy(srcfile, con->filename, sizeof(srcfile));
 
+    if ((fp = cupsFileOpen(srcfile, "rb")))
+    {
+     /*
+      * Yes; get the first line from it...
+      */
 
-/*
- * 'check_quotas()' - Check quotas for a printer and user.
- */
+      line[0] = '\0';
+      cupsFileGets(fp, line, sizeof(line));
+      cupsFileClose(fp);
 
-static int                             /* O - 1 if OK, 0 if not */
-check_quotas(cupsd_client_t  *con,     /* I - Client connection */
-             cupsd_printer_t *p)       /* I - Printer or class */
-{
-  int          i;                      /* Looping var */
-  char         username[33];           /* Username */
-  cupsd_quota_t        *q;                     /* Quota data */
-  struct passwd        *pw;                    /* User password data */
+     /*
+      * Then see what kind of file it is...
+      */
 
+      snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
+               printer->name);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])",
-                  con, con->http.fd, p, p->name);
+      if (!strncmp(line, "*PPD-Adobe", 10))
+      {
+       /*
+       * The new file is a PPD file, so remove any old interface script
+       * that might be lying around...
+       */
 
- /*
-  * Check input...
-  */
+       unlink(dstfile);
+      }
+      else
+      {
+       /*
+       * This must be an interface script, so move the file over to the
+       * interfaces directory and make it executable...
+       */
 
-  if (!con || !p)
-    return (0);
+       if (copy_file(srcfile, dstfile))
+       {
+          send_ipp_status(con, IPP_INTERNAL_ERROR,
+                         _("Unable to copy interface script - %s!"),
+                         strerror(errno));
+         return;
+       }
+       else
+       {
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Copied interface script successfully!");
+          chmod(dstfile, 0755);
+       }
+      }
 
- /*
-  * Figure out who is printing...
-  */
+      snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
+               printer->name);
 
-  strlcpy(username, get_username(con), sizeof(username));
+      if (!strncmp(line, "*PPD-Adobe", 10))
+      {
+       /*
+       * The new file is a PPD file, so move the file over to the
+       * ppd directory and make it readable by all...
+       */
 
- /*
-  * Check global active job limits for printers and users...
-  */
+       if (copy_file(srcfile, dstfile))
+       {
+          send_ipp_status(con, IPP_INTERNAL_ERROR,
+                         _("Unable to copy PPD file - %s!"),
+                         strerror(errno));
+         return;
+       }
+       else
+       {
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Copied PPD file successfully!");
+          chmod(dstfile, 0644);
+       }
+      }
+      else
+      {
+       /*
+       * This must be an interface script, so remove any old PPD file that
+       * may be lying around...
+       */
 
-  if (MaxJobsPerPrinter)
+       unlink(dstfile);
+      }
+    }
+  }
+  else if ((attr = ippFindAttribute(con->request, "ppd-name",
+                                    IPP_TAG_NAME)) != NULL)
   {
-   /*
-    * Check if there are too many pending jobs on this printer...
-    */
+    need_restart_job = 1;
 
-    if (cupsdGetPrinterJobCount(p->name) >= MaxJobsPerPrinter)
+    if (!strcmp(attr->values[0].string.text, "raw"))
     {
-      cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for printer \"%s\"...",
-                      p->name);
-      return (0);
-    }
-  }
+     /*
+      * Raw driver, remove any existing PPD or interface script files.
+      */
 
-  if (MaxJobsPerUser)
-  {
-   /*
-    * Check if there are too many pending jobs for this user...
-    */
+      snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
+               printer->name);
+      unlink(dstfile);
 
-    if (cupsdGetUserJobCount(username) >= MaxJobsPerUser)
+      snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
+               printer->name);
+      unlink(dstfile);
+    }
+    else
     {
-      cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for user \"%s\"...",
-                      username);
-      return (0);
+     /*
+      * PPD model file...
+      */
+
+      snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
+               printer->name);
+      unlink(dstfile);
+
+      snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
+               printer->name);
+
+      if (copy_model(con, attr->values[0].string.text, dstfile))
+      {
+        send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file!"));
+       return;
+      }
+      else
+      {
+        cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "Copied PPD file successfully!");
+        chmod(dstfile, 0644);
+      }
     }
   }
 
  /*
-  * Check against users...
+  * Update the printer attributes and return...
   */
 
-  if (p->num_users == 0 && p->k_limit == 0 && p->page_limit == 0)
-    return (1);
+  cupsdSetPrinterAttrs(printer);
+  cupsdSaveAllPrinters();
 
-  if (p->num_users)
+  if (need_restart_job && printer->job)
   {
-    pw = getpwnam(username);
-    endpwent();
+    cupsd_job_t *job;
 
-    for (i = 0; i < p->num_users; i ++)
-      if (p->users[i][0] == '@')
-      {
-       /*
-        * Check group membership...
-       */
+   /*
+    * Stop the current job and then restart it below...
+    */
 
-        if (cupsdCheckGroup(username, pw, p->users[i] + 1))
-         break;
-      }
-      else if (!strcasecmp(username, p->users[i]))
-       break;
+    job = (cupsd_job_t *)printer->job;
 
-    if ((i < p->num_users) == p->deny_users)
-    {
-      cupsdLogMessage(CUPSD_LOG_INFO,
-                      "Denying user \"%s\" access to printer \"%s\"...",
-                     username, p->name);
-      return (0);
-    }
+    cupsdStopJob(job, 1);
+
+    job->state->values[0].integer = IPP_JOB_PENDING;
+    job->state_value              = IPP_JOB_PENDING;
   }
 
- /*
-  * Check quotas...
-  */
+  if (need_restart_job)
+    cupsdCheckJobs();
 
-  if (p->k_limit || p->page_limit)
+  cupsdWritePrintcap();
+
+  if (modify)
   {
-    if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL)
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to allocate quota data for user \"%s\"!",
-                      username);
-      return (0);
-    }
+    cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL,
+                  "Printer \"%s\" modified by \"%s\".", printer->name,
+                 get_username(con));
 
-    if ((q->k_count >= p->k_limit && p->k_limit) ||
-        (q->page_count >= p->page_limit && p->page_limit))
-    {
-      cupsdLogMessage(CUPSD_LOG_INFO, "User \"%s\" is over the quota limit...",
-                      username);
-      return (0);
-    }
+    cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" modified by \"%s\".",
+                    printer->name, get_username(con));
   }
+  else
+  {
+    cupsdAddPrinterHistory(printer);
 
- /*
-  * If we have gotten this far, we're done!
-  */
+    cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, printer, NULL,
+                  "New printer \"%s\" added by \"%s\".", printer->name,
+                 get_username(con));
 
-  return (1);
+    cupsdLogMessage(CUPSD_LOG_INFO, "New printer \"%s\" added by \"%s\".",
+                    printer->name, get_username(con));
+  }
+
+  con->response->request.status.status_code = IPP_OK;
 }
 
 
 /*
- * 'copy_attribute()' - Copy a single attribute.
+ * 'add_printer_state_reasons()' - Add the "printer-state-reasons" attribute
+ *                                 based upon the printer state...
  */
 
-static ipp_attribute_t *               /* O - New attribute */
-copy_attribute(
-    ipp_t           *to,               /* O - Destination request/response */
-    ipp_attribute_t *attr,             /* I - Attribute to copy */
-    int             quickcopy)         /* I - Do a quick copy? */
+static void
+add_printer_state_reasons(
+    cupsd_client_t  *con,              /* I - Client connection */
+    cupsd_printer_t *p)                        /* I - Printer info */
 {
-  int                  i;              /* Looping var */
-  ipp_attribute_t      *toattr;        /* Destination attribute */
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "add_printer_state_reasons(%p[%d], %p[%s])",
+                  con, con->http.fd, p, p->name);
 
+  if (p->num_reasons == 0)
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                 "printer-state-reasons", NULL,
+                p->state == IPP_PRINTER_STOPPED ? "paused" : "none");
+  else
+    ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                  "printer-state-reasons", p->num_reasons, NULL,
+                 (const char * const *)p->reasons);
+}
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "copy_attribute(%p, %p[%s,%x,%x])", to, attr,
-                 attr->name ? attr->name : "(null)", attr->group_tag,
-                 attr->value_tag);
 
-  switch (attr->value_tag & ~IPP_TAG_COPY)
-  {
-    case IPP_TAG_ZERO :
-        toattr = ippAddSeparator(to);
-       break;
+/*
+ * 'add_queued_job_count()' - Add the "queued-job-count" attribute for
+ *                            the specified printer or class.
+ */
 
-    case IPP_TAG_INTEGER :
-    case IPP_TAG_ENUM :
-        toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
-                               attr->name, attr->num_values, NULL);
+static void
+add_queued_job_count(
+    cupsd_client_t  *con,              /* I - Client connection */
+    cupsd_printer_t *p)                        /* I - Printer or class */
+{
+  int          count;                  /* Number of jobs on destination */
 
-        for (i = 0; i < attr->num_values; i ++)
-         toattr->values[i].integer = attr->values[i].integer;
-        break;
 
-    case IPP_TAG_BOOLEAN :
-        toattr = ippAddBooleans(to, attr->group_tag, attr->name,
-                               attr->num_values, NULL);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])",
+                  con, con->http.fd, p, p->name);
 
-        for (i = 0; i < attr->num_values; i ++)
-         toattr->values[i].boolean = attr->values[i].boolean;
-        break;
+  count = cupsdGetPrinterJobCount(p->name);
 
-    case IPP_TAG_STRING :
-    case IPP_TAG_TEXT :
-    case IPP_TAG_NAME :
-    case IPP_TAG_KEYWORD :
-    case IPP_TAG_URI :
-    case IPP_TAG_URISCHEME :
-    case IPP_TAG_CHARSET :
-    case IPP_TAG_LANGUAGE :
-    case IPP_TAG_MIMETYPE :
-        toattr = ippAddStrings(to, attr->group_tag,
-                              (ipp_tag_t)(attr->value_tag | quickcopy),
-                              attr->name, attr->num_values, NULL, NULL);
+  ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                "queued-job-count", count);
+}
 
-        if (quickcopy)
-       {
-          for (i = 0; i < attr->num_values; i ++)
-           toattr->values[i].string.text = attr->values[i].string.text;
-        }
-       else
-       {
-          for (i = 0; i < attr->num_values; i ++)
-           toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text);
-       }
-        break;
 
-    case IPP_TAG_DATE :
-        toattr = ippAddDate(to, attr->group_tag, attr->name,
-                           attr->values[0].date);
-        break;
+/*
+ * 'apply_printer_defaults()' - Apply printer default options to a job.
+ */
 
-    case IPP_TAG_RESOLUTION :
-        toattr = ippAddResolutions(to, attr->group_tag, attr->name,
-                                  attr->num_values, IPP_RES_PER_INCH,
-                                  NULL, NULL);
+static void
+apply_printer_defaults(
+    cupsd_printer_t *printer,          /* I - Printer */
+    cupsd_job_t     *job)              /* I - Job */
+{
+  int          i,                      /* Looping var */
+               num_options;            /* Number of default options */
+  cups_option_t        *options,               /* Default options */
+               *option;                /* Current option */    
 
-        for (i = 0; i < attr->num_values; i ++)
-       {
-         toattr->values[i].resolution.xres  = attr->values[i].resolution.xres;
-         toattr->values[i].resolution.yres  = attr->values[i].resolution.yres;
-         toattr->values[i].resolution.units = attr->values[i].resolution.units;
-       }
-        break;
 
-    case IPP_TAG_RANGE :
-        toattr = ippAddRanges(to, attr->group_tag, attr->name,
-                             attr->num_values, NULL, NULL);
+ /*
+  * Collect all of the default options and add the missing ones to the
+  * job object...
+  */
 
-        for (i = 0; i < attr->num_values; i ++)
-       {
-         toattr->values[i].range.lower = attr->values[i].range.lower;
-         toattr->values[i].range.upper = attr->values[i].range.upper;
-       }
-        break;
+  for (i = printer->num_options, num_options = 0, option = printer->options;
+       i > 0;
+       i --, option ++)
+    if (!ippFindAttribute(job->attrs, option->name, IPP_TAG_ZERO))
+    {
+      num_options = cupsAddOption(option->name, option->value, num_options,
+                                  &options);
+    }
 
-    case IPP_TAG_TEXTLANG :
-    case IPP_TAG_NAMELANG :
-        toattr = ippAddStrings(to, attr->group_tag,
-                              (ipp_tag_t)(attr->value_tag | quickcopy),
-                              attr->name, attr->num_values, NULL, NULL);
+ /*
+  * Encode these options as attributes in the job object...
+  */
 
-        if (quickcopy)
-       {
-          for (i = 0; i < attr->num_values; i ++)
-         {
-            toattr->values[i].string.charset = attr->values[i].string.charset;
-           toattr->values[i].string.text    = attr->values[i].string.text;
-          }
-        }
-       else
-       {
-          for (i = 0; i < attr->num_values; i ++)
-         {
-           if (!i)
-              toattr->values[i].string.charset =
-                 _cups_sp_alloc(attr->values[i].string.charset);
-           else
-              toattr->values[i].string.charset =
-                 toattr->values[0].string.charset;
+  cupsEncodeOptions2(job->attrs, num_options, options, IPP_TAG_JOB);
+  cupsFreeOptions(num_options, options);
+}
+
+
+/*
+ * 'authenticate_job()' - Set job authentication info.
+ */
+
+static void
+authenticate_job(cupsd_client_t  *con, /* I - Client connection */
+                ipp_attribute_t *uri)  /* I - Job URI */
+{
+  ipp_attribute_t      *attr;          /* Job-id attribute */
+  int                  jobid;          /* Job ID */
+  cupsd_job_t          *job;           /* Current job */
+  char                 method[HTTP_MAX_URI],
+                                       /* Method portion of URI */
+                       username[HTTP_MAX_URI],
+                                       /* Username portion of URI */
+                       host[HTTP_MAX_URI],
+                                       /* Host portion of URI */
+                       resource[HTTP_MAX_URI];
+                                       /* Resource portion of URI */
+  int                  port;           /* Port portion of URI */
 
-           toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text);
-          }
-        }
-        break;
 
-    case IPP_TAG_BEGIN_COLLECTION :
-        toattr = ippAddCollections(to, attr->group_tag, attr->name,
-                                  attr->num_values, NULL);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)",
+                  con, con->http.fd, uri->values[0].string.text);
 
-        for (i = 0; i < attr->num_values; i ++)
-       {
-         toattr->values[i].collection = ippNew();
-         copy_attrs(toattr->values[i].collection, attr->values[i].collection,
-                    NULL, IPP_TAG_ZERO, 0);
-       }
-        break;
+ /*
+  * Start with "everything is OK" status...
+  */
 
-    default :
-        toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
-                               attr->name, attr->num_values, NULL);
+  con->response->request.status.status_code = IPP_OK;
 
-        for (i = 0; i < attr->num_values; i ++)
-       {
-         toattr->values[i].unknown.length = attr->values[i].unknown.length;
+ /*
+  * See if we have a job URI or a printer URI...
+  */
 
-         if (toattr->values[i].unknown.length > 0)
-         {
-           if ((toattr->values[i].unknown.data =
-                    malloc(toattr->values[i].unknown.length)) == NULL)
-             toattr->values[i].unknown.length = 0;
-           else
-             memcpy(toattr->values[i].unknown.data,
-                    attr->values[i].unknown.data,
-                    toattr->values[i].unknown.length);
-         }
-       }
-        break; /* anti-compiler-warning-code */
-  }
+  if (!strcmp(uri->name, "printer-uri"))
+  {
+   /*
+    * Got a printer URI; see if we also have a job-id attribute...
+    */
 
-  return (toattr);
-}
+    if ((attr = ippFindAttribute(con->request, "job-id",
+                                 IPP_TAG_INTEGER)) == NULL)
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Got a printer-uri attribute but no job-id!"));
+      return;
+    }
+
+    jobid = attr->values[0].integer;
+  }
+  else
+  {
+   /*
+    * Got a job URI; parse it to get the job ID...
+    */
 
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                    sizeof(method), username, sizeof(username), host,
+                   sizeof(host), &port, resource, sizeof(resource));
+    if (strncmp(resource, "/jobs/", 6))
+    {
+     /*
+      * Not a valid URI!
+      */
 
-/*
- * 'copy_attrs()' - Copy attributes from one request to another.
- */
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\"!"),
+                      uri->values[0].string.text);
+      return;
+    }
 
-static void
-copy_attrs(ipp_t        *to,           /* I - Destination request */
-           ipp_t        *from,         /* I - Source request */
-           cups_array_t *ra,           /* I - Requested attributes */
-          ipp_tag_t    group,          /* I - Group to copy */
-          int          quickcopy)      /* I - Do a quick copy? */
-{
-  ipp_attribute_t      *fromattr;      /* Source attribute */
+    jobid = atoi(resource + 6);
+  }
 
+ /*
+  * See if the job exists...
+  */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "copy_attrs(to=%p, from=%p, ra=%p, group=%x, quickcopy=%d)",
-                 to, from, ra, group, quickcopy);
+  if ((job = cupsdFindJob(jobid)) == NULL)
+  {
+   /*
+    * Nope - return a "not found" error...
+    */
 
-  if (!to || !from)
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("Job #%d does not exist!"), jobid);
     return;
+  }
 
-  for (fromattr = from->attrs; fromattr; fromattr = fromattr->next)
+ /*
+  * See if the job has been completed...
+  */
+
+  if (job->state_value != IPP_JOB_HELD)
   {
    /*
-    * Filter attributes as needed...
+    * Return a "not-possible" error...
     */
 
-    if (group != IPP_TAG_ZERO && fromattr->group_tag != group &&
-        fromattr->group_tag != IPP_TAG_ZERO && !fromattr->name)
-      continue;
+    send_ipp_status(con, IPP_NOT_POSSIBLE,
+                    _("Job #%d is not held for authentication!"),
+                   jobid);
+    return;
+  }
 
-    if (!ra || cupsArrayFind(ra, fromattr->name))
-      copy_attribute(to, fromattr, quickcopy);
+ /*
+  * See if we have already authenticated...
+  */
+
+  if (!con->username[0])
+  {
+    send_ipp_status(con, IPP_NOT_AUTHORIZED,
+                    _("No authentication information provided!"));
+    return;
+  }
+
+ /*
+  * See if the job is owned by the requesting user...
+  */
+
+  if (!validate_user(job, con, job->username, username, sizeof(username)))
+  {
+    send_http_error(con, HTTP_UNAUTHORIZED);
+    return;
+  }
+
+ /*
+  * Save the authentication information for this job...
+  */
+
+  save_auth_info(con, job);
+
+ /*
+  * Reset the job-hold-until value to "no-hold"...
+  */
+
+  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
+                               IPP_TAG_KEYWORD)) == NULL)
+    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+  if (attr)
+  {
+    attr->value_tag = IPP_TAG_KEYWORD;
+    cupsdSetString(&(attr->values[0].string.text), "no-hold");
   }
+
+ /*
+  * Release the job and return...
+  */
+
+  cupsdReleaseJob(job);
+
+  cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was authenticated by \"%s\".", jobid,
+                  con->username);
 }
 
 
 /*
- * 'copy_banner()' - Copy a banner file to the requests directory for the
- *                   specified job.
+ * 'cancel_all_jobs()' - Cancel all print jobs.
  */
 
-static int                             /* O - Size of banner file in kbytes */
-copy_banner(cupsd_client_t *con,       /* I - Client connection */
-            cupsd_job_t    *job,       /* I - Job information */
-            const char     *name)      /* I - Name of banner */
+static void
+cancel_all_jobs(cupsd_client_t  *con,  /* I - Client connection */
+               ipp_attribute_t *uri)   /* I - Job or Printer URI */
 {
-  int          i;                      /* Looping var */
-  int          kbytes;                 /* Size of banner file in kbytes */
-  char         filename[1024];         /* Job filename */
-  cupsd_banner_t *banner;              /* Pointer to banner */
-  cups_file_t  *in;                    /* Input file */
-  cups_file_t  *out;                   /* Output file */
-  int          ch;                     /* Character from file */
-  char         attrname[255],          /* Name of attribute */
-               *s;                     /* Pointer into name */
-  ipp_attribute_t *attr;               /* Attribute */
+  http_status_t        status;                 /* Policy status */
+  const char   *dest;                  /* Destination */
+  cups_ptype_t dtype;                  /* Destination type */
+  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+               userpass[HTTP_MAX_URI], /* Username portion of URI */
+               host[HTTP_MAX_URI],     /* Host portion of URI */
+               resource[HTTP_MAX_URI]; /* Resource portion of URI */
+  int          port;                   /* Port portion of URI */
+  ipp_attribute_t *attr;               /* Attribute in request */
+  const char   *username;              /* Username */
+  int          purge;                  /* Purge? */
+  cupsd_printer_t *printer;            /* Printer */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner(%p[%d], %p[%d], %s)",
-                  con, con->http.fd, job, job->id, name ? name : "(null)");
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
 
  /*
-  * Find the banner; return if not found or "none"...
+  * See if we have a printer URI...
   */
 
-  if (!name || !strcmp(name, "none") ||
-      (banner = cupsdFindBanner(name)) == NULL)
-    return (0);
+  if (strcmp(uri->name, "printer-uri"))
+  {
+    send_ipp_status(con, IPP_BAD_REQUEST,
+                    _("The printer-uri attribute is required!"));
+    return;
+  }
 
  /*
-  * Open the banner and job files...
+  * Get the username (if any) for the jobs we want to cancel (only if
+  * "my-jobs" is specified...
   */
 
-  if (add_file(con, job, banner->filetype, 0))
-    return (0);
-
-  snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
-           job->num_files);
-  if ((out = cupsFileOpen(filename, "w")) == NULL)
+  if ((attr = ippFindAttribute(con->request, "my-jobs",
+                               IPP_TAG_BOOLEAN)) != NULL &&
+      attr->values[0].boolean)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "copy_banner: Unable to create banner job file %s - %s",
-                    filename, strerror(errno));
-    job->num_files --;
-    return (0);
+    if ((attr = ippFindAttribute(con->request, "requesting-user-name",
+                                 IPP_TAG_NAME)) != NULL)
+      username = attr->values[0].string.text;
+    else
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Missing requesting-user-name attribute!"));
+      return;
+    }
   }
+  else
+    username = NULL;
 
-  fchmod(cupsFileNumber(out), 0640);
-  fchown(cupsFileNumber(out), RunUser, Group);
+ /*
+  * Look for the "purge-jobs" attribute...
+  */
+
+  if ((attr = ippFindAttribute(con->request, "purge-jobs",
+                               IPP_TAG_BOOLEAN)) != NULL)
+    purge = attr->values[0].boolean;
+  else
+    purge = 1;
 
  /*
-  * Try the localized banner file under the subdirectory...
+  * And if the destination is valid...
   */
 
-  strlcpy(attrname, con->request->attrs->next->values[0].string.text,
-          sizeof(attrname));
-  if (strlen(attrname) > 2 && attrname[2] == '-')
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                  sizeof(method), userpass, sizeof(userpass), host,
+                 sizeof(host), &port, resource, sizeof(resource));
+
+  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
   {
    /*
-    * Convert ll-cc to ll_CC...
+    * Bad URI?
     */
 
-    attrname[2] = '_';
-    attrname[3] = toupper(attrname[3] & 255);
-    attrname[4] = toupper(attrname[4] & 255);
-  }
+    if ((!strncmp(resource, "/printers/", 10) && resource[10]) ||
+        (!strncmp(resource, "/classes/", 9) && resource[9]))
+    {
+      send_ipp_status(con, IPP_NOT_FOUND,
+                      _("The printer or class was not found."));
+      return;
+    }
+    else if (strcmp(resource, "/printers/"))
+    {
+      send_ipp_status(con, IPP_NOT_FOUND,
+                      _("The printer-uri \"%s\" is not valid."),
+                     uri->values[0].string.text);
+      return;
+    }
 
-  snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
-           attrname, name);
+   /*
+    * Check policy...
+    */
+
+    if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+    {
+      send_http_error(con, status);
+      return;
+    }
 
-  if (access(filename, 0) && strlen(attrname) > 2)
-  {
    /*
-    * Wasn't able to find "ll_CC" locale file; try the non-national
-    * localization banner directory.
+    * Cancel all jobs on all printers...
     */
 
-    attrname[2] = '\0';
+    cupsdCancelJobs(NULL, username, purge);
 
-    snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
-             attrname, name);
+    cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".",
+                    purge ? "purged" : "cancelled", get_username(con));
   }
-
-  if (access(filename, 0))
+  else
   {
    /*
-    * Use the non-localized banner file.
+    * Check policy...
     */
 
-    snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name);
-  }
+    if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
+    {
+      send_http_error(con, status);
+      return;
+    }
 
-  if ((in = cupsFileOpen(filename, "r")) == NULL)
-  {
-    cupsFileClose(out);
-    unlink(filename);
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "copy_banner: Unable to open banner template file %s - %s",
-                    filename, strerror(errno));
-    job->num_files --;
-    return (0);
+   /*
+    * Cancel all of the jobs on the named printer...
+    */
+
+    cupsdCancelJobs(dest, username, purge);
+
+    cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".",
+                    dest, purge ? "purged" : "cancelled", get_username(con));
   }
 
+  con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'cancel_job()' - Cancel a print job.
+ */
+
+static void
+cancel_job(cupsd_client_t  *con,       /* I - Client connection */
+          ipp_attribute_t *uri)        /* I - Job or Printer URI */
+{
+  ipp_attribute_t *attr;               /* Current attribute */
+  int          jobid;                  /* Job ID */
+  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+               username[HTTP_MAX_URI], /* Username portion of URI */
+               host[HTTP_MAX_URI],     /* Host portion of URI */
+               resource[HTTP_MAX_URI]; /* Resource portion of URI */
+  int          port;                   /* Port portion of URI */
+  cupsd_job_t  *job;                   /* Job information */
+  const char   *dest;                  /* Destination */
+  cups_ptype_t dtype;                  /* Destination type (printer or class) */
+  cupsd_printer_t *printer;            /* Printer data */
+
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
+
  /*
-  * Parse the file to the end...
+  * See if we have a job URI or a printer URI...
   */
 
-  while ((ch = cupsFileGetChar(in)) != EOF)
-    if (ch == '{')
+  if (!strcmp(uri->name, "printer-uri"))
+  {
+   /*
+    * Got a printer URI; see if we also have a job-id attribute...
+    */
+
+    if ((attr = ippFindAttribute(con->request, "job-id",
+                                 IPP_TAG_INTEGER)) == NULL)
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Got a printer-uri attribute but no job-id!"));
+      return;
+    }
+
+    if ((jobid = attr->values[0].integer) == 0)
     {
      /*
-      * Get an attribute name...
+      * Find the current job on the specified printer...
       */
 
-      for (s = attrname; (ch = cupsFileGetChar(in)) != EOF;)
-        if (!isalpha(ch & 255) && ch != '-' && ch != '?')
-          break;
-       else if (s < (attrname + sizeof(attrname) - 1))
-          *s++ = ch;
-       else
-         break;
-
-      *s = '\0';
+      httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                      sizeof(method), username, sizeof(username), host,
+                     sizeof(host), &port, resource, sizeof(resource));
 
-      if (ch != '}')
+      if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
       {
        /*
-        * Ignore { followed by stuff that is not an attribute name...
+       * Bad URI...
        */
 
-        cupsFilePrintf(out, "{%s%c", attrname, ch);
-       continue;
+       send_ipp_status(con, IPP_NOT_FOUND,
+                       _("The printer or class was not found."));
+       return;
       }
 
      /*
-      * See if it is defined...
+      * See if the printer is currently printing a job...
       */
 
-      if (attrname[0] == '?')
-        s = attrname + 1;
+      if (printer->job)
+        jobid = ((cupsd_job_t *)printer->job)->id;
       else
-        s = attrname;
-
-      if (!strcmp(s, "printer-name"))
-      {
-        cupsFilePuts(out, job->dest);
-       continue;
-      }
-      else if ((attr = ippFindAttribute(job->attrs, s, IPP_TAG_ZERO)) == NULL)
       {
        /*
-        * See if we have a leading question mark...
+        * No, see if there are any pending jobs...
        */
+        
+        for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
+            job;
+            job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
+         if (job->state_value <= IPP_JOB_PROCESSING &&
+             !strcasecmp(job->dest, dest))
+           break;
 
-       if (attrname[0] != '?')
+       if (job)
+         jobid = job->id;
+       else
        {
-        /*
-          * Nope, write to file as-is; probably a PostScript procedure...
-         */
+         send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"),
+                         dest);
+         return;
+       }
+      }
+    }
+  }
+  else
+  {
+   /*
+    * Got a job URI; parse it to get the job ID...
+    */
 
-         cupsFilePrintf(out, "{%s}", attrname);
-        }
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                    sizeof(method), username, sizeof(username), host,
+                   sizeof(host), &port, resource, sizeof(resource));
+    if (strncmp(resource, "/jobs/", 6))
+    {
+     /*
+      * Not a valid URI!
+      */
 
-        continue;
-      }
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Bad job-uri attribute \"%s\"!"),
+                      uri->values[0].string.text);
+      return;
+    }
+
+    jobid = atoi(resource + 6);
+  }
+
+ /*
+  * See if the job exists...
+  */
+
+  if ((job = cupsdFindJob(jobid)) == NULL)
+  {
+   /*
+    * Nope - return a "not found" error...
+    */
+
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+    return;
+  }
+
+ /*
+  * See if the job is owned by the requesting user...
+  */
+
+  if (!validate_user(job, con, job->username, username, sizeof(username)))
+  {
+    send_http_error(con, HTTP_UNAUTHORIZED);
+    return;
+  }
+
+ /*
+  * See if the job is already completed, cancelled, or aborted; if so,
+  * we can't cancel...
+  */
+
+  if (job->state_value >= IPP_JOB_CANCELLED)
+  {
+    send_ipp_status(con, IPP_NOT_POSSIBLE,
+                    _("Job #%d is already %s - can\'t cancel."), jobid,
+                   job->state_value == IPP_JOB_CANCELLED ? "cancelled" :
+                   job->state_value == IPP_JOB_ABORTED ? "aborted" :
+                   "completed");
+    return;
+  }
 
    /*
-      * Output value(s)...
-      */
+ /*
+  * Cancel the job and return...
+  */
 
-      for (i = 0; i < attr->num_values; i ++)
-      {
-       if (i)
-         cupsFilePutChar(out, ',');
+  cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job,
+                "Job cancelled by \"%s\".", username);
 
-       switch (attr->value_tag)
-       {
-         case IPP_TAG_INTEGER :
-         case IPP_TAG_ENUM :
-             if (!strncmp(s, "time-at-", 8))
-               cupsFilePuts(out, cupsdGetDateTime(attr->values[i].integer));
-             else
-               cupsFilePrintf(out, "%d", attr->values[i].integer);
-             break;
+  cupsdCancelJob(job, 0);
+  cupsdCheckJobs();
 
-         case IPP_TAG_BOOLEAN :
-             cupsFilePrintf(out, "%d", attr->values[i].boolean);
-             break;
+  cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was cancelled by \"%s\".", jobid,
+                  username);
 
-         case IPP_TAG_NOVALUE :
-             cupsFilePuts(out, "novalue");
-             break;
+  con->response->request.status.status_code = IPP_OK;
+}
 
-         case IPP_TAG_RANGE :
-             cupsFilePrintf(out, "%d-%d", attr->values[i].range.lower,
-                     attr->values[i].range.upper);
-             break;
 
-         case IPP_TAG_RESOLUTION :
-             cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres,
-                     attr->values[i].resolution.yres,
-                     attr->values[i].resolution.units == IPP_RES_PER_INCH ?
-                         "dpi" : "dpc");
-             break;
+/*
+ * 'cancel_subscription()' - Cancel a subscription.
+ */
 
-         case IPP_TAG_URI :
-          case IPP_TAG_STRING :
-         case IPP_TAG_TEXT :
-         case IPP_TAG_NAME :
-         case IPP_TAG_KEYWORD :
-         case IPP_TAG_CHARSET :
-         case IPP_TAG_LANGUAGE :
-             if (!strcasecmp(banner->filetype->type, "postscript"))
-             {
-              /*
-               * Need to quote strings for PS banners...
-               */
+static void
+cancel_subscription(
+    cupsd_client_t *con,               /* I - Client connection */
+    int            sub_id)             /* I - Subscription ID */
+{
+  http_status_t                status;         /* Policy status */
+  cupsd_subscription_t *sub;           /* Subscription */
 
-               const char *p;
 
-               for (p = attr->values[i].string.text; *p; p ++)
-               {
-                 if (*p == '(' || *p == ')' || *p == '\\')
-                 {
-                   cupsFilePutChar(out, '\\');
-                   cupsFilePutChar(out, *p);
-                 }
-                 else if (*p < 32 || *p > 126)
-                   cupsFilePrintf(out, "\\%03o", *p & 255);
-                 else
-                   cupsFilePutChar(out, *p);
-               }
-             }
-             else
-               cupsFilePuts(out, attr->values[i].string.text);
-             break;
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "cancel_subscription(con=%p[%d], sub_id=%d)",
+                  con, con->http.fd, sub_id);
 
-          default :
-             break; /* anti-compiler-warning-code */
-       }
-      }
-    }
-    else if (ch == '\\')       /* Quoted char */
-    {
-      ch = cupsFileGetChar(in);
+ /*
+  * Is the subscription ID valid?
+  */
 
-      if (ch != '{')           /* Only do special handling for \{ */
-        cupsFilePutChar(out, '\\');
+  if ((sub = cupsdFindSubscription(sub_id)) == NULL)
+  {
+   /*
+    * Bad subscription ID...
+    */
 
-      cupsFilePutChar(out, ch);
-    }
-    else
-      cupsFilePutChar(out, ch);
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("notify-subscription-id %d no good!"), sub_id);
+    return;
+  }
 
-  cupsFileClose(in);
+ /*
+  * Check policy...
+  */
 
-  kbytes = (cupsFileTell(out) + 1023) / 1024;
+  if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr :
+                                             DefaultPolicyPtr,
+                                 con, sub->owner)) != HTTP_OK)
+  {
+    send_http_error(con, status);
+    return;
+  }
 
-  if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
-                               IPP_TAG_INTEGER)) != NULL)
-    attr->values[0].integer += kbytes;
+ /*
+  * Cancel the subscription...
+  */
 
-  cupsFileClose(out);
+  cupsdDeleteSubscription(sub, 1);
 
-  return (kbytes);
+  con->response->request.status.status_code = IPP_OK;
 }
 
 
 /*
- * 'copy_file()' - Copy a PPD file or interface script...
+ * 'check_quotas()' - Check quotas for a printer and user.
  */
 
-static int                             /* O - 0 = success, -1 = error */
-copy_file(const char *from,            /* I - Source file */
-          const char *to)              /* I - Destination file */
+static int                             /* O - 1 if OK, 0 if not */
+check_quotas(cupsd_client_t  *con,     /* I - Client connection */
+             cupsd_printer_t *p)       /* I - Printer or class */
 {
-  cups_file_t  *src,                   /* Source file */
-               *dst;                   /* Destination file */
-  int          bytes;                  /* Bytes to read/write */
-  char         buffer[2048];           /* Copy buffer */
+  int          i;                      /* Looping var */
+  char         username[33];           /* Username */
+  cupsd_quota_t        *q;                     /* Quota data */
+  struct passwd        *pw;                    /* User password data */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_file(\"%s\", \"%s\")", from, to);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])",
+                  con, con->http.fd, p, p->name);
 
  /*
-  * Open the source and destination file for a copy...
+  * Check input...
   */
 
-  if ((src = cupsFileOpen(from, "rb")) == NULL)
-    return (-1);
+  if (!con || !p)
+    return (0);
 
-  if ((dst = cupsFileOpen(to, "wb")) == NULL)
+ /*
+  * Figure out who is printing...
+  */
+
+  strlcpy(username, get_username(con), sizeof(username));
+
+ /*
+  * Check global active job limits for printers and users...
+  */
+
+  if (MaxJobsPerPrinter)
   {
-    cupsFileClose(src);
-    return (-1);
+   /*
+    * Check if there are too many pending jobs on this printer...
+    */
+
+    if (cupsdGetPrinterJobCount(p->name) >= MaxJobsPerPrinter)
+    {
+      cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for printer \"%s\"...",
+                      p->name);
+      return (0);
+    }
+  }
+
+  if (MaxJobsPerUser)
+  {
+   /*
+    * Check if there are too many pending jobs for this user...
+    */
+
+    if (cupsdGetUserJobCount(username) >= MaxJobsPerUser)
+    {
+      cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for user \"%s\"...",
+                      username);
+      return (0);
+    }
   }
 
  /*
-  * Copy the source file to the destination...
+  * Check against users...
   */
 
-  while ((bytes = cupsFileRead(src, buffer, sizeof(buffer))) > 0)
-    if (cupsFileWrite(dst, buffer, bytes) < bytes)
+  if (p->num_users == 0 && p->k_limit == 0 && p->page_limit == 0)
+    return (1);
+
+  if (p->num_users)
+  {
+    pw = getpwnam(username);
+    endpwent();
+
+    for (i = 0; i < p->num_users; i ++)
+      if (p->users[i][0] == '@')
+      {
+       /*
+        * Check group membership...
+       */
+
+        if (cupsdCheckGroup(username, pw, p->users[i] + 1))
+         break;
+      }
+      else if (!strcasecmp(username, p->users[i]))
+       break;
+
+    if ((i < p->num_users) == p->deny_users)
     {
-      cupsFileClose(src);
-      cupsFileClose(dst);
-      return (-1);
+      cupsdLogMessage(CUPSD_LOG_INFO,
+                      "Denying user \"%s\" access to printer \"%s\"...",
+                     username, p->name);
+      return (0);
     }
+  }
 
  /*
-  * Close both files and return...
+  * Check quotas...
   */
 
-  cupsFileClose(src);
+  if (p->k_limit || p->page_limit)
+  {
+    if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to allocate quota data for user \"%s\"!",
+                      username);
+      return (0);
+    }
 
-  return (cupsFileClose(dst));
+    if ((q->k_count >= p->k_limit && p->k_limit) ||
+        (q->page_count >= p->page_limit && p->page_limit))
+    {
+      cupsdLogMessage(CUPSD_LOG_INFO, "User \"%s\" is over the quota limit...",
+                      username);
+      return (0);
+    }
+  }
+
+ /*
+  * If we have gotten this far, we're done!
+  */
+
+  return (1);
 }
 
 
 /*
- * 'copy_model()' - Copy a PPD model file, substituting default values
- *                  as needed...
+ * 'copy_attribute()' - Copy a single attribute.
  */
 
-static int                             /* O - 0 = success, -1 = error */
-copy_model(cupsd_client_t *con,                /* I - Client connection */
-           const char     *from,       /* I - Source file */
-           const char     *to)         /* I - Destination file */
+static ipp_attribute_t *               /* O - New attribute */
+copy_attribute(
+    ipp_t           *to,               /* O - Destination request/response */
+    ipp_attribute_t *attr,             /* I - Attribute to copy */
+    int             quickcopy)         /* I - Do a quick copy? */
 {
-  fd_set       *input;                 /* select() input set */
-  struct timeval timeout;              /* select() timeout */
-  int          maxfd;                  /* Maximum file descriptor for select() */
-  char         tempfile[1024];         /* Temporary PPD file */
-  int          tempfd;                 /* Temporary PPD file descriptor */
-  int          temppid;                /* Process ID of cups-driverd */
-  int          temppipe[2];            /* Temporary pipes */
-  char         *argv[4],               /* Command-line arguments */
-               *envp[MAX_ENV];         /* Environment */
-  cups_file_t  *src,                   /* Source file */
-               *dst;                   /* Destination file */
-  int          bytes,                  /* Bytes from pipe */
-               total;                  /* Total bytes from pipe */
-  char         buffer[2048],           /* Copy buffer */
-               *ptr;                   /* Pointer into buffer */
-  int          i;                      /* Looping var */
-  char         option[PPD_MAX_NAME],   /* Option name */
-               choice[PPD_MAX_NAME];   /* Choice name */
-  int          num_defaults;           /* Number of default options */
-  ppd_default_t        *defaults;              /* Default options */
-  char         cups_protocol[PPD_MAX_LINE];
-                                       /* cupsProtocol attribute */
-  int          have_letter,            /* Have Letter size */
-               have_a4;                /* Have A4 size */
-#ifdef HAVE_LIBPAPER
-  char         *paper_result;          /* Paper size name from libpaper */
-  char         system_paper[64];       /* Paper size name buffer */
-#endif /* HAVE_LIBPAPER */
+  int                  i;              /* Looping var */
+  ipp_attribute_t      *toattr;        /* Destination attribute */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                 "copy_model(con=%p, from=\"%s\", to=\"%s\")",
-                 con, from, to);
-
- /*
-  * Run cups-driverd to get the PPD file...
-  */
+                  "copy_attribute(%p, %p[%s,%x,%x])", to, attr,
+                 attr->name ? attr->name : "(null)", attr->group_tag,
+                 attr->value_tag);
 
-  argv[0] = "cups-driverd";
-  argv[1] = "cat";
-  argv[2] = (char *)from;
-  argv[3] = NULL;
+  switch (attr->value_tag & ~IPP_TAG_COPY)
+  {
+    case IPP_TAG_ZERO :
+        toattr = ippAddSeparator(to);
+       break;
 
-  cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
+    case IPP_TAG_INTEGER :
+    case IPP_TAG_ENUM :
+        toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
+                               attr->name, attr->num_values, NULL);
 
-  snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin);
-  snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd);
-  tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-  if (tempfd < 0)
-    return (-1);
+        for (i = 0; i < attr->num_values; i ++)
+         toattr->values[i].integer = attr->values[i].integer;
+        break;
 
-  cupsdOpenPipe(temppipe);
+    case IPP_TAG_BOOLEAN :
+        toattr = ippAddBooleans(to, attr->group_tag, attr->name,
+                               attr->num_values, NULL);
 
-  if ((input = calloc(1, SetSize)) == NULL)
-  {
-    close(tempfd);
-    unlink(tempfile);
+        for (i = 0; i < attr->num_values; i ++)
+         toattr->values[i].boolean = attr->values[i].boolean;
+        break;
 
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-                    "copy_model: Unable to allocate %d bytes for select()...",
-                    SetSize);
-    return (-1);
-  }
+    case IPP_TAG_STRING :
+    case IPP_TAG_TEXT :
+    case IPP_TAG_NAME :
+    case IPP_TAG_KEYWORD :
+    case IPP_TAG_URI :
+    case IPP_TAG_URISCHEME :
+    case IPP_TAG_CHARSET :
+    case IPP_TAG_LANGUAGE :
+    case IPP_TAG_MIMETYPE :
+        toattr = ippAddStrings(to, attr->group_tag,
+                              (ipp_tag_t)(attr->value_tag | quickcopy),
+                              attr->name, attr->num_values, NULL, NULL);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG,
-                  "copy_model: Running \"cups-driverd cat %s\"...", from);
+        if (quickcopy)
+       {
+          for (i = 0; i < attr->num_values; i ++)
+           toattr->values[i].string.text = attr->values[i].string.text;
+        }
+       else
+       {
+          for (i = 0; i < attr->num_values; i ++)
+           toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text);
+       }
+        break;
 
-  if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1],
-                         -1, 0, &temppid))
-  {
-    free(input);
-    close(tempfd);
-    unlink(tempfile);
-    return (-1);
-  }
+    case IPP_TAG_DATE :
+        toattr = ippAddDate(to, attr->group_tag, attr->name,
+                           attr->values[0].date);
+        break;
 
-  close(temppipe[1]);
+    case IPP_TAG_RESOLUTION :
+        toattr = ippAddResolutions(to, attr->group_tag, attr->name,
+                                  attr->num_values, IPP_RES_PER_INCH,
+                                  NULL, NULL);
 
- /*
-  * Wait up to 30 seconds for the PPD file to be copied...
-  */
+        for (i = 0; i < attr->num_values; i ++)
+       {
+         toattr->values[i].resolution.xres  = attr->values[i].resolution.xres;
+         toattr->values[i].resolution.yres  = attr->values[i].resolution.yres;
+         toattr->values[i].resolution.units = attr->values[i].resolution.units;
+       }
+        break;
 
-  total = 0;
+    case IPP_TAG_RANGE :
+        toattr = ippAddRanges(to, attr->group_tag, attr->name,
+                             attr->num_values, NULL, NULL);
 
-  if (temppipe[0] > CGIPipes[0])
-    maxfd = temppipe[0] + 1;
-  else
-    maxfd = CGIPipes[0] + 1;
+        for (i = 0; i < attr->num_values; i ++)
+       {
+         toattr->values[i].range.lower = attr->values[i].range.lower;
+         toattr->values[i].range.upper = attr->values[i].range.upper;
+       }
+        break;
 
-  for (;;)
-  {
-   /*
-    * See if we have data ready...
-    */
+    case IPP_TAG_TEXTLANG :
+    case IPP_TAG_NAMELANG :
+        toattr = ippAddStrings(to, attr->group_tag,
+                              (ipp_tag_t)(attr->value_tag | quickcopy),
+                              attr->name, attr->num_values, NULL, NULL);
 
-    bytes = 0;
+        if (quickcopy)
+       {
+          for (i = 0; i < attr->num_values; i ++)
+         {
+            toattr->values[i].string.charset = attr->values[i].string.charset;
+           toattr->values[i].string.text    = attr->values[i].string.text;
+          }
+        }
+       else
+       {
+          for (i = 0; i < attr->num_values; i ++)
+         {
+           if (!i)
+              toattr->values[i].string.charset =
+                 _cups_sp_alloc(attr->values[i].string.charset);
+           else
+              toattr->values[i].string.charset =
+                 toattr->values[0].string.charset;
 
-    FD_SET(temppipe[0], input);
-    FD_SET(CGIPipes[0], input);
+           toattr->values[i].string.text = _cups_sp_alloc(attr->values[i].string.text);
+          }
+        }
+        break;
 
-    timeout.tv_sec  = 30;
-    timeout.tv_usec = 0;
+    case IPP_TAG_BEGIN_COLLECTION :
+        toattr = ippAddCollections(to, attr->group_tag, attr->name,
+                                  attr->num_values, NULL);
 
-    if ((i = select(maxfd, input, NULL, NULL, &timeout)) < 0)
-    {
-      if (errno == EINTR)
-        continue;
-      else
+        for (i = 0; i < attr->num_values; i ++)
+       {
+         toattr->values[i].collection = ippNew();
+         copy_attrs(toattr->values[i].collection, attr->values[i].collection,
+                    NULL, IPP_TAG_ZERO, 0);
+       }
         break;
-    }
-    else if (i == 0)
-    {
-     /*
-      * We have timed out...
-      */
 
-      break;
-    }
+    default :
+        toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
+                               attr->name, attr->num_values, NULL);
 
-    if (FD_ISSET(temppipe[0], input))
-    {
-     /*
-      * Read the PPD file from the pipe, and write it to the PPD file.
-      */
+        for (i = 0; i < attr->num_values; i ++)
+       {
+         toattr->values[i].unknown.length = attr->values[i].unknown.length;
 
-      if ((bytes = read(temppipe[0], buffer, sizeof(buffer))) > 0)
-      {
-       if (write(tempfd, buffer, bytes) < bytes)
-          break;
+         if (toattr->values[i].unknown.length > 0)
+         {
+           if ((toattr->values[i].unknown.data =
+                    malloc(toattr->values[i].unknown.length)) == NULL)
+             toattr->values[i].unknown.length = 0;
+           else
+             memcpy(toattr->values[i].unknown.data,
+                    attr->values[i].unknown.data,
+                    toattr->values[i].unknown.length);
+         }
+       }
+        break; /* anti-compiler-warning-code */
+  }
 
-       total += bytes;
-      }
-      else
-       break;
-    }
+  return (toattr);
+}
+
+
+/*
+ * 'copy_attrs()' - Copy attributes from one request to another.
+ */
+
+static void
+copy_attrs(ipp_t        *to,           /* I - Destination request */
+           ipp_t        *from,         /* I - Source request */
+           cups_array_t *ra,           /* I - Requested attributes */
+          ipp_tag_t    group,          /* I - Group to copy */
+          int          quickcopy)      /* I - Do a quick copy? */
+{
+  ipp_attribute_t      *fromattr;      /* Source attribute */
 
-    if (FD_ISSET(CGIPipes[0], input))
-      cupsdUpdateCGI();
-  }
 
-  close(temppipe[0]);
-  close(tempfd);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "copy_attrs(to=%p, from=%p, ra=%p, group=%x, quickcopy=%d)",
+                 to, from, ra, group, quickcopy);
 
-  free(input);
+  if (!to || !from)
+    return;
 
-  if (!total)
+  for (fromattr = from->attrs; fromattr; fromattr = fromattr->next)
   {
    /*
-    * No data from cups-deviced...
+    * Filter attributes as needed...
     */
 
-    cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file!");
-    unlink(tempfile);
-    return (-1);
+    if (group != IPP_TAG_ZERO && fromattr->group_tag != group &&
+        fromattr->group_tag != IPP_TAG_ZERO && !fromattr->name)
+      continue;
+
+    if (!ra || cupsArrayFind(ra, fromattr->name))
+      copy_attribute(to, fromattr, quickcopy);
   }
+}
 
- /*
-  * Read the source file and see what page sizes are supported...
-  */
 
-  if ((src = cupsFileOpen(tempfile, "rb")) == NULL)
-  {
-    unlink(tempfile);
-    return (-1);
-  }
+/*
+ * 'copy_banner()' - Copy a banner file to the requests directory for the
+ *                   specified job.
+ */
 
-  have_letter = 0;
-  have_a4     = 0;
+static int                             /* O - Size of banner file in kbytes */
+copy_banner(cupsd_client_t *con,       /* I - Client connection */
+            cupsd_job_t    *job,       /* I - Job information */
+            const char     *name)      /* I - Name of banner */
+{
+  int          i;                      /* Looping var */
+  int          kbytes;                 /* Size of banner file in kbytes */
+  char         filename[1024];         /* Job filename */
+  cupsd_banner_t *banner;              /* Pointer to banner */
+  cups_file_t  *in;                    /* Input file */
+  cups_file_t  *out;                   /* Output file */
+  int          ch;                     /* Character from file */
+  char         attrname[255],          /* Name of attribute */
+               *s;                     /* Pointer into name */
+  ipp_attribute_t *attr;               /* Attribute */
 
-  while (cupsFileGets(src, buffer, sizeof(buffer)))
-    if (!strncmp(buffer, "*PageSize ", 10))
-    {
-     /*
-      * Strip UI text and command data from the end of the line...
-      */
 
-      if ((ptr = strchr(buffer + 10, '/')) != NULL)
-        *ptr = '\0';
-      if ((ptr = strchr(buffer + 10, ':')) != NULL)
-        *ptr = '\0';
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner(%p[%d], %p[%d], %s)",
+                  con, con->http.fd, job, job->id, name ? name : "(null)");
 
-      for (ptr = buffer + 10; isspace(*ptr); ptr ++);
+ /*
+  * Find the banner; return if not found or "none"...
+  */
 
-     /*
-      * Look for Letter and A4 page sizes...
-      */
+  if (!name || !strcmp(name, "none") ||
+      (banner = cupsdFindBanner(name)) == NULL)
+    return (0);
 
-      if (!strcmp(ptr, "Letter"))
-       have_letter = 1;
+ /*
+  * Open the banner and job files...
+  */
 
-      if (!strcmp(ptr, "A4"))
-       have_a4 = 1;
-    }
+  if (add_file(con, job, banner->filetype, 0))
+    return (0);
 
-  cupsFileRewind(src);
+  snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
+           job->num_files);
+  if ((out = cupsFileOpen(filename, "w")) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "copy_banner: Unable to create banner job file %s - %s",
+                    filename, strerror(errno));
+    job->num_files --;
+    return (0);
+  }
+
+  fchmod(cupsFileNumber(out), 0640);
+  fchown(cupsFileNumber(out), RunUser, Group);
 
  /*
-  * Open the destination (if possible) and set the default options...
+  * Try the localized banner file under the subdirectory...
   */
 
-  num_defaults     = 0;
-  defaults         = NULL;
-  cups_protocol[0] = '\0';
-
-  if ((dst = cupsFileOpen(to, "rb")) != NULL)
+  strlcpy(attrname, con->request->attrs->next->values[0].string.text,
+          sizeof(attrname));
+  if (strlen(attrname) > 2 && attrname[2] == '-')
   {
    /*
-    * Read all of the default lines from the old PPD...
+    * Convert ll-cc to ll_CC...
     */
 
-    while (cupsFileGets(dst, buffer, sizeof(buffer)))
-      if (!strncmp(buffer, "*Default", 8))
-      {
-       /*
-       * Add the default option...
-       */
+    attrname[2] = '_';
+    attrname[3] = toupper(attrname[3] & 255);
+    attrname[4] = toupper(attrname[4] & 255);
+  }
 
-        if (!ppd_parse_line(buffer, option, sizeof(option),
-                           choice, sizeof(choice)))
-          num_defaults = ppd_add_default(option, choice, num_defaults,
-                                        &defaults);
-      }
-      else if (!strncmp(buffer, "*cupsProtocol:", 14))
-        strlcpy(cups_protocol, buffer, sizeof(cups_protocol));
+  snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
+           attrname, name);
 
-    cupsFileClose(dst);
-  }
-#ifdef HAVE_LIBPAPER
-  else if ((paper_result = systempapername()) != NULL)
+  if (access(filename, 0) && strlen(attrname) > 2)
   {
    /*
-    * Set the default media sizes from the systemwide default...
+    * Wasn't able to find "ll_CC" locale file; try the non-national
+    * localization banner directory.
     */
 
-    strlcpy(system_paper, paper_result, sizeof(system_paper));
-    system_paper[0] = toupper(system_paper[0] & 255);
+    attrname[2] = '\0';
 
-    if ((!strcmp(system_paper, "Letter") && have_letter) ||
-        (!strcmp(system_paper, "A4") && have_a4))
-    {
-      num_defaults = ppd_add_default("PageSize", system_paper, 
-                                    num_defaults, &defaults);
-      num_defaults = ppd_add_default("PageRegion", system_paper, 
-                                    num_defaults, &defaults);
-      num_defaults = ppd_add_default("PaperDimension", system_paper, 
-                                    num_defaults, &defaults);
-      num_defaults = ppd_add_default("ImageableArea", system_paper, 
-                                    num_defaults, &defaults);
-    }
+    snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
+             attrname, name);
   }
-#endif /* HAVE_LIBPAPER */
-  else
+
+  if (access(filename, 0))
   {
    /*
-    * Add the default media sizes...
-    *
-    * Note: These values are generally not valid for large-format devices
-    *       like plotters, however it is probably safe to say that those
-    *       users will configure the media size after initially adding
-    *       the device anyways...
+    * Use the non-localized banner file.
     */
 
-    if (!DefaultLanguage ||
-        !strcasecmp(DefaultLanguage, "C") ||
-        !strcasecmp(DefaultLanguage, "POSIX") ||
-       !strcasecmp(DefaultLanguage, "en") ||
-       !strncasecmp(DefaultLanguage, "en_US", 5) ||
-       !strncasecmp(DefaultLanguage, "en_CA", 5) ||
-       !strncasecmp(DefaultLanguage, "fr_CA", 5))
-    {
-     /*
-      * These are the only locales that will default to "letter" size...
-      */
-
-      if (have_letter)
-      {
-       num_defaults = ppd_add_default("PageSize", "Letter", num_defaults,
-                                       &defaults);
-       num_defaults = ppd_add_default("PageRegion", "Letter", num_defaults,
-                                       &defaults);
-       num_defaults = ppd_add_default("PaperDimension", "Letter", num_defaults,
-                                       &defaults);
-       num_defaults = ppd_add_default("ImageableArea", "Letter", num_defaults,
-                                       &defaults);
-      }
-    }
-    else if (have_a4)
-    {
-     /*
-      * The rest default to "a4" size...
-      */
+    snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name);
+  }
 
-      num_defaults = ppd_add_default("PageSize", "A4", num_defaults,
-                                     &defaults);
-      num_defaults = ppd_add_default("PageRegion", "A4", num_defaults,
-                                     &defaults);
-      num_defaults = ppd_add_default("PaperDimension", "A4", num_defaults,
-                                     &defaults);
-      num_defaults = ppd_add_default("ImageableArea", "A4", num_defaults,
-                                     &defaults);
-    }
+  if ((in = cupsFileOpen(filename, "r")) == NULL)
+  {
+    cupsFileClose(out);
+    unlink(filename);
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "copy_banner: Unable to open banner template file %s - %s",
+                    filename, strerror(errno));
+    job->num_files --;
+    return (0);
   }
 
  /*
-  * Open the destination file for a copy...
+  * Parse the file to the end...
   */
 
-  if ((dst = cupsFileOpen(to, "wb")) == NULL)
-  {
-    if (num_defaults > 0)
-      free(defaults);
+  while ((ch = cupsFileGetChar(in)) != EOF)
+    if (ch == '{')
+    {
+     /*
+      * Get an attribute name...
+      */
 
-    cupsFileClose(src);
-    unlink(tempfile);
-    return (-1);
-  }
+      for (s = attrname; (ch = cupsFileGetChar(in)) != EOF;)
+        if (!isalpha(ch & 255) && ch != '-' && ch != '?')
+          break;
+       else if (s < (attrname + sizeof(attrname) - 1))
+          *s++ = ch;
+       else
+         break;
 
- /*
-  * Copy the source file to the destination...
-  */
+      *s = '\0';
+
+      if (ch != '}')
+      {
+       /*
+        * Ignore { followed by stuff that is not an attribute name...
+       */
+
+        cupsFilePrintf(out, "{%s%c", attrname, ch);
+       continue;
+      }
 
-  while (cupsFileGets(src, buffer, sizeof(buffer)))
-  {
-    if (!strncmp(buffer, "*Default", 8))
-    {
      /*
-      * Check for an previous default option choice...
+      * See if it is defined...
       */
 
-      if (!ppd_parse_line(buffer, option, sizeof(option),
-                         choice, sizeof(choice)))
-      {
-        for (i = 0; i < num_defaults; i ++)
-         if (!strcmp(option, defaults[i].option))
-         {
-          /*
-           * Substitute the previous choice...
-           */
+      if (attrname[0] == '?')
+        s = attrname + 1;
+      else
+        s = attrname;
 
-           snprintf(buffer, sizeof(buffer), "*Default%s: %s", option,
-                    defaults[i].choice);
-           break;
-         }
+      if (!strcmp(s, "printer-name"))
+      {
+        cupsFilePuts(out, job->dest);
+       continue;
       }
-    }
+      else if ((attr = ippFindAttribute(job->attrs, s, IPP_TAG_ZERO)) == NULL)
+      {
+       /*
+        * See if we have a leading question mark...
+       */
 
-    cupsFilePrintf(dst, "%s\n", buffer);
-  }
+       if (attrname[0] != '?')
+       {
+        /*
+          * Nope, write to file as-is; probably a PostScript procedure...
+         */
 
-  if (cups_protocol[0])
-    cupsFilePrintf(dst, "%s\n", cups_protocol);
+         cupsFilePrintf(out, "{%s}", attrname);
+        }
 
-  if (num_defaults > 0)
-    free(defaults);
+        continue;
+      }
 
- /*
-  * Close both files and return...
-  */
    /*
+      * Output value(s)...
+      */
 
-  cupsFileClose(src);
+      for (i = 0; i < attr->num_values; i ++)
+      {
+       if (i)
+         cupsFilePutChar(out, ',');
 
-  unlink(tempfile);
+       switch (attr->value_tag)
+       {
+         case IPP_TAG_INTEGER :
+         case IPP_TAG_ENUM :
+             if (!strncmp(s, "time-at-", 8))
+               cupsFilePuts(out, cupsdGetDateTime(attr->values[i].integer));
+             else
+               cupsFilePrintf(out, "%d", attr->values[i].integer);
+             break;
 
-  return (cupsFileClose(dst));
-}
+         case IPP_TAG_BOOLEAN :
+             cupsFilePrintf(out, "%d", attr->values[i].boolean);
+             break;
 
+         case IPP_TAG_NOVALUE :
+             cupsFilePuts(out, "novalue");
+             break;
 
-/*
- * 'copy_job_attrs()' - Copy job attributes.
- */
+         case IPP_TAG_RANGE :
+             cupsFilePrintf(out, "%d-%d", attr->values[i].range.lower,
+                     attr->values[i].range.upper);
+             break;
 
-static void
-copy_job_attrs(cupsd_client_t *con,    /* I - Client connection */
-              cupsd_job_t    *job,     /* I - Job */
-              cups_array_t   *ra)      /* I - Requested attributes array */
-{
-  char job_uri[HTTP_MAX_URI];          /* Job URI */
+         case IPP_TAG_RESOLUTION :
+             cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres,
+                     attr->values[i].resolution.yres,
+                     attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+                         "dpi" : "dpc");
+             break;
 
+         case IPP_TAG_URI :
+          case IPP_TAG_STRING :
+         case IPP_TAG_TEXT :
+         case IPP_TAG_NAME :
+         case IPP_TAG_KEYWORD :
+         case IPP_TAG_CHARSET :
+         case IPP_TAG_LANGUAGE :
+             if (!strcasecmp(banner->filetype->type, "postscript"))
+             {
+              /*
+               * Need to quote strings for PS banners...
+               */
 
- /*
-  * Send the requested attributes for each job...
-  */
+               const char *p;
 
-  httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
-                   con->servername, con->serverport, "/jobs/%d",
-                  job->id);
+               for (p = attr->values[i].string.text; *p; p ++)
+               {
+                 if (*p == '(' || *p == ')' || *p == '\\')
+                 {
+                   cupsFilePutChar(out, '\\');
+                   cupsFilePutChar(out, *p);
+                 }
+                 else if (*p < 32 || *p > 126)
+                   cupsFilePrintf(out, "\\%03o", *p & 255);
+                 else
+                   cupsFilePutChar(out, *p);
+               }
+             }
+             else
+               cupsFilePuts(out, attr->values[i].string.text);
+             break;
 
-  if (!ra || cupsArrayFind(ra, "job-more-info"))
-    ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
-                "job-more-info", NULL, job_uri);
+          default :
+             break; /* anti-compiler-warning-code */
+       }
+      }
+    }
+    else if (ch == '\\')       /* Quoted char */
+    {
+      ch = cupsFileGetChar(in);
 
-  if (job->state_value > IPP_JOB_PROCESSING &&
-      (!ra || cupsArrayFind(ra, "job-preserved")))
-    ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved",
-                  job->num_files > 0);
+      if (ch != '{')           /* Only do special handling for \{ */
+        cupsFilePutChar(out, '\\');
 
-  if (!ra || cupsArrayFind(ra, "job-printer-up-time"))
-    ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                  "job-printer-up-time", time(NULL));
+      cupsFilePutChar(out, ch);
+    }
+    else
+      cupsFilePutChar(out, ch);
 
-  if (!ra || cupsArrayFind(ra, "job-state-reasons"))
-    add_job_state_reasons(con, job);
+  cupsFileClose(in);
 
-  if (!ra || cupsArrayFind(ra, "job-uri"))
-    ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
-                "job-uri", NULL, job_uri);
+  kbytes = (cupsFileTell(out) + 1023) / 1024;
 
-  copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0);
+  if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
+                               IPP_TAG_INTEGER)) != NULL)
+    attr->values[0].integer += kbytes;
+
+  cupsFileClose(out);
+
+  return (kbytes);
 }
 
 
 /*
- * 'copy_printer_attrs()' - Copy printer attributes.
+ * 'copy_file()' - Copy a PPD file or interface script...
  */
 
-static void
-copy_printer_attrs(
-    cupsd_client_t  *con,              /* I - Client connection */
-    cupsd_printer_t *printer,          /* I - Printer */
-    cups_array_t    *ra)               /* I - Requested attributes array */
+static int                             /* O - 0 = success, -1 = error */
+copy_file(const char *from,            /* I - Source file */
+          const char *to)              /* I - Destination file */
 {
-  char                 printer_uri[HTTP_MAX_URI];
-                                       /* Printer URI */
-  time_t               curtime;        /* Current time */
-  int                  i;              /* Looping var */
-  ipp_attribute_t      *history;       /* History collection */
+  cups_file_t  *src,                   /* Source file */
+               *dst;                   /* Destination file */
+  int          bytes;                  /* Bytes to read/write */
+  char         buffer[2048];           /* Copy buffer */
 
 
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_file(\"%s\", \"%s\")", from, to);
+
  /*
-  * Copy the printer attributes to the response using requested-attributes
-  * and document-format attributes that may be provided by the client.
+  * Open the source and destination file for a copy...
   */
 
-  curtime = time(NULL);
-
-#ifdef __APPLE__
-  if ((!ra || cupsArrayFind(ra, "com.apple.print.recoverable-message")) &&
-      printer->recoverable)
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
-                 "com.apple.print.recoverable-message", NULL,
-                printer->recoverable);
-#endif /* __APPLE__ */
-
-  if (!ra || cupsArrayFind(ra, "printer-current-time"))
-    ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
-               ippTimeToDate(curtime));
-
-  if (!ra || cupsArrayFind(ra, "printer-error-policy"))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
-                "printer-error-policy", NULL, printer->error_policy);
-
-  if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs"))
-    ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
-                  printer->accepting);
-
-  if (!ra || cupsArrayFind(ra, "printer-is-shared"))
-    ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared",
-                  printer->shared);
+  if ((src = cupsFileOpen(from, "rb")) == NULL)
+    return (-1);
 
-  if (!ra || cupsArrayFind(ra, "printer-op-policy"))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
-                "printer-op-policy", NULL, printer->op_policy);
+  if ((dst = cupsFileOpen(to, "wb")) == NULL)
+  {
+    cupsFileClose(src);
+    return (-1);
+  }
 
-  if (!ra || cupsArrayFind(ra, "printer-state"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
-                  printer->state);
+ /*
+  * Copy the source file to the destination...
+  */
 
-  if (!ra || cupsArrayFind(ra, "printer-state-change-time"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                  "printer-state-change-time", printer->state_time);
-                
-  if (MaxPrinterHistory > 0 && printer->num_history > 0 &&
-      cupsArrayFind(ra, "printer-state-history"))
-  {
-   /*
-    * Printer history is only sent if specifically requested, so that
-    * older CUPS/IPP clients won't barf on the collection attributes.
-    */
+  while ((bytes = cupsFileRead(src, buffer, sizeof(buffer))) > 0)
+    if (cupsFileWrite(dst, buffer, bytes) < bytes)
+    {
+      cupsFileClose(src);
+      cupsFileClose(dst);
+      return (-1);
+    }
 
-    history = ippAddCollections(con->response, IPP_TAG_PRINTER,
-                                "printer-state-history",
-                                printer->num_history, NULL);
+ /*
+  * Close both files and return...
+  */
 
-    for (i = 0; i < printer->num_history; i ++)
-      copy_attrs(history->values[i].collection = ippNew(), printer->history[i],
-                 NULL, IPP_TAG_ZERO, 0);
-  }
+  cupsFileClose(src);
 
-  if (!ra || cupsArrayFind(ra, "printer-state-message"))
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
-                "printer-state-message", NULL, printer->state_message);
+  return (cupsFileClose(dst));
+}
 
-  if (!ra || cupsArrayFind(ra, "printer-state-reasons"))
-    add_printer_state_reasons(con, printer);
 
-  if (!ra || cupsArrayFind(ra, "printer-type"))
-  {
-    int type;                          /* printer-type value */
+/*
+ * 'copy_model()' - Copy a PPD model file, substituting default values
+ *                  as needed...
+ */
 
+static int                             /* O - 0 = success, -1 = error */
+copy_model(cupsd_client_t *con,                /* I - Client connection */
+           const char     *from,       /* I - Source file */
+           const char     *to)         /* I - Destination file */
+{
+  fd_set       *input;                 /* select() input set */
+  struct timeval timeout;              /* select() timeout */
+  int          maxfd;                  /* Maximum file descriptor for select() */
+  char         tempfile[1024];         /* Temporary PPD file */
+  int          tempfd;                 /* Temporary PPD file descriptor */
+  int          temppid;                /* Process ID of cups-driverd */
+  int          temppipe[2];            /* Temporary pipes */
+  char         *argv[4],               /* Command-line arguments */
+               *envp[MAX_ENV];         /* Environment */
+  cups_file_t  *src,                   /* Source file */
+               *dst;                   /* Destination file */
+  int          bytes,                  /* Bytes from pipe */
+               total;                  /* Total bytes from pipe */
+  char         buffer[2048],           /* Copy buffer */
+               *ptr;                   /* Pointer into buffer */
+  int          i;                      /* Looping var */
+  char         option[PPD_MAX_NAME],   /* Option name */
+               choice[PPD_MAX_NAME];   /* Choice name */
+  int          num_defaults;           /* Number of default options */
+  ppd_default_t        *defaults;              /* Default options */
+  char         cups_protocol[PPD_MAX_LINE];
+                                       /* cupsProtocol attribute */
+  int          have_letter,            /* Have Letter size */
+               have_a4;                /* Have A4 size */
+#ifdef HAVE_LIBPAPER
+  char         *paper_result;          /* Paper size name from libpaper */
+  char         system_paper[64];       /* Paper size name buffer */
+#endif /* HAVE_LIBPAPER */
 
-   /*
-    * Add the CUPS-specific printer-type attribute...
-    */
 
-    type = printer->type;
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                 "copy_model(con=%p, from=\"%s\", to=\"%s\")",
+                 con, from, to);
 
-    if (printer == DefaultPrinter)
-      type |= CUPS_PRINTER_DEFAULT;
+ /*
+  * Run cups-driverd to get the PPD file...
+  */
 
-    if (!printer->accepting)
-      type |= CUPS_PRINTER_REJECTING;
+  argv[0] = "cups-driverd";
+  argv[1] = "cat";
+  argv[2] = (char *)from;
+  argv[3] = NULL;
 
-    if (!printer->shared)
-      type |= CUPS_PRINTER_NOT_SHARED;
+  cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
 
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type",
-                 type);
+  snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin);
+  snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd);
+  tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+  if (tempfd < 0)
+    return (-1);
+
+  cupsdOpenPipe(temppipe);
+
+  if ((input = calloc(1, SetSize)) == NULL)
+  {
+    close(tempfd);
+    unlink(tempfile);
+
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "copy_model: Unable to allocate %d bytes for select()...",
+                    SetSize);
+    return (-1);
   }
 
-  if (!ra || cupsArrayFind(ra, "printer-up-time"))
-    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                  "printer-up-time", curtime);
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
+                  "copy_model: Running \"cups-driverd cat %s\"...", from);
 
-  if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) &&
-      !ippFindAttribute(printer->attrs, "printer-uri-supported",
-                        IPP_TAG_URI))
+  if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1],
+                         -1, 0, &temppid))
   {
-    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
-                     "ipp", NULL, con->servername, con->serverport,
-                    "/printers/%s", printer->name);
-    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
-                "printer-uri-supported", NULL, printer_uri);
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"",
-                    printer_uri);
+    free(input);
+    close(tempfd);
+    unlink(tempfile);
+    return (-1);
   }
 
-  if (!ra || cupsArrayFind(ra, "queued-job-count"))
-    add_queued_job_count(con, printer);
+  close(temppipe[1]);
 
-  copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0);
-  copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY);
-}
+ /*
+  * Wait up to 30 seconds for the PPD file to be copied...
+  */
 
+  total = 0;
 
-/*
- * 'copy_subscription_attrs()' - Copy subscription attributes.
- */
+  if (temppipe[0] > CGIPipes[0])
+    maxfd = temppipe[0] + 1;
+  else
+    maxfd = CGIPipes[0] + 1;
 
-static void
-copy_subscription_attrs(
-    cupsd_client_t       *con,         /* I - Client connection */
-    cupsd_subscription_t *sub,         /* I - Subscription */
-    cups_array_t         *ra)          /* I - Requested attributes array */
-{
-  ipp_attribute_t      *attr;          /* Current attribute */
-  char                 printer_uri[HTTP_MAX_URI];
-                                       /* Printer URI */
-  int                  count;          /* Number of events */
-  unsigned             mask;           /* Current event mask */
-  const char           *name;          /* Current event name */
+  for (;;)
+  {
+   /*
+    * See if we have data ready...
+    */
 
+    bytes = 0;
 
- /*
-  * Copy the subscription attributes to the response using the
-  * requested-attributes attribute that may be provided by the client.
-  */
+    FD_SET(temppipe[0], input);
+    FD_SET(CGIPipes[0], input);
 
-  if (!ra || cupsArrayFind(ra, "notify-events"))
-  {
-    if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL)
+    timeout.tv_sec  = 30;
+    timeout.tv_usec = 0;
+
+    if ((i = select(maxfd, input, NULL, NULL, &timeout)) < 0)
+    {
+      if (errno == EINTR)
+        continue;
+      else
+        break;
+    }
+    else if (i == 0)
     {
      /*
-      * Simple event list...
+      * We have timed out...
       */
 
-      ippAddString(con->response, IPP_TAG_SUBSCRIPTION,
-                   IPP_TAG_KEYWORD | IPP_TAG_COPY,
-                   "notify-events", NULL, name);
+      break;
     }
-    else
+
+    if (FD_ISSET(temppipe[0], input))
     {
      /*
-      * Complex event list...
+      * Read the PPD file from the pipe, and write it to the PPD file.
       */
 
-      for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1)
-       if (sub->mask & mask)
-          count ++;
-
-      attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION,
-                           IPP_TAG_KEYWORD | IPP_TAG_COPY,
-                           "notify-events", count, NULL, NULL);
-
-      for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1)
-       if (sub->mask & mask)
-       {
-          attr->values[count].string.text =
-             (char *)cupsdEventName((cupsd_eventmask_t)mask);
+      if ((bytes = read(temppipe[0], buffer, sizeof(buffer))) > 0)
+      {
+       if (write(tempfd, buffer, bytes) < bytes)
+          break;
 
-          count ++;
-       }
+       total += bytes;
+      }
+      else
+       break;
     }
+
+    if (FD_ISSET(CGIPipes[0], input))
+      cupsdUpdateCGI();
   }
 
-  if (sub->job && (!ra || cupsArrayFind(ra, "notify-job-id")))
-    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
-                  "notify-job-id", sub->job->id);
+  close(temppipe[0]);
+  close(tempfd);
 
-  if (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration")))
-    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
-                  "notify-lease-duration", sub->lease);
+  free(input);
 
-  if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri")))
+  if (!total)
   {
-    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
-                     "ipp", NULL, con->servername, con->serverport,
-                    "/printers/%s", sub->dest->name);
-    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
-                "notify-printer-uri", NULL, printer_uri);
+   /*
+    * No data from cups-deviced...
+    */
+
+    cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file!");
+    unlink(tempfile);
+    return (-1);
   }
 
-  if (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri")))
-    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
-                "notify-recipient-uri", NULL, sub->recipient);
-  else if (!ra || cupsArrayFind(ra, "notify-pull-method"))
-    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
-                 "notify-pull-method", NULL, "ippget");
+ /*
+  * Read the source file and see what page sizes are supported...
+  */
 
-  if (!ra || cupsArrayFind(ra, "notify-subscriber-user-name"))
-    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME,
-                "notify-subscriber-user-name", NULL, sub->owner);
+  if ((src = cupsFileOpen(tempfile, "rb")) == NULL)
+  {
+    unlink(tempfile);
+    return (-1);
+  }
 
-  if (!ra || cupsArrayFind(ra, "notify-subscription-id"))
-    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
-                  "notify-subscription-id", sub->id);
+  have_letter = 0;
+  have_a4     = 0;
 
-  if (!ra || cupsArrayFind(ra, "notify-time-interval"))
-    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
-                  "notify-time-interval", sub->interval);
+  while (cupsFileGets(src, buffer, sizeof(buffer)))
+    if (!strncmp(buffer, "*PageSize ", 10))
+    {
+     /*
+      * Strip UI text and command data from the end of the line...
+      */
 
-  if (sub->user_data_len > 0 && (!ra || cupsArrayFind(ra, "notify-user-data")))
-    ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data",
-                      sub->user_data, sub->user_data_len);
-}
+      if ((ptr = strchr(buffer + 10, '/')) != NULL)
+        *ptr = '\0';
+      if ((ptr = strchr(buffer + 10, ':')) != NULL)
+        *ptr = '\0';
 
+      for (ptr = buffer + 10; isspace(*ptr); ptr ++);
 
-/*
* 'create_job()' - Print a file to a printer or class.
- */
+     /*
     * Look for Letter and A4 page sizes...
     */
 
-static void
-create_job(cupsd_client_t  *con,       /* I - Client connection */
-          ipp_attribute_t *uri)        /* I - Printer URI */
-{
-  http_status_t        status;                 /* Policy status */
-  ipp_attribute_t *attr;               /* Current attribute */
-  const char   *dest;                  /* Destination */
-  cups_ptype_t dtype;                  /* Destination type (printer or class) */
-  int          priority;               /* Job priority */
-  char         *title;                 /* Job name/title */
-  cupsd_job_t  *job;                   /* Current job */
-  char         job_uri[HTTP_MAX_URI],  /* Job URI */
-               method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
-               host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI]; /* Resource portion of URI */
-  int          port;                   /* Port portion of URI */
-  cupsd_printer_t *printer;            /* Printer data */
-  int          kbytes;                 /* Size of print file */
-  int          i;                      /* Looping var */
-  int          lowerpagerange;         /* Page range bound */
+      if (!strcmp(ptr, "Letter"))
+       have_letter = 1;
 
+      if (!strcmp(ptr, "A4"))
+       have_a4 = 1;
+    }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con,
-                  con->http.fd, uri->values[0].string.text);
+  cupsFileRewind(src);
 
  /*
-  * Is the destination valid?
+  * Open the destination (if possible) and set the default options...
   */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
+  num_defaults     = 0;
+  defaults         = NULL;
+  cups_protocol[0] = '\0';
 
-  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
+  if ((dst = cupsFileOpen(to, "rb")) != NULL)
   {
    /*
-    * Bad URI...
+    * Read all of the default lines from the old PPD...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
-    return;
-  }
+    while (cupsFileGets(dst, buffer, sizeof(buffer)))
+      if (!strncmp(buffer, "*Default", 8))
+      {
+       /*
+       * Add the default option...
+       */
 
- /*
-  * Check remote printing to non-shared printer...
-  */
+        if (!ppd_parse_line(buffer, option, sizeof(option),
+                           choice, sizeof(choice)))
+          num_defaults = ppd_add_default(option, choice, num_defaults,
+                                        &defaults);
+      }
+      else if (!strncmp(buffer, "*cupsProtocol:", 14))
+        strlcpy(cups_protocol, buffer, sizeof(cups_protocol));
 
-  if (!printer->shared &&
-      strcasecmp(con->http.hostname, "localhost") &&
-      strcasecmp(con->http.hostname, ServerName))
-  {
-    send_ipp_status(con, IPP_NOT_AUTHORIZED,
-                    _("The printer or class is not shared!"));
-    return;
+    cupsFileClose(dst);
   }
+#ifdef HAVE_LIBPAPER
+  else if ((paper_result = systempapername()) != NULL)
+  {
+   /*
+    * Set the default media sizes from the systemwide default...
+    */
 
- /*
-  * Check policy...
-  */
+    strlcpy(system_paper, paper_result, sizeof(system_paper));
+    system_paper[0] = toupper(system_paper[0] & 255);
 
-  if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status);
-    return;
+    if ((!strcmp(system_paper, "Letter") && have_letter) ||
+        (!strcmp(system_paper, "A4") && have_a4))
+    {
+      num_defaults = ppd_add_default("PageSize", system_paper, 
+                                    num_defaults, &defaults);
+      num_defaults = ppd_add_default("PageRegion", system_paper, 
+                                    num_defaults, &defaults);
+      num_defaults = ppd_add_default("PaperDimension", system_paper, 
+                                    num_defaults, &defaults);
+      num_defaults = ppd_add_default("ImageableArea", system_paper, 
+                                    num_defaults, &defaults);
+    }
   }
-  else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && !con->username[0])
+#endif /* HAVE_LIBPAPER */
+  else
   {
-    send_http_error(con, HTTP_UNAUTHORIZED);
-    return;
+   /*
+    * Add the default media sizes...
+    *
+    * Note: These values are generally not valid for large-format devices
+    *       like plotters, however it is probably safe to say that those
+    *       users will configure the media size after initially adding
+    *       the device anyways...
+    */
+
+    if (!DefaultLanguage ||
+        !strcasecmp(DefaultLanguage, "C") ||
+        !strcasecmp(DefaultLanguage, "POSIX") ||
+       !strcasecmp(DefaultLanguage, "en") ||
+       !strncasecmp(DefaultLanguage, "en_US", 5) ||
+       !strncasecmp(DefaultLanguage, "en_CA", 5) ||
+       !strncasecmp(DefaultLanguage, "fr_CA", 5))
+    {
+     /*
+      * These are the only locales that will default to "letter" size...
+      */
+
+      if (have_letter)
+      {
+       num_defaults = ppd_add_default("PageSize", "Letter", num_defaults,
+                                       &defaults);
+       num_defaults = ppd_add_default("PageRegion", "Letter", num_defaults,
+                                       &defaults);
+       num_defaults = ppd_add_default("PaperDimension", "Letter", num_defaults,
+                                       &defaults);
+       num_defaults = ppd_add_default("ImageableArea", "Letter", num_defaults,
+                                       &defaults);
+      }
+    }
+    else if (have_a4)
+    {
+     /*
+      * The rest default to "a4" size...
+      */
+
+      num_defaults = ppd_add_default("PageSize", "A4", num_defaults,
+                                     &defaults);
+      num_defaults = ppd_add_default("PageRegion", "A4", num_defaults,
+                                     &defaults);
+      num_defaults = ppd_add_default("PaperDimension", "A4", num_defaults,
+                                     &defaults);
+      num_defaults = ppd_add_default("ImageableArea", "A4", num_defaults,
+                                     &defaults);
+    }
   }
 
  /*
-  * See if the printer is accepting jobs...
+  * Open the destination file for a copy...
   */
 
-  if (!printer->accepting)
+  if ((dst = cupsFileOpen(to, "wb")) == NULL)
   {
-    send_ipp_status(con, IPP_NOT_ACCEPTING,
-                    _("Destination \"%s\" is not accepting jobs."),
-                    dest);
-    return;
+    if (num_defaults > 0)
+      free(defaults);
+
+    cupsFileClose(src);
+    unlink(tempfile);
+    return (-1);
   }
 
  /*
-  * Validate job template attributes; for now just copies and page-ranges...
+  * Copy the source file to the destination...
   */
 
-  if ((attr = ippFindAttribute(con->request, "copies",
-                               IPP_TAG_INTEGER)) != NULL)
+  while (cupsFileGets(src, buffer, sizeof(buffer)))
   {
-    if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies)
+    if (!strncmp(buffer, "*Default", 8))
     {
-      send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."),
-                      attr->values[0].integer);
-      ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER,
-                   "copies", attr->values[0].integer);
-      return;
-    }
-  }
+     /*
+      * Check for an previous default option choice...
+      */
 
-  if ((attr = ippFindAttribute(con->request, "page-ranges",
-                               IPP_TAG_RANGE)) != NULL)
-  {
-    for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++)
-    {
-      if (attr->values[i].range.lower < lowerpagerange || 
-         attr->values[i].range.lower > attr->values[i].range.upper)
+      if (!ppd_parse_line(buffer, option, sizeof(option),
+                         choice, sizeof(choice)))
       {
-       send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Bad page-ranges values %d-%d."),
-                       attr->values[i].range.lower,
-                       attr->values[i].range.upper);
-       return;
-      }
+        for (i = 0; i < num_defaults; i ++)
+         if (!strcmp(option, defaults[i].option))
+         {
+          /*
+           * Substitute the previous choice...
+           */
 
-      lowerpagerange = attr->values[i].range.upper + 1;
+           snprintf(buffer, sizeof(buffer), "*Default%s: %s", option,
+                    defaults[i].choice);
+           break;
+         }
+      }
     }
+
+    cupsFilePrintf(dst, "%s\n", buffer);
   }
 
+  if (cups_protocol[0])
+    cupsFilePrintf(dst, "%s\n", cups_protocol);
+
+  if (num_defaults > 0)
+    free(defaults);
+
  /*
-  * Make sure we aren't over our limit...
+  * Close both files and return...
   */
 
-  if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs)
-    cupsdCleanJobs();
+  cupsFileClose(src);
+
+  unlink(tempfile);
+
+  return (cupsFileClose(dst));
+}
+
+
+/*
+ * 'copy_job_attrs()' - Copy job attributes.
+ */
 
-  if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs)
-  {
-    send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Too many active jobs."));
-    return;
-  }
+static void
+copy_job_attrs(cupsd_client_t *con,    /* I - Client connection */
+              cupsd_job_t    *job,     /* I - Job */
+              cups_array_t   *ra)      /* I - Requested attributes array */
+{
+  char job_uri[HTTP_MAX_URI];          /* Job URI */
 
-  if (!check_quotas(con, printer))
-  {
-    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached."));
-    return;
-  }
 
  /*
-  * Create the job and set things up...
+  * Send the requested attributes for each job...
   */
 
-  if ((attr = ippFindAttribute(con->request, "job-priority",
-                               IPP_TAG_INTEGER)) != NULL)
-    priority = attr->values[0].integer;
-  else
-    ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
-                  priority = 50);
+  httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
+                   con->servername, con->serverport, "/jobs/%d",
+                  job->id);
 
-  if ((attr = ippFindAttribute(con->request, "job-name",
-                               IPP_TAG_NAME)) != NULL)
-    title = attr->values[0].string.text;
-  else
-    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
-                 title = "Untitled");
+  if (!ra || cupsArrayFind(ra, "job-more-info"))
+    ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+                "job-more-info", NULL, job_uri);
 
-  if ((job = cupsdAddJob(priority, printer->name)) == NULL)
-  {
-    send_ipp_status(con, IPP_INTERNAL_ERROR,
-                    _("Unable to add job for destination \"%s\"!"), dest);
-    return;
-  }
+  if (job->state_value > IPP_JOB_PROCESSING &&
+      (!ra || cupsArrayFind(ra, "job-preserved")))
+    ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved",
+                  job->num_files > 0);
 
-  job->dtype   = dtype;
-  job->attrs   = con->request;
-  con->request = NULL;
+  if (!ra || cupsArrayFind(ra, "job-printer-up-time"))
+    ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
+                  "job-printer-up-time", time(NULL));
 
-  add_job_uuid(con, job);
+  if (!ra || cupsArrayFind(ra, "job-state-reasons"))
+    add_job_state_reasons(con, job);
 
-  attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME);
+  if (!ra || cupsArrayFind(ra, "job-uri"))
+    ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+                "job-uri", NULL, job_uri);
 
-  if (con->username[0])
-  {
-    cupsdSetString(&job->username, con->username);
+  copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0);
+}
 
-    if (attr)
-      cupsdSetString(&attr->values[0].string.text, con->username);
 
-    save_auth_info(con, job);
-  }
-  else if (attr)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "create_job: requesting-user-name = \"%s\"",
-                    attr->values[0].string.text);
+/*
+ * 'copy_printer_attrs()' - Copy printer attributes.
+ */
 
-    cupsdSetString(&job->username, attr->values[0].string.text);
-  }
-  else
-    cupsdSetString(&job->username, "anonymous");
+static void
+copy_printer_attrs(
+    cupsd_client_t  *con,              /* I - Client connection */
+    cupsd_printer_t *printer,          /* I - Printer */
+    cups_array_t    *ra)               /* I - Requested attributes array */
+{
+  char                 printer_uri[HTTP_MAX_URI];
+                                       /* Printer URI */
+  time_t               curtime;        /* Current time */
+  int                  i;              /* Looping var */
+  ipp_attribute_t      *history;       /* History collection */
 
-  if (!attr)
-    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
-                 "job-originating-user-name", NULL, job->username);
-  else
-  {
-    attr->group_tag = IPP_TAG_JOB;
-    cupsdSetString(&attr->name, "job-originating-user-name");
-  }
 
-  if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
-                               IPP_TAG_ZERO)) != NULL)
-  {
-   /*
-    * Request contains a job-originating-host-name attribute; validate it...
-    */
+ /*
+  * Copy the printer attributes to the response using requested-attributes
+  * and document-format attributes that may be provided by the client.
+  */
 
-    if (attr->value_tag != IPP_TAG_NAME ||
-        attr->num_values != 1 ||
-        strcmp(con->http.hostname, "localhost"))
-    {
-     /*
-      * Can't override the value if we aren't connected via localhost.
-      * Also, we can only have 1 value and it must be a name value.
-      */
+  curtime = time(NULL);
 
-      switch (attr->value_tag)
-      {
-        case IPP_TAG_STRING :
-       case IPP_TAG_TEXTLANG :
-       case IPP_TAG_NAMELANG :
-       case IPP_TAG_TEXT :
-       case IPP_TAG_NAME :
-       case IPP_TAG_KEYWORD :
-       case IPP_TAG_URI :
-       case IPP_TAG_URISCHEME :
-       case IPP_TAG_CHARSET :
-       case IPP_TAG_LANGUAGE :
-       case IPP_TAG_MIMETYPE :
-          /*
-           * Free old strings...
-           */
+#ifdef __APPLE__
+  if ((!ra || cupsArrayFind(ra, "com.apple.print.recoverable-message")) &&
+      printer->recoverable)
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+                 "com.apple.print.recoverable-message", NULL,
+                printer->recoverable);
+#endif /* __APPLE__ */
 
-           for (i = 0; i < attr->num_values; i ++)
-           {
-             _cups_sp_free(attr->values[i].string.text);
-             attr->values[i].string.text = NULL;
-             if (attr->values[i].string.charset)
-             {
-               _cups_sp_free(attr->values[i].string.charset);
-               attr->values[i].string.charset = NULL;
-             }
-            }
+  if (!ra || cupsArrayFind(ra, "printer-current-time"))
+    ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
+               ippTimeToDate(curtime));
 
-       default :
-            break;
-      }
+  if (!ra || cupsArrayFind(ra, "printer-error-policy"))
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
+                "printer-error-policy", NULL, printer->error_policy);
 
-     /*
-      * Use the default connection hostname instead...
-      */
+  if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs"))
+    ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
+                  printer->accepting);
 
-      attr->value_tag             = IPP_TAG_NAME;
-      attr->num_values            = 1;
-      attr->values[0].string.text = _cups_sp_alloc(con->http.hostname);
-    }
+  if (!ra || cupsArrayFind(ra, "printer-is-shared"))
+    ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared",
+                  printer->shared);
 
-    attr->group_tag = IPP_TAG_JOB;
-  }
-  else
+  if (!ra || cupsArrayFind(ra, "printer-op-policy"))
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
+                "printer-op-policy", NULL, printer->op_policy);
+
+  if (!ra || cupsArrayFind(ra, "printer-state"))
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+                  printer->state);
+
+  if (!ra || cupsArrayFind(ra, "printer-state-change-time"))
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                  "printer-state-change-time", printer->state_time);
+                
+  if (MaxPrinterHistory > 0 && printer->num_history > 0 &&
+      cupsArrayFind(ra, "printer-state-history"))
   {
    /*
-    * No job-originating-host-name attribute, so use the hostname from
-    * the connection...
+    * Printer history is only sent if specifically requested, so that
+    * older CUPS/IPP clients won't barf on the collection attributes.
     */
 
-    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, 
-                "job-originating-host-name", NULL, con->http.hostname);
+    history = ippAddCollections(con->response, IPP_TAG_PRINTER,
+                                "printer-state-history",
+                                printer->num_history, NULL);
+
+    for (i = 0; i < printer->num_history; i ++)
+      copy_attrs(history->values[i].collection = ippNew(), printer->history[i],
+                 NULL, IPP_TAG_ZERO, 0);
   }
 
-  ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation",
-                time(NULL));
-  attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                       "time-at-processing", 0);
-  attr->value_tag = IPP_TAG_NOVALUE;
-  attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                       "time-at-completed", 0);
-  attr->value_tag = IPP_TAG_NOVALUE;
+  if (!ra || cupsArrayFind(ra, "printer-state-message"))
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+                "printer-state-message", NULL, printer->state_message);
 
- /*
-  * Add remaining job attributes...
-  */
+  if (!ra || cupsArrayFind(ra, "printer-state-reasons"))
+    add_printer_state_reasons(con, printer);
 
-  ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
-  job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM,
-                             "job-state", IPP_JOB_STOPPED);
-  job->state_value = job->state->values[0].integer;
-  job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                              "job-media-sheets-completed", 0);
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
-               printer->uri);
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
-               title);
+  if (!ra || cupsArrayFind(ra, "printer-type"))
+  {
+    int type;                          /* printer-type value */
 
-  if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
-                               IPP_TAG_INTEGER)) != NULL)
-    attr->values[0].integer = 0;
-  else
-    attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                         "job-k-octets", 0);
 
-  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
-                               IPP_TAG_KEYWORD)) == NULL)
-    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
-  if (!attr)
-    attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                        "job-hold-until", NULL, "no-hold");
-  if (attr && strcmp(attr->values[0].string.text, "no-hold") &&
-      !(printer->type & CUPS_PRINTER_REMOTE))
-  {
    /*
-    * Hold job until specified time...
+    * Add the CUPS-specific printer-type attribute...
     */
 
-    cupsdSetJobHoldUntil(job, attr->values[0].string.text);
+    type = printer->type;
+
+    if (printer == DefaultPrinter)
+      type |= CUPS_PRINTER_DEFAULT;
+
+    if (!printer->accepting)
+      type |= CUPS_PRINTER_REJECTING;
+
+    if (!printer->shared)
+      type |= CUPS_PRINTER_NOT_SHARED;
+
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type",
+                 type);
   }
-  else
-    job->hold_until = time(NULL) + 60;
 
-  job->state->values[0].integer = IPP_JOB_HELD;
-  job->state_value              = IPP_JOB_HELD;
+  if (!ra || cupsArrayFind(ra, "printer-up-time"))
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                  "printer-up-time", curtime);
 
-  if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
-      Classification)
+  if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) &&
+      !ippFindAttribute(printer->attrs, "printer-uri-supported",
+                        IPP_TAG_URI))
   {
-   /*
-    * Add job sheets options...
-    */
+    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
+                     "ipp", NULL, con->servername, con->serverport,
+                    "/printers/%s", printer->name);
+    ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
+                "printer-uri-supported", NULL, printer_uri);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"",
+                    printer_uri);
+  }
 
-    if ((attr = ippFindAttribute(job->attrs, "job-sheets",
-                                 IPP_TAG_ZERO)) == NULL)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "Adding default job-sheets values \"%s,%s\"...",
-                      printer->job_sheets[0], printer->job_sheets[1]);
+  if (!ra || cupsArrayFind(ra, "queued-job-count"))
+    add_queued_job_count(con, printer);
 
-      attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
-                           2, NULL, NULL);
-      attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]);
-      attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]);
-    }
+  copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0);
+  copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY);
+}
 
-    job->job_sheets = attr;
 
-   /*
   * Enforce classification level if set...
   */
+/*
* 'copy_subscription_attrs()' - Copy subscription attributes.
+ */
 
-    if (Classification)
-    {
-      cupsdLogMessage(CUPSD_LOG_INFO,
-                      "Classification=\"%s\", ClassifyOverride=%d",
-                      Classification ? Classification : "(null)",
-                     ClassifyOverride);
+static void
+copy_subscription_attrs(
+    cupsd_client_t       *con,         /* I - Client connection */
+    cupsd_subscription_t *sub,         /* I - Subscription */
+    cups_array_t         *ra)          /* I - Requested attributes array */
+{
+  ipp_attribute_t      *attr;          /* Current attribute */
+  char                 printer_uri[HTTP_MAX_URI];
+                                       /* Printer URI */
+  int                  count;          /* Number of events */
+  unsigned             mask;           /* Current event mask */
+  const char           *name;          /* Current event name */
 
-      if (ClassifyOverride)
-      {
-        if (!strcmp(attr->values[0].string.text, "none") &&
-           (attr->num_values == 1 ||
-            !strcmp(attr->values[1].string.text, "none")))
-        {
-        /*
-          * Force the leading banner to have the classification on it...
-         */
 
-          cupsdSetString(&attr->values[0].string.text, Classification);
+ /*
+  * Copy the subscription attributes to the response using the
+  * requested-attributes attribute that may be provided by the client.
+  */
 
-         cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED "
-                                           "job-sheets=\"%s,none\", "
-                                           "job-originating-user-name=\"%s\"",
-                        job->id, Classification, job->username);
-       }
-       else if (attr->num_values == 2 &&
-                strcmp(attr->values[0].string.text,
-                       attr->values[1].string.text) &&
-                strcmp(attr->values[0].string.text, "none") &&
-                strcmp(attr->values[1].string.text, "none"))
-        {
-        /*
-         * Can't put two different security markings on the same document!
-         */
+  if (!ra || cupsArrayFind(ra, "notify-events"))
+  {
+    if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL)
+    {
+     /*
+      * Simple event list...
+      */
 
-          cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
+      ippAddString(con->response, IPP_TAG_SUBSCRIPTION,
+                   IPP_TAG_KEYWORD | IPP_TAG_COPY,
+                   "notify-events", NULL, name);
+    }
+    else
+    {
+     /*
+      * Complex event list...
+      */
 
-         cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED "
-                                           "job-sheets=\"%s,%s\", "
-                                           "job-originating-user-name=\"%s\"",
-                        job->id, attr->values[0].string.text,
-                        attr->values[1].string.text, job->username);
-       }
-       else if (strcmp(attr->values[0].string.text, Classification) &&
-                strcmp(attr->values[0].string.text, "none") &&
-                (attr->num_values == 1 ||
-                 (strcmp(attr->values[1].string.text, Classification) &&
-                  strcmp(attr->values[1].string.text, "none"))))
-        {
-         if (attr->num_values == 1)
-            cupsdLogMessage(CUPSD_LOG_NOTICE,
-                           "[Job %d] CLASSIFICATION OVERRIDDEN "
-                           "job-sheets=\"%s\", "
-                           "job-originating-user-name=\"%s\"",
-                      job->id, attr->values[0].string.text, job->username);
-          else
-            cupsdLogMessage(CUPSD_LOG_NOTICE,
-                           "[Job %d] CLASSIFICATION OVERRIDDEN "
-                           "job-sheets=\"%s,%s\",fffff "
-                           "job-originating-user-name=\"%s\"",
-                           job->id, attr->values[0].string.text,
-                           attr->values[1].string.text, job->username);
-        }
-      }
-      else if (strcmp(attr->values[0].string.text, Classification) &&
-               (attr->num_values == 1 ||
-              strcmp(attr->values[1].string.text, Classification)))
-      {
-       /*
-        * Force the banner to have the classification on it...
-       */
+      for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1)
+       if (sub->mask & mask)
+          count ++;
 
-        if (attr->num_values > 1 &&
-           !strcmp(attr->values[0].string.text, attr->values[1].string.text))
-       {
-          cupsdSetString(&(attr->values[0].string.text), Classification);
-          cupsdSetString(&(attr->values[1].string.text), Classification);
-       }
-        else
-       {
-          if (attr->num_values == 1 ||
-             strcmp(attr->values[0].string.text, "none"))
-            cupsdSetString(&(attr->values[0].string.text), Classification);
+      attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION,
+                           IPP_TAG_KEYWORD | IPP_TAG_COPY,
+                           "notify-events", count, NULL, NULL);
 
-          if (attr->num_values > 1 &&
-             strcmp(attr->values[1].string.text, "none"))
-            cupsdSetString(&(attr->values[1].string.text), Classification);
-        }
+      for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1)
+       if (sub->mask & mask)
+       {
+          attr->values[count].string.text =
+             (char *)cupsdEventName((cupsd_eventmask_t)mask);
 
-        if (attr->num_values > 1)
-         cupsdLogMessage(CUPSD_LOG_NOTICE,
-                         "[Job %d] CLASSIFICATION FORCED "
-                         "job-sheets=\"%s,%s\", "
-                         "job-originating-user-name=\"%s\"",
-                         job->id, attr->values[0].string.text,
-                         attr->values[1].string.text, job->username);
-        else
-         cupsdLogMessage(CUPSD_LOG_NOTICE,
-                         "[Job %d] CLASSIFICATION FORCED "
-                         "job-sheets=\"%s\", "
-                         "job-originating-user-name=\"%s\"",
-                        job->id, Classification, job->username);
-      }
+          count ++;
+       }
     }
+  }
 
-   /*
-    * See if we need to add the starting sheet...
-    */
-
-    if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
-    {
-      cupsdLogMessage(CUPSD_LOG_INFO,
-                      "Adding start banner page \"%s\" to job %d.",
-                      attr->values[0].string.text, job->id);
+  if (sub->job && (!ra || cupsArrayFind(ra, "notify-job-id")))
+    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+                  "notify-job-id", sub->job->id);
 
-      kbytes = copy_banner(con, job, attr->values[0].string.text);
+  if (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration")))
+    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+                  "notify-lease-duration", sub->lease);
 
-      cupsdUpdateQuota(printer, job->username, 0, kbytes);
-    }
+  if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri")))
+  {
+    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
+                     "ipp", NULL, con->servername, con->serverport,
+                    "/printers/%s", sub->dest->name);
+    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
+                "notify-printer-uri", NULL, printer_uri);
   }
-  else if ((attr = ippFindAttribute(job->attrs, "job-sheets",
-                                    IPP_TAG_ZERO)) != NULL)
-    job->sheets = attr;
 
- /*
-  * Fill in the response info...
-  */
+  if (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri")))
+    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
+                "notify-recipient-uri", NULL, sub->recipient);
+  else if (!ra || cupsArrayFind(ra, "notify-pull-method"))
+    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
+                 "notify-pull-method", NULL, "ippget");
 
-  snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
-          LocalPort, job->id);
+  if (!ra || cupsArrayFind(ra, "notify-subscriber-user-name"))
+    ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME,
+                "notify-subscriber-user-name", NULL, sub->owner);
 
-  ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, job_uri);
+  if (!ra || cupsArrayFind(ra, "notify-subscription-id"))
+    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+                  "notify-subscription-id", sub->id);
 
-  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+  if (!ra || cupsArrayFind(ra, "notify-time-interval"))
+    ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+                  "notify-time-interval", sub->interval);
 
-  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
-                job->state_value);
+  if (sub->user_data_len > 0 && (!ra || cupsArrayFind(ra, "notify-user-data")))
+    ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data",
+                      sub->user_data, sub->user_data_len);
+}
 
-  con->response->request.status.status_code = IPP_OK;
 
- /*
-  * Add any job subscriptions...
-  */
+/*
+ * 'create_job()' - Print a file to a printer or class.
+ */
+
+static void
+create_job(cupsd_client_t  *con,       /* I - Client connection */
+          ipp_attribute_t *uri)        /* I - Printer URI */
+{
+  cupsd_job_t  *job;                   /* New job */
+
 
-  add_job_subscriptions(con, job);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
 
  /*
-  * Set all but the first two attributes to the job attributes group...
+  * Create the job object...
   */
 
-  for (attr = job->attrs->attrs->next->next; attr; attr = attr->next)
-    attr->group_tag = IPP_TAG_JOB;
+  if ((job = add_job(con, uri, NULL)) == NULL)
+    return;
 
  /*
   * Save and log the job...
@@ -4515,8 +4429,6 @@ create_job(cupsd_client_t  *con,  /* I - Client connection */
 
   cupsdLogMessage(CUPSD_LOG_INFO, "Job %d created on \"%s\" by \"%s\".",
                   job->id, job->dest, job->username);
-
-  cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created.");
 }
 
 
@@ -5210,7 +5122,7 @@ get_devices(cupsd_client_t *con)  /* I - Client connection */
 
   snprintf(command, sizeof(command), "%s/daemon/cups-deviced", ServerBin);
   snprintf(options, sizeof(options),
-           "cups-deviced %d+%d+%d+requested-attributes=%s",
+           "%d+%d+%d+requested-attributes=%s",
            con->request->request.op.request_id,
            limit ? limit->values[0].integer : 0, User,
           attrs);
@@ -5662,378 +5574,168 @@ get_notifications(cupsd_client_t *con)        /* I - Client connection */
     else
       j = min_seq - sub->first_event_id;
 
-    for (; j < sub->num_events; j ++)
-    {
-      ippAddSeparator(con->response);
-
-      copy_attrs(con->response, sub->events[j]->attrs, NULL,
-                IPP_TAG_EVENT_NOTIFICATION, 0);
-    }
-  }
-}
-
-
-/*
- * 'get_ppds()' - Get the list of PPD files on the local system.
- */
-
-static void
-get_ppds(cupsd_client_t *con)          /* I - Client connection */
-{
-  http_status_t                status;         /* Policy status */
-  int                  i;              /* Looping var */
-  ipp_attribute_t      *limit,         /* Limit attribute */
-                       *make,          /* ppd-make attribute */
-                       *requested;     /* requested-attributes attribute */
-  char                 command[1024],  /* cups-deviced command */
-                       options[1024],  /* Options to pass to command */
-                       attrs[1024],    /* String for requested attributes */
-                       *aptr;          /* Pointer into string */
-  int                  alen;           /* Length of attribute value */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd);
-
- /*
-  * Check policy...
-  */
-
-  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status);
-    return;
-  }
-
- /*
-  * Run cups-driverd command with the given options...
-  */
-
-  limit     = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER);
-  make      = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT);
-  requested = ippFindAttribute(con->request, "requested-attributes",
-                               IPP_TAG_KEYWORD);
-
-  if (requested)
-  {
-    for (i = 0, aptr = attrs; i < requested->num_values; i ++)
-    {
-     /*
-      * Check that we have enough room...
-      */
-
-      alen = strlen(requested->values[i].string.text);
-      if (alen > (sizeof(attrs) - (aptr - attrs) - 2))
-        break;
-
-     /*
-      * Put commas between values...
-      */
-
-      if (i)
-        *aptr++ = ',';
-
-     /*
-      * Add the value to the end of the string...
-      */
-
-      strcpy(aptr, requested->values[i].string.text);
-      aptr += alen;
-    }
-
-   /*
-    * If we have more attribute names than will fit, default to "all"...
-    */
-
-    if (i < requested->num_values)
-      strcpy(attrs, "all");
-  }
-  else
-    strcpy(attrs, "all");
-
-  snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin);
-  snprintf(options, sizeof(options),
-           "cups-driverd list+%d+%d+requested-attributes=%s%s%s",
-           con->request->request.op.request_id,
-           limit ? limit->values[0].integer : 0,
-          attrs,
-          make ? "%20ppd-make=" : "",
-          make ? make->values[0].string.text : "");
-
-  if (cupsdSendCommand(con, command, options, 0))
-  {
-   /*
-    * Command started successfully, don't send an IPP response here...
-    */
-
-    ippDelete(con->response);
-    con->response = NULL;
-  }
-  else
-  {
-   /*
-    * Command failed, return "internal error" so the user knows something
-    * went wrong...
-    */
-
-    send_ipp_status(con, IPP_INTERNAL_ERROR,
-                    _("cups-driverd failed to execute."));
-  }
-}
-
-
-/*
- * 'get_printer_attrs()' - Get printer attributes.
- */
-
-static void
-get_printer_attrs(cupsd_client_t  *con,        /* I - Client connection */
-                 ipp_attribute_t *uri) /* I - Printer URI */
-{
-  http_status_t                status;         /* Policy status */
-  const char           *dest;          /* Destination */
-  cups_ptype_t         dtype;          /* Destination type (printer or class) */
-  char                 method[HTTP_MAX_URI],
-                                       /* Method portion of URI */
-                       username[HTTP_MAX_URI],
-                                       /* Username portion of URI */
-                       host[HTTP_MAX_URI],
-                                       /* Host portion of URI */
-                       resource[HTTP_MAX_URI];
-                                       /* Resource portion of URI */
-  int                  port;           /* Port portion of URI */
-  cupsd_printer_t      *printer;       /* Printer/class */
-  cups_array_t         *ra;            /* Requested attributes array */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con,
-                  con->http.fd, uri->values[0].string.text);
-
- /*
-  * Is the destination valid?
-  */
-
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
-
-  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
-  {
-   /*
-    * Bad URI...
-    */
-
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
-    return;
-  }
-
- /*
-  * Check policy...
-  */
-
-  if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status);
-    return;
-  }
-
- /*
-  * Send the attributes...
-  */
-
-  ra = create_requested_array(con->request);
-
-  copy_printer_attrs(con, printer, ra);
-
-  cupsArrayDelete(ra);
-
-  con->response->request.status.status_code = IPP_OK;
-}
-
-
-/*
- * 'get_printers()' - Get a list of printers or classes.
- */
-
-static void
-get_printers(cupsd_client_t *con,      /* I - Client connection */
-             int            type)      /* I - 0 or CUPS_PRINTER_CLASS */
-{
-  http_status_t        status;                 /* Policy status */
-  ipp_attribute_t *attr;               /* Current attribute */
-  int          limit;                  /* Maximum number of printers to return */
-  int          count;                  /* Number of printers that match */
-  cupsd_printer_t *printer;            /* Current printer pointer */
-  int          printer_type,           /* printer-type attribute */
-               printer_mask;           /* printer-type-mask attribute */
-  char         *location;              /* Location string */
-  const char   *username;              /* Current user */
-  char         *first_printer_name;    /* first-printer-name attribute */
-  cups_array_t *ra;                    /* Requested attributes array */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con,
-                  con->http.fd, type);
-
- /*
-  * Check policy...
-  */
-
-  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status);
-    return;
-  }
-
- /*
-  * Check for printers...
-  */
-
-  if (!Printers || !cupsArrayCount(Printers))
-  {
-    send_ipp_status(con, IPP_NOT_FOUND, _("No destinations added."));
-    return;
-  }
-
- /*
-  * See if they want to limit the number of printers reported...
-  */
-
-  if ((attr = ippFindAttribute(con->request, "limit",
-                               IPP_TAG_INTEGER)) != NULL)
-    limit = attr->values[0].integer;
-  else
-    limit = 10000000;
-
-  if ((attr = ippFindAttribute(con->request, "first-printer-name",
-                               IPP_TAG_NAME)) != NULL)
-    first_printer_name = attr->values[0].string.text;
-  else
-    first_printer_name = NULL;
+    for (; j < sub->num_events; j ++)
+    {
+      ippAddSeparator(con->response);
 
- /*
-  * Support filtering...
-  */
+      copy_attrs(con->response, sub->events[j]->attrs, NULL,
+                IPP_TAG_EVENT_NOTIFICATION, 0);
+    }
+  }
+}
 
-  if ((attr = ippFindAttribute(con->request, "printer-type",
-                               IPP_TAG_ENUM)) != NULL)
-    printer_type = attr->values[0].integer;
-  else
-    printer_type = 0;
 
-  if ((attr = ippFindAttribute(con->request, "printer-type-mask",
-                               IPP_TAG_ENUM)) != NULL)
-    printer_mask = attr->values[0].integer;
-  else
-    printer_mask = 0;
+/*
+ * 'get_ppds()' - Get the list of PPD files on the local system.
+ */
 
-  if ((attr = ippFindAttribute(con->request, "printer-location",
-                               IPP_TAG_TEXT)) != NULL)
-    location = attr->values[0].string.text;
-  else
-    location = NULL;
+static void
+get_ppds(cupsd_client_t *con)          /* I - Client connection */
+{
+  http_status_t                status;         /* Policy status */
+  int                  i;              /* Looping var */
+  ipp_attribute_t      *limit,         /* Limit attribute */
+                       *make,          /* ppd-make attribute */
+                       *requested;     /* requested-attributes attribute */
+  char                 command[1024],  /* cups-deviced command */
+                       options[1024],  /* Options to pass to command */
+                       attrs[1024],    /* String for requested attributes */
+                       *aptr;          /* Pointer into string */
+  int                  alen;           /* Length of attribute value */
 
-  if (con->username[0])
-    username = con->username;
-  else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
-                                    IPP_TAG_NAME)) != NULL)
-    username = attr->values[0].string.text;
-  else
-    username = NULL;
 
-  ra = create_requested_array(con->request);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd);
 
  /*
-  * OK, build a list of printers for this printer...
+  * Check policy...
   */
 
-  if (first_printer_name)
+  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
   {
-    if ((printer = cupsdFindDest(first_printer_name)) == NULL)
-      printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
+    send_http_error(con, status);
+    return;
   }
-  else
-    printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
 
-  for (count = 0;
-       count < limit && printer;
-       printer = (cupsd_printer_t *)cupsArrayNext(Printers))
+ /*
+  * Run cups-driverd command with the given options...
+  */
+
+  limit     = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER);
+  make      = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT);
+  requested = ippFindAttribute(con->request, "requested-attributes",
+                               IPP_TAG_KEYWORD);
+
+  if (requested)
   {
-    if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) &&
-        (printer->type & printer_mask) == printer_type &&
-       (!location || !printer->location ||
-        !strcasecmp(printer->location, location)))
+    for (i = 0, aptr = attrs; i < requested->num_values; i ++)
     {
      /*
-      * If HideImplicitMembers is enabled, see if this printer or class
-      * is a member of an implicit class...
+      * Check that we have enough room...
       */
 
-      if (ImplicitClasses && HideImplicitMembers &&
-          printer->in_implicit_class)
-        continue;
+      alen = strlen(requested->values[i].string.text);
+      if (alen > (sizeof(attrs) - (aptr - attrs) - 2))
+        break;
 
      /*
-      * If a username is specified, see if it is allowed or denied
-      * access...
+      * Put commas between values...
       */
 
-      if (printer->num_users && username && !user_allowed(printer, username))
-        continue;
+      if (i)
+        *aptr++ = ',';
 
      /*
-      * Add the group separator as needed...
+      * Add the value to the end of the string...
       */
 
-      if (count > 0)
-        ippAddSeparator(con->response);
-
-      count ++;
+      strcpy(aptr, requested->values[i].string.text);
+      aptr += alen;
+    }
 
-     /*
-      * Send the attributes...
-      */
+   /*
+    * If we have more attribute names than will fit, default to "all"...
+    */
 
-      copy_printer_attrs(con, printer, ra);
-    }
+    if (i < requested->num_values)
+      strcpy(attrs, "all");
   }
+  else
+    strcpy(attrs, "all");
 
-  cupsArrayDelete(ra);
+  snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin);
+  snprintf(options, sizeof(options),
+           "list+%d+%d+requested-attributes=%s%s%s",
+           con->request->request.op.request_id,
+           limit ? limit->values[0].integer : 0,
+          attrs,
+          make ? "%20ppd-make=" : "",
+          make ? make->values[0].string.text : "");
 
-  con->response->request.status.status_code = IPP_OK;
+  if (cupsdSendCommand(con, command, options, 0))
+  {
+   /*
+    * Command started successfully, don't send an IPP response here...
+    */
+
+    ippDelete(con->response);
+    con->response = NULL;
+  }
+  else
+  {
+   /*
+    * Command failed, return "internal error" so the user knows something
+    * went wrong...
+    */
+
+    send_ipp_status(con, IPP_INTERNAL_ERROR,
+                    _("cups-driverd failed to execute."));
+  }
 }
 
 
 /*
- * 'get_subscription_attrs()' - Get subscription attributes.
+ * 'get_printer_attrs()' - Get printer attributes.
  */
 
 static void
-get_subscription_attrs(
-    cupsd_client_t *con,               /* I - Client connection */
-    int            sub_id)             /* I - Subscription ID */
+get_printer_attrs(cupsd_client_t  *con,        /* I - Client connection */
+                 ipp_attribute_t *uri) /* I - Printer URI */
 {
   http_status_t                status;         /* Policy status */
-  cupsd_subscription_t *sub;           /* Subscription */
+  const char           *dest;          /* Destination */
+  cups_ptype_t         dtype;          /* Destination type (printer or class) */
+  char                 method[HTTP_MAX_URI],
+                                       /* Method portion of URI */
+                       username[HTTP_MAX_URI],
+                                       /* Username portion of URI */
+                       host[HTTP_MAX_URI],
+                                       /* Host portion of URI */
+                       resource[HTTP_MAX_URI];
+                                       /* Resource portion of URI */
+  int                  port;           /* Port portion of URI */
+  cupsd_printer_t      *printer;       /* Printer/class */
   cups_array_t         *ra;            /* Requested attributes array */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "get_subscription_attrs(con=%p[%d], sub_id=%d)",
-                  con, con->http.fd, sub_id);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
 
  /*
-  * Is the subscription ID valid?
+  * Is the destination valid?
   */
 
-  if ((sub = cupsdFindSubscription(sub_id)) == NULL)
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                  sizeof(method), username, sizeof(username), host,
+                 sizeof(host), &port, resource, sizeof(resource));
+
+  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
   {
    /*
-    * Bad subscription ID...
+    * Bad URI...
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good!"), sub_id);
+                    _("The printer or class was not found."));
     return;
   }
 
@@ -6041,22 +5743,19 @@ get_subscription_attrs(
   * Check policy...
   */
 
-  if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr :
-                                             DefaultPolicyPtr,
-                                 con, sub->owner)) != HTTP_OK)
+  if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
   {
     send_http_error(con, status);
     return;
   }
 
  /*
-  * Copy the subscription attributes to the response using the
-  * requested-attributes attribute that may be provided by the client.
+  * Send the attributes...
   */
 
   ra = create_requested_array(con->request);
 
-  copy_subscription_attrs(con, sub, ra);
+  copy_printer_attrs(con, printer, ra);
 
   cupsArrayDelete(ra);
 
@@ -6065,364 +5764,188 @@ get_subscription_attrs(
 
 
 /*
- * 'get_subscriptions()' - Get subscriptions.
+ * 'get_printers()' - Get a list of printers or classes.
  */
 
 static void
-get_subscriptions(cupsd_client_t  *con,        /* I - Client connection */
-                  ipp_attribute_t *uri)        /* I - Printer/job URI */
+get_printers(cupsd_client_t *con,      /* I - Client connection */
+             int            type)      /* I - 0 or CUPS_PRINTER_CLASS */
 {
-  http_status_t                status;         /* Policy status */
-  int                  count;          /* Number of subscriptions */
-  int                  limit;          /* Limit */
-  cupsd_subscription_t *sub;           /* Subscription */
-  cups_array_t         *ra;            /* Requested attributes array */
-  ipp_attribute_t      *attr;          /* Attribute */
-  cups_ptype_t         dtype;          /* Destination type (printer or class) */
-  char                 method[HTTP_MAX_URI],
-                                       /* Method portion of URI */
-                       username[HTTP_MAX_URI],
-                                       /* Username portion of URI */
-                       host[HTTP_MAX_URI],
-                                       /* Host portion of URI */
-                       resource[HTTP_MAX_URI];
-                                       /* Resource portion of URI */
-  int                  port;           /* Port portion of URI */
-  cupsd_job_t          *job;           /* Job pointer */
-  cupsd_printer_t      *printer;       /* Printer */
-
-
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "get_subscriptions(con=%p[%d], uri=%s)",
-                  con, con->http.fd, uri->values[0].string.text);
-
- /*
-  * Is the destination valid?
-  */
-
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
-
-  if (!strcmp(resource, "/") ||
-      (!strncmp(resource, "/jobs", 5) && strlen(resource) <= 6) ||
-      (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) ||
-      (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9))
-  {
-    printer = NULL;
-    job     = NULL;
-  }
-  else if (!strncmp(resource, "/jobs/", 6) && resource[6])
-  {
-    printer = NULL;
-    job     = cupsdFindJob(atoi(resource + 6));
-
-    if (!job)
-    {
-      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist!"),
-                      resource + 6);
-      return;
-    }
-  }
-  else if (!cupsdValidateDest(host, resource, &dtype, &printer))
-  {
-   /*
-    * Bad URI...
-    */
+  http_status_t        status;                 /* Policy status */
+  ipp_attribute_t *attr;               /* Current attribute */
+  int          limit;                  /* Maximum number of printers to return */
+  int          count;                  /* Number of printers that match */
+  cupsd_printer_t *printer;            /* Current printer pointer */
+  int          printer_type,           /* printer-type attribute */
+               printer_mask;           /* printer-type-mask attribute */
+  char         *location;              /* Location string */
+  const char   *username;              /* Current user */
+  char         *first_printer_name;    /* first-printer-name attribute */
+  cups_array_t *ra;                    /* Requested attributes array */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
-    return;
-  }
-  else if ((attr = ippFindAttribute(con->request, "notify-job-id",
-                                    IPP_TAG_INTEGER)) != NULL)
-  {
-    job = cupsdFindJob(attr->values[0].integer);
 
-    if (!job)
-    {
-      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"),
-                      attr->values[0].integer);
-      return;
-    }
-  }
-  else
-    job = NULL;
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con,
+                  con->http.fd, type);
 
  /*
   * Check policy...
   */
 
-  if ((status = cupsdCheckPolicy(printer ? printer->op_policy_ptr :
-                                           DefaultPolicyPtr,
-                                 con, NULL)) != HTTP_OK)
+  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
   {
     send_http_error(con, status);
     return;
   }
 
  /*
-  * Copy the subscription attributes to the response using the
-  * requested-attributes attribute that may be provided by the client.
+  * Check for printers...
   */
 
-  ra = create_requested_array(con->request);
+  if (!Printers || !cupsArrayCount(Printers))
+  {
+    send_ipp_status(con, IPP_NOT_FOUND, _("No destinations added."));
+    return;
+  }
+
+ /*
+  * See if they want to limit the number of printers reported...
+  */
 
   if ((attr = ippFindAttribute(con->request, "limit",
                                IPP_TAG_INTEGER)) != NULL)
     limit = attr->values[0].integer;
   else
-    limit = 0;
+    limit = 10000000;
+
+  if ((attr = ippFindAttribute(con->request, "first-printer-name",
+                               IPP_TAG_NAME)) != NULL)
+    first_printer_name = attr->values[0].string.text;
+  else
+    first_printer_name = NULL;
 
  /*
-  * See if we only want to see subscriptions for a specific user...
+  * Support filtering...
   */
 
-  if ((attr = ippFindAttribute(con->request, "my-subscriptions",
-                               IPP_TAG_BOOLEAN)) != NULL &&
-      attr->values[0].boolean)
-    strlcpy(username, get_username(con), sizeof(username));
+  if ((attr = ippFindAttribute(con->request, "printer-type",
+                               IPP_TAG_ENUM)) != NULL)
+    printer_type = attr->values[0].integer;
   else
-    username[0] = '\0';
-
-  for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), count = 0;
-       sub;
-       sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions))
-    if ((!printer || sub->dest == printer) && (!job || sub->job == job) &&
-        (!username[0] || !strcasecmp(username, sub->owner)))
-    {
-      ippAddSeparator(con->response);
-      copy_subscription_attrs(con, sub, ra);
-
-      count ++;
-      if (limit && count >= limit)
-        break;
-    }
-
-  cupsArrayDelete(ra);
+    printer_type = 0;
 
-  if (count)
-    con->response->request.status.status_code = IPP_OK;
+  if ((attr = ippFindAttribute(con->request, "printer-type-mask",
+                               IPP_TAG_ENUM)) != NULL)
+    printer_mask = attr->values[0].integer;
   else
-    send_ipp_status(con, IPP_NOT_FOUND, _("No subscriptions found."));
-}
-
-
-/*
- * 'get_username()' - Get the username associated with a request.
- */
-
-static const char *                    /* O - Username */
-get_username(cupsd_client_t *con)      /* I - Connection */
-{
-  ipp_attribute_t      *attr;          /* Attribute */
+    printer_mask = 0;
 
+  if ((attr = ippFindAttribute(con->request, "printer-location",
+                               IPP_TAG_TEXT)) != NULL)
+    location = attr->values[0].string.text;
+  else
+    location = NULL;
 
   if (con->username[0])
-    return (con->username);
+    username = con->username;
   else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
                                     IPP_TAG_NAME)) != NULL)
-    return (attr->values[0].string.text);
+    username = attr->values[0].string.text;
   else
-    return ("anonymous");
-}
-
-
-/*
- * 'hold_job()' - Hold a print job.
- */
-
-static void
-hold_job(cupsd_client_t  *con,         /* I - Client connection */
-         ipp_attribute_t *uri)         /* I - Job or Printer URI */
-{
-  ipp_attribute_t *attr,               /* Current job-hold-until */
-               *newattr;               /* New job-hold-until */
-  int          jobid;                  /* Job ID */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
-               host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI]; /* Resource portion of URI */
-  int          port;                   /* Port portion of URI */
-  cupsd_job_t  *job;                   /* Job information */
-
+    username = NULL;
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->http.fd,
-                  uri->values[0].string.text);
+  ra = create_requested_array(con->request);
 
  /*
-  * See if we have a job URI or a printer URI...
+  * OK, build a list of printers for this printer...
   */
 
-  if (!strcmp(uri->name, "printer-uri"))
+  if (first_printer_name)
   {
-   /*
-    * Got a printer URI; see if we also have a job-id attribute...
-    */
-
-    if ((attr = ippFindAttribute(con->request, "job-id",
-                                 IPP_TAG_INTEGER)) == NULL)
-    {
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id!"));
-      return;
-    }
-
-    jobid = attr->values[0].integer;
+    if ((printer = cupsdFindDest(first_printer_name)) == NULL)
+      printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
   }
   else
-  {
-   /*
-    * Got a job URI; parse it to get the job ID...
-    */
-
-    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                    sizeof(method), username, sizeof(username), host,
-                   sizeof(host), &port, resource, sizeof(resource));
+    printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
 
-    if (strncmp(resource, "/jobs/", 6))
+  for (count = 0;
+       count < limit && printer;
+       printer = (cupsd_printer_t *)cupsArrayNext(Printers))
+  {
+    if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) &&
+        (printer->type & printer_mask) == printer_type &&
+       (!location || !printer->location ||
+        !strcasecmp(printer->location, location)))
     {
      /*
-      * Not a valid URI!
+      * If HideImplicitMembers is enabled, see if this printer or class
+      * is a member of an implicit class...
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\"!"),
-                      uri->values[0].string.text);
-      return;
-    }
-
-    jobid = atoi(resource + 6);
-  }
-
- /*
-  * See if the job exists...
-  */
-
-  if ((job = cupsdFindJob(jobid)) == NULL)
-  {
-   /*
-    * Nope - return a "not found" error...
-    */
-
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
-    return;
-  }
-
- /*
-  * See if the job is owned by the requesting user...
-  */
-
-  if (!validate_user(job, con, job->username, username, sizeof(username)))
-  {
-    send_http_error(con, HTTP_UNAUTHORIZED);
-    return;
-  }
-
- /*
-  * Hold the job and return...
-  */
-
-  cupsdHoldJob(job);
+      if (ImplicitClasses && HideImplicitMembers &&
+          printer->in_implicit_class)
+        continue;
 
-  if ((newattr = ippFindAttribute(con->request, "job-hold-until",
-                                  IPP_TAG_KEYWORD)) == NULL)
-    newattr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME);
+     /*
+      * If a username is specified, see if it is allowed or denied
+      * access...
+      */
 
-  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
-                               IPP_TAG_KEYWORD)) == NULL)
-    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+      if (printer->num_users && username && !user_allowed(printer, username))
+        continue;
 
-  if (attr)
-  {
-   /*
-    * Free the old hold value and copy the new one over...
-    */
+     /*
+      * Add the group separator as needed...
+      */
 
-    _cups_sp_free(attr->values[0].string.text);
+      if (count > 0)
+        ippAddSeparator(con->response);
 
-    if (newattr)
-    {
-      attr->value_tag = newattr->value_tag;
-      attr->values[0].string.text =
-          _cups_sp_alloc(newattr->values[0].string.text);
-    }
-    else
-    {
-      attr->value_tag = IPP_TAG_KEYWORD;
-      attr->values[0].string.text = _cups_sp_alloc("indefinite");
-    }
+      count ++;
 
-   /*
-    * Hold job until specified time...
-    */
+     /*
+      * Send the attributes...
+      */
 
-    cupsdSetJobHoldUntil(job, attr->values[0].string.text);
+      copy_printer_attrs(con, printer, ra);
+    }
   }
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was held by \"%s\".", jobid,
-                  username);
+  cupsArrayDelete(ra);
 
   con->response->request.status.status_code = IPP_OK;
 }
 
 
 /*
- * 'move_job()' - Move a job to a new destination.
+ * 'get_subscription_attrs()' - Get subscription attributes.
  */
 
 static void
-move_job(cupsd_client_t  *con,         /* I - Client connection */
-        ipp_attribute_t *uri)          /* I - Job URI */
+get_subscription_attrs(
+    cupsd_client_t *con,               /* I - Client connection */
+    int            sub_id)             /* I - Subscription ID */
 {
-  http_status_t        status;                 /* Policy status */
-  ipp_attribute_t *attr;               /* Current attribute */
-  int          jobid;                  /* Job ID */
-  cupsd_job_t  *job;                   /* Current job */
-  const char   *src,                   /* Source printer/class */
-               *dest;                  /* Destination */
-  cups_ptype_t stype,                  /* Source type (printer or class) */
-               dtype;                  /* Destination type (printer or class) */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
-               username[HTTP_MAX_URI], /* Username portion of URI */
-               host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI]; /* Resource portion of URI */
-  int          port;                   /* Port portion of URI */
-  cupsd_printer_t *sprinter,           /* Source printer */
-               *dprinter;              /* Destination printer */
+  http_status_t                status;         /* Policy status */
+  cupsd_subscription_t *sub;           /* Subscription */
+  cups_array_t         *ra;            /* Requested attributes array */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->http.fd,
-                  uri->values[0].string.text);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "get_subscription_attrs(con=%p[%d], sub_id=%d)",
+                  con, con->http.fd, sub_id);
 
  /*
-  * Get the new printer or class...
+  * Is the subscription ID valid?
   */
 
-  if ((attr = ippFindAttribute(con->request, "job-printer-uri",
-                               IPP_TAG_URI)) == NULL)
-  {
-   /*
-    * Need job-printer-uri...
-    */
-
-    send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("job-printer-uri attribute missing!"));
-    return;
-  }
-    
-  httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
-
-  if ((dest = cupsdValidateDest(host, resource, &dtype, &dprinter)) == NULL)
+  if ((sub = cupsdFindSubscription(sub_id)) == NULL)
   {
    /*
-    * Bad URI...
+    * Bad subscription ID...
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("notify-subscription-id %d no good!"), sub_id);
     return;
   }
 
@@ -6430,952 +5953,893 @@ move_job(cupsd_client_t  *con,                /* I - Client connection */
   * Check policy...
   */
 
-  if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, NULL)) != HTTP_OK)
+  if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr :
+                                             DefaultPolicyPtr,
+                                 con, sub->owner)) != HTTP_OK)
   {
     send_http_error(con, status);
     return;
   }
 
  /*
-  * See if we have a job URI or a printer URI...
+  * Copy the subscription attributes to the response using the
+  * requested-attributes attribute that may be provided by the client.
   */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
+  ra = create_requested_array(con->request);
 
-  if (!strcmp(uri->name, "printer-uri"))
-  {
-   /*
-    * Got a printer URI; see if we also have a job-id attribute...
-    */
+  copy_subscription_attrs(con, sub, ra);
 
-    if ((attr = ippFindAttribute(con->request, "job-id",
-                                 IPP_TAG_INTEGER)) == NULL)
-    {
-     /*
-      * Move all jobs...
-      */
+  cupsArrayDelete(ra);
 
-      if ((src = cupsdValidateDest(host, resource, &stype, &sprinter)) == NULL)
-      {
-       /*
-       * Bad URI...
-       */
+  con->response->request.status.status_code = IPP_OK;
+}
 
-       send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
-       return;
-      }
 
-      job = NULL;
-    }
-    else
-    {
-     /*
-      * Otherwise, just move a single job...
-      */
+/*
+ * 'get_subscriptions()' - Get subscriptions.
+ */
 
-      if ((job = cupsdFindJob(attr->values[0].integer)) == NULL)
-      {
-       /*
-       * Nope - return a "not found" error...
-       */
+static void
+get_subscriptions(cupsd_client_t  *con,        /* I - Client connection */
+                  ipp_attribute_t *uri)        /* I - Printer/job URI */
+{
+  http_status_t                status;         /* Policy status */
+  int                  count;          /* Number of subscriptions */
+  int                  limit;          /* Limit */
+  cupsd_subscription_t *sub;           /* Subscription */
+  cups_array_t         *ra;            /* Requested attributes array */
+  ipp_attribute_t      *attr;          /* Attribute */
+  cups_ptype_t         dtype;          /* Destination type (printer or class) */
+  char                 method[HTTP_MAX_URI],
+                                       /* Method portion of URI */
+                       username[HTTP_MAX_URI],
+                                       /* Username portion of URI */
+                       host[HTTP_MAX_URI],
+                                       /* Host portion of URI */
+                       resource[HTTP_MAX_URI];
+                                       /* Resource portion of URI */
+  int                  port;           /* Port portion of URI */
+  cupsd_job_t          *job;           /* Job pointer */
+  cupsd_printer_t      *printer;       /* Printer */
 
-       send_ipp_status(con, IPP_NOT_FOUND,
-                       _("Job #%d does not exist!"), attr->values[0].integer);
-       return;
-      }
-      else
-      {
-       /*
-        * Job found, initialize source pointers...
-       */
 
-       src      = NULL;
-       sprinter = NULL;
-      }
-    }
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "get_subscriptions(con=%p[%d], uri=%s)",
+                  con, con->http.fd, uri->values[0].string.text);
+
+ /*
+  * Is the destination valid?
+  */
+
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                  sizeof(method), username, sizeof(username), host,
+                 sizeof(host), &port, resource, sizeof(resource));
+
+  if (!strcmp(resource, "/") ||
+      (!strncmp(resource, "/jobs", 5) && strlen(resource) <= 6) ||
+      (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) ||
+      (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9))
+  {
+    printer = NULL;
+    job     = NULL;
   }
-  else
+  else if (!strncmp(resource, "/jobs/", 6) && resource[6])
   {
-   /*
-    * Got a job URI; parse it to get the job ID...
-    */
+    printer = NULL;
+    job     = cupsdFindJob(atoi(resource + 6));
 
-    if (strncmp(resource, "/jobs/", 6))
+    if (!job)
     {
-     /*
-      * Not a valid URI!
-      */
-
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\"!"),
-                      uri->values[0].string.text);
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist!"),
+                      resource + 6);
       return;
     }
-
+  }
+  else if (!cupsdValidateDest(host, resource, &dtype, &printer))
+  {
    /*
-    * See if the job exists...
+    * Bad URI...
     */
 
-    jobid = atoi(resource + 6);
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("The printer or class was not found."));
+    return;
+  }
+  else if ((attr = ippFindAttribute(con->request, "notify-job-id",
+                                    IPP_TAG_INTEGER)) != NULL)
+  {
+    job = cupsdFindJob(attr->values[0].integer);
 
-    if ((job = cupsdFindJob(jobid)) == NULL)
+    if (!job)
     {
-     /*
-      * Nope - return a "not found" error...
-      */
-
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("Job #%d does not exist!"), jobid);
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"),
+                      attr->values[0].integer);
       return;
     }
-    else
-    {
-     /*
-      * Job found, initialize source pointers...
-      */
-
-      src      = NULL;
-      sprinter = NULL;
-    }
   }
+  else
+    job = NULL;
 
  /*
-  * Now move the job or jobs...
+  * Check policy...
   */
 
-  if (job)
+  if ((status = cupsdCheckPolicy(printer ? printer->op_policy_ptr :
+                                           DefaultPolicyPtr,
+                                 con, NULL)) != HTTP_OK)
   {
-   /*
-    * See if the job has been completed...
-    */
-
-    if (job->state_value > IPP_JOB_STOPPED)
-    {
-     /*
-      * Return a "not-possible" error...
-      */
+    send_http_error(con, status);
+    return;
+  }
 
-      send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Job #%d is finished and cannot be altered!"),
-                     job->id);
-      return;
-    }
+ /*
+  * Copy the subscription attributes to the response using the
+  * requested-attributes attribute that may be provided by the client.
+  */
 
-   /*
-    * See if the job is owned by the requesting user...
-    */
+  ra = create_requested_array(con->request);
 
-    if (!validate_user(job, con, job->username, username, sizeof(username)))
-    {
-      send_http_error(con, HTTP_UNAUTHORIZED);
-      return;
-    }
+  if ((attr = ippFindAttribute(con->request, "limit",
+                               IPP_TAG_INTEGER)) != NULL)
+    limit = attr->values[0].integer;
+  else
+    limit = 0;
 
  /*
-    * Move the job to a different printer or class...
-    */
+ /*
+  * See if we only want to see subscriptions for a specific user...
+  */
 
-    cupsdMoveJob(job, dest);
-  }
+  if ((attr = ippFindAttribute(con->request, "my-subscriptions",
+                               IPP_TAG_BOOLEAN)) != NULL &&
+      attr->values[0].boolean)
+    strlcpy(username, get_username(con), sizeof(username));
   else
-  {
-   /*
-    * Got the source printer, now look through the jobs...
-    */
+    username[0] = '\0';
 
-    for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
-         job;
-        job = (cupsd_job_t *)cupsArrayNext(Jobs))
+  for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), count = 0;
+       sub;
+       sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions))
+    if ((!printer || sub->dest == printer) && (!job || sub->job == job) &&
+        (!username[0] || !strcasecmp(username, sub->owner)))
     {
-     /*
-      * See if the job is pointing at the source printer or has not been
-      * completed...
-      */
-
-      if (strcasecmp(job->dest, src) ||
-          job->state_value > IPP_JOB_STOPPED)
-       continue;
+      ippAddSeparator(con->response);
+      copy_subscription_attrs(con, sub, ra);
 
-     /*
-      * See if the job can be moved by the requesting user...
-      */
+      count ++;
+      if (limit && count >= limit)
+        break;
+    }
 
-      if (!validate_user(job, con, job->username, username, sizeof(username)))
-        continue;
+  cupsArrayDelete(ra);
 
-     /*
-      * Move the job to a different printer or class...
-      */
+  if (count)
+    con->response->request.status.status_code = IPP_OK;
+  else
+    send_ipp_status(con, IPP_NOT_FOUND, _("No subscriptions found."));
+}
 
-      cupsdMoveJob(job, dest);
-    }
-  }
 
- /*
 * Start jobs if possible...
 */
+/*
* 'get_username()' - Get the username associated with a request.
+ */
 
-  cupsdCheckJobs();
+static const char *                    /* O - Username */
+get_username(cupsd_client_t *con)      /* I - Connection */
+{
+  ipp_attribute_t      *attr;          /* Attribute */
 
- /*
-  * Return with "everything is OK" status...
-  */
 
-  con->response->request.status.status_code = IPP_OK;
+  if (con->username[0])
+    return (con->username);
+  else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
+                                    IPP_TAG_NAME)) != NULL)
+    return (attr->values[0].string.text);
+  else
+    return ("anonymous");
 }
 
 
 /*
- * 'ppd_add_default()' - Add a PPD default choice.
+ * 'hold_job()' - Hold a print job.
  */
 
-static int                             /* O  - Number of defaults */
-ppd_add_default(
-    const char    *option,             /* I  - Option name */
-    const char    *choice,             /* I  - Choice name */
-    int           num_defaults,                /* I  - Number of defaults */
-    ppd_default_t **defaults)          /* IO - Defaults */
+static void
+hold_job(cupsd_client_t  *con,         /* I - Client connection */
+         ipp_attribute_t *uri)         /* I - Job or Printer URI */
 {
-  int          i;                      /* Looping var */
-  ppd_default_t        *temp;                  /* Temporary defaults array */
+  ipp_attribute_t *attr,               /* Current job-hold-until */
+               *newattr;               /* New job-hold-until */
+  int          jobid;                  /* Job ID */
+  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+               username[HTTP_MAX_URI], /* Username portion of URI */
+               host[HTTP_MAX_URI],     /* Host portion of URI */
+               resource[HTTP_MAX_URI]; /* Resource portion of URI */
+  int          port;                   /* Port portion of URI */
+  cupsd_job_t  *job;                   /* Job information */
+
 
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->http.fd,
+                  uri->values[0].string.text);
 
  /*
-  * First check if the option already has a default value; the PPD spec
-  * says that the first one is used...
+  * See if we have a job URI or a printer URI...
   */
 
-  for (i = 0, temp = *defaults; i < num_defaults; i ++)
-    if (!strcmp(option, temp[i].option))
-      return (num_defaults);
+  if (!strcmp(uri->name, "printer-uri"))
+  {
+   /*
+    * Got a printer URI; see if we also have a job-id attribute...
+    */
 
- /*
-  * Now add the option...
-  */
+    if ((attr = ippFindAttribute(con->request, "job-id",
+                                 IPP_TAG_INTEGER)) == NULL)
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Got a printer-uri attribute but no job-id!"));
+      return;
+    }
 
-  if (num_defaults == 0)
-    temp = malloc(sizeof(ppd_default_t));
+    jobid = attr->values[0].integer;
+  }
   else
-    temp = realloc(*defaults, (num_defaults + 1) * sizeof(ppd_default_t));
-
-  if (!temp)
   {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "ppd_add_default: Unable to add default value for \"%s\" - %s",
-               option, strerror(errno));
-    return (num_defaults);
-  }
-
-  *defaults = temp;
-  temp      += num_defaults;
+   /*
+    * Got a job URI; parse it to get the job ID...
+    */
 
-  strlcpy(temp->option, option, sizeof(temp->option));
-  strlcpy(temp->choice, choice, sizeof(temp->choice));
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                    sizeof(method), username, sizeof(username), host,
+                   sizeof(host), &port, resource, sizeof(resource));
 
-  return (num_defaults + 1);
-}
+    if (strncmp(resource, "/jobs/", 6))
+    {
+     /*
+      * Not a valid URI!
+      */
 
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Bad job-uri attribute \"%s\"!"),
+                      uri->values[0].string.text);
+      return;
+    }
 
-/*
- * 'ppd_parse_line()' - Parse a PPD default line.
- */
+    jobid = atoi(resource + 6);
+  }
 
-static int                             /* O - 0 on success, -1 on failure */
-ppd_parse_line(const char *line,       /* I - Line */
-               char       *option,     /* O - Option name */
-              int        olen,         /* I - Size of option name */
-               char       *choice,     /* O - Choice name */
-              int        clen)         /* I - Size of choice name */
-{
  /*
-  * Verify this is a default option line...
+  * See if the job exists...
   */
 
-  if (strncmp(line, "*Default", 8))
-    return (-1);
+  if ((job = cupsdFindJob(jobid)) == NULL)
+  {
+   /*
+    * Nope - return a "not found" error...
+    */
+
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+    return;
+  }
 
  /*
-  * Read the option name...
+  * See if the job is owned by the requesting user...
   */
 
-  for (line += 8, olen --; isalnum(*line & 255); line ++)
-    if (olen > 0)
-    {
-      *option++ = *line;
-      olen --;
-    }
-
-  *option = '\0';
+  if (!validate_user(job, con, job->username, username, sizeof(username)))
+  {
+    send_http_error(con, HTTP_UNAUTHORIZED);
+    return;
+  }
 
  /*
-  * Skip everything else up to the colon (:)...
+  * Hold the job and return...
   */
 
-  while (*line && *line != ':')
-    line ++;
+  cupsdHoldJob(job);
 
-  if (!*line)
-    return (-1);
+  if ((newattr = ippFindAttribute(con->request, "job-hold-until",
+                                  IPP_TAG_KEYWORD)) == NULL)
+    newattr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME);
 
-  line ++;
+  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
+                               IPP_TAG_KEYWORD)) == NULL)
+    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
 
- /*
-  * Now grab the option choice, skipping leading whitespace...
-  */
+  if (attr)
+  {
+   /*
+    * Free the old hold value and copy the new one over...
+    */
 
-  while (isspace(*line & 255))
-    line ++;
+    _cups_sp_free(attr->values[0].string.text);
 
-  for (clen --; isalnum(*line & 255); line ++)
-    if (clen > 0)
+    if (newattr)
     {
-      *choice++ = *line;
-      clen --;
+      attr->value_tag = newattr->value_tag;
+      attr->values[0].string.text =
+          _cups_sp_alloc(newattr->values[0].string.text);
+    }
+    else
+    {
+      attr->value_tag = IPP_TAG_KEYWORD;
+      attr->values[0].string.text = _cups_sp_alloc("indefinite");
     }
 
-  *choice = '\0';
+   /*
+    * Hold job until specified time...
+    */
 
- /*
-  * Return with no errors...
-  */
+    cupsdSetJobHoldUntil(job, attr->values[0].string.text);
+  }
 
-  return (0);
+  cupsdLogMessage(CUPSD_LOG_INFO, "Job %d was held by \"%s\".", jobid,
+                  username);
+
+  con->response->request.status.status_code = IPP_OK;
 }
 
 
 /*
- * 'print_job()' - Print a file to a printer or class.
+ * 'move_job()' - Move a job to a new destination.
  */
 
 static void
-print_job(cupsd_client_t  *con,                /* I - Client connection */
-         ipp_attribute_t *uri)         /* I - Printer URI */
+move_job(cupsd_client_t  *con,         /* I - Client connection */
+        ipp_attribute_t *uri)          /* I - Job URI */
 {
   http_status_t        status;                 /* Policy status */
   ipp_attribute_t *attr;               /* Current attribute */
-  ipp_attribute_t *format;             /* Document-format attribute */
-  const char   *dest;                  /* Destination */
-  cups_ptype_t dtype;                  /* Destination type (printer or class) */
-  int          priority;               /* Job priority */
-  char         *title;                 /* Job name/title */
+  int          jobid;                  /* Job ID */
   cupsd_job_t  *job;                   /* Current job */
-  char         job_uri[HTTP_MAX_URI],  /* Job URI */
-               method[HTTP_MAX_URI],   /* Method portion of URI */
+  const char   *src,                   /* Source printer/class */
+               *dest;                  /* Destination */
+  cups_ptype_t stype,                  /* Source type (printer or class) */
+               dtype;                  /* Destination type (printer or class) */
+  char         method[HTTP_MAX_URI],   /* Method portion of URI */
                username[HTTP_MAX_URI], /* Username portion of URI */
                host[HTTP_MAX_URI],     /* Host portion of URI */
-               resource[HTTP_MAX_URI], /* Resource portion of URI */
-               filename[1024];         /* Job filename */
+               resource[HTTP_MAX_URI]; /* Resource portion of URI */
   int          port;                   /* Port portion of URI */
-  mime_type_t  *filetype;              /* Type of file */
-  char         super[MIME_MAX_SUPER],  /* Supertype of file */
-               type[MIME_MAX_TYPE],    /* Subtype of file */
-               mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2];
-                                       /* Textual name of mime type */
-  cupsd_printer_t *printer;            /* Printer data */
-  struct stat  fileinfo;               /* File information */
-  int          kbytes;                 /* Size of file */
-  int          i;                      /* Looping var */
-  int          lowerpagerange;         /* Page range bound */
-  int          compression;            /* Document compression */
+  cupsd_printer_t *sprinter,           /* Source printer */
+               *dprinter;              /* Destination printer */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->http.fd,
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->http.fd,
                   uri->values[0].string.text);
 
  /*
-  * Validate job template attributes; for now just copies and page-ranges...
+  * Get the new printer or class...
   */
 
-  if ((attr = ippFindAttribute(con->request, "copies",
-                               IPP_TAG_INTEGER)) != NULL)
-  {
-    if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies)
-    {
-      send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."),
-                      attr->values[0].integer);
-      ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER,
-                   "copies", attr->values[0].integer);
-      return;
-    }
-  }
-
-  if ((attr = ippFindAttribute(con->request, "page-ranges",
-                               IPP_TAG_RANGE)) != NULL)
+  if ((attr = ippFindAttribute(con->request, "job-printer-uri",
+                               IPP_TAG_URI)) == NULL)
   {
-    for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++)
-    {
-      if (attr->values[i].range.lower < lowerpagerange || 
-         attr->values[i].range.lower > attr->values[i].range.upper)
-      {
-       send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Bad page-ranges values %d-%d."),
-                       attr->values[i].range.lower,
-                       attr->values[i].range.upper);
-       return;
-      }
+   /*
+    * Need job-printer-uri...
+    */
 
-      lowerpagerange = attr->values[i].range.upper + 1;
-    }
+    send_ipp_status(con, IPP_BAD_REQUEST,
+                    _("job-printer-uri attribute missing!"));
+    return;
   }
+    
+  httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method,
+                  sizeof(method), username, sizeof(username), host,
+                 sizeof(host), &port, resource, sizeof(resource));
 
- /*
-  * OK, see if the client is sending the document compressed - CUPS
-  * only supports "none" and "gzip".
-  */
-
-  compression = CUPS_FILE_NONE;
-
-  if ((attr = ippFindAttribute(con->request, "compression",
-                               IPP_TAG_KEYWORD)) != NULL)
+  if ((dest = cupsdValidateDest(host, resource, &dtype, &dprinter)) == NULL)
   {
-    if (strcmp(attr->values[0].string.text, "none")
-#ifdef HAVE_LIBZ
-        && strcmp(attr->values[0].string.text, "gzip")
-#endif /* HAVE_LIBZ */
-      )
-    {
-      send_ipp_status(con, IPP_ATTRIBUTES,
-                      _("Unsupported compression \"%s\"!"),
-                     attr->values[0].string.text);
-      ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
-                  "compression", NULL, attr->values[0].string.text);
-      return;
-    }
+   /*
+    * Bad URI...
+    */
 
-#ifdef HAVE_LIBZ
-    if (!strcmp(attr->values[0].string.text, "gzip"))
-      compression = CUPS_FILE_GZIP;
-#endif /* HAVE_LIBZ */
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("The printer or class was not found."));
+    return;
   }
 
  /*
-  * Do we have a file to print?
+  * Check policy...
   */
 
-  if (!con->filename)
+  if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, NULL)) != HTTP_OK)
   {
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!"));
+    send_http_error(con, status);
     return;
   }
 
  /*
-  * Is it a format we support?
+  * See if we have a job URI or a printer URI...
   */
 
-  if ((format = ippFindAttribute(con->request, "document-format",
-                                 IPP_TAG_MIMETYPE)) != NULL)
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
+                  sizeof(method), username, sizeof(username), host,
+                 sizeof(host), &port, resource, sizeof(resource));
+
+  if (!strcmp(uri->name, "printer-uri"))
   {
    /*
-    * Grab format from client...
+    * Got a printer URI; see if we also have a job-id attribute...
     */
 
-    if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2)
+    if ((attr = ippFindAttribute(con->request, "job-id",
+                                 IPP_TAG_INTEGER)) == NULL)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Could not scan type \"%s\"!"),
-                     format->values[0].string.text);
-      return;
+     /*
+      * Move all jobs...
+      */
+
+      if ((src = cupsdValidateDest(host, resource, &stype, &sprinter)) == NULL)
+      {
+       /*
+       * Bad URI...
+       */
+
+       send_ipp_status(con, IPP_NOT_FOUND,
+                       _("The printer or class was not found."));
+       return;
+      }
+
+      job = NULL;
+    }
+    else
+    {
+     /*
+      * Otherwise, just move a single job...
+      */
+
+      if ((job = cupsdFindJob(attr->values[0].integer)) == NULL)
+      {
+       /*
+       * Nope - return a "not found" error...
+       */
+
+       send_ipp_status(con, IPP_NOT_FOUND,
+                       _("Job #%d does not exist!"), attr->values[0].integer);
+       return;
+      }
+      else
+      {
+       /*
+        * Job found, initialize source pointers...
+       */
+
+       src      = NULL;
+       sprinter = NULL;
+      }
     }
   }
   else
   {
    /*
-    * No document format attribute?  Auto-type it!
+    * Got a job URI; parse it to get the job ID...
     */
 
-    strcpy(super, "application");
-    strcpy(type, "octet-stream");
-  }
+    if (strncmp(resource, "/jobs/", 6))
+    {
+     /*
+      * Not a valid URI!
+      */
+
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Bad job-uri attribute \"%s\"!"),
+                      uri->values[0].string.text);
+      return;
+    }
 
-  if (!strcmp(super, "application") && !strcmp(type, "octet-stream"))
-  {
    /*
-    * Auto-type the file...
+    * See if the job exists...
     */
 
-    ipp_attribute_t    *doc_name;      /* document-name attribute */
-
-
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: auto-typing file...");
-
-    doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME);
-    filetype = mimeFileType(MimeDatabase, con->filename,
-                            doc_name ? doc_name->values[0].string.text : NULL,
-                           &compression);
+    jobid = atoi(resource + 6);
 
-    if (filetype)
+    if ((job = cupsdFindJob(jobid)) == NULL)
     {
      /*
-      * Replace the document-format attribute value with the auto-typed one.
+      * Nope - return a "not found" error...
       */
 
-      snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super,
-               filetype->type);
-
-      if (format)
-      {
-         _cups_sp_free(format->values[0].string.text);
-
-       format->values[0].string.text = _cups_sp_alloc(mimetype);
-      }
-      else
-        ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
-                    "document-format", NULL, mimetype);
+      send_ipp_status(con, IPP_NOT_FOUND,
+                      _("Job #%d does not exist!"), jobid);
+      return;
     }
     else
-      filetype = mimeType(MimeDatabase, super, type);
-  }
-  else
-    filetype = mimeType(MimeDatabase, super, type);
-
-  if (!filetype)
-  {
-    send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s/%s\'!"), super, type);
-    cupsdLogMessage(CUPSD_LOG_INFO,
-                    "Hint: Do you have the raw file printing rules enabled?");
-
-    if (format)
-      ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
-                   "document-format", NULL, format->values[0].string.text);
+    {
+     /*
+      * Job found, initialize source pointers...
+      */
 
-    return;
+      src      = NULL;
+      sprinter = NULL;
+    }
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: request file type is %s/%s.",
-            filetype->super, filetype->type);
-
  /*
-  * Read any embedded job ticket info from PS files...
+  * Now move the job or jobs...
   */
 
-  if (!strcasecmp(filetype->super, "application") &&
-      !strcasecmp(filetype->type, "postscript"))
-    read_ps_job_ticket(con);
+  if (job)
+  {
+   /*
+    * See if the job has been completed...
+    */
+
+    if (job->state_value > IPP_JOB_STOPPED)
+    {
+     /*
+      * Return a "not-possible" error...
+      */
+
+      send_ipp_status(con, IPP_NOT_POSSIBLE,
+                      _("Job #%d is finished and cannot be altered!"),
+                     job->id);
+      return;
+    }
 
- /*
-  * Is the destination valid?
-  */
  /*
+    * See if the job is owned by the requesting user...
+    */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
-                 sizeof(host), &port, resource, sizeof(resource));
+    if (!validate_user(job, con, job->username, username, sizeof(username)))
+    {
+      send_http_error(con, HTTP_UNAUTHORIZED);
+      return;
+    }
 
-  if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL)
-  {
    /*
-    * Bad URI...
+    * Move the job to a different printer or class...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
-    return;
+    cupsdMoveJob(job, dest);
   }
+  else
+  {
+   /*
+    * Got the source printer, now look through the jobs...
+    */
 
- /*
-  * Check remote printing to non-shared printer...
-  */
+    for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
+         job;
+        job = (cupsd_job_t *)cupsArrayNext(Jobs))
+    {
+     /*
+      * See if the job is pointing at the source printer or has not been
+      * completed...
+      */
 
-  if (!printer->shared &&
-      strcasecmp(con->http.hostname, "localhost") &&
-      strcasecmp(con->http.hostname, ServerName))
-  {
-    send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer not shared!"));
-    return;
-  }
+      if (strcasecmp(job->dest, src) ||
+          job->state_value > IPP_JOB_STOPPED)
+       continue;
 
- /*
-  * Check policy...
-  */
    /*
+      * See if the job can be moved by the requesting user...
+      */
 
-  if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status);
-    return;
-  }
-  else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) && !con->username[0])
-  {
-    send_http_error(con, status);
-    return;
-  }
+      if (!validate_user(job, con, job->username, username, sizeof(username)))
+        continue;
 
- /*
-  * See if the printer is accepting jobs...
-  */
    /*
+      * Move the job to a different printer or class...
+      */
 
-  if (!printer->accepting)
-  {
-    send_ipp_status(con, IPP_NOT_ACCEPTING,
-                    _("Destination \"%s\" is not accepting jobs."), dest);
-    return;
+      cupsdMoveJob(job, dest);
+    }
   }
 
  /*
-  * Make sure we aren't over our limit...
+  * Start jobs if possible...
   */
 
-  if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs)
-    cupsdCleanJobs();
-
-  if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs)
-  {
-    send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Too many jobs - %d jobs, max jobs is %d."),
-                    cupsArrayCount(Jobs), MaxJobs);
-    return;
-  }
-
-  if (!check_quotas(con, printer))
-  {
-    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached."));
-    return;
-  }
+  cupsdCheckJobs();
 
  /*
-  * Create the job and set things up...
+  * Return with "everything is OK" status...
   */
 
-  if ((attr = ippFindAttribute(con->request, "job-priority",
-                               IPP_TAG_INTEGER)) != NULL)
-    priority = attr->values[0].integer;
-  else
-    ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
-                  priority = 50);
+  con->response->request.status.status_code = IPP_OK;
+}
 
-  if ((attr = ippFindAttribute(con->request, "job-name",
-                               IPP_TAG_NAME)) != NULL)
-    title = attr->values[0].string.text;
-  else
-    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
-                 title = "Untitled");
 
-  if ((job = cupsdAddJob(priority, printer->name)) == NULL)
-  {
-    send_ipp_status(con, IPP_INTERNAL_ERROR,
-                    _("Unable to add job for destination \"%s\"!"), dest);
-    return;
-  }
+/*
+ * 'ppd_add_default()' - Add a PPD default choice.
+ */
 
-  job->dtype   = dtype;
-  job->attrs   = con->request;
-  con->request = NULL;
+static int                             /* O  - Number of defaults */
+ppd_add_default(
+    const char    *option,             /* I  - Option name */
+    const char    *choice,             /* I  - Choice name */
+    int           num_defaults,                /* I  - Number of defaults */
+    ppd_default_t **defaults)          /* IO - Defaults */
+{
+  int          i;                      /* Looping var */
+  ppd_default_t        *temp;                  /* Temporary defaults array */
 
-  add_job_uuid(con, job);
 
  /*
-  * Copy the rest of the job info...
+  * First check if the option already has a default value; the PPD spec
+  * says that the first one is used...
   */
 
-  attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME);
-
-  if (con->username[0])
-  {
-    cupsdSetString(&job->username, con->username);
-
-    if (attr)
-      cupsdSetString(&attr->values[0].string.text, con->username);
+  for (i = 0, temp = *defaults; i < num_defaults; i ++)
+    if (!strcmp(option, temp[i].option))
+      return (num_defaults);
 
-    save_auth_info(con, job);
-  }
-  else if (attr)
-  {
-    cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: requesting-user-name = \"%s\"",
-               attr->values[0].string.text);
+ /*
+  * Now add the option...
+  */
 
-    cupsdSetString(&job->username, attr->values[0].string.text);
-  }
+  if (num_defaults == 0)
+    temp = malloc(sizeof(ppd_default_t));
   else
-    cupsdSetString(&job->username, "anonymous");
+    temp = realloc(*defaults, (num_defaults + 1) * sizeof(ppd_default_t));
 
-  if (!attr)
-    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
-                 "job-originating-user-name", NULL, job->username);
-  else
+  if (!temp)
   {
-    attr->group_tag = IPP_TAG_JOB;
-    cupsdSetString(&attr->name, "job-originating-user-name");
+    cupsdLogMessage(CUPSD_LOG_ERROR, "ppd_add_default: Unable to add default value for \"%s\" - %s",
+               option, strerror(errno));
+    return (num_defaults);
   }
 
- /*
-  * Add remaining job attributes...
-  */
+  *defaults = temp;
+  temp      += num_defaults;
 
-  if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
-                               IPP_TAG_ZERO)) != NULL)
-  {
-   /*
-    * Request contains a job-originating-host-name attribute; validate it...
-    */
+  strlcpy(temp->option, option, sizeof(temp->option));
+  strlcpy(temp->choice, choice, sizeof(temp->choice));
 
-    if (attr->value_tag != IPP_TAG_NAME ||
-        attr->num_values != 1 ||
-        strcmp(con->http.hostname, "localhost"))
-    {
-     /*
-      * Can't override the value if we aren't connected via localhost.
-      * Also, we can only have 1 value and it must be a name value.
-      */
+  return (num_defaults + 1);
+}
 
-      switch (attr->value_tag)
-      {
-        case IPP_TAG_STRING :
-       case IPP_TAG_TEXTLANG :
-       case IPP_TAG_NAMELANG :
-       case IPP_TAG_TEXT :
-       case IPP_TAG_NAME :
-       case IPP_TAG_KEYWORD :
-       case IPP_TAG_URI :
-       case IPP_TAG_URISCHEME :
-       case IPP_TAG_CHARSET :
-       case IPP_TAG_LANGUAGE :
-       case IPP_TAG_MIMETYPE :
-          /*
-           * Free old strings...
-           */
 
-           for (i = 0; i < attr->num_values; i ++)
-           {
-             _cups_sp_free(attr->values[i].string.text);
-             attr->values[i].string.text = NULL;
-             if (attr->values[i].string.charset)
-             {
-               _cups_sp_free(attr->values[i].string.charset);
-               attr->values[i].string.charset = NULL;
-             }
-            }
+/*
+ * 'ppd_parse_line()' - Parse a PPD default line.
+ */
 
-       default :
-            break;
-      }
+static int                             /* O - 0 on success, -1 on failure */
+ppd_parse_line(const char *line,       /* I - Line */
+               char       *option,     /* O - Option name */
+              int        olen,         /* I - Size of option name */
+               char       *choice,     /* O - Choice name */
+              int        clen)         /* I - Size of choice name */
+{
+ /*
+  * Verify this is a default option line...
+  */
 
-     /*
-      * Use the default connection hostname instead...
-      */
+  if (strncmp(line, "*Default", 8))
+    return (-1);
 
-      attr->value_tag             = IPP_TAG_NAME;
-      attr->num_values            = 1;
-      attr->values[0].string.text = _cups_sp_alloc(con->http.hostname);
+ /*
+  * Read the option name...
+  */
+
+  for (line += 8, olen --; isalnum(*line & 255); line ++)
+    if (olen > 0)
+    {
+      *option++ = *line;
+      olen --;
     }
 
-    attr->group_tag = IPP_TAG_JOB;
-  }
-  else
-  {
-   /*
-    * No job-originating-host-name attribute, so use the hostname from
-    * the connection...
-    */
+  *option = '\0';
 
-    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, 
-                "job-originating-host-name", NULL, con->http.hostname);
-  }
+ /*
+  * Skip everything else up to the colon (:)...
+  */
 
-  ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
-  job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM,
-                             "job-state", IPP_JOB_PENDING);
-  job->state_value = job->state->values[0].integer;
-  job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                              "job-media-sheets-completed", 0);
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
-               printer->uri);
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
-               title);
+  while (*line && *line != ':')
+    line ++;
 
-  if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
-                               IPP_TAG_INTEGER)) == NULL)
-    attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                         "job-k-octets", 0);
+  if (!*line)
+    return (-1);
 
-  if (stat(con->filename, &fileinfo))
-    kbytes = 0;
-  else
-    kbytes = (fileinfo.st_size + 1023) / 1024;
+  line ++;
 
-  cupsdUpdateQuota(printer, job->username, 0, kbytes);
-  attr->values[0].integer += kbytes;
+ /*
+  * Now grab the option choice, skipping leading whitespace...
+  */
 
-  ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation",
-                time(NULL));
-  attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                       "time-at-processing", 0);
-  attr->value_tag = IPP_TAG_NOVALUE;
-  attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
-                       "time-at-completed", 0);
-  attr->value_tag = IPP_TAG_NOVALUE;
+  while (isspace(*line & 255))
+    line ++;
 
-  if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
-                               IPP_TAG_KEYWORD)) == NULL)
-    attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
-  if (!attr)
-    attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                        "job-hold-until", NULL, "no-hold");
+  for (clen --; isalnum(*line & 255); line ++)
+    if (clen > 0)
+    {
+      *choice++ = *line;
+      clen --;
+    }
 
-  if (attr && strcmp(attr->values[0].string.text, "no-hold") &&
-      !(printer->type & CUPS_PRINTER_REMOTE))
-  {
-   /*
-    * Hold job until specified time...
-    */
+  *choice = '\0';
 
-    job->state->values[0].integer = IPP_JOB_HELD;
-    job->state_value              = IPP_JOB_HELD;
-    cupsdSetJobHoldUntil(job, attr->values[0].string.text);
-  }
+ /*
+  * Return with no errors...
+  */
 
-  if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
-      Classification)
-  {
-   /*
-    * Add job sheets options...
-    */
+  return (0);
+}
 
-    if ((attr = ippFindAttribute(job->attrs, "job-sheets",
-                                 IPP_TAG_ZERO)) == NULL)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "Adding default job-sheets values \"%s,%s\"...",
-                      printer->job_sheets[0], printer->job_sheets[1]);
 
-      attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
-                           2, NULL, NULL);
-      attr->values[0].string.text = _cups_sp_alloc(printer->job_sheets[0]);
-      attr->values[1].string.text = _cups_sp_alloc(printer->job_sheets[1]);
-    }
+/*
+ * 'print_job()' - Print a file to a printer or class.
+ */
 
-    job->job_sheets = attr;
+static void
+print_job(cupsd_client_t  *con,                /* I - Client connection */
+         ipp_attribute_t *uri)         /* I - Printer URI */
+{
+  ipp_attribute_t *attr;               /* Current attribute */
+  ipp_attribute_t *format;             /* Document-format attribute */
+  cupsd_job_t  *job;                   /* New job */
+  char         filename[1024];         /* Job filename */
+  mime_type_t  *filetype;              /* Type of file */
+  char         super[MIME_MAX_SUPER],  /* Supertype of file */
+               type[MIME_MAX_TYPE],    /* Subtype of file */
+               mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2];
+                                       /* Textual name of mime type */
+  cupsd_printer_t *printer;            /* Printer data */
+  struct stat  fileinfo;               /* File information */
+  int          kbytes;                 /* Size of file */
+  int          compression;            /* Document compression */
 
-   /*
-    * Enforce classification level if set...
-    */
 
-    if (Classification)
-    {
-      cupsdLogMessage(CUPSD_LOG_INFO,
-                      "Classification=\"%s\", ClassifyOverride=%d",
-                      Classification ? Classification : "(null)",
-                     ClassifyOverride);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->http.fd,
+                  uri->values[0].string.text);
 
-      if (ClassifyOverride)
-      {
-        if (!strcmp(attr->values[0].string.text, "none") &&
-           (attr->num_values == 1 ||
-            !strcmp(attr->values[1].string.text, "none")))
-        {
-        /*
-          * Force the leading banner to have the classification on it...
-         */
+ /*
+  * Validate print file attributes, for now just document-format and
+  * compression (CUPS only supports "none" and "gzip")...
+  */
 
-          cupsdSetString(&attr->values[0].string.text, Classification);
+  compression = CUPS_FILE_NONE;
 
-         cupsdLogMessage(CUPSD_LOG_NOTICE,
-                         "[Job %d] CLASSIFICATION FORCED "
-                         "job-sheets=\"%s,none\", "
-                         "job-originating-user-name=\"%s\"",
-                         job->id, Classification, job->username);
-       }
-       else if (attr->num_values == 2 &&
-                strcmp(attr->values[0].string.text,
-                       attr->values[1].string.text) &&
-                strcmp(attr->values[0].string.text, "none") &&
-                strcmp(attr->values[1].string.text, "none"))
-        {
-        /*
-         * Can't put two different security markings on the same document!
-         */
+  if ((attr = ippFindAttribute(con->request, "compression",
+                               IPP_TAG_KEYWORD)) != NULL)
+  {
+    if (strcmp(attr->values[0].string.text, "none")
+#ifdef HAVE_LIBZ
+        && strcmp(attr->values[0].string.text, "gzip")
+#endif /* HAVE_LIBZ */
+      )
+    {
+      send_ipp_status(con, IPP_ATTRIBUTES,
+                      _("Unsupported compression \"%s\"!"),
+                     attr->values[0].string.text);
+      ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+                  "compression", NULL, attr->values[0].string.text);
+      return;
+    }
 
-          cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
+#ifdef HAVE_LIBZ
+    if (!strcmp(attr->values[0].string.text, "gzip"))
+      compression = CUPS_FILE_GZIP;
+#endif /* HAVE_LIBZ */
+  }
 
-         cupsdLogMessage(CUPSD_LOG_NOTICE,
-                         "[Job %d] CLASSIFICATION FORCED "
-                         "job-sheets=\"%s,%s\", "
-                         "job-originating-user-name=\"%s\"",
-                         job->id, attr->values[0].string.text,
-                         attr->values[1].string.text, job->username);
-       }
-       else if (strcmp(attr->values[0].string.text, Classification) &&
-                strcmp(attr->values[0].string.text, "none") &&
-                (attr->num_values == 1 ||
-                 (strcmp(attr->values[1].string.text, Classification) &&
-                  strcmp(attr->values[1].string.text, "none"))))
-        {
-         if (attr->num_values == 1)
-            cupsdLogMessage(CUPSD_LOG_NOTICE,
-                           "[Job %d] CLASSIFICATION OVERRIDDEN "
-                           "job-sheets=\"%s\", "
-                           "job-originating-user-name=\"%s\"",
-                           job->id, attr->values[0].string.text,
-                           job->username);
-          else
-            cupsdLogMessage(CUPSD_LOG_NOTICE,
-                           "[Job %d] CLASSIFICATION OVERRIDDEN "
-                           "job-sheets=\"%s,%s\", "
-                           "job-originating-user-name=\"%s\"",
-                           job->id, attr->values[0].string.text,
-                           attr->values[1].string.text, job->username);
-        }
-      }
-      else if (strcmp(attr->values[0].string.text, Classification) &&
-               (attr->num_values == 1 ||
-              strcmp(attr->values[1].string.text, Classification)))
-      {
-       /*
-        * Force the banner to have the classification on it...
-       */
+ /*
+  * Do we have a file to print?
+  */
 
-        if (attr->num_values > 1 &&
-           !strcmp(attr->values[0].string.text, attr->values[1].string.text))
-       {
-          cupsdSetString(&(attr->values[0].string.text), Classification);
-          cupsdSetString(&(attr->values[1].string.text), Classification);
-       }
-        else
-       {
-          if (attr->num_values == 1 ||
-             strcmp(attr->values[0].string.text, "none"))
-            cupsdSetString(&(attr->values[0].string.text), Classification);
+  if (!con->filename)
+  {
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!"));
+    return;
+  }
 
-          if (attr->num_values > 1 &&
-             strcmp(attr->values[1].string.text, "none"))
-            cupsdSetString(&(attr->values[1].string.text), Classification);
-        }
+ /*
+  * Is it a format we support?
+  */
 
-        if (attr->num_values > 1)
-         cupsdLogMessage(CUPSD_LOG_NOTICE,
-                         "[Job %d] CLASSIFICATION FORCED "
-                         "job-sheets=\"%s,%s\", "
-                         "job-originating-user-name=\"%s\"",
-                         job->id, attr->values[0].string.text,
-                         attr->values[1].string.text, job->username);
-        else
-         cupsdLogMessage(CUPSD_LOG_NOTICE,
-                         "[Job %d] CLASSIFICATION FORCED "
-                         "job-sheets=\"%s\", "
-                         "job-originating-user-name=\"%s\"",
-                         job->id, Classification, job->username);
-      }
+  if ((format = ippFindAttribute(con->request, "document-format",
+                                 IPP_TAG_MIMETYPE)) != NULL)
+  {
+   /*
+    * Grab format from client...
+    */
+
+    if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2)
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Could not scan type \"%s\"!"),
+                     format->values[0].string.text);
+      return;
     }
+  }
+  else
+  {
+   /*
+    * No document format attribute?  Auto-type it!
+    */
+
+    strcpy(super, "application");
+    strcpy(type, "octet-stream");
+  }
 
+  if (!strcmp(super, "application") && !strcmp(type, "octet-stream"))
+  {
    /*
-    * Add the starting sheet...
+    * Auto-type the file...
     */
 
-    if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+    ipp_attribute_t    *doc_name;      /* document-name attribute */
+
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: auto-typing file...");
+
+    doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME);
+    filetype = mimeFileType(MimeDatabase, con->filename,
+                            doc_name ? doc_name->values[0].string.text : NULL,
+                           &compression);
+
+    if (filetype)
     {
-      cupsdLogMessage(CUPSD_LOG_INFO,
-                      "Adding start banner page \"%s\" to job %d.",
-                     attr->values[0].string.text, job->id);
+     /*
+      * Replace the document-format attribute value with the auto-typed one.
+      */
 
-      kbytes = copy_banner(con, job, attr->values[0].string.text);
+      snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super,
+               filetype->type);
 
-      cupsdUpdateQuota(printer, job->username, 0, kbytes);
+      if (format)
+      {
+         _cups_sp_free(format->values[0].string.text);
+
+       format->values[0].string.text = _cups_sp_alloc(mimetype);
+      }
+      else
+        ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+                    "document-format", NULL, mimetype);
     }
+    else
+      filetype = mimeType(MimeDatabase, super, type);
   }
-  else if ((attr = ippFindAttribute(job->attrs, "job-sheets",
-                                    IPP_TAG_ZERO)) != NULL)
-    job->sheets = attr;
-   
+  else
+    filetype = mimeType(MimeDatabase, super, type);
+
+  if (!filetype)
+  {
+    send_ipp_status(con, IPP_DOCUMENT_FORMAT,
+                    _("Unsupported format \'%s/%s\'!"), super, type);
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Hint: Do you have the raw file printing rules enabled?");
+
+    if (format)
+      ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
+                   "document-format", NULL, format->values[0].string.text);
+
+    return;
+  }
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: request file type is %s/%s.",
+            filetype->super, filetype->type);
+
+ /*
+  * Read any embedded job ticket info from PS files...
+  */
+
+  if (!strcasecmp(filetype->super, "application") &&
+      !strcasecmp(filetype->type, "postscript"))
+    read_ps_job_ticket(con);
+
+ /*
+  * Create the job object...
+  */
+
+  if ((job = add_job(con, uri, &printer)) == NULL)
+    return;
+
+ /*
+  * Update quota data...
+  */
+
+  if (stat(con->filename, &fileinfo))
+    kbytes = 0;
+  else
+    kbytes = (fileinfo.st_size + 1023) / 1024;
+
+  cupsdUpdateQuota(printer, job->username, 0, kbytes);
+
+  if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
+                               IPP_TAG_INTEGER)) != NULL)
+    attr->values[0].integer += kbytes;
+
  /*
   * Add the job file...
   */
@@ -7407,37 +6871,6 @@ print_job(cupsd_client_t  *con,          /* I - Client connection */
     cupsdUpdateQuota(printer, job->username, 0, kbytes);
   }
 
- /*
-  * Fill in the response info...
-  */
-
-  snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
-          LocalPort, job->id);
-
-  ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
-               job_uri);
-
-  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
-
-  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
-                job->state_value);
-  add_job_state_reasons(con, job);
-
-  con->response->request.status.status_code = IPP_OK;
-
- /*
-  * Add any job subscriptions...
-  */
-
-  add_job_subscriptions(con, job);
-
- /*
-  * Set all but the first two attributes to the job attributes group...
-  */
-
-  for (attr = job->attrs->attrs->next->next; attr; attr = attr->next)
-    attr->group_tag = IPP_TAG_JOB;
-
  /*
   * Log and save the job...
   */
@@ -7449,8 +6882,6 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
 
   cupsdSaveJob(job);
 
-  cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created.");
-
  /*
   * Start the job if possible...
   */
@@ -9020,6 +8451,256 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
 }
 
 
+/*
+ * 'set_printer_defaults()' - Set printer default options from a request.
+ */
+
+static void
+set_printer_defaults(
+    cupsd_client_t  *con,              /* I - Client connection */
+    cupsd_printer_t *printer)          /* I - Printer */
+{
+  int                  i;              /* Looping var */
+  ipp_attribute_t      *attr;          /* Current attribute */
+  int                  namelen;        /* Length of attribute name */
+  char                 name[256],      /* New attribute name */
+                       value[256];     /* String version of integer attrs */
+
+
+  for (attr = con->request->attrs; attr; attr = attr->next)
+  {
+   /*
+    * Skip non-printer attributes...
+    */
+
+    if (attr->group_tag != IPP_TAG_PRINTER || !attr->name)
+      continue;
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_defaults: %s", attr->name);
+
+    if (!strcmp(attr->name, "job-sheets-default"))
+    {
+     /*
+      * Only allow keywords and names...
+      */
+
+      if (attr->value_tag != IPP_TAG_NAME && attr->value_tag != IPP_TAG_KEYWORD)
+        continue;
+
+     /*
+      * Only allow job-sheets-default to be set when running without a
+      * system high classification level...
+      */
+
+      if (Classification)
+        continue;
+
+      cupsdSetString(&printer->job_sheets[0], attr->values[0].string.text);
+
+      if (attr->num_values > 1)
+       cupsdSetString(&printer->job_sheets[1], attr->values[1].string.text);
+      else
+       cupsdSetString(&printer->job_sheets[1], "none");
+    }
+    else if (!strcmp(attr->name, "requesting-user-name-allowed"))
+    {
+      cupsdFreePrinterUsers(printer);
+
+      printer->deny_users = 0;
+
+      if (attr->value_tag == IPP_TAG_NAME &&
+          (attr->num_values > 1 ||
+          strcmp(attr->values[0].string.text, "all")))
+      {
+       for (i = 0; i < attr->num_values; i ++)
+         cupsdAddPrinterUser(printer, attr->values[i].string.text);
+      }
+    }
+    else if (!strcmp(attr->name, "requesting-user-name-denied"))
+    {
+      cupsdFreePrinterUsers(printer);
+
+      printer->deny_users = 1;
+
+      if (attr->value_tag == IPP_TAG_NAME &&
+          (attr->num_values > 1 ||
+          strcmp(attr->values[0].string.text, "none")))
+      {
+       for (i = 0; i < attr->num_values; i ++)
+         cupsdAddPrinterUser(printer, attr->values[i].string.text);
+      }
+    }
+    else if (!strcmp(attr->name, "job-quota-period"))
+    {
+      if (attr->value_tag != IPP_TAG_INTEGER)
+        continue;
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-quota-period to %d...",
+                     attr->values[0].integer);
+      cupsdFreeQuotas(printer);
+
+      printer->quota_period = attr->values[0].integer;
+    }
+    else if (!strcmp(attr->name, "job-k-limit"))
+    {
+      if (attr->value_tag != IPP_TAG_INTEGER)
+        continue;
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-k-limit to %d...",
+                     attr->values[0].integer);
+      cupsdFreeQuotas(printer);
+
+      printer->k_limit = attr->values[0].integer;
+    }
+    else if (!strcmp(attr->name, "job-page-limit"))
+    {
+      if (attr->value_tag != IPP_TAG_INTEGER)
+        continue;
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-page-limit to %d...",
+                     attr->values[0].integer);
+      cupsdFreeQuotas(printer);
+
+      printer->page_limit = attr->values[0].integer;
+    }
+    else if (!strcmp(attr->name, "printer-op-policy"))
+    {
+      cupsd_policy_t *p;               /* Policy */
+
+
+      if (attr->value_tag != IPP_TAG_NAME)
+        continue;
+
+      if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL)
+      {
+       cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "Setting printer-op-policy to \"%s\"...",
+                       attr->values[0].string.text);
+       cupsdSetString(&printer->op_policy, attr->values[0].string.text);
+       printer->op_policy_ptr = p;
+      }
+      else
+      {
+       send_ipp_status(con, IPP_NOT_POSSIBLE,
+                       _("Unknown printer-op-policy \"%s\"."),
+                       attr->values[0].string.text);
+       return;
+      }
+    }
+    else if (!strcmp(attr->name, "printer-error-policy"))
+    {
+      if (attr->value_tag != IPP_TAG_NAME && attr->value_tag != IPP_TAG_KEYWORD)
+        continue;
+
+      if (strcmp(attr->values[0].string.text, "abort-job") &&
+          strcmp(attr->values[0].string.text, "retry-job") &&
+          strcmp(attr->values[0].string.text, "stop-printer"))
+      {
+       send_ipp_status(con, IPP_NOT_POSSIBLE,
+                       _("Unknown printer-error-policy \"%s\"."),
+                       attr->values[0].string.text);
+       return;
+      }
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "Setting printer-error-policy to \"%s\"...",
+                      attr->values[0].string.text);
+      cupsdSetString(&printer->error_policy, attr->values[0].string.text);
+    }
+    else if (!strcmp(attr->name, "document-format-default") ||
+             !strcmp(attr->name, "notify-lease-duration-default") ||
+             !strcmp(attr->name, "notify-notify-events-default"))
+      continue;
+
+   /*
+    * Skip any other non-default attributes...
+    */
+
+    namelen = strlen(attr->name);
+    if (namelen < 9 || strcmp(attr->name + namelen - 8, "-default") ||
+        namelen > (sizeof(name) - 1) || attr->num_values != 1)
+      continue;
+
+   /*
+    * OK, anything else must be a user-defined default...
+    */
+
+    strlcpy(name, attr->name, sizeof(name));
+    name[namelen - 8] = '\0';          /* Strip "-default" */
+
+    switch (attr->value_tag)
+    {
+      case IPP_TAG_DELETEATTR :
+          printer->num_options = cupsRemoveOption(name,
+                                                 printer->num_options,
+                                                 &(printer->options));
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Deleting %s", attr->name);
+          break;
+
+      case IPP_TAG_NAME :
+      case IPP_TAG_KEYWORD :
+      case IPP_TAG_URI :
+          printer->num_options = cupsAddOption(name,
+                                              attr->values[0].string.text,
+                                              printer->num_options,
+                                              &(printer->options));
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Setting %s to \"%s\"...", attr->name,
+                         attr->values[0].string.text);
+          break;
+
+      case IPP_TAG_BOOLEAN :
+          printer->num_options = cupsAddOption(name,
+                                              attr->values[0].boolean ?
+                                                  "true" : "false",
+                                              printer->num_options,
+                                              &(printer->options));
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Setting %s to %s...", attr->name,
+                         attr->values[0].boolean ? "true" : "false");
+          break;
+
+      case IPP_TAG_INTEGER :
+      case IPP_TAG_ENUM :
+          sprintf(value, "%d", attr->values[0].integer);
+          printer->num_options = cupsAddOption(name, value,
+                                              printer->num_options,
+                                              &(printer->options));
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Setting %s to %s...", attr->name, value);
+          break;
+
+      case IPP_TAG_RANGE :
+          sprintf(value, "%d-%d", attr->values[0].range.lower,
+                 attr->values[0].range.upper);
+          printer->num_options = cupsAddOption(name, value,
+                                              printer->num_options,
+                                              &(printer->options));
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Setting %s to %s...", attr->name, value);
+          break;
+
+      case IPP_TAG_RESOLUTION :
+          sprintf(value, "%dx%d%s", attr->values[0].resolution.xres,
+                 attr->values[0].resolution.yres,
+                 attr->values[0].resolution.units == IPP_RES_PER_INCH ?
+                     "dpi" : "dpc");
+          printer->num_options = cupsAddOption(name, value,
+                                              printer->num_options,
+                                              &(printer->options));
+          cupsdLogMessage(CUPSD_LOG_DEBUG,
+                         "Setting %s to %s...", attr->name, value);
+          break;
+
+      default :
+          /* Do nothing for other values */
+         break;
+    }
+  }
+}
+
+
 /*
  * 'start_printer()' - Start a printer.
  */
@@ -9413,5 +9094,5 @@ validate_user(cupsd_job_t    *job,        /* I - Job */
 
 
 /*
- * End of "$Id: ipp.c 5131 2006-02-18 05:31:36Z mike $".
+ * End of "$Id: ipp.c 5164 2006-02-24 20:40:00Z mike $".
  */
index 0c65f3e34b91bdbf3f717c43df0085f1823ebb3e..3fbc59f92b77e83e09cf862000e4ca3dc877ac6b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: job.c 5131 2006-02-18 05:31:36Z mike $"
+ * "$Id: job.c 5196 2006-02-27 21:23:00Z mike $"
  *
  *   Job management routines for the Common UNIX Printing System (CUPS).
  *
@@ -2868,7 +2868,7 @@ free_job(cupsd_job_t *job)                /* I - Job */
  *                 the textual IPP attributes.
  */
 
-int                                    /* O - Size of attribute buffer */
+static int                             /* O - Size of attribute buffer */
 ipp_length(ipp_t *ipp)                 /* I - IPP request */
 {
   int                  bytes;          /* Number of bytes */
@@ -3424,5 +3424,5 @@ set_hold_until(cupsd_job_t *job,  /* I - Job to update */
 
 
 /*
- * End of "$Id: job.c 5131 2006-02-18 05:31:36Z mike $".
+ * End of "$Id: job.c 5196 2006-02-27 21:23:00Z mike $".
  */
index 1aa41a704a49613a168a0bdb8aad0daa37de53ea..52a61132b279d9d3a94c2fb8902479e233b28073 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: log.c 4860 2005-12-01 22:07:26Z mike $"
+ * "$Id: log.c 5194 2006-02-27 20:57:07Z mike $"
  *
  *   Log file routines for the Common UNIX Printing System (CUPS).
  *
 
 #include "cupsd.h"
 #include <stdarg.h>
-
-#ifdef HAVE_VSYSLOG
-#  include <syslog.h>
-#endif /* HAVE_VSYSLOG */
+#include <syslog.h>
 
 
 /*
@@ -549,5 +546,5 @@ check_log_file(cups_file_t **lf,    /* IO - Log file */
 
 
 /*
- * End of "$Id: log.c 4860 2005-12-01 22:07:26Z mike $".
+ * End of "$Id: log.c 5194 2006-02-27 20:57:07Z mike $".
  */
index d0371248b20af499f1c566a39b1c345c59c3f0ce..018fba69afb83e2dcfe4d4d9c245f0aad7bf87e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: main.c 5108 2006-02-15 19:33:09Z mike $"
+ * "$Id: main.c 5157 2006-02-23 20:58:57Z mike $"
  *
  *   Scheduler main loop for the Common UNIX Printing System (CUPS).
  *
@@ -865,10 +865,16 @@ main(int  argc,                           /* I - Number of command-line args */
         cupsdUpdatePolling();
 
 #ifdef HAVE_LIBSLP
-      if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) &&
+      if ((BrowseRemoteProtocols & BROWSE_SLP) &&
           BrowseSLPRefresh <= current_time)
         cupsdUpdateSLPBrowse();
 #endif /* HAVE_LIBSLP */
+
+#ifdef HAVE_LDAP
+      if ((BrowseRemoteProtocols & BROWSE_LDAP) &&
+          BrowseLDAPRefresh <= current_time)
+        cupsdUpdateLDAPBrowse();
+#endif /* HAVE_LDAP */
     }
 
     if (Browsing && BrowseLocalProtocols && current_time > browse_time)
@@ -2209,6 +2215,14 @@ select_timeout(int fds)                  /* I - Number of descriptors returned */
     }
 #endif /* HAVE_LIBSLP */
 
+#ifdef HAVE_LDAP
+    if ((BrowseLocalProtocols & BROWSE_LDAP) && (BrowseLDAPRefresh < timeout))
+    {
+      timeout = BrowseLDAPRefresh;
+      why     = "update LDAP browsing";
+    }
+#endif /* HAVE_LDAP */
+
     if (BrowseLocalProtocols & BROWSE_CUPS)
     {
       for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
@@ -2324,5 +2338,5 @@ usage(int status)                 /* O - Exit status */
 
 
 /*
- * End of "$Id: main.c 5108 2006-02-15 19:33:09Z mike $".
+ * End of "$Id: main.c 5157 2006-02-23 20:58:57Z mike $".
  */
index 9423e1b378655ba757b024c6c78839cdbf0f356e..96ccbcaa858727bb6dde4718a2ac129954c17e36 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: printers.c 5143 2006-02-21 19:13:01Z mike $"
+ * "$Id: printers.c 5178 2006-02-26 00:24:23Z mike $"
  *
  *   Printer routines for the Common UNIX Printing System (CUPS).
  *
@@ -32,6 +32,7 @@
  *   cupsdFindPrinter()          - Find a printer in the list.
  *   cupsdFreePrinterUsers()     - Free allow/deny users.
  *   cupsdLoadAllPrinters()      - Load printers from the printers.conf file.
+ *   cupsdRenamePrinter()        - Rename a printer.
  *   cupsdSaveAllPrinters()      - Save all printer definitions to the
  *                                 printers.conf file.
  *   cupsdSetPrinterAttrs()      - Set printer attributes based upon the PPD
@@ -44,6 +45,8 @@
  *   cupsdWritePrintcap()        - Write a pseudo-printcap file for older
  *                                 applications that need it...
  *   cupsdSanitizeURI()          - Sanitize a device URI...
+ *   add_printer_defaults()      - Add name-default attributes to the printer
+ *                                 attributes.
  *   add_printer_filter()        - Add a MIME filter for a printer.
  *   add_printer_formats()       - Add document-format-supported values for
  *                                 a printer.
@@ -67,6 +70,7 @@
  * Local functions...
  */
 
+static void    add_printer_defaults(cupsd_printer_t *p);
 static void    add_printer_filter(cupsd_printer_t *p, const char *filter);
 static void    add_printer_formats(cupsd_printer_t *p);
 static int     compare_printers(void *first, void *second, void *data);
@@ -401,15 +405,9 @@ cupsdCreateCommonData(void)
                sizeof(compressions) / sizeof(compressions[0]),
                NULL, compressions);
 
-  /* TODO: move to printer-specific section! */
-  /* copies-default */
-  ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                "copies-default", 1);
-
   /* copies-supported */
   ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies);
 
-  /* TODO: move to printer-specific section! */
   /* document-format-default */
   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
                "document-format-default", NULL, "application/octet-stream");
@@ -423,21 +421,11 @@ cupsdCreateCommonData(void)
                 "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]),
                NULL, versions);
 
-  /* TODO: move to printer-specific section! */
-  /* job-hold-until-default */
-  ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-               "job-hold-until-default", NULL, "no-hold");
-
   /* job-hold-until-supported */
   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                 "job-hold-until-supported", sizeof(holds) / sizeof(holds[0]),
                NULL, holds);
 
-  /* TODO: move to printer-specific section! */
-  /* job-priority-default */
-  ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                "job-priority-default", 50);
-
   /* job-priority-supported */
   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                 "job-priority-supported", 100);
@@ -503,7 +491,6 @@ cupsdCreateCommonData(void)
                (int)(sizeof(notify_attrs) / sizeof(notify_attrs[0])),
                NULL, notify_attrs);
 
-  /* TODO: move to printer-specific section! */
   /* notify-lease-duration-default */
   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                "notify-lease-duration-default", DefaultLeaseDuration);
@@ -536,11 +523,6 @@ cupsdCreateCommonData(void)
   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                "notify-schemes-supported", NULL, "mailto");
 
-  /* TODO: move to printer-specific section! */
-  /* number-up-default */
-  ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                "number-up-default", 1);
-
   /* number-up-supported */
   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                  "number-up-supported", sizeof(nups) / sizeof(nups[0]), nups);
@@ -550,11 +532,6 @@ cupsdCreateCommonData(void)
                  "operations-supported",
                  sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops);
 
-  /* TODO: move to printer-specific section! */
-  /* orientation-requested-default */
-  ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
-                "orientation-requested-default", IPP_PORTRAIT);
-
   /* orientation-requested-supported */
   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
                  "orientation-requested-supported", 4, (int *)orients);
@@ -746,10 +723,15 @@ cupsdDeletePrinter(
   cupsdClearString(&p->op_policy);
   cupsdClearString(&p->error_policy);
 
+  if (p->browse_attrs)
+    free(p->browse_attrs);
+
 #ifdef __APPLE__
   cupsdClearString(&p->recoverable);
 #endif /* __APPLE__ */
 
+  cupsFreeOptions(p->num_options, p->options);
+
   free(p);
 
  /*
@@ -999,6 +981,25 @@ cupsdLoadAllPrinters(void)
        return;
       }
     }
+    else if (!strcasecmp(line, "Option") && value)
+    {
+     /*
+      * Option name value
+      */
+
+      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
+
+      if (!*valueptr)
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of printers.conf.", linenum);
+      else
+      {
+        for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
+
+        p->num_options = cupsAddOption(value, valueptr, p->num_options,
+                                      &(p->options));
+      }
+    }
     else if (!strcasecmp(line, "PortMonitor"))
     {
       if (value && strcmp(value, "none"))
@@ -1227,6 +1228,53 @@ cupsdLoadAllPrinters(void)
 }
 
 
+/*
+ * 'cupsdRenamePrinter()' - Rename a printer.
+ */
+
+void
+cupsdRenamePrinter(
+    cupsd_printer_t *p,                        /* I - Printer */
+    const char      *name)             /* I - New name */
+{
+ /*
+  * Remove the printer from the array(s) first...
+  */
+
+  cupsArrayRemove(Printers, p);
+
+  if (p->type & CUPS_PRINTER_IMPLICIT)
+    cupsArrayRemove(ImplicitPrinters, p);
+
+ /*
+  * Rename the printer type...
+  */
+
+  mimeDeleteType(MimeDatabase, p->filetype);
+  p->filetype = mimeAddType(MimeDatabase, "printer", name);
+
+ /*
+  * Rename the printer...
+  */
+
+  cupsdSetStringf(&p->name, name);
+
+ /*
+  * Reset printer attributes...
+  */
+
+  cupsdSetPrinterAttrs(p);
+
+ /*
+  * Add the printer back to the printer array(s)...
+  */
+
+  cupsArrayAdd(Printers, p);
+  if (p->type & CUPS_PRINTER_IMPLICIT)
+    cupsArrayAdd(ImplicitPrinters, p);
+}
+
+
 /*
  * 'cupsdSaveAllPrinters()' - Save all printer definitions to the printers.conf
  *                            file.
@@ -1242,6 +1290,7 @@ cupsdSaveAllPrinters(void)
   cupsd_printer_t      *printer;       /* Current printer class */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
+  cups_option_t                *option;        /* Current option */
 
 
  /*
@@ -1363,6 +1412,11 @@ cupsdSaveAllPrinters(void)
     if (printer->error_policy)
       cupsFilePrintf(fp, "ErrorPolicy %s\n", printer->error_policy);
 
+    for (i = printer->num_options, option = printer->options;
+         i > 0;
+        i --, option ++)
+      cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+
     cupsFilePuts(fp, "</Printer>\n");
 
 #ifdef __sgi
@@ -1385,32 +1439,33 @@ cupsdSaveAllPrinters(void)
 void
 cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
 {
-  char                 uri[HTTP_MAX_URI];
-                                       /* URI for printer */
-  char                 resource[HTTP_MAX_URI];
-                                       /* Resource portion of URI */
-  int                  i;              /* Looping var */
-  char                 filename[1024]; /* Name of PPD file */
-  int                  num_media;      /* Number of media options */
-  cupsd_location_t     *auth;          /* Pointer to authentication element */
-  const char           *auth_supported;/* Authentication supported */
-  cups_ptype_t         printer_type;   /* Printer type data */
-  ppd_file_t           *ppd;           /* PPD file data */
-  ppd_option_t         *input_slot,    /* InputSlot options */
-                       *media_type,    /* MediaType options */
-                       *page_size,     /* PageSize options */
-                       *output_bin,    /* OutputBin options */
-                       *media_quality; /* EFMediaQualityMode options */
-  ppd_attr_t           *ppdattr;       /* PPD attribute */
-  ipp_attribute_t      *attr;          /* Attribute data */
-  ipp_value_t          *val;           /* Attribute value */
-  int                  num_finishings; /* Number of finishings */
-  ipp_finish_t         finishings[5];  /* finishings-supported values */
+  int          i,                      /* Looping var */
+               length;                 /* Length of browse attributes */
+  char         uri[HTTP_MAX_URI];      /* URI for printer */
+  char         resource[HTTP_MAX_URI]; /* Resource portion of URI */
+  char         filename[1024];         /* Name of PPD file */
+  int          num_media;              /* Number of media options */
+  cupsd_location_t *auth;              /* Pointer to authentication element */
+  const char   *auth_supported;        /* Authentication supported */
+  cups_ptype_t printer_type;           /* Printer type data */
+  ppd_file_t   *ppd;                   /* PPD file data */
+  ppd_option_t *input_slot,            /* InputSlot options */
+               *media_type,            /* MediaType options */
+               *page_size,             /* PageSize options */
+               *output_bin,            /* OutputBin options */
+               *media_quality,         /* EFMediaQualityMode options */
+               *duplex;                /* Duplex options */
+  ppd_attr_t   *ppdattr;               /* PPD attribute */
+  ipp_attribute_t *attr;               /* Attribute data */
+  ipp_value_t  *val;                   /* Attribute value */
+  int          num_finishings;         /* Number of finishings */
+  ipp_finish_t finishings[5];          /* finishings-supported values */
+  cups_option_t        *option;                /* Current printer option */
   static const char * const sides[3] = /* sides-supported values */
                {
-                 "one",
-                 "two-long-edge",
-                 "two-short-edge"
+                 "one-sided",
+                 "two-sided-long-edge",
+                 "two-sided-short-edge"
                };
 
 
@@ -1699,9 +1754,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
         if (num_media == 0)
        {
          cupsdLogMessage(CUPSD_LOG_CRIT,
-                         "The PPD file for printer %s "
-                         "contains no media options and is therefore "
-                         "invalid!", p->name);
+                         "The PPD file for printer %s contains no media "
+                         "options and is therefore invalid!", p->name);
        }
        else
        {
@@ -1728,21 +1782,21 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
              for (i = 0; i < page_size->num_choices; i ++, val ++)
                val->string.text = _cups_sp_alloc(page_size->choices[i].choice);
 
-             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
-                          NULL, page_size->defchoice);
+             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                          "media-default", NULL, page_size->defchoice);
             }
            else if (input_slot != NULL)
-             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
-                          NULL, input_slot->defchoice);
+             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                          "media-default", NULL, input_slot->defchoice);
            else if (media_type != NULL)
-             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
-                          NULL, media_type->defchoice);
+             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                          "media-default", NULL, media_type->defchoice);
            else if (media_quality != NULL)
-             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
-                          NULL, media_quality->defchoice);
+             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                          "media-default", NULL, media_quality->defchoice);
            else
-             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
-                          NULL, "none");
+             ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                          "media-default", NULL, "none");
           }
         }
 
@@ -1769,14 +1823,28 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
         * Duplexing, etc...
        */
 
-       if (ppdFindOption(ppd, "Duplex") != NULL)
+       if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL)
+         if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL)
+           if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL)
+             if ((duplex = ppdFindOption(ppd, "KD03Duplex")) == NULL)
+               duplex = ppdFindOption(ppd, "JCLDuplex");
+
+       if (duplex && duplex->num_choices > 1)
        {
          p->type |= CUPS_PRINTER_DUPLEX;
 
-         ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-supported",
-                       3, NULL, sides);
-         ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-default",
-                       NULL, "one");
+         ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                       "sides-supported", 3, NULL, sides);
+
+          if (!strcasecmp(duplex->defchoice, "DuplexTumble"))
+           ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                        "sides-default", NULL, "two-sided-short-edge");
+          else if (!strcasecmp(duplex->defchoice, "DuplexNoTumble"))
+           ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                        "sides-default", NULL, "two-sided-long-edge");
+         else
+           ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                        "sides-default", NULL, "one-sided");
        }
 
        if (ppdFindOption(ppd, "Collate") != NULL)
@@ -1883,16 +1951,18 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
 
         pstatus = ppdLastError(&pline);
 
-       cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded!", p->name);
+       cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded!",
+                       p->name);
 
        if (pstatus <= PPD_ALLOC_ERROR)
          cupsdLogMessage(CUPSD_LOG_ERROR, "%s", strerror(errno));
         else
-         cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d.", ppdErrorString(pstatus),
-                    pline);
+         cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d.",
+                         ppdErrorString(pstatus), pline);
 
-        cupsdLogMessage(CUPSD_LOG_INFO, "Hint: Run \"cupstestppd %s\" and fix any errors.",
-                  filename);
+        cupsdLogMessage(CUPSD_LOG_INFO,
+                       "Hint: Run \"cupstestppd %s\" and fix any errors.",
+                       filename);
 
        /*
        * Add a filter from application/vnd.cups-raw to printer/name to
@@ -1915,7 +1985,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
 
        snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot,
                 p->name);
-       if (access(filename, X_OK) == 0)
+       if (!access(filename, X_OK))
        {
         /*
          * Yes, we have a System V style interface script; use it!
@@ -1981,6 +2051,99 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
     }
   }
 
+ /*
+  * Copy the printer options into a browse attributes string we can re-use.
+  */
+
+  if (!(p->type & CUPS_PRINTER_REMOTE))
+  {
+    const char *valptr;                /* Pointer into value */
+    char       *attrptr;               /* Pointer into attribute string */
+
+
+   /*
+    * Free the old browse attributes as needed...
+    */
+
+    if (p->browse_attrs)
+      free(p->browse_attrs);
+
+   /*
+    * Compute the length of all attributes + job-sheets, lease-duration,
+    * and BrowseLocalOptions.
+    */
+
+    for (length = 1, i = p->num_options, option = p->options;
+         i > 0;
+        i --, option ++)
+    {
+      length += strlen(option->name) + 2;
+
+      if (option->value)
+      {
+        for (valptr = option->value; *valptr; valptr ++)
+         if (strchr(" \"\'\\", *valptr))
+           length += 2;
+         else
+           length ++;
+      }
+    }
+
+    length += 13 + strlen(p->job_sheets[0]) + strlen(p->job_sheets[1]);
+    length += 32;
+    if (BrowseLocalOptions)
+      length += 12 + strlen(BrowseLocalOptions); 
+
+   /*
+    * Allocate the new string...
+    */
+    if ((p->browse_attrs = calloc(1, length)) == NULL)
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to allocate %d bytes for browse data!",
+                     length);
+    else
+    {
+     /*
+      * Got the allocated string, now copy the options and attributes over...
+      */
+
+      sprintf(p->browse_attrs, "job-sheets=%s,%s lease-duration=%d",
+              p->job_sheets[0], p->job_sheets[1], BrowseTimeout);
+      attrptr = p->browse_attrs + strlen(p->browse_attrs);
+
+      if (BrowseLocalOptions)
+      {
+        sprintf(attrptr, " ipp-options=%s", BrowseLocalOptions);
+        attrptr += strlen(attrptr);
+      }
+
+      for (i = p->num_options, option = p->options;
+           i > 0;
+          i --, option ++)
+      {
+        *attrptr++ = ' ';
+       strcpy(attrptr, option->name);
+       attrptr += strlen(attrptr);
+
+       if (option->value)
+       {
+         *attrptr++ = '=';
+
+          for (valptr = option->value; *valptr; valptr ++)
+         {
+           if (strchr(" \"\'\\", *valptr))
+             *attrptr++ = '\\';
+
+           *attrptr++ = *valptr;
+         }
+       }
+      }
+
+      *attrptr = '\0';
+    }
+  }
+
  /*
   * Populate the document-format-supported attribute...
   */
@@ -1990,6 +2153,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
   DEBUG_printf(("cupsdSetPrinterAttrs: leaving name = %s, type = %x\n", p->name,
                 p->type));
 
+ /*
+  * Add name-default attributes...
+  */
+
+  add_printer_defaults(p);
+
 #ifdef __sgi
  /*
   * Write the IRIX printer config and status files...
@@ -2586,6 +2755,70 @@ cupsdSanitizeURI(const char *uri,        /* I - Original device URI */
 }
 
 
+/*
+ * 'add_printer_defaults()' - Add name-default attributes to the printer attributes.
+ */
+
+static void
+add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
+{
+  int          i;                      /* Looping var */
+  int          num_options;            /* Number of default options */
+  cups_option_t        *options,               /* Default options */
+               *option;                /* Current option */
+  char         name[256];              /* name-default */
+
+
+ /*
+  * Add all of the default options from the .conf files...
+  */
+
+  for (num_options = 0, i = p->num_options, option = p->options;
+       i > 0;
+       i --, option ++)
+  {
+    if (strcmp(option->name, "ipp-options") &&
+       strcmp(option->name, "job-sheets") &&
+        strcmp(option->name, "lease-duration"))
+    {
+      snprintf(name, sizeof(name), "%s-default", option->name);
+      num_options = cupsAddOption(name, option->value, num_options, &options);
+    }
+  }
+
+ /*
+  * Convert options to IPP attributes...
+  */
+
+  cupsEncodeOptions2(p->attrs, num_options, options, IPP_TAG_PRINTER);
+  cupsFreeOptions(num_options, options);
+
+ /*
+  * Add standard -default attributes as needed...
+  */
+
+  if (!cupsGetOption("copies", p->num_options, p->options))
+    ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default",
+                  1);
+
+  if (!cupsGetOption("job-hold-until", p->num_options, p->options))
+    ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                 "job-hold-until-default", NULL, "no-hold");
+
+  if (!cupsGetOption("job-priority", p->num_options, p->options))
+    ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                  "job-priority-default", 50);
+
+  if (!cupsGetOption("number-up", p->num_options, p->options))
+    ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                  "number-up-default", 1);
+
+  if (!cupsGetOption("orientation-requested", p->num_options, p->options))
+    ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+                  "orientation-requested-default", IPP_PORTRAIT);
+}
+
+
 /*
  * 'add_printer_filter()' - Add a MIME filter for a printer.
  */
@@ -2641,6 +2874,15 @@ add_printer_filter(
     }
   }
 
+ /*
+  * Mark the CUPS_PRINTER_COMMANDS bit if we have a filter for
+  * application/vnd.cups-command...
+  */
+
+  if (!strcasecmp(super, "application") &&
+      !strcasecmp(type, "vnd.cups-command"))
+    p->type |= CUPS_PRINTER_COMMANDS;
+
  /*
   * Add the filter to the MIME database, supporting wildcards as needed...
   */
@@ -3109,5 +3351,5 @@ write_irix_state(cupsd_printer_t *p)      /* I - Printer to update */
 
 
 /*
- * End of "$Id: printers.c 5143 2006-02-21 19:13:01Z mike $".
+ * End of "$Id: printers.c 5178 2006-02-26 00:24:23Z mike $".
  */
index 79872ecddaf3b18bae74a5fb7f14b6d066922c79..cdc5756d27611e41dbffc9c0bb54a8a2274699c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: printers.h 5083 2006-02-06 02:57:43Z mike $"
+ * "$Id: printers.h 5178 2006-02-26 00:24:23Z mike $"
  *
  *   Printer definitions for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -60,6 +60,8 @@ typedef struct cupsd_printer_s
   time_t       state_time;             /* Time at this state */
   char         *job_sheets[2];         /* Banners/job sheets */
   cups_ptype_t type;                   /* Printer type (color, small, etc.) */
+  char         *browse_attrs;          /* Attributes sent with browse data */
+  time_t       browse_expire;          /* Expiration time for printer */
   time_t       browse_time;            /* Last time update was sent/received */
   char         *device_uri;            /* Device URI */
   char         *port_monitor;          /* Port monitor */
@@ -80,6 +82,8 @@ typedef struct cupsd_printer_s
   int          num_history;            /* Number of history collections */
   ipp_t                **history;              /* History data */
   int          sequence_number;        /* Increasing sequence number */
+  int          num_options;            /* Number of default options */
+  cups_option_t        *options;               /* Default options */
 #ifdef __APPLE__
   char         *recoverable;           /* com.apple.print.recoverable-message */
 #endif /* __APPLE__ */
@@ -123,6 +127,7 @@ extern cupsd_quota_t        *cupsdFindQuota(cupsd_printer_t *p, const char *username);
 extern void            cupsdFreePrinterUsers(cupsd_printer_t *p);
 extern void            cupsdFreeQuotas(cupsd_printer_t *p);
 extern void            cupsdLoadAllPrinters(void);
+extern void            cupsdRenamePrinter(cupsd_printer_t *p, const char *name);
 extern void            cupsdSaveAllPrinters(void);
 extern void            cupsdSetPrinterAttrs(cupsd_printer_t *p);
 extern void            cupsdSetPrinterReasons(cupsd_printer_t *p, const char *s);
@@ -143,5 +148,5 @@ extern char         *cupsdSanitizeURI(const char *uri, char *buffer,
 
 
 /*
- * End of "$Id: printers.h 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: printers.h 5178 2006-02-26 00:24:23Z mike $".
  */
index 74c2fc0712ad5dbff6d0a29eb7535c17bd3157dc..79a393a820ba0a633b3c399e577f17cd141ba8e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: server.c 5095 2006-02-09 16:22:48Z mike $"
+ * "$Id: server.c 5200 2006-02-28 00:10:32Z mike $"
  *
  *   Server start/stop routines for the Common UNIX Printing System (CUPS).
  *
@@ -152,18 +152,6 @@ cupsdStopServer(void)
     Clients = NULL;
   }
 
-#if defined(HAVE_SSL) && defined(HAVE_CDSASSL)
- /*
-  * Free all of the certificates...
-  */
-
-  if (ServerCertificatesArray)
-  {
-    CFRelease(ServerCertificatesArray);
-    ServerCertificatesArray = NULL;
-  }
-#endif /* HAVE_SSL && HAVE_CDSASSL */
-
  /*
   * Close the pipe for CGI processes...
   */
@@ -223,5 +211,5 @@ cupsdStopServer(void)
 
 
 /*
- * End of "$Id: server.c 5095 2006-02-09 16:22:48Z mike $".
+ * End of "$Id: server.c 5200 2006-02-28 00:10:32Z mike $".
  */
index 51c2cc5234544fa7c642eafd103300bdf8b1c8de..c38d0c21e40e948c3bebb634c8e4add805fef2f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: testdirsvc.c 4821 2005-11-04 19:36:39Z mike $"
+ * "$Id: testdirsvc.c 5178 2006-02-26 00:24:23Z mike $"
  *
  *   Browsing test program for the Common UNIX Printing System (CUPS).
  *
@@ -55,10 +55,13 @@ main(int  argc,                             /* I - Number of command-line arguments */
   int          i,                      /* Looping var */
                printer,                /* Current printer */
                num_printers,           /* Number of printers */
+               pclass,                 /* Current printer class */
+               num_pclasses,           /* Number of printer classes */
                server,                 /* Current server */
                num_servers,            /* Number of servers */
                count,                  /* Number of printers sent this cycle */
                interval,               /* Browse Interval */
+               lease,                  /* Browse lease-duration */
                continuous,             /* Run continuously? */
                port,                   /* Browse port */
                sock,                   /* Browse socket */
@@ -106,8 +109,10 @@ main(int  argc,                            /* I - Number of command-line arguments */
   */
 
   num_printers = 10;
+  num_pclasses = 5;
   num_servers  = 1;
   interval     = 30;
+  lease        = 60;
   port         = 0;
   verbose      = 0;
   continuous   = 0;
@@ -117,8 +122,6 @@ main(int  argc,                             /* I - Number of command-line arguments */
   {
     if (!strcmp(argv[i], "-c"))
       continuous = 1;
-    if (!strcmp(argv[i], "-v"))
-      verbose = 1;
     else if (!strcmp(argv[i], "-i"))
     {
       i ++;
@@ -127,6 +130,14 @@ main(int  argc,                            /* I - Number of command-line arguments */
       else
         usage();
     }
+    else if (!strcmp(argv[i], "-l"))
+    {
+      i ++;
+      if (i < argc)
+        lease = atoi(argv[i]);
+      else
+        usage();
+    }
     else if (!strcmp(argv[i], "-o"))
     {
       i ++;
@@ -135,6 +146,14 @@ main(int  argc,                            /* I - Number of command-line arguments */
       else
         usage();
     }
+    else if (!strcmp(argv[i], "-C"))
+    {
+      i ++;
+      if (i < argc)
+        num_pclasses = atoi(argv[i]);
+      else
+        usage();
+    }
     else if (!strcmp(argv[i], "-p"))
     {
       i ++;
@@ -151,6 +170,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
       else
         usage();
     }
+    else if (!strcmp(argv[i], "-v"))
+      verbose = 1;
     else if (isdigit(argv[i][0] & 255))
     {
       port = atoi(argv[i]);
@@ -159,7 +180,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
       usage();
   }
 
-  if (num_printers <= 0 || num_servers <= 0 || interval <= 0 || port <= 0)
+  if ((num_printers <= 0 && num_pclasses <= 0) || num_servers <= 0 ||
+      interval <= 0 || lease < 1 || port <= 0)
     usage();
 
  /*
@@ -207,7 +229,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
     printf("Sending %d printers from %d servers...\n", num_printers,
            num_servers);
 
-    count   = num_servers * num_printers / interval + 1;
+    count   = num_servers * (num_printers + num_pclasses) / interval + 1;
     curtime = time(NULL);
     curdate = localtime(&curtime);
     seconds = interval;
@@ -227,11 +249,45 @@ main(int  argc,                           /* I - Number of command-line arguments */
 
         snprintf(packet, sizeof(packet),
                 "%x %x ipp://testserver-%d/printers/%s-%d \"Server Room %d\" "
-                "\"Test Printer %d\" \"Acme Blazer 2000\"%s%s\n",
+                "\"Test Printer %d\" \"Acme Blazer 2000\"%s%s "
+                "lease-duration=%d\n",
                  CUPS_PRINTER_REMOTE, IPP_PRINTER_IDLE, server + 1,
                 names[printer % 26], printer / 26 + 1, server + 1,
                 printer + 1, options ? " ipp-options=" : "",
-                options ? options : "");
+                options ? options : "", lease);
+
+        if (verbose)
+         printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min,
+                curdate->tm_sec, packet);
+
+        if (sendto(sock, packet, strlen(packet), 0,
+                  (struct sockaddr *)&addr, sizeof(addr)) < 0)
+         perror("Unabled to send packet");
+      }
+    }
+
+
+    for (i = 0, pclass = 0; pclass < num_pclasses; pclass ++)
+    {
+      for (server = 0; server < num_servers; server ++, i ++)
+      {
+        if (i == count)
+       {
+         seconds --;
+         i = 0;
+         sleep(1);
+         curtime = time(NULL);
+         curdate = localtime(&curtime);
+       }
+
+        snprintf(packet, sizeof(packet),
+                "%x %x ipp://testserver-%d/classes/class-%s-%d \"Server Room %d\" "
+                "\"Test Class %d\" \"Acme Blazer 2000\"%s%s "
+                "lease-duration=%d\n",
+                 CUPS_PRINTER_REMOTE | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE,
+                server + 1, names[pclass % 26], pclass / 26 + 1, server + 1,
+                pclass + 1, options ? " ipp-options=" : "",
+                options ? options : "", lease);
 
         if (verbose)
          printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min,
@@ -265,11 +321,13 @@ main(int  argc,                           /* I - Number of command-line arguments */
 void
 usage(void)
 {
-  puts("Usage: testdirsvc [-i interval] [-o ipp-options] [-p printers] [-s servers] [-v] port");
+  puts("Usage: testdirsvc [-c] [-i interval] [-l lease-duration] "
+       "[-o ipp-options] [-p printers] "
+       "[-C classes] [-s servers] [-v] port");
   exit(0);
 }
 
 
 /*
- * End of "$Id: testdirsvc.c 4821 2005-11-04 19:36:39Z mike $".
+ * End of "$Id: testdirsvc.c 5178 2006-02-26 00:24:23Z mike $".
  */
index 50d49d26a627b5dfb94f6d26937116b4b0fedef9..79f7a229b150ddc0cecda33834a31de610eb1844 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: type.c 5052 2006-02-02 16:21:13Z mike $"
+ * "$Id: type.c 5180 2006-02-26 01:31:45Z mike $"
  *
  *   MIME typing routines for the Common UNIX Printing System (CUPS).
  *
@@ -544,11 +544,11 @@ mimeFileType(mime_t     *mime,            /* I - MIME database */
   mime_type_t          *type;          /* File type */
 
 
-  DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", basename=\"%s\", "
+  DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", filename=\"%s\", "
                 "compression=%p)\n",
                 mime, pathname ? pathname : "(nil)",
                filename ? filename : "(nil)",
-               basenamecompression));
+               compression));
 
  /*
   * Range check input parameters...
@@ -690,8 +690,8 @@ checkrules(const char      *filename,       /* I - Filename */
 #endif /* DEBUG */
 
 
-  DEBUG_printf(("checkrules(filename=\"%s\", fp=%p, rules=%p)\n", filename,
-                fp, rules));
+  DEBUG_printf(("checkrules(filename=\"%s\", fb=%p, rules=%p)\n", filename,
+                fb, rules));
 
   if (rules == NULL)
     return (0);
@@ -1161,5 +1161,5 @@ patmatch(const char *s,           /* I - String to match against */
 
 
 /*
- * End of "$Id: type.c 5052 2006-02-02 16:21:13Z mike $".
+ * End of "$Id: type.c 5180 2006-02-26 01:31:45Z mike $".
  */
index a2cbd92b9244657de89ec5ec9546c731bc9f2c30..84fdf459d181af6af8c4003496912cff63faa138 100644 (file)
@@ -1,13 +1,13 @@
 package com.easysw.cups;
 
 /**
- * @version 1.00 06-NOV-2002
+ * @version 1.2 26-FEB-2006
  * @author  Easy Software Products
  *
  *   Internet Printing Protocol definitions for the Common UNIX Printing
  *   System (CUPS).
  *
- *   Copyright 1997-2002 by Easy Software Products.
+ *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
@@ -19,11 +19,11 @@ package com.easysw.cups;
  *       Attn: CUPS Licensing Information
  *       Easy Software Products
  *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636-3111 USA
+ *       Hollywood, Maryland 20636 USA
  *
- *       Voice: (301) 373-9603
+ *       Voice: (301) 373-9600
  *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *         WWW: http://www.cups.org/
  */
 
 /**
@@ -31,7 +31,7 @@ package com.easysw.cups;
  * reading and writing data, and performing common CUPS operations.
  *
  * @author     TDB
- * @version    1.0.1
+ * @version    1.2
  * @since      JDK1.3
  */
 
@@ -1175,7 +1175,9 @@ public class Cups
             
       a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI,
                             "printer-uri" );
-      a.addString( "", site + "/printers/" + printer_name );  
+      String p_uri = "ipp://" + address + ":" +
+            port + "/printers/" + printer_name;
+      a.addString( "", p_uri );
       ipp.addAttribute(a);
 
       if (doRequest("cupsGetPrinterAttributes"))
index c5e45a09ca05f19cf75f20ca3a3c3be7d0927947..f674ca767cbd4018a0e2cf972203a364257ee766 100644 (file)
@@ -1,6 +1,6 @@
 # DO NOT DELETE
 
-phpcups.o: php_phpcups.h ../../cups/cups.h ../../cups/ipp.h ../../cups/http.h
-phpcups.o: ../../cups/md5.h ../../cups/ppd.h ../../cups/ipp.h
-phpcups.o: ../../cups/language.h ../../cups/string.h ../../config.h
-phpcups.o: ../../cups/debug.h
+phpcups.o: phpcups.h ../../cups/cups.h ../../cups/ipp.h ../../cups/http.h
+phpcups.o: ../../cups/md5.h ../../cups/ppd.h ../../cups/array.h
+phpcups.o: ../../cups/file.h ../../cups/language.h ../../cups/language.h
+phpcups.o: ../../cups/string.h ../../config.h ../../cups/debug.h
diff --git a/scripting/php/Example/phpcups.inc.php4 b/scripting/php/Example/phpcups.inc.php4
deleted file mode 100644 (file)
index dfb11fb..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-<?php
-/*
- *   PHP module for the Common UNIX Printing System (CUPS).
- *
- *   Copyright 1997-2003 by Easy Software Products.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products 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 missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636-3111 USA
- *
- *       Voice: (301) 373-9603
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
- *
- * Contents:
- *
- *  Basic CupsPrinter class.  Will be extended in next release.
- *
- */
-if (!$INCLUDED_PHPCUPS_INC)
-{
-  $INCLUDED_PHPCUPS_INC = True;
-
-
-  class CupsPrinter
-  {
-    var $printer_name;
-    var $printer_server;
-    var $printer_instance;
-    var $is_default;
-    var $printer_options;
-    var $printer_state;
-    var $printer_state_message;
-    var $accepting_jobs;
-    var $queued_job_count;
-    var $description;
-    var $location;
-    var $printer_info;
-    var $printer_more_info;
-    var $make_and_model;
-    var $printer_uri;
-    var $device_uri;
-    var $job_quota_period;
-    var $job_k_limit;
-    var $job_page_limit;
-    var $color_supported;
-    var $pages_per_minute;
-    var $finishings_supported;             // Array
-    var $finishings_default;
-    var $printer_type;
-    var $operations_supported;             // Array
-    var $multiple_document_jobs_supported;
-    var $multiple_operation_time_out;
-    var $job_priority_supported_lower;
-    var $job_priority_supported_upper;
-    var $job_priority_default;
-    var $copies_supported_lower;
-    var $copies_supported_upper;
-    var $copies_default;
-    var $page_range_supported;
-    var $number_up_supported;              // Array
-    var $number_up_default;
-    var $orientation_requested_supported;  // Array
-    var $orientation_requested_default;
-    var $media_supported;                  // Array
-    var $media_default;
-
-    function CupsPrinter()
-    {
-      $this->printer_name = "";
-      $this->printer_destination = "";
-      $this->is_default = 0;
-      $this->options = Array();
-      $this->printer_state   = -1;
-      $this->printer_state_message = "";
-      $this->accepting_jobs = FALSE;
-      $this->queued_job_count = 0;
-      $this->description = "";
-      $this->location = "";
-      $this->printer_info = "";
-      $this->printer_more_info = "";
-      $this->make_and_model = "";
-      $this->printer_uri_supported = Array();
-      $this->device_uri  = "";
-      $this->job_quota_period = 0;
-      $this->job_k_limit = 0;
-      $this->job_page_limit = 0;
-      $this->color_supported = FALSE;
-      $this->pages_per_minute = 0;
-      $this->finishings_supported = Array();
-      $this->finishings_default = 0;
-      $this->printer_type = 0;
-      $this->operations_supported = Array();
-      $this->multiple_document_jobs_supported = FALSE;
-      $this->multiple_operation_time_out = 0;
-      $this->job_priority_supported_lower = 0;
-      $this->job_priority_supported_upper = 100;
-      $this->job_priority_default = 50;
-      $this->copies_supported_lower = 1;
-      $this->copies_supported_upper = 1;
-      $this->copies_default = 1;
-      $this->page_range_supported = FALSE;
-      $this->number_up_supported = Array();
-      $this->number_up_default = 0;
-      $this->orientation_requested_supported = Array();
-      $this->orientation_requested_default = 3;
-      $this->media_supported = Array();
-      $this->media_default = "";
-
-    }  // End of constructor
-
-
-    //
-    //  Get the attributes
-    //
-    function getAttributes()
-    {
-      $o_arr = cups_get_dest_options($this->printer_server,
-                                     $this->printer_name,
-                                     $this->printer_instance);
-      $this->printer_options  = $o_arr;
-
-      $attrs = cups_get_printer_attributes( "localhost", $this->printer_name );
-      while ($obj = current($attrs))
-      {
-        next($attrs);
-
-        if ($obj->name == "printer-state")
-        {
-           $this->printer_state = $obj->value;
-        }
-        else if ($obj->name == "printer-state-message")
-        {
-           $this->printer_state_message = $obj->value;
-        }
-        else if ($obj->name == "printer-location")
-        {
-           $this->location = $obj->value;
-        }
-        else if ($obj->name == "printer-make-and-model")
-        {
-           $this->description = $obj->value;
-        }
-        else if ($obj->name == "printer-uri-supported")
-        {
-           $this->printer_uri_supported[$obj->value] = $obj->value;
-        }
-        else if ($obj->name == "device-uri")
-        {
-           $this->device_uri = $obj->value;
-        }
-        else if ($obj->name == "queued-job-count")
-        {
-           $this->queued_job_count = $obj->value;
-        }
-        else if ($obj->name == "printer-is-accepting-jobs")
-        {
-           $this->accepting_jobs = $obj->value ? TRUE : FALSE;
-        }
-        else if ($obj->name == "color-supported")
-        {
-           $this->color_supported = $obj->value ? TRUE : FALSE;
-        }
-        else if ($obj->name == "pages-per-minute")
-        {
-           $this->pages_per_minute = $obj->value;
-        }
-        else if ($obj->name == "operations-supported")
-        {
-           $this->operations_supported["O$obj->value"] = $obj->value;
-        }
-        else if ($obj->name == "orientation-requested-supported")
-        {
-           $this->orientation_requested_supported["O$obj->value"] = $obj->value;
-        }
-        else if ($obj->name == "orientation-requested-default")
-        {
-           $this->orientation_requested_default = $obj->value;
-        }
-        else if ($obj->name == "finishings-supported")
-        {
-           $this->finishings_supported["F$obj->value"] = $obj->value;
-        }
-        else if ($obj->name == "finishings-default")
-        {
-           $this->finishings_default = $obj->value;
-        }
-        else if ($obj->name == "number-up-supported")
-        {
-           $this->number_up_supported["N$obj->value"] = $obj->value;
-        }
-        else if ($obj->name == "number-up-default")
-        {
-           $this->number_up_default = $obj->value;
-        }
-        else if ($obj->name == "printer-type")
-        {
-           $this->printer_type = $obj->value;
-        }
-        else if ($obj->name == "multiple-document-jobs-suppoted")
-        {
-           $this->multiple_document_jobs_supported = $obj->value ? TRUE : FALSE;
-        }
-        else if ($obj->name == "multiple-operation-time-out")
-        {
-           $this->multiple_operation_time_out = $obj->value;
-        }
-        else if ($obj->name == "job-priority-supported")
-        {
-           $this->job_priority_supported_upper = $obj->value;
-        }
-        else if ($obj->name == "job-priority-default")
-        {
-           $this->job_priority_default = $obj->value;
-        }
-        else if ($obj->name == "copies-supported")
-        {
-           $tmpa = explode("-",$obj->value);
-           if (count($tmpa) > 1)
-           {
-             $this->copies_supported_lower = $tmpa[0];
-             $this->copies_supported_upper = $tmpa[1];
-           }
-           else if (count($tmpa) == 1)
-           {
-             $this->copies_supported_lower = $tmpa[0];
-             $this->copies_supported_upper = $tmpa[0];
-           }
-        }
-        else if ($obj->name == "copies-default")
-        {
-          $this->copies_supported_default = $obj->value;
-        }
-        else if ($obj->name == "page-ranges-supported")
-        {
-          $this->page_ranges_supported = $obj->value ? TRUE : FALSE;
-        }
-        else if ($obj->name == "media-default")
-        {
-          $this->media_default = $obj->value;
-        }
-        else if ($obj->name == "media-supported")
-        {
-          $this->media_supported[$obj->value] = $obj->value;
-        }
-
-      } // while
-
-    }  // End of getAttributes
-
-
-  }  //  End of CupsPrinter class
-
-
-
-
-  //
-  //  Get the printer / destination list.
-  //
-  function phpcups_getDestList()
-  {
-    $return_value = Array();
-
-    //
-    //  Get the destination objects array.
-    //
-    $p_arr = cups_get_dest_list();
-
-    if (!IS_ARRAY($p_arr))
-    {
-      return(NULL);
-    }
-
-    reset($p_arr);
-
-    while ($p_obj = current($p_arr))
-    {
-      next($p_arr);
-
-      //
-      //  Get the options for the current destination.
-      //
-      $o_arr = cups_get_dest_options("localhost",$p_obj->name,$p_obj->instance);
-
-      $p = new CupsPrinter();
-      $p->printer_name     = $p_obj->name;
-      $p->printer_instance = $p_obj->instance;
-      $p->is_default       = $p_obj->is_default;
-      $p->printer_options  = $o_arr;
-      $p->getAttributes();
-
-      $return_value[$p->printer_name] = $p;
-    }
-    return($return_value);
-
-  } // End of phpcups_getDestList()
-
-
-
-
-}   // if included.
-?>
index c93559e4b6940a6332a4e9e9cb873da9924845f5..398c2714ec85b8a0afbcb839df2df0e1ec759ab5 100644 (file)
@@ -3,7 +3,7 @@
 #
 #   PHP Makefile for the Common UNIX Printing System (CUPS).
 #
-#   Copyright 1997-2005 by Easy Software Products, all rights reserved.
+#   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 #
 #   These coded instructions, statements, and computer programs are the
 #   property of Easy Software Products and are protected by Federal
 #       Attn: CUPS Licensing Information
 #       Easy Software Products
 #       44141 Airport View Drive, Suite 204
-#       Hollywood, Maryland 20636-3111 USA
+#       Hollywood, Maryland 20636 USA
 #
 #       Voice: (301) 373-9603
 #       EMail: cups-info@cups.org
-#         WWW: http://www.cups.org
+#         WWW: http://www.cups.org/
 #
 
 include ../../Makedefs
 
 
 #
-# Where to install the PHP module...
+# Where to install and how to compile the PHP module...
 #
 
-PHPDIR =       `php-config --extension-dir`
-OPTIONS        =       `php-config --includes` -I../.. -DCOMPILE_DL_PHPCUPS
-PHPLIBS        =       `php-config --ldflags` `php-config --libs`
+PHPDIR =       $(BUILDROOT)`$(PHPCONFIG) --extension-dir`
+OPTIONS        =       -I../.. `$(PHPCONFIG) --includes`
+PHPLIBS        =       `$(PHPCONFIG) --ldflags` `$(PHPCONFIG) --libs`
+
 
 #
 # Object files...
index 0cb23f1d59676321a9f6fac36852629a45faaf3b..e4ab27d8401a1cf4f3fad6c260d03aa25b8682dd 100644 (file)
-README - 04/08/2003
+README - 02/25/2006
 -------------------
 
-This directory contains a dynamically loadable CUPS extension
-module for PHP 4.  To compile it type:
+INTRODUCTION
 
-    make
+    This directory contains a dynamically loadable CUPS extension
+    module for PHP 4 and 5.  The CUPS 1.2 module has been
+    substantially updated to provide an API more consistent with
+    the C API and is NOT compatible with the CUPS 1.1 module.
 
-To install it, type:
 
-    make install
+COMPILING AND INSTALLING
 
-Questions should be reported to the CUPS newsgroups/mailing
-lists at:
+    Run "make" to compile the PHP CUPS extension:
 
-    http://www.cups.org/newsgroups.php
+       make
 
-Bug reports and enhancement requests can be submitted via the
-form at:
+    To install it, type:
+
+       make install
+
+
+RESOURCES AND SUPPORT
+
+    Questions should be reported to the CUPS newsgroups/mailing
+    lists at:
+
+       http://www.cups.org/newsgroups.php
+
+    Bug reports and enhancement requests can be submitted via the
+    form at:
+
+       http://www.cups.org/str.php
+
+
+QUICK REFERENCE DOCUMENTATION
+
+    In lieu of actual documentation, the following definitions
+    can be used as a quick reference to the supported functions:
+
+
+    CUPS_CANCEL_JOB
+
+    Cancels a job on the named destination:
+
+        bool cups_cancel_job(string dest, int id)
+
+    The return value is TRUE on success and FALSE on failure.
+
+    Example:
+
+        if (!cups_cancel_job("myprinter", 123))
+         print("Unable to cancel job: " . cups_last_error_string() . "\n");
+
+
+    CUPS_GET_DESTS
+
+    Gets a list of available destinations:
+
+        array cups_get_dests()
+
+    The return value is an array of objects with the following
+    properties:
+
+        name        The name of the printer or class
+       instance    The instance of the printer or class
+       is_default  TRUE if the printer or class is the default destination
+       options     Associative array of options and their values
+
+    Example:
+
+        $dest = cups_get_dests();
+
+
+    CUPS_GET_JOBS
+
+    Gets a list of jobs:
+
+        array cups_get_jobs(string dest, bool myjobs, int completed)
+
+    The "dest" string can be blank for jobs on all destinations.
+    Pass TRUE for "myjobs" to only get jobs for the current user.
+    The "completed" argument can be 0 for pending jobs, 1 for
+    completed jobs, and -1 for all jobs.
+
+    The return value is an array of objects with the following
+    properties:
+
+        id                The job ID
+        dest              Printer or class name
+        title             Title/job name
+        user              User the submitted the job
+        format            Document format
+        state             Job state
+        size              Size in kilobytes
+        priority          Priority (1-100)
+        completed_time    Time the job was completed
+        creation_time     Time the job was created
+        processing_time   Time the job was processed
+
+    Example:
+
+        $jobs = cups_get_jobs("", FALSE, -1);
+
+
+    CUPS_LAST_ERROR
+    
+    Returns the IPP status code for the most recent request:
+
+        int cups_last_error()
+
+    Example:
+
+        $error = cups_last_error();
+
+
+    CUPS_LAST_ERROR_STRING
+    
+    Returns the IPP status-message string for the most recent request:
+
+        string cups_last_error_string()
+
+    Example:
+
+        $message = cups_last_error_string();
+
+
+    CUPS_PRINT_FILE
+
+    Prints a single file to a printer or class:
+
+        int cups_print_file(string dest, string filename, string title,
+                           array options)
+
+    The return value is the job ID or 0 if there was an error.
+
+    Example:
+
+        $options = array("name" => "value", "name2" => "value2");
+       $id      = cups_print_file("dest", "filename", "title", $options);
+
+
+    CUPS_PRINT_FILES
+
+    Prints one or more files to a printer or class:
+
+        int cups_print_files(string dest, array files, string title,
+                            array options);
+
+    The return value is the job ID or 0 if there was an error.
+
+    Example:
+
+        $files   = array("file1", "file2", "file3");
+        $options = array("name" => "value", "name2" => "value2");
+       $id      = cups_print_file("dest", $files, "title", $options);
 
-    http://www.cups.org/str.php
diff --git a/scripting/php/config.m4 b/scripting/php/config.m4
deleted file mode 100644 (file)
index 562e9e2..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-dnl $Id: config.m4 3867 2003-08-14 22:29:23Z ted $
-dnl config.m4 for extension phpcups
-
-dnl Comments in this file start with the string 'dnl'.
-dnl Remove where necessary. This file will not work
-dnl without editing.
-
-dnl If your extension references something external, use with:
-
-PHP_ARG_WITH(phpcups, for phpcups support,
-dnl Make sure that the comment is aligned:
-[  --with-phpcups             Include phpcups support])
-
-dnl Otherwise use enable:
-
-dnl PHP_ARG_ENABLE(phpcups, whether to enable phpcups support,
-dnl Make sure that the comment is aligned:
-dnl [  --enable-phpcups           Enable phpcups support])
-
-if test "$PHP_PHPCUPS" != "no"; then
-  dnl Write more examples of tests here...
-
-  dnl # --with-phpcups -> check with-path
-       dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this
-  dnl SEARCH_FOR="/include/phpcups.h"  # you most likely want to change this
-  dnl if test -r $PHP_PHPCUPS/; then # path given as parameter
-  dnl   PHPCUPS_DIR=$PHP_PHPCUPS
-  dnl else # search default path list
-  dnl   AC_MSG_CHECKING(for phpcups files in default path)
-  dnl   for i in $SEARCH_PATH ; do
-  dnl     if test -r $i/$SEARCH_FOR; then
-  dnl       PHPCUPS_DIR=$i
-  dnl       AC_MSG_RESULT(found in $i)
-  dnl     fi
-  dnl   done
-  dnl fi
-  dnl
-  dnl if test -z "$PHPCUPS_DIR"; then
-  dnl   AC_MSG_RESULT(not found)
-  dnl   AC_MSG_ERROR(Please reinstall the phpcups distribution)
-  dnl fi
-
-  dnl # --with-phpcups -> add include path
-  PHP_ADD_INCLUDE(/var/httpd2/web2/cups)
-  PHP_ADD_INCLUDE(/var/httpd2/web2/cups/cups)
-
-  dnl # --with-phpcups -> chech for lib and symbol presence
-  dnl LIBNAME=phpcups # you may want to change this
-  dnl LIBSYMBOL=phpcups # you most likely want to change this 
-  dnl old_LIBS=$LIBS
-  dnl LIBS="$LIBS -L$PHPCUPS_DIR/lib -lm -ldl"
-  dnl AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_PHPCUPSLIB,1,[ ])],
-       dnl                     [AC_MSG_ERROR(wrong phpcups lib version or lib not found)])
-  dnl LIBS=$old_LIBS
-  dnl
-  dnl PHP_SUBST(PHPCUPS_SHARED_LIBADD)
-  PHP_ADD_LIBRARY_WITH_PATH("cups", "/var/httpd2/web2/cups/cups", PHPCUPS_SHARED_LIBADD)
-
-  PHP_EXTENSION(phpcups, $ext_shared)
-fi
diff --git a/scripting/php/php_phpcups.h b/scripting/php/php_phpcups.h
deleted file mode 100644 (file)
index 8b3fdee..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * "$Id: php_phpcups.h 4523 2005-05-23 20:14:19Z mike $"
- *
- *   PHP module include file for the Common UNIX Printing System (CUPS).
- *
- *   Copyright 1997-2003 by Easy Software Products.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products 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 missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636-3111 USA
- *
- *       Voice: (301) 373-9603
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
- */
-
-#ifndef PHP_PHPCUPS_H
-#  define PHP_PHPCUPS_H
-
-extern zend_module_entry phpcups_module_entry;
-#  define phpext_phpcups_ptr &phpcups_module_entry
-
-#  ifdef PHP_WIN32
-#    define PHP_PHPCUPS_API __declspec(dllexport)
-#  else
-#    define PHP_PHPCUPS_API
-#  endif
-
-#  ifdef ZTS
-#    include "TSRM.h"
-#  endif
-
-PHP_MINIT_FUNCTION(phpcups);
-PHP_MSHUTDOWN_FUNCTION(phpcups);
-PHP_RINIT_FUNCTION(phpcups);
-PHP_RSHUTDOWN_FUNCTION(phpcups);
-PHP_MINFO_FUNCTION(phpcups);
-
-PHP_FUNCTION(confirm_phpcups_compiled);        
-PHP_FUNCTION(cups_get_dest_options);   
-PHP_FUNCTION(cups_get_dest_list);      
-PHP_FUNCTION(cups_get_jobs);   
-PHP_FUNCTION(cups_cancel_job); 
-PHP_FUNCTION(cups_print_file); 
-PHP_FUNCTION(cups_last_error); 
-PHP_FUNCTION(cups_get_printer_attributes);     
-
-/* 
-       Declare any global variables you may need between the BEGIN
-       and END macros here:     
-
-ZEND_BEGIN_MODULE_GLOBALS(phpcups)
-       int   global_value;
-       char *global_string;
-ZEND_END_MODULE_GLOBALS(phpcups)
-*/
-
-/* In every utility function you add that needs to use variables 
-   in php_phpcups_globals, call TSRM_FETCH(); after declaring other 
-   variables used by that function, or better yet, pass in TSRMG_CC
-   after the last function argument and declare your utility function
-   with TSRMG_DC after the last declared argument.  Always refer to
-   the globals in your function as PHPCUPS_G(variable).  You are 
-   encouraged to rename these macros something shorter, see
-   examples in any other php module directory.
-*/
-
-#  ifdef ZTS
-#    define PHPCUPS_G(v) TSRMG(phpcups_globals_id, zend_phpcups_globals *, v)
-#  else
-#    define PHPCUPS_G(v) (phpcups_globals.v)
-#  endif
-
-#endif /* !PHP_PHPCUPS_H */
-
-
-/*
- * End of "$Id: php_phpcups.h 4523 2005-05-23 20:14:19Z mike $".
- */
index 5d34314c5b1af39baf21aae9c3b7324bc220d63d..8451773457a8743408f50be300abceb6378a8493 100644 (file)
@@ -1,28 +1,9 @@
 /*
-   +----------------------------------------------------------------------+
-   | PHP version 4.0                                                      |
-   +----------------------------------------------------------------------+
-   | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |
-   +----------------------------------------------------------------------+
-   | This source file is subject to version 2.02 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available at through the world-wide-web at                           |
-   | http://www.php.net/license/2_02.txt.                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
-   +----------------------------------------------------------------------+
-   | Authors:                                                             |
-   |                                                                      |
-   +----------------------------------------------------------------------+
- */
-
-/*
- * "$Id: phpcups.c 4530 2005-06-01 20:15:51Z mike $"
+ * "$Id: phpcups.c 5171 2006-02-25 08:44:43Z mike $"
  *
  *   Printing utilities for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1997-2002 by Easy Software Products.
+ *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Easy Software Products and are protected by Federal
  *       Attn: CUPS Licensing Information
  *       Easy Software Products
  *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636-3111 USA
+ *       Hollywood, Maryland 20636 USA
  *
  *       Voice: (301) 373-9603
  *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *         WWW: http://www.cups.org/
+ *
+ * Contents:
+ *
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_phpcups.h"
-
 /*
  * Include necessary headers...
  */
 
-#include <config.h>
-#include <cups/cups.h>
-#include <cups/ipp.h>
-#include <cups/language.h>
 #include <cups/string.h>
-#include <cups/debug.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#if defined(WIN32) || defined(__EMX__)
-#  include <io.h>
-#else
-#  include <unistd.h>
-#endif /* WIN32 || __EMX__ */
-
-
-static int le_result, le_link, le_plink;
-
-
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "phpcups.h"
 
 
-/*
- * Local globals...
+/* 
+ * PHP function list...
  */
 
-static http_t          *cups_server = NULL;    /* Current server connection */
-static ipp_status_t    last_error = IPP_OK;    /* Last IPP error */
-static char            authstring[HTTP_MAX_VALUE] = "";
-                                               /* Authorization string */
-static char            pwdstring[33] = "";     /* Last password string */
-
-
-
+function_entry phpcups_functions[] =
+{
+  PHP_FE(cups_cancel_job, NULL)
+  PHP_FE(cups_get_dests, NULL)
+  PHP_FE(cups_get_jobs, NULL)
+  PHP_FE(cups_last_error, NULL)
+  PHP_FE(cups_last_error_string, NULL)
+  PHP_FE(cups_print_file, NULL)
+  PHP_FE(cups_print_files, NULL)
+  {NULL, NULL, NULL}
+};
 
 
 /*
- *  *********************************************************************
+ * PHP module info...
  */
 
-
-
-
-/* If you declare any globals in php_phpcups.h uncomment this:
-ZEND_DECLARE_MODULE_GLOBALS(phpcups)
-*/
-
-/* True global resources - no need for thread safety here */
-static int le_phpcups;
-
-/* 
- * Every user visible function must have an entry in phpcups_functions[].
- */
-function_entry phpcups_functions[] = {
-       PHP_FE(confirm_phpcups_compiled,NULL)
-       PHP_FE(cups_get_dest_list,      NULL)           
-       PHP_FE(cups_get_dest_options,   NULL)           
-       PHP_FE(cups_get_jobs,   NULL)           
-       PHP_FE(cups_cancel_job, NULL)           
-       PHP_FE(cups_last_error, NULL)           
-       PHP_FE(cups_print_file, NULL)           
-       PHP_FE(cups_get_printer_attributes,     NULL)           
-       {NULL, NULL, NULL}      
+zend_module_entry phpcups_module_entry =
+{
+  STANDARD_MODULE_HEADER,
+  "phpcups",
+  phpcups_functions,
+  PHP_MINIT(phpcups),
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  CUPS_SVERSION,
+  STANDARD_MODULE_PROPERTIES
 };
 
 
-
-
-zend_module_entry phpcups_module_entry = {
-       STANDARD_MODULE_HEADER,
-       "phpcups",
-       phpcups_functions,
-       PHP_MINIT(phpcups),
-       PHP_MSHUTDOWN(phpcups),
-       PHP_RINIT(phpcups),             /* Replace with NULL if there's nothing to do at request start */
-       PHP_RSHUTDOWN(phpcups), /* Replace with NULL if there's nothing to do at request end */
-       PHP_MINFO(phpcups),
-    "0.1", /* Replace with version number for your extension */
-       STANDARD_MODULE_PROPERTIES
-};
-
-#ifdef COMPILE_DL_PHPCUPS
 ZEND_GET_MODULE(phpcups)
-#endif
-
-
-
-
-/* Remove comments and fill if you need to have entries in php.ini
-PHP_INI_BEGIN()
-    STD_PHP_INI_ENTRY("phpcups.value",      "42", PHP_INI_ALL, OnUpdateInt, global_value, zend_phpcups_globals, phpcups_globals)
-    STD_PHP_INI_ENTRY("phpcups.string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_phpcups_globals, phpcups_globals)
-PHP_INI_END()
-*/
-
 
 
+/*
+ * 'cups_convert_options()' - Convert a PHP options array to a CUPS options array.
+ */
 
-/* Uncomment this function if you have INI entries
-static void php_phpcups_init_globals(zend_phpcups_globals *phpcups_globals)
+static int                             /* O - Number of options */
+cups_convert_options(
+    zval          *optionsobj,         /* I - Options array object */
+    cups_option_t **options)           /* O - Options */
 {
-       phpcups_globals->value = 0;
-       phpcups_globals->string = NULL;
-}
-*/
+  int          num_options;            /* Number of options */
+  HashTable    *ht;                    /* Option array hash table */
+  Bucket       *current;               /* Current element in array */
 
 
+  ht          = Z_ARRVAL_P(optionsobj);
+  num_options = 0;
 
+  for (current = ht->pListHead; current; current = current->pListNext)
+    num_options = cupsAddOption(current->arKey,
+                                Z_STRVAL_P(((zval *)current->pDataPtr)),
+                               num_options, options);
 
-PHP_MINIT_FUNCTION(phpcups)
-{
-       /* If you have INI entries, uncomment these lines 
-       ZEND_INIT_MODULE_GLOBALS(phpcups, php_phpcups_init_globals, NULL);
-       REGISTER_INI_ENTRIES();
-       */
-       return SUCCESS;
+  return (num_options);
 }
 
-PHP_MSHUTDOWN_FUNCTION(phpcups)
-{
-       /* uncomment this line if you have INI entries
-       UNREGISTER_INI_ENTRIES();
-       */
-       return SUCCESS;
-}
 
-/* Remove if there's nothing to do at request start */
-PHP_RINIT_FUNCTION(phpcups)
-{
-       return SUCCESS;
-}
+/*
+ * 'zm_startup_phpcups()' - Initialize the CUPS module.
+ */
 
-/* Remove if there's nothing to do at request end */
-PHP_RSHUTDOWN_FUNCTION(phpcups)
+PHP_MINIT_FUNCTION(phpcups)
 {
-       return SUCCESS;
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_LOCAL", CUPS_PRINTER_LOCAL, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_CLASS", CUPS_PRINTER_CLASS, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_REMOTE", CUPS_PRINTER_REMOTE, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_BW", CUPS_PRINTER_BW, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLOR", CUPS_PRINTER_COLOR, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_DUPLEX", CUPS_PRINTER_DUPLEX, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_STAPLE", CUPS_PRINTER_STAPLE, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_COPIES", CUPS_PRINTER_COPIES, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLLATE", CUPS_PRINTER_COLLATE, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_PUNCH", CUPS_PRINTER_PUNCH, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_COVER", CUPS_PRINTER_COVER, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_BIND", CUPS_PRINTER_BIND, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_SORT", CUPS_PRINTER_SORT, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_SMALL", CUPS_PRINTER_SMALL, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_MEDIUM", CUPS_PRINTER_MEDIUM, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_LARGE", CUPS_PRINTER_LARGE, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_VARIABLE", CUPS_PRINTER_VARIABLE, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_IMPLICIT", CUPS_PRINTER_IMPLICIT, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_DEFAULT", CUPS_PRINTER_DEFAULT, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_FAX", CUPS_PRINTER_FAX, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_REJECTING", CUPS_PRINTER_REJECTING, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_DELETE", CUPS_PRINTER_DELETE, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_NOT_SHARED", CUPS_PRINTER_NOT_SHARED, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_AUTHENTICATED", CUPS_PRINTER_AUTHENTICATED, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_COMMANDS", CUPS_PRINTER_COMMANDS, CONST_CS);
+  REGISTER_LONG_CONSTANT("CUPS_PRINTER_OPTIONS", CUPS_PRINTER_OPTIONS, CONST_CS);
+
+  REGISTER_LONG_CONSTANT("IPP_OK", IPP_OK, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_SUBST", IPP_OK_SUBST, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_CONFLICT", IPP_OK_CONFLICT, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_SUBSCRIPTIONS", IPP_OK_IGNORED_SUBSCRIPTIONS, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_NOTIFICATIONS", IPP_OK_IGNORED_NOTIFICATIONS, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_TOO_MANY_EVENTS", IPP_OK_TOO_MANY_EVENTS, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_BUT_CANCEL_SUBSCRIPTION", IPP_OK_BUT_CANCEL_SUBSCRIPTION, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OK_EVENTS_COMPLETE", IPP_OK_EVENTS_COMPLETE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_REDIRECTION_OTHER_SITE", IPP_REDIRECTION_OTHER_SITE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_BAD_REQUEST", IPP_BAD_REQUEST, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_FORBIDDEN", IPP_FORBIDDEN, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_NOT_AUTHENTICATED", IPP_NOT_AUTHENTICATED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_NOT_AUTHORIZED", IPP_NOT_AUTHORIZED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_NOT_POSSIBLE", IPP_NOT_POSSIBLE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_TIMEOUT", IPP_TIMEOUT, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_NOT_FOUND", IPP_NOT_FOUND, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_GONE", IPP_GONE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_REQUEST_ENTITY", IPP_REQUEST_ENTITY, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_REQUEST_VALUE", IPP_REQUEST_VALUE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT", IPP_DOCUMENT_FORMAT, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES", IPP_ATTRIBUTES, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_URI_SCHEME", IPP_URI_SCHEME, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_CHARSET", IPP_CHARSET, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_CONFLICT", IPP_CONFLICT, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_COMPRESSION_NOT_SUPPORTED", IPP_COMPRESSION_NOT_SUPPORTED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_COMPRESSION_ERROR", IPP_COMPRESSION_ERROR, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT_ERROR", IPP_DOCUMENT_FORMAT_ERROR, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_DOCUMENT_ACCESS_ERROR", IPP_DOCUMENT_ACCESS_ERROR, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES_NOT_SETTABLE", IPP_ATTRIBUTES_NOT_SETTABLE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_SUBSCRIPTIONS", IPP_IGNORED_ALL_SUBSCRIPTIONS, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_TOO_MANY_SUBSCRIPTIONS", IPP_TOO_MANY_SUBSCRIPTIONS, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_NOTIFICATIONS", IPP_IGNORED_ALL_NOTIFICATIONS, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_PRINT_SUPPORT_FILE_NOT_FOUND", IPP_PRINT_SUPPORT_FILE_NOT_FOUND, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_INTERNAL_ERROR", IPP_INTERNAL_ERROR, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_OPERATION_NOT_SUPPORTED", IPP_OPERATION_NOT_SUPPORTED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_SERVICE_UNAVAILABLE", IPP_SERVICE_UNAVAILABLE, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_VERSION_NOT_SUPPORTED", IPP_VERSION_NOT_SUPPORTED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_DEVICE_ERROR", IPP_DEVICE_ERROR, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_TEMPORARY_ERROR", IPP_TEMPORARY_ERROR, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_NOT_ACCEPTING", IPP_NOT_ACCEPTING, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_PRINTER_BUSY", IPP_PRINTER_BUSY, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_ERROR_JOB_CANCELLED", IPP_ERROR_JOB_CANCELLED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_MULTIPLE_JOBS_NOT_SUPPORTED", IPP_MULTIPLE_JOBS_NOT_SUPPORTED, CONST_CS);
+  REGISTER_LONG_CONSTANT("IPP_PRINTER_IS_DEACTIVATED", IPP_PRINTER_IS_DEACTIVATED, CONST_CS);
+
+  return (SUCCESS);
 }
 
+/*
+ * 'zif_cups_cancel_job()' - Cancel a job.
+ */
 
-
-PHP_MINFO_FUNCTION(phpcups)
+PHP_FUNCTION(cups_cancel_job)
 {
-       php_info_print_table_start();
-       php_info_print_table_header(2, "phpcups support", "enabled");
-       php_info_print_table_end();
+  char *dest;                          /* Destination */
+  int  dest_len,                       /* Length of destination */
+       id;                             /* Job ID */
 
-       /* Remove comments if you have entries in php.ini
-       DISPLAY_INI_ENTRIES();
-       */
-}
-
-
-
-
-
-
-
-/* Remove the following function when you have succesfully modified config.m4
-   so that your module can be compiled into PHP, it exists only for testing
-   purposes. */
-
-/* Every user-visible function in PHP should document itself in the source */
-PHP_FUNCTION(confirm_phpcups_compiled)
-{
-       char *arg = NULL;
-       int arg_len, len;
-       char string[256];
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
-               return;
-       }
+  if (ZEND_NUM_ARGS() != 2 ||
+      zend_parse_parameters(2, "sl", &dest, &dest_len, &id))
+  {
+    WRONG_PARAM_COUNT;
+  }
 
-       len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "phpcups", arg);
-       RETURN_STRINGL(string, len, 1);
+  RETURN_LONG(cupsCancelJob(dest, id));
 }
-/* The previous line is meant for vim and emacs, so it can correctly fold and 
-   unfold functions in source code. See the corresponding marks just before 
-   function definition, where the functions purpose is also documented. Please 
-   follow this convention for the convenience of others editing your code.
-*/
-
-
-
-
-
-
-
-
-
 
 
 /*
- *  Function:    cups_get_dest_options
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  d_name     - String  - Name of destination.
- *               d_instance - String  - Name of instance on destination.
- *
- *  Returns:     Array of option "objects", with each object
- *               containing the members:
- *
- *                 name  - String - Option name
- *                 value - String - Option value
- *
- *  Comments:
- *
+ * 'zif_cups_get_dests()' - .
  */
-PHP_FUNCTION(cups_get_dest_options)
-{
-    char        *arg = NULL;
-    int         arg_len, len;
 
-    zval        *new_object;
-
-    zval        **d_server,
-                **d_name, 
-                **d_instance;
-
-    char       c_server[256],
-                c_name[256], 
-                c_instance[256];
-
-    char       l_server[256],
-                l_name[256], 
-                l_instance[256];
+PHP_FUNCTION(cups_get_dests)
+{
+  int          i, j,                   /* Looping vars */
+               num_dests;              /* Number of destinations */
+  cups_dest_t  *dests,                 /* Destinations */
+               *dest;                  /* Current destination */
+  cups_option_t        *option;                /* Current option */
+  zval         *destobj,               /* Destination object */
+               *optionsobj;            /* Options object */
 
-    cups_dest_t *dests, *dptr;
-    int         num_dests;
-    int         i, j;
 
-    array_init(return_value);
+  if (ZEND_NUM_ARGS() != 0)
+  {
+    WRONG_PARAM_COUNT;
+  }
 
-    if ((ZEND_NUM_ARGS() != 3) ||
-        (zend_get_parameters_ex(3,&d_server,&d_name,&d_instance) != SUCCESS))
-    {
-      WRONG_PARAM_COUNT;
-    }
+  if ((num_dests = cupsGetDests(&dests)) <= 0)
+  {
+    RETURN_NULL();
+  }
 
-    convert_to_string_ex( d_server );
-    convert_to_string_ex( d_name );
-    convert_to_string_ex( d_instance );
-
-    /*
-     *  Find the dest/instance we want options for.
-     */
-    bzero( c_server, 256 );
-    bzero( c_name, 256 );
-    bzero( c_instance, 256 );
-
-    if ( (char *)(*d_server)->value.str.val != NULL )
-      strcpy( c_server,(char *)(*d_server)->value.str.val );
-    if ( (char *)(*d_name)->value.str.val != NULL )
-      strcpy( c_name,(char *)(*d_name)->value.str.val );
-    if ( (char *)(*d_instance)->value.str.val != NULL )
-      strcpy( c_instance,(char *)(*d_instance)->value.str.val );
-      
-
-    if (strlen(c_server))
-      cupsSetServer(c_server);
-
-    num_dests = cupsGetDests(&dests); 
-    for (i=0, j = -1; (i < num_dests) && (j < 0); i++)
+  if (array_init(return_value) == SUCCESS)
+  {
+    for (i = 0, dest = dests; i < num_dests; i ++, dest ++)
     {
-      dptr = &dests[i];
-
-      if (dptr->name == NULL)
-        strcpy( l_name, "" );
-      else
-           strcpy( l_name, dptr->name );
-
-      if (dptr->instance == NULL)
-           strcpy( l_instance, "" );
-      else
-        strcpy( l_instance, dptr->instance );
+      MAKE_STD_ZVAL(destobj);
 
-      if ((!strcmp( l_name, c_name )) &&
-          (!strcmp( l_instance, c_instance )))
+      if (object_init(destobj) == SUCCESS)
       {
+       /*
+        * Add properties to the destination for each of the cups_dest_t
+       * members...
+       */
 
-        for (j=0; j < dptr->num_options; j++ )
-        {
-          if ((dptr->options[j].name != NULL) &&
-              (dptr->options[j].value != NULL))
-         {
-            MAKE_STD_ZVAL(new_object);
-            if (object_init(new_object) == SUCCESS)
-            {
-              add_property_string(new_object,"name",dptr->options[j].name, 1 );
-              add_property_string(new_object,"value",dptr->options[j].value,1);
-              add_next_index_zval( return_value, new_object );
-            }
-          }
-        }
-      }
-    }
-    cupsFreeDests(num_dests,dests); 
-}
-
-
-
-
-/*
- *  Function:    cups_get_dest_list
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  cups server (optional)
- *
- *  Returns:     Array of destination "objects", with each object
- *               containing the members:
- *
- *                 name        - String - Name of destination.
- *                 instance    - String - Name of instance on destination.
- *                 is_default  - Long   - 1 if default printer.
- *                 num_options - Long   - Number of options for destination.
- *
- *  Comments:
- *
- */
-PHP_FUNCTION(cups_get_dest_list)
-{
-    char        *arg = NULL;
-    int         arg_len, len;
-
-    zval        **z_server;
-    zval        *new_object;
-
-    char        c_server[256];
-
-    char        string[2560];
-    char        temp[256];
-
-    cups_dest_t *dests, *dptr;
-    int         num_dests;
-    int         i;
-
-    /*
-     *  Initialize the return array.
-     */
-    array_init(return_value);
+        add_property_string(destobj, "name", dest->name, 1);
+        add_property_string(destobj, "instance",
+                           dest->instance ? dest->instance : "", 1);
+        add_property_long(destobj, "is_default", dest->is_default);
 
-    switch (ZEND_NUM_ARGS())
-    {
-      /*
-       *  Change servers if passed.
-       */
-      case 1: if (zend_get_parameters_ex(1,&z_server) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              convert_to_string_ex( z_server );
-              if ( (char *)(*z_server)->value.str.val != NULL )
-              {
-                strcpy( c_server,(char *)(*z_server)->value.str.val );
-                cupsSetServer( c_server );
-              }
-              break;
-    }
+       /*
+        * Create an associative array for the options...
+       */
 
+        MAKE_STD_ZVAL(optionsobj);
 
-    /*
-     *  First get the destination list from the cups server.
-     */
-    num_dests = cupsGetDests(&dests); 
+       if (array_init(optionsobj) == SUCCESS)
+       {
+         for (j = 0, option = dest->options;
+              j < dest->num_options;
+              j ++, option ++)
+           add_assoc_string(optionsobj, option->name, option->value, 1);
 
-    /*
-     *  Loop through the list, create and fill in the objects, and
-     *  add them to the array.
-     */
-    string[0] = '\0';
-    for (i=0; i < num_dests; i++)
-    {
-      dptr = &dests[i];
+         add_property_zval(destobj, "options", optionsobj);
+       }
 
-      MAKE_STD_ZVAL(new_object);
-      if (object_init(new_object) == SUCCESS)
-      {
-        if (strlen(c_server))
-          add_property_string( new_object, "server", c_server, 1 );
-        else
-          add_property_string( new_object, "server", "", 1 );
-
-        if (dptr->name != NULL)
-          add_property_string( new_object, "name", dptr->name, 1 );
-        else
-          add_property_string( new_object, "name", "", 1 );
-
-        if (dptr->instance != NULL)
-          add_property_string( new_object, "instance", dptr->instance, 1 );
-        else
-          add_property_string( new_object, "instance", "", 1 );
-
-        add_property_long( new_object, "is_default", dptr->is_default );
-        add_property_long( new_object, "num_options", dptr->num_options );
-        add_next_index_zval( return_value, new_object );
+        add_index_zval(return_value, i, destobj);
       }
     }
+  }
 
-    /*
-     *  free the list .....
-     */
-    cupsFreeDests(num_dests,dests); 
+  cupsFreeDests(num_dests, dests);
 }
 
 
-
 /*
- *  Function:    cups_get_jobs
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  server    - String  - Name or IP of cups server.  Blank
- *                                     for localhost.
- *
- *               name      - String  - Name of destination to query.
- *
- *               user      - String  - Username to get job list for.
- *                         * Optional, default all users
- *
- *               my_jobs   - Long    - Show only my jobs
- *                         * Optional, default FALSE
- *
- *               completed - Long    - Show completed jobs
- *                         * Optional, default FALSE
- *
- *  Returns:     Array of print job "objects", with each object
- *               containing the members:
- *
- *               id             - Long    - Job id
- *               dest           - String  - Name of destination.
- *               title          - String  - Title of document.
- *               user           - String  - User who submitted job.
- *               format         - String  - Document format (MIME type)
- *               state          - Long    - Current state of the job.
- *               size           - Long    - Size in bytes of the job.
- *               priority       - Long    - Job priority.
- *               completed_time - Long    - Time job completed (UNIX time).
- *               creation_time  - Long    - Time job created (UNIX time).
- *               processing_time- Long    - Processing time in seconds?
- *
- *  Comments:
- *
+ * 'zif_cups_get_jobs()' - Get a list of jobs.
  */
-PHP_FUNCTION( cups_get_jobs )
-{
-    char        *arg = NULL;
 
-    int         arg_len, 
-                len;
-
-    zval        *new_object;
-
-    zval        **z_server,
-                **z_name, 
-                **z_user,
-                **z_myjobs, 
-                **z_completed;
-
-    char       p_server[256],
-                p_name[256],
-                p_user[256];
+PHP_FUNCTION(cups_get_jobs)
+{
+  char         *dest;                  /* Destination */
+  int          dest_len,               /* Length of destination */
+               myjobs,                 /* Only show my jobs? */
+               completed;              /* Show completed jobs? */
+  int          i,                      /* Looping var */
+               num_jobs;               /* Number of jobs */
+  cups_job_t   *jobs,                  /* Jobs */
+               *job;                   /* Current job */
+  zval         *jobobj;                /* Job object */
 
-    int         p_myjobs, 
-                p_completed;
 
-    cups_job_t  *jobs, 
-                *jptr;
 
-    int         num_jobs;
-    int         i;
 
-    bzero( p_server, 256 );
-    bzero( p_name, 256 );
-    bzero( p_user, 256 );
-    p_myjobs    = 0;
-    p_completed = 0;
+  if (ZEND_NUM_ARGS() != 3 ||
+      zend_parse_parameters(3, "sll", &dest, &dest_len, &myjobs, &completed))
+  {
+    WRONG_PARAM_COUNT;
+  }
 
-    /*
-     *  Initialize return value.
-     */
-    array_init(return_value);
+  if (!*dest)
+    dest = NULL;
 
-    /*
-     *  Parse params.
-     */
-    switch(ZEND_NUM_ARGS())
-    {
-      /*
-       *  server, destination only provided.
-       */
-      case 2: 
-              if (zend_get_parameters_ex( 2, &z_server,&z_name ) == SUCCESS)
-              {
-                convert_to_string_ex( z_server);
-                if ( (char *)(*z_server)->value.str.val != NULL )
-                  strcpy( p_server,(char *)(*z_server)->value.str.val );
-                convert_to_string_ex( z_name );
-                if ( (char *)(*z_name)->value.str.val != NULL )
-                  strcpy( p_name,(char *)(*z_name)->value.str.val );
-              }
-              break;
-
-      /*
-       *  server, destination and user
-       */
-      case 3: 
-              if (zend_get_parameters_ex( 3, &z_server, &z_name, 
-                                             &z_user ) == SUCCESS)
-              {
-                convert_to_string_ex( z_name );
-                convert_to_string_ex( z_user );
-                convert_to_string_ex( z_server);
-                if ( (char *)(*z_server)->value.str.val != NULL )
-                  strcpy( p_server,(char *)(*z_server)->value.str.val );
-                if ( (char *)(*z_name)->value.str.val != NULL )
-                  strcpy( p_name,(char *)(*z_name)->value.str.val );
-                if ( (char *)(*z_user)->value.str.val != NULL )
-                  strcpy( p_user,(char *)(*z_user)->value.str.val );
-              }
-              break;
-
-      /*
-       *  server, destination, user, and myjobs
-       */
-      case 4: 
-              if (zend_get_parameters_ex( 4, &z_server, &z_name, &z_user, 
-                                             &z_myjobs ) == SUCCESS)
-              {
-                convert_to_string_ex( z_name );
-                convert_to_string_ex( z_user );
-                convert_to_string_ex( z_server);
-                if ( (char *)(*z_server)->value.str.val != NULL )
-                  strcpy( p_server,(char *)(*z_server)->value.str.val );
-                if ( (char *)(*z_name)->value.str.val != NULL )
-                  strcpy( p_name,(char *)(*z_name)->value.str.val );
-                if ( (char *)(*z_user)->value.str.val != NULL )
-                  strcpy( p_user,(char *)(*z_user)->value.str.val );
-
-                convert_to_string_ex( z_myjobs );
-                p_myjobs = strtoul((char *)(*z_myjobs)->value.str.val,NULL,10);
-              }
-              break;
-
-      /*
-       *  server, destination, user, myjobs, and completed
-       */
-      case 5: 
-              if (zend_get_parameters_ex( 5, &z_server, &z_name, &z_user, 
-                                          &z_myjobs, &z_completed ) == SUCCESS)
-              {
-                convert_to_string_ex( z_name );
-                convert_to_string_ex( z_user );
-                convert_to_string_ex( z_server);
-                if ( (char *)(*z_server)->value.str.val != NULL )
-                  strcpy( p_server,(char *)(*z_server)->value.str.val );
-                if ( (char *)(*z_name)->value.str.val != NULL )
-                  strcpy( p_name,(char *)(*z_name)->value.str.val );
-                if ( (char *)(*z_user)->value.str.val != NULL )
-                  strcpy( p_user,(char *)(*z_user)->value.str.val );
-
-                convert_to_string_ex( z_myjobs );
-                p_myjobs = strtoul((char *)(*z_myjobs)->value.str.val,NULL,10);
-
-                convert_to_string_ex( z_completed);
-                p_completed = strtoul((char *)(*z_completed)->value.str.val,NULL,10);
-              }
-              break;
-    }
+  if ((num_jobs = cupsGetJobs(&jobs, dest, myjobs, completed)) <= 0)
+  {
+    RETURN_NULL();
+  }
 
-    /*
-     *  Set the cups server if given.
-     */
-    if (strlen(p_server))
-      cupsSetServer(p_server);
-
-    /*
-     *  Set the cups user if given, otherwise get all jobs.
-     */
-    if (strlen(p_user))
-      cupsSetUser(p_user); 
-    else
-      cupsSetUser("root"); 
-
-    /*
-     *  Get the jobs list from the CUPS server.
-     */
-    num_jobs = cupsGetJobs(&jobs,p_name,p_myjobs,p_completed); 
-
-    /*
-     *  Build the array of objects to return.
-     */
-    for (i=0; i < num_jobs; i++)
+  if (array_init(return_value) == SUCCESS)
+  {
+    for (i = 0, job = jobs; i < num_jobs; i ++, job ++)
     {
-      jptr = &jobs[i];
+      MAKE_STD_ZVAL(jobobj);
 
-      MAKE_STD_ZVAL(new_object);
-      if (object_init(new_object) == SUCCESS)
-      {
-        add_property_long(new_object,"id",jptr->id  );
-        add_property_string(new_object,"dest",jptr->dest, 1 );
-        add_property_string(new_object,"title",jptr->title, 1 );
-        add_property_string(new_object,"user",jptr->user, 1 );
-        add_property_string(new_object,"format",jptr->format, 1 );
-        add_property_long(new_object,"state",jptr->state );
-        add_property_long(new_object,"size",jptr->size );
-        add_property_long(new_object,"priority",jptr->priority );
-        add_property_long(new_object,"completed_time",jptr->completed_time);
-        add_property_long(new_object,"creation_time",jptr->creation_time);
-        add_property_long(new_object,"processing_time",jptr->processing_time);
-        add_next_index_zval( return_value, new_object );
-      }
-      else
+      if (object_init(jobobj) == SUCCESS)
       {
-        printf("\nError creating new object\n");
+       /*
+        * Add properties to the job for each of the cups_job_t
+       * members...
+       */
+
+        add_property_long(jobobj, "id", job->id);
+        add_property_string(jobobj, "dest", job->dest, 1);
+        add_property_string(jobobj, "title", job->title, 1);
+        add_property_string(jobobj, "user", job->user, 1);
+        add_property_string(jobobj, "format", job->format, 1);
+        add_property_long(jobobj, "state", job->state);
+        add_property_long(jobobj, "size", job->size);
+        add_property_long(jobobj, "priority", job->priority);
+        add_property_long(jobobj, "completed_time", job->completed_time);
+        add_property_long(jobobj, "creation_time", job->creation_time);
+        add_property_long(jobobj, "processing_time", job->processing_time);
+
+        add_index_zval(return_value, i, jobobj);
       }
     }
-    cupsFreeJobs(num_jobs,jobs); 
-}
-
+  }
 
+  cupsFreeJobs(num_jobs, jobs);
+}
 
 
 /*
- *  Function:    cups_last_error
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  none.
- *
- *  Returns:     error number - Long
- *
- *  Comments:
- *
+ * 'zif_cups_last_error()' - Return the last IPP status code.
  */
+
 PHP_FUNCTION(cups_last_error)
 {
-  static char error[1024];
-
-  zval **z_server;
-  char c_server[256];
-
-  bzero( c_server, 256 );
-
-  switch (ZEND_NUM_ARGS())
+  if (ZEND_NUM_ARGS() != 0)
   {
-      /*
-       *  Change servers if passed.
-       */
-      case 1: if (zend_get_parameters_ex(1,&z_server) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              convert_to_string_ex( z_server );
-              if ( (char *)(*z_server)->value.str.val != NULL )
-              {
-                strcpy( c_server,(char *)(*z_server)->value.str.val );
-                cupsSetServer( c_server );
-              }
-              break;
+    WRONG_PARAM_COUNT;
   }
-  sprintf( error,"%d", cupsLastError());
 
-  RETURN_STRINGL(error, strlen(error)+1, 1);
+  RETURN_LONG(cupsLastError());
 }
 
 
-
-
-
-
 /*
- *  Function:    cups_cancel_job
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  server - String  -  Name or IP of cups server.
- *               name   - String  -  Name of destination.
- *               job    - Long    -  Job ID to cancel.
- *
- *  Returns:     error number - Long?????????
- *
- *  Comments:
- *
+ * 'zif_cups_last_error_string()' - Return the last IPP status-message.
  */
-PHP_FUNCTION(cups_cancel_job)
-{
-    zval        **z_server, **z_name, **z_job;
-
-    char       p_server[256], p_name[256];
-    int         p_job;
-
-    int         ret_val = -1;
-
-    /*
-     *  Get parameters .....
-     */
-    if ((ZEND_NUM_ARGS() != 3) ||
-        (zend_get_parameters_ex( 3, &z_server, &z_name, &z_job ) != SUCCESS))
-    {
-      WRONG_PARAM_COUNT;
-    }
-
-    convert_to_string_ex( z_server);
-    if ( (char *)(*z_name)->value.str.val != NULL )
-    {
-      strcpy( p_server,(char *)(*z_server)->value.str.val );
-      cupsSetServer(p_server);
-    }
-
-    convert_to_string_ex( z_name );
-    if ( (char *)(*z_name)->value.str.val != NULL )
-      strcpy( p_name,(char *)(*z_name)->value.str.val );
-
-    convert_to_string_ex( z_job );
-    p_job = strtoul((char *)(*z_job)->value.str.val,NULL,10);
-
-    if (strlen(p_server))
-      cupsSetServer(p_server);
-    cupsSetUser("root");
-
-    /*
-     *  Errrr ....  Cancel the job ......
-     */
-    ret_val = cupsCancelJob(p_name,p_job);
-
-    RETURN_LONG(ret_val);
-}
-
 
-
-cups_option_t *_phpcups_parse_options( cups_option_t *options, 
-                                       int *num_options, char *param )
+PHP_FUNCTION(cups_last_error_string)
 {
-  char name[1024], value[1024];
-
-  sscanf(param,"%1023[^=]=%1023s", name, value ); 
-
-  if (strlen(name) && strlen(value))
+  if (ZEND_NUM_ARGS() != 0)
   {
-    if (options == NULL)
-    {
-      options = (cups_option_t *)emalloc(sizeof(cups_option_t));
-      options->name = (char *)emalloc(strlen(name)+1);
-      options->value = (char *)emalloc(strlen(value)+1);
-      strcpy( options->name, name );
-      strcpy( options->value, value );
-      *num_options++;
-    }
-    else
-    {
-      options = (cups_option_t *)erealloc(options,
-                                  (*num_options+1) * sizeof(cups_option_t));
-      options[*num_options].name = (char *)emalloc(strlen(name)+1);
-      options[*num_options].value = (char *)emalloc(strlen(value)+1);
-      strcpy( options[*num_options].name, name );
-      strcpy( options[*num_options].value, value );
-      *num_options++;
-    }
+    WRONG_PARAM_COUNT;
   }
-  return(options);
-}
-
-
-/*
- *  Function:    cups_print_file
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  printer    - String  -  Name of destination.
- *               filename   - String  -  Name of file to print (full path).
- *               title      - String  -  Title of document.
- *
- *  Returns:     Job ID     - Long
- *
- *  Comments:
- *
- */
-PHP_FUNCTION(cups_print_file)
-{
-    zval        **z_server, **z_printer, **z_filename, **z_title, 
-                **z_options, **keydata;
-
-    HashTable   *param_ht;
 
-    char       p_server[256];
-    char       p_printer[256];
-    char       p_filename[256];
-    char       p_title[256];
-
-    char           temp[4096];
-    cups_option_t  *options = NULL;
-
-    int         count, current;
-    int         ret_val = -1;
-
-    bzero( p_server, 256 );
-    bzero( p_printer, 256 );
-    bzero( p_filename, 256 );
-    bzero( p_title, 256 );
-    bzero( temp, 4096);
-    current = 0;
-
-    int zend_num_args = ZEND_NUM_ARGS();
-    switch (zend_num_args) 
-    {
-      /*
-       *  Server / Destination / filename only.
-       */
-      case 3:
-              if (zend_get_parameters_ex( 3, &z_server, &z_printer, 
-                                             &z_filename) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              convert_to_string_ex( z_server);
-              if ( (char *)(*z_server)->value.str.val != NULL )
-              {
-                strcpy( p_server,(char *)(*z_server)->value.str.val );
-                cupsSetServer(p_server);
-              }
-              convert_to_string_ex( z_printer);
-              if ( (char *)(*z_printer)->value.str.val != NULL )
-                strcpy( p_printer,(char *)(*z_printer)->value.str.val );
-              convert_to_string_ex( z_filename );
-              if ( (char *)(*z_filename)->value.str.val != NULL )
-                strcpy( p_filename,(char *)(*z_filename)->value.str.val );
-              strcpy( p_title,"untitled");
-              break;
-
-      /*
-       *  Server, destination, filename and title.
-       */
-      case 4:
-              if (zend_get_parameters_ex( 4, &z_server,
-                                             &z_printer, 
-                                             &z_filename, 
-                                             &z_title) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-
-              convert_to_string_ex( z_server);
-              if ( (char *)(*z_server)->value.str.val != NULL )
-              {
-                strcpy( p_server,(char *)(*z_server)->value.str.val );
-                cupsSetServer(p_server);
-              }
-
-              convert_to_string_ex( z_printer);
-              if ( (char *)(*z_printer)->value.str.val != NULL )
-                strcpy( p_printer,(char *)(*z_printer)->value.str.val );
-
-              convert_to_string_ex( z_filename );
-              if ( (char *)(*z_filename)->value.str.val != NULL )
-                strcpy( p_filename,(char *)(*z_filename)->value.str.val );
-
-              convert_to_string_ex( z_title );
-              if ( (char *)(*z_title)->value.str.val != NULL )
-                strcpy( p_title,(char *)(*z_title)->value.str.val );
-
-              _zz_internal_log( "cups_print_file", p_server );
-              _zz_internal_log( "cups_print_file", p_printer );
-              _zz_internal_log( "cups_print_file", p_filename );
-              _zz_internal_log( "cups_print_file", p_title );
-              break;
-
-      /*
-       *  Server, destination, filename and title plus printer options.
-       */
-      case 5:
-              if (zend_get_parameters_ex( 5, &z_server,
-                                             &z_printer, 
-                                             &z_filename, 
-                                             &z_title,
-                                             &z_options) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              convert_to_string_ex( z_server);
-              if ( (char *)(*z_server)->value.str.val != NULL )
-              {
-                strcpy( p_server,(char *)(*z_server)->value.str.val );
-                cupsSetServer(p_server);
-              }
-              convert_to_string_ex( z_printer);
-              if ( (char *)(*z_printer)->value.str.val != NULL )
-                strcpy( p_printer,(char *)(*z_printer)->value.str.val );
-              convert_to_string_ex( z_filename );
-              if ( (char *)(*z_filename)->value.str.val != NULL )
-                strcpy( p_filename,(char *)(*z_filename)->value.str.val );
-              convert_to_string_ex( z_title );
-              if ( (char *)(*z_title)->value.str.val != NULL )
-                strcpy( p_title,(char *)(*z_title)->value.str.val );
-
-              _zz_internal_log( "cups_print_file(server)", p_server );
-              _zz_internal_log( "cups_print_file(printer)", p_printer );
-              _zz_internal_log( "cups_print_file(filename)", p_filename );
-              _zz_internal_log( "cups_print_file(title)", p_title );
-
-              /*
-               *  Convert options array.
-               */
-              convert_to_array_ex( z_options );
-              param_ht = Z_ARRVAL_PP( z_options );
-              count    = zend_hash_num_elements( param_ht );
-              options  = emalloc(sizeof(zval **) * count);
-
-              current = 0;
-              zend_hash_internal_pointer_reset(param_ht);
-              for (current=0; current < count; current++)
-              {
-                zend_hash_get_current_data(param_ht,(void **)&keydata);   
-                switch(Z_TYPE_PP(keydata))
-                {
-                  case IS_STRING:
-                         convert_to_string_ex(keydata);
-                         strcpy(temp,(char *)(*keydata)->value.str.val );
-              _zz_internal_log( "cups_print_file(option)", temp );
-                         options = _phpcups_parse_options( options, &current,
-                                                           temp );
-                         break;
-                }
-                zend_hash_move_forward(param_ht);
-              }
-              break;
-
-      default: WRONG_PARAM_COUNT;
-    }
-
-    if (current > 0)
-    {
-      
-      bzero(temp,4096);
-      sprintf(temp,"(2) - P: %s F: %s T: %s C: %d", p_printer, p_filename,
-                                              p_title, current );
-      _zz_internal_log( "cups_print_file", temp );
-      ret_val = cupsPrintFile( p_printer,p_filename,p_title,current,options);
-      for (current=0; current < count; current++)
-      {
-        efree( options[current].name );
-        efree( options[current].value );
-      }
-      efree(options);
-    }
-    else
-    {
-      _zz_internal_log( "cups_print_file", "going to print");
-      ret_val = cupsPrintFile( p_printer,p_filename,p_title,0,NULL );
-    }
-
-    RETURN_LONG(ret_val);
+  RETURN_STRING((char *)cupsLastErrorString(), 1);
 }
 
 
-int _phpcups_get_printer_status(char *server, int port, char *name );
-
-typedef struct printer_attrs_type
-{
-  char      *name;
-  char      *value;
-} printer_attrs_t;
-
-
-
-int              num_attrs = 0;
-printer_attrs_t  *printer_attrs = NULL;
-
-void free_attrs_list(void);
-void _phpcups_free_attrs_list(void);
-
 /*
- *  Function:    cups_get_printer_attributes
- *
- *  Date:        8 April 2002 - TDB
- *
- *  Parameters:  name   - String  -  Name of destination.
- *
- *  Returns:     state  - String
- *
- *  Comments:
- *
+ * 'zif_cups_print_file()' - Print a single file.
  */
-PHP_FUNCTION(cups_get_printer_attributes)
-{
-    zval    **z_server, **z_port, **z_name;
-
-    zval    *new_object;
-
-    char    p_server[256], p_name[256];
-    int     p_port = 631;
 
-    int     i, count;
-
-
-    /*
-     *  Initialize return value.
-     */
-    array_init(return_value);
-
-    /*
-     *  Get parameters .....
-     */
-    switch(ZEND_NUM_ARGS())
-    {
-      //
-      //  Destination name only, assume localhost
-      //
-      case 1: 
-              if (zend_get_parameters_ex( 1, &z_name ) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              strcpy( p_server,"localhost" );
-              convert_to_string_ex( z_name );
-              if ( (char *)(*z_name)->value.str.val != NULL )
-                strcpy( p_name,(char *)(*z_name)->value.str.val );
-              break;
-
-      //
-      //  Server and estination name only, assume port 631
-      //
-      case 2: 
-              if (zend_get_parameters_ex( 2, &z_server, &z_name ) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              convert_to_string_ex( z_server);
-              if ((char *)(*z_server)->value.str.val != NULL)
-                strcpy( p_server,(char *)(*z_server)->value.str.val );
-              convert_to_string_ex( z_name );
-              if ( (char *)(*z_name)->value.str.val != NULL )
-                strcpy( p_name,(char *)(*z_name)->value.str.val );
-              break;
-
-      //
-      //  Server, destination name and port.
-      //
-      case 3: 
-              if(zend_get_parameters_ex(3,&z_server,&z_port,&z_name) != SUCCESS)
-              {
-                WRONG_PARAM_COUNT;
-              }
-              convert_to_string_ex(z_server);
-              if ((char *)(*z_server)->value.str.val != NULL)
-                strcpy( p_server,(char *)(*z_server)->value.str.val );
-              convert_to_string_ex(z_name);
-              if ( (char *)(*z_name)->value.str.val != NULL )
-                strcpy( p_name,(char *)(*z_name)->value.str.val );
-              convert_to_string_ex(z_port);
-              if ( (char *)(*z_port)->value.str.val != NULL )
-                p_port = atoi( (char *)(*z_name)->value.str.val );
-              break;
-
-      default: WRONG_PARAM_COUNT;
-    }
-
-    printer_attrs = NULL;
-    count = _phpcups_get_printer_status( p_server, p_port, p_name );
-
-    /*
-     *  Create an array of objects containing name / value pairs.
-     */
-    for (i=0; i < count; i++)
-    {
-      if ((printer_attrs[i].name != NULL) && (printer_attrs[i].value != NULL))
-      {
-        MAKE_STD_ZVAL(new_object);
-        if (object_init(new_object) == SUCCESS)
-        {
-          add_property_string(new_object,"name",printer_attrs[i].name, 1 );
-          add_property_string(new_object,"value",printer_attrs[i].value, 1 );
-          add_next_index_zval( return_value, new_object );
-        }
-      }
-    }
-    _phpcups_free_attrs_list();
-}
-
-
-
-
-void _phpcups_free_attrs_list(void)
+PHP_FUNCTION(cups_print_file)
 {
-  int i;
-
-  if (num_attrs < 1)
-    return;
-
-  for ( i=0; i < num_attrs; i++ )
+  char         *dest;                  /* Destination */
+  int          dest_len;               /* Length of destination */
+  char         *filename;              /* Filename */
+  int          filename_len;           /* Length of filename */
+  char         *title;                 /* Title */
+  int          title_len;              /* Length of title */
+  zval         *optionsobj;            /* Array of options */
+  int          num_options;            /* Number of options */
+  cups_option_t        *options;               /* Options */
+  int          id;                     /* Job ID */
+
+
+  if (ZEND_NUM_ARGS() != 4 ||
+      zend_parse_parameters(4, "sssa", &dest, &dest_len,
+                            &filename, &filename_len,
+                           &title, &title_len, &optionsobj))
   {
-      if (printer_attrs[i].name != NULL)
-        efree(printer_attrs[i].name);
-      if (printer_attrs[i].value != NULL)
-        efree(printer_attrs[i].value );
+    WRONG_PARAM_COUNT;
   }
-  efree(printer_attrs);
-  num_attrs = 0;
-}
 
+  num_options = cups_convert_options(optionsobj, &options);
 
+  id = cupsPrintFile(dest, filename, title, num_options, options);
 
+  cupsFreeOptions(num_options, options);
 
-
-
-
-int _phpcups_update_attrs_list( char *name, char *value )
-{
-  if (num_attrs < 1)
-  {
-    printer_attrs = (printer_attrs_t *)emalloc(sizeof(printer_attrs_t));
-    printer_attrs->name = (char *)emalloc(strlen(name)+1);
-    printer_attrs->value = (char *)emalloc(strlen(value)+1);
-    strcpy( printer_attrs->name, name );
-    strcpy( printer_attrs->value, value );
-    num_attrs = 1;
-  }
-  else
-  {
-    printer_attrs = (printer_attrs_t *)erealloc(printer_attrs, 
-                                     (num_attrs + 1) * sizeof(printer_attrs_t));
-
-    printer_attrs[num_attrs].name = (char *)emalloc(strlen(name)+1);
-    printer_attrs[num_attrs].value = (char *)emalloc(strlen(value)+1);
-    strcpy( printer_attrs[num_attrs].name, name );
-    strcpy( printer_attrs[num_attrs].value, value );
-    num_attrs++;
-  }
-  return(num_attrs);
+  RETURN_LONG(id);
 }
 
 
+/*
+ * 'zif_cups_print_files()' - Print multiple files.
+ */
 
-int _phpcups_get_printer_status( char *server, int port, char *name )
+PHP_FUNCTION(cups_print_files)
 {
-  http_encryption_t encrypt = HTTP_ENCRYPT_IF_REQUESTED;
-
-  ipp_t                *request,       /* IPP Request */
-               *response;      /* IPP Response */
-  ipp_attribute_t *attr;       /* Current attribute */
-  cups_lang_t  *language;      /* Default language */
-
-  char          printer_uri[1024];
-  char          temp[1024];
-  static char  *req_attrs[] = {"printer-state", "printer-state-reason" };
-  int          i;
-  FILE         *fp;
-
-  if (name == NULL)
-  {
-    last_error = IPP_INTERNAL_ERROR;
-    return (0);
-  }
-
- /*
-  * Try to connect to the server...
-  */
-
-  if ((cups_server = httpConnectEncrypt(server, port, encrypt)) == NULL)
+  char         *dest;                  /* Destination */
+  int          dest_len;               /* Length of destination */
+  zval         *filesobj;              /* Files array */
+  int          num_files;              /* Number of files */
+  const char   *files[1000];           /* Files */
+  char         *title;                 /* Title */
+  int          title_len;              /* Length of title */
+  zval         *optionsobj;            /* Array of options */
+  int          num_options;            /* Number of options */
+  cups_option_t        *options;               /* Options */
+  HashTable    *ht2;                   /* Option array hash table */
+  Bucket       *current;               /* Current element in array */
+  int          id;                     /* Job ID */
+
+
+  if (ZEND_NUM_ARGS() != 4 ||
+      zend_parse_parameters(4, "sasa", &dest, &dest_len, &filesobj,
+                           &title, &title_len, &optionsobj))
   {
-    last_error = IPP_SERVICE_UNAVAILABLE;
-    return (0);
+    WRONG_PARAM_COUNT;
   }
 
- /*
-  * Build a CUPS_GET_PRINTERS request, which requires the following
-  * attributes:
-  *
-  *    attributes-charset
-  *    attributes-natural-language
-  *    requested-attributes
-  */
-
-  request = ippNew();
-
-  request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
-  request->request.op.request_id   = 1;
+  ht2       = Z_ARRVAL_P(filesobj);
+  num_files = 0;
 
-  language = cupsLangDefault();
-
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-               "attributes-charset", NULL, cupsLangEncoding(language));
-
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-               "attributes-natural-language", NULL, language->language);
-
-  sprintf(printer_uri, "ipp://localhost/printers/%-s", name );
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
-               "printer-uri", NULL, printer_uri );
-
- /*
-  * Do the request and get back a response...
-  */
-
-  num_attrs = 0;
-  printer_attrs = NULL;
-
-  if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+  for (current = ht2->pListHead; current; current = current->pListNext)
   {
-    last_error = response->request.status.status_code;
-
-    for (attr = response->attrs; attr != NULL; attr = attr->next)
-    {
+    files[num_files ++] = Z_STRVAL_P(((zval *)current->pDataPtr));
 
-      if (attr->num_values < 1)
-        continue;
-
-      if (attr->name != NULL &&
-          strcasecmp(attr->name, "printer-state") == 0 &&
-          attr->value_tag == IPP_TAG_ENUM)
-      {
-       strcpy( temp, "unknown" );
-        switch( attr->values[0].integer )
-        {
-          case 3: strcpy( temp, "idle" );
-                  break;
-          case 4: strcpy( temp, "processing" );
-                  break;
-          case 5: strcpy( temp, "stopped" );
-                  break;
-          default: continue;
-        }
-        _phpcups_update_attrs_list( attr->name, temp );
-      }
-      else if (attr->name != NULL &&
-               (attr->value_tag == IPP_TAG_TEXT ||
-                attr->value_tag == IPP_TAG_URI ||
-                attr->value_tag == IPP_TAG_KEYWORD ||
-                attr->value_tag == IPP_TAG_STRING))
-      {
-        for (i=0; i < attr->num_values; i++)
-          _phpcups_update_attrs_list(attr->name, attr->values[i].string.text );
-      }
-      else if (attr->name != NULL &&
-               (attr->value_tag == IPP_TAG_ENUM ||
-                attr->value_tag == IPP_TAG_BOOLEAN ||
-                attr->value_tag == IPP_TAG_INTEGER))
-      {
-        for (i=0; i < attr->num_values; i++)
-        {
-          sprintf(temp,"%-d", attr->values[i].integer );
-          _phpcups_update_attrs_list(attr->name, temp );
-        }
-      }
-      else if (attr->name != NULL &&
-               attr->value_tag == IPP_TAG_RESOLUTION)
-      {
-        for (i=0; i < attr->num_values; i++)
-        {
-          sprintf(temp,"%-dx%-dx%-d",
-                         attr->values[i].resolution.xres,
-                         attr->values[i].resolution.yres,
-                         attr->values[i].resolution.units );
-          _phpcups_update_attrs_list(attr->name, temp );
-        }
-      }
-      else if (attr->name != NULL &&
-               attr->value_tag == IPP_TAG_RANGE)
-      {
-        for (i=0; i < attr->num_values; i++)
-        {
-          sprintf(temp,"%d-%d",
-                         attr->values[i].range.lower,
-                         attr->values[i].range.upper );
-          _phpcups_update_attrs_list(attr->name, temp );
-        }
-      }
-    }
-    ippDelete(response);
+    if (num_files >= (int)(sizeof(files) / sizeof(files[0])))
+      break;
   }
-  else
-  {
-    last_error = IPP_BAD_REQUEST;
-    return(0);
-  }
-  return (num_attrs);
-}
 
+  num_options = cups_convert_options(optionsobj, &options);
 
-void _zz_internal_log( char *func, char *line )
-{
-  FILE *fp;
+  id = cupsPrintFiles(dest, num_files, files, title, num_options, options);
 
-  if ((fp = fopen("/var/log/cups/project.log","a")) == NULL)
-       return;
+  cupsFreeOptions(num_options, options);
 
-  fprintf(fp,"phpcups: %s - %s\n", func, line );
-  fflush(fp);
-  fclose(fp);
+  RETURN_LONG(id);
 }
 
 
-
-/*
- * End of "$Id: phpcups.c 4530 2005-06-01 20:15:51Z mike $".
- */
-
-
 /*
+ * End of "$Id: phpcups.c 5171 2006-02-25 08:44:43Z mike $".
  */
diff --git a/scripting/php/phpcups.h b/scripting/php/phpcups.h
new file mode 100644 (file)
index 0000000..a318dad
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * "$Id: phpcups.h 5171 2006-02-25 08:44:43Z mike $"
+ *
+ *   PHP module include file for the Common UNIX Printing System (CUPS).
+ *
+ *   Copyright 1997-2006 by Easy Software Products.
+ *
+ *   These coded instructions, statements, and computer programs are the
+ *   property of Easy Software Products 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 missing or damaged please contact Easy Software Products
+ *   at:
+ *
+ *       Attn: CUPS Licensing Information
+ *       Easy Software Products
+ *       44141 Airport View Drive, Suite 204
+ *       Hollywood, Maryland 20636 USA
+ *
+ *       Voice: (301) 373-9603
+ *       EMail: cups-info@cups.org
+ *         WWW: http://www.cups.org/
+ */
+
+#ifndef PHPCUPS_H
+#  define PHPCUPS_H
+
+/*
+ * Include necessary headers...
+ */
+
+#  include <cups/cups.h>
+#  include <cups/language.h>
+#  include <cups/debug.h>
+#  include <stdlib.h>
+#  include <ctype.h>
+#  include <errno.h>
+#  include <fcntl.h>
+#  include <sys/stat.h>
+#  if defined(WIN32) || defined(__EMX__)
+#    include <io.h>
+#  else
+#    include <unistd.h>
+#  endif /* WIN32 || __EMX__ */
+
+
+/*
+ * Zend definitions...
+ */
+
+extern zend_module_entry       phpcups_module_entry;
+#  define phpext_phpcups_ptr   &phpcups_module_entry
+
+#  ifdef PHP_WIN32
+#    define PHP_PHPCUPS_API    __declspec(dllexport)
+#  else
+#    define PHP_PHPCUPS_API
+#  endif
+
+#  ifdef ZTS
+#    include "TSRM.h"
+#  endif
+
+PHP_MINIT_FUNCTION(phpcups);
+
+PHP_FUNCTION(cups_cancel_job);
+PHP_FUNCTION(cups_get_dests);
+PHP_FUNCTION(cups_get_jobs);
+PHP_FUNCTION(cups_last_error);
+PHP_FUNCTION(cups_last_error_string);
+PHP_FUNCTION(cups_print_file);
+PHP_FUNCTION(cups_print_files);
+
+#endif /* !PHPCUPS_H */
+
+
+/*
+ * End of "$Id: phpcups.h 5171 2006-02-25 08:44:43Z mike $".
+ */
old mode 100644 (file)
new mode 100755 (executable)
index 01ce6a8..0b56693
@@ -1,10 +1,11 @@
+#!/usr/bin/php -f
 <?
 //
 // "$Id: phpcups.php 3603 2003-04-11 18:42:52Z mike $"
 //
 //   PHP test script for the Common UNIX Printing System (CUPS).
 //
-//   Copyright 1997-2003 by Easy Software Products, all rights reserved.
+//   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 //
 //   These coded instructions, statements, and computer programs are the
 //   property of Easy Software Products and are protected by Federal
 //       Attn: CUPS Licensing Information
 //       Easy Software Products
 //       44141 Airport View Drive, Suite 204
-//       Hollywood, Maryland 20636-3111 USA
+//       Hollywood, Maryland 20636 USA
 //
 //       Voice: (301) 373-9603
 //       EMail: cups-info@cups.org
-//         WWW: http://www.cups.org
+//         WWW: http://www.cups.org/
 //
 
 // Make sure the module is loaded...
-if(!extension_loaded('phpcups')) {
-       dl('phpcups.so');
+if(!extension_loaded("phpcups"))
+{
+  dl("phpcups.so");
 }
 
 // Get the list of functions in the module...
-$module    = 'phpcups';
+$module    = "phpcups";
 $functions = get_extension_funcs($module);
 
-echo "Functions available in the $module extension:<br>\n";
+print("Functions available in the $module extension:\n");
 
-foreach($functions as $func) {
-    echo $func."<br>\n";
+foreach ($functions as $func)
+{
+  print("$func\n");
 }
-echo "<br>\n";
 
-$function = 'confirm_' . $module . '_compiled';
-if (extension_loaded($module)) {
-       $str = $function($module);
-} else {
-       $str = "Module $module is not compiled into PHP";
-}
-echo "$str\n";
+print("\n");
+
+print("cups_get_dests:\n");
+print_r(cups_get_dests());
+
+print("cups_get_jobs(\"\", 0, -1):\n");
+print_r(cups_get_jobs("", 0, -1));
+
+print("cups_print_file(\"test\", \"../../test/testfile.jpg\", "
+     ."\"testfile.jpg\", ...):\n");
+print_r(cups_print_file("test", "../../test/testfile.jpg", "testfile.jpg",
+                        array("scaling" => "100",
+                             "page-label" => "testfile.jpg")));
+
+print("cups_print_files(\"test\", array(\"../../test/testfile.jpg\", "
+     ."\"../../test/testfile.ps\"), \"testfiles\", ...):\n");
+print_r(cups_print_files("test", array("../../test/testfile.jpg",
+                                       "../../test/testfile.ps"),
+                         "testfiles",
+                         array("scaling" => "100",
+                              "page-label" => "testfile.jpg")));
 
 //
 // End of "$Id: phpcups.php 3603 2003-04-11 18:42:52Z mike $".
index b1cad6572c1050ca9fbbe0f6c7507b6814b14b46..4d0bdc15e3185a154bf4849340010f70b718cba0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cupsaddsmb.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: cupsaddsmb.c 5187 2006-02-26 20:36:03Z mike $"
  *
  *   "cupsaddsmb" command for the Common UNIX Printing System (CUPS).
  *
@@ -564,8 +564,8 @@ export_dest(const char *dest)               /* I - Destination to export */
   {
     _cupsLangPrintf(stderr,
                     _("cupsaddsmb: No PPD file for printer \"%s\" - "
-                     "skipping!\n"),
-                   dest);
+                     "%s\n"),
+                   dest, cupsLastErrorString());
     httpClose(http);
     return (0);
   }
@@ -1026,5 +1026,5 @@ write_option(FILE            *dstfp,      /* I - PPD file */
 
 
 /*
- * End of "$Id: cupsaddsmb.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: cupsaddsmb.c 5187 2006-02-26 20:36:03Z mike $".
  */
index 09f45d5ae0a5c4583c2fbac165f1f677c384060d..96ad93d9273e4cebcdabe6f6ffcd2c2203ebba56 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cupstestppd.c 4990 2006-01-26 02:21:45Z mike $"
+ * "$Id: cupstestppd.c 5189 2006-02-27 01:45:57Z mike $"
  *
  *   PPD test program for the Common UNIX Printing System (CUPS).
  *
@@ -302,31 +302,55 @@ main(int  argc,                   /* I - Number of command-line arguments */
           attr->value)
         ppdversion = (int)(10 * atof(attr->value) + 0.5);
 
-      if (verbose > 0)
+     /*
+      * Look for default keywords with no matching option...
+      */
+
+      for (i = 0; i < ppd->num_attrs; i ++)
       {
-       /*
-        * Look for default keywords with no matching option...
-       */
+       attr = ppd->attrs[i];
 
-        for (i = 0; i < ppd->num_attrs; i ++)
+        if (!strcmp(attr->name, "DefaultColorSpace") ||
+           !strcmp(attr->name, "DefaultFont") ||
+           !strcmp(attr->name, "DefaultImageableArea") ||
+           !strcmp(attr->name, "DefaultOutputOrder") ||
+           !strcmp(attr->name, "DefaultPaperDimension") ||
+           !strcmp(attr->name, "DefaultTransfer"))
+         continue;
+
+       if (!strncmp(attr->name, "Default", 7))
        {
-         attr = ppd->attrs[i];
-
-          if (!strcmp(attr->name, "DefaultColorSpace") ||
-             !strcmp(attr->name, "DefaultFont") ||
-             !strcmp(attr->name, "DefaultImageableArea") ||
-             !strcmp(attr->name, "DefaultOutputOrder") ||
-             !strcmp(attr->name, "DefaultPaperDimension") ||
-             !strcmp(attr->name, "DefaultTransfer"))
-           continue;
-             
-         if (!strncmp(attr->name, "Default", 7) &&
-             !ppdFindOption(ppd, attr->name + 7))
+         if ((option = ppdFindOption(ppd, attr->name + 7)) == NULL)
             _cupsLangPrintf(stdout,
                            _("        WARN    %s has no corresponding "
                              "options!\n"),
                            attr->name);
-        }
+          else if (strcmp(attr->value, "Unknown"))
+         {
+          /*
+           * Check that the default option value matches a choice...
+           */
+
+           for (j = 0; j < option->num_choices; j ++)
+             if (!strcmp(option->choices[j].choice, attr->value))
+               break;
+
+            if (j >= option->num_choices)
+           {
+             if (verbose >= 0)
+             {
+               if (!errors && !verbose)
+                 _cupsLangPuts(stdout, _(" FAIL\n"));
+
+               _cupsLangPrintf(stdout,
+                               _("      **FAIL**  %s %s does not exist!\n"),
+                               attr->name, attr->value);
+              }
+
+             errors ++;
+           }
+         }
+       }
       }
 
       if ((attr = ppdFindAttr(ppd, "DefaultImageableArea", NULL)) == NULL)
@@ -980,6 +1004,182 @@ main(int  argc,                  /* I - Number of command-line arguments */
          }
       }
 
+      if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) != NULL &&
+          attr->value)
+      {
+       /*
+        * This file contains localizations, check them...
+       */
+
+        char   *languages,             /* Copy of attribute value */
+               *langstart,             /* Start of current language */
+               *langptr,               /* Pointer into languages */
+               keyword[PPD_MAX_NAME];  /* Localization keyword */
+
+
+        languages = strdup(attr->value);
+       for (langptr = languages; *langptr;)
+       {
+        /*
+         * Skip leading whitespace...
+         */
+
+         while (isspace(*langptr & 255))
+           langptr ++;
+
+         if (!*langptr)
+           break;
+
+         /*
+         * Find the end of this language name...
+         */
+
+         for (langstart = langptr;
+              *langptr && !isspace(*langptr & 255);
+              langptr ++);
+
+          if (*langptr)
+           *langptr++ = '\0';
+
+          j = strlen(langstart);
+         if (j != 2 && j != 5)
+         {
+           if (verbose >= 0)
+           {
+             if (!errors && !verbose)
+               _cupsLangPuts(stdout, _(" FAIL\n"));
+
+             _cupsLangPrintf(stdout,
+                             _("      **FAIL**  Bad language \"%s\"!\n"),
+                             langstart);
+            }
+
+           errors ++;
+           continue;
+         }
+
+         /*
+         * Loop through all options and choices...
+         */
+
+          for (option = ppdFirstOption(ppd);
+              option;
+              option = ppdNextOption(ppd))
+         {
+           snprintf(keyword, sizeof(keyword), "%s.Translation", langstart);
+           if (!ppdFindAttr(ppd, keyword, option->keyword))
+           {
+             if (verbose >= 0)
+             {
+               if (!errors && !verbose)
+                 _cupsLangPuts(stdout, _(" FAIL\n"));
+
+               _cupsLangPrintf(stdout,
+                               _("      **FAIL**  Missing \"%s\" translation "
+                                 "string for option %s!\n"),
+                               langstart, option->keyword);
+              }
+
+             errors ++;
+           }
+
+            for (ptr = option->text; *ptr; ptr ++)
+             if (*ptr & 128)
+               break;
+
+            if (*ptr)
+           {
+             if (verbose >= 0)
+             {
+               if (!errors && !verbose)
+                 _cupsLangPuts(stdout, _(" FAIL\n"));
+
+               _cupsLangPrintf(stdout,
+                               _("      **FAIL**  Default translation "
+                                 "string for option %s contains 8-bit "
+                                 "characters!\n"),
+                               option->keyword);
+              }
+
+             errors ++;
+           }
+
+           snprintf(keyword, sizeof(keyword), "%s.%s", langstart,
+                    option->keyword);
+            for (j = 0; j < option->num_choices; j ++)
+           {
+             if (!ppdFindAttr(ppd, keyword, option->choices[j].choice))
+             {
+               if (verbose >= 0)
+               {
+                 if (!errors && !verbose)
+                   _cupsLangPuts(stdout, _(" FAIL\n"));
+
+                 _cupsLangPrintf(stdout,
+                                 _("      **FAIL**  Missing \"%s\" "
+                                   "translation string for option %s, "
+                                   "choice %s!\n"),
+                                 langstart, option->keyword,
+                                 option->choices[j].choice);
+               }
+
+               errors ++;
+             }
+
+              for (ptr = option->choices[j].text; *ptr; ptr ++)
+               if (*ptr & 128)
+                 break;
+
+              if (*ptr)
+             {
+               if (verbose >= 0)
+               {
+                 if (!errors && !verbose)
+                   _cupsLangPuts(stdout, _(" FAIL\n"));
+
+                 _cupsLangPrintf(stdout,
+                                 _("      **FAIL**  Default translation "
+                                   "string for option %s choice %s contains "
+                                   "8-bit characters!\n"),
+                                 option->keyword,
+                                 option->choices[j].choice);
+               }
+
+               errors ++;
+             }
+            }
+         }
+        }
+      }
+
+      for (attr = ppdFindAttr(ppd, "cupsFilter", NULL);
+           attr;
+          attr = ppdFindNextAttr(ppd, "cupsFilter", NULL))
+      {
+        char   super[16],              /* Filter super type */
+               type[256],              /* Filter type */
+               program[256];           /* Filter program */
+       int     cost;                   /* Filter cost */
+
+
+        if (!attr->value ||
+           sscanf(attr->value, "%15[^/]/%255s%d%255s", super, type, &cost,
+                  program) != 4)
+        {
+         if (verbose >= 0)
+         {
+           if (!errors && !verbose)
+             _cupsLangPuts(stdout, _(" FAIL\n"));
+
+           _cupsLangPrintf(stdout,
+                           _("      **FAIL**  Bad cupsFilter value \"%s\"!\n"),
+                           attr->value ? attr->value : "");
+          }
+
+         errors ++;
+       }
+      }
+
       if (errors)
        status = ERROR_CONFORMANCE;
       else if (!verbose)
@@ -1487,5 +1687,5 @@ usage(void)
 
 
 /*
- * End of "$Id: cupstestppd.c 4990 2006-01-26 02:21:45Z mike $".
+ * End of "$Id: cupstestppd.c 5189 2006-02-27 01:45:57Z mike $".
  */
index 2cfe3281919a63f9d1022b0152d8c46837d20a4b..35498d904a63e01b1055d810434b858bcb3deb40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: lpadmin.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: lpadmin.c 5154 2006-02-23 01:36:15Z mike $"
  *
  *   "lpadmin" command for the Common UNIX Printing System (CUPS).
  *
@@ -1714,8 +1714,10 @@ set_printer_options(
                *response;              /* IPP Response */
   ipp_attribute_t *attr;               /* IPP attribute */
   ipp_op_t     op;                     /* Operation to perform */
-  const char   *val,                   /* Option value */
-               *ppdfile;               /* PPD filename */
+  const char   *ppdfile;               /* PPD filename */
+  int          ppdchanged;             /* PPD changed? */
+  ppd_file_t   *ppd;                   /* PPD file */
+  ppd_choice_t *choice;                /* Marked choice */
   char         uri[HTTP_MAX_URI],      /* URI for printer/class */
                line[1024],             /* Line from PPD file */
                keyword[1024],          /* Keyword from Default line */
@@ -1724,7 +1726,7 @@ set_printer_options(
   FILE         *in,                    /* PPD file */
                *out;                   /* Temporary file */
   int          outfd;                  /* Temporary file descriptor */
-  const char   *protocol;              /* Protocol */
+  const char   *protocol;              /* Old protocol option */
 
 
   DEBUG_printf(("set_printer_options(%p, \"%s\", %d, %p)\n", http, printer,
@@ -1763,7 +1765,8 @@ set_printer_options(
     * See what kind of printer or class it is...
     */
 
-    if ((attr = ippFindAttribute(response, "printer-type", IPP_TAG_ENUM)) != NULL)
+    if ((attr = ippFindAttribute(response, "printer-type",
+                                 IPP_TAG_ENUM)) != NULL)
     {
       if (attr->values[0].integer & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
       {
@@ -1795,7 +1798,17 @@ set_printer_options(
   * Add the options...
   */
 
-  cupsEncodeOptions(request, num_options, options);
+  cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
+
+  if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL)
+  {
+    if (!strcasecmp(protocol, "bcp"))
+      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "port-monitor",
+                   NULL, "bcp");
+    else if (!strcasecmp(protocol, "tbcp"))
+      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "port-monitor",
+                   NULL, "tbcp");
+  }
 
   if (op == CUPS_ADD_PRINTER)
     ppdfile = cupsGetPPD(printer);
@@ -1808,6 +1821,10 @@ set_printer_options(
     * Set default options in the PPD file...
     */
 
+    ppd = ppdOpenFile(ppdfile);
+    ppdMarkDefaults(ppd);
+    cupsMarkOptions(ppd, num_options, options);
+
     if ((outfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
     {
       _cupsLangPrintf(stderr,
@@ -1830,20 +1847,12 @@ set_printer_options(
       return (1);
     }
 
-    out      = fdopen(outfd, "wb");
-    protocol = cupsGetOption("protocol", num_options, options);    
+    out        = fdopen(outfd, "wb");
+    ppdchanged = 0;
 
     while (get_line(line, sizeof(line), in) != NULL)
     {
-      if (!strncmp(line, "*cupsProtocol:", 14) && protocol)
-      {
-       /*
-        * Set a new output protocol (BCP or TBCP) below...
-       */
-
-        continue;
-      }
-      else if (strncmp(line, "*Default", 8))
+      if (strncmp(line, "*Default", 8))
         fprintf(out, "%s\n", line);
       else
       {
@@ -1857,32 +1866,42 @@ set_printer_options(
          if (*keyptr == ':' || isspace(*keyptr & 255))
            break;
 
-        *keyptr = '\0';
-
-        if (!strcmp(keyword, "PageRegion"))
-         val = cupsGetOption("PageSize", num_options, options);
+        *keyptr++ = '\0';
+        while (isspace(*keyptr & 255))
+         keyptr ++;
+
+        if (!strcmp(keyword, "PageRegion") ||
+           !strcmp(keyword, "PageSize") ||
+           !strcmp(keyword, "PaperDimension") ||
+           !strcmp(keyword, "ImageableArea"))
+       {
+         if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL)
+           choice = ppdFindMarkedChoice(ppd, "PageRegion");
+        }
        else
-         val = cupsGetOption(keyword, num_options, options);
+         choice = ppdFindMarkedChoice(ppd, keyword);
 
-        if (val != NULL)
-         fprintf(out, "*Default%s: %s\n", keyword, val);
+        if (choice && strcmp(choice->choice, keyptr))
+       {
+         fprintf(out, "*Default%s: %s\n", keyword, choice->choice);
+         ppdchanged = 1;
+       }
        else
          fprintf(out, "%s\n", line);
       }
     }
 
-    if (protocol)
-      fprintf(out, "*cupsProtocol: \"%s\"\n", protocol);
-
     fclose(in);
     fclose(out);
     close(outfd);
+    ppdClose(ppd);
 
    /*
     * Do the request...
     */
 
-    response = cupsDoFileRequest(http, request, "/admin/", tempfile);
+    ippDelete(cupsDoFileRequest(http, request, "/admin/",
+                                ppdchanged ? tempfile : NULL));
 
    /*
     * Clean up temp files... (TODO: catch signals in case we CTRL-C during
@@ -1898,14 +1917,13 @@ set_printer_options(
     * No PPD file - just set the options...
     */
 
-    response = cupsDoRequest(http, request, "/admin/");
+    ippDelete(cupsDoRequest(http, request, "/admin/"));
   }
 
  /*
   * Check the response...
   */
 
-  ippDelete(response);
   if (cupsLastError() > IPP_OK_CONFLICT)
   {
     _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString());
@@ -1947,5 +1965,5 @@ validate_name(const char *name)           /* I - Name to check */
 
 
 /*
- * End of "$Id: lpadmin.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: lpadmin.c 5154 2006-02-23 01:36:15Z mike $".
  */
index b0aaa43f39fa6c4094fe72cd23cae5fae3f97173..fd58f2774bebfdb0b7031d030be73e0b47b6d71f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: lpstat.c 5023 2006-01-29 14:39:44Z mike $"
+ * "$Id: lpstat.c 5199 2006-02-27 22:01:02Z mike $"
  *
  *   "lpstat" command for the Common UNIX Printing System (CUPS).
  *
@@ -2070,7 +2070,7 @@ show_printers(http_t      *http,  /* I - HTTP connection to server */
           }
          _cupsLangPuts(stdout, _("\tOn fault: no alert\n"));
          _cupsLangPuts(stdout, _("\tAfter fault: continue\n"));
-             // TODO update to use printer-error-policy
+             /* TODO update to use printer-error-policy */
           if (allowed)
          {
            _cupsLangPuts(stdout, _("\tUsers allowed:\n"));
@@ -2183,7 +2183,7 @@ show_printers(http_t      *http,  /* I - HTTP connection to server */
               }
              _cupsLangPuts(stdout, _("\tOn fault: no alert\n"));
              _cupsLangPuts(stdout, _("\tAfter fault: continue\n"));
-                 // TODO update to use printer-error-policy
+                 /* TODO update to use printer-error-policy */
               if (allowed)
              {
                _cupsLangPuts(stdout, _("\tUsers allowed:\n"));
@@ -2246,5 +2246,5 @@ show_scheduler(http_t *http)      /* I - HTTP connection to server */
 
 
 /*
- * End of "$Id: lpstat.c 5023 2006-01-29 14:39:44Z mike $".
+ * End of "$Id: lpstat.c 5199 2006-02-27 22:01:02Z mike $".
  */
index 182023329b556a184f67226871abee9f32194bce..1dcfcb2bfa5b5f07dc881dd53b7136f9b44173c4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# "$Id: Makefile 5110 2006-02-15 21:42:46Z mike $"
+# "$Id: Makefile 5156 2006-02-23 04:24:32Z mike $"
 #
 #   Template makefile for the Common UNIX Printing System (CUPS).
 #
@@ -58,6 +58,7 @@ FILES =       \
                job-restart.tmpl \
                jobs.tmpl \
                jobs-header.tmpl \
+               maintenance.tmpl \
                modify-class.tmpl \
                modify-printer.tmpl \
                option-boolean.tmpl \
@@ -126,5 +127,5 @@ install: all
 
 
 #
-# End of "$Id: Makefile 5110 2006-02-15 21:42:46Z mike $".
+# End of "$Id: Makefile 5156 2006-02-23 04:24:32Z mike $".
 #
diff --git a/templates/maintenance.tmpl b/templates/maintenance.tmpl
new file mode 100644 (file)
index 0000000..ab57fb1
--- /dev/null
@@ -0,0 +1,2 @@
+<P>Maintenance commands sent; job ID is <A HREF="/printers/{printer_name}">
+{printer_name}-{job_id}</A>.</P>
index e3ee1aa87f073dcd78ed04c08f58a21cafe2fc4a..da28244578255b075ff243be2ddca7bf1f916997 100644 (file)
@@ -1,4 +1,4 @@
-{#printer_name=0?:
+{printer_type?:}{#printer_name=0?:
 {[printer_name]
 <H2 CLASS="title"><A HREF="{printer_uri_supported}">{printer_name}</A>{default_name={printer_name}? (Default Printer):}
 {?printer_state_message=?:<SPAN CLASS="message">"{printer_state_message}"</SPAN>}</H2>
 <P>
 <A HREF="{printer_uri_supported}?op=print-test-page">
 <IMG SRC="/images/print-test-page.gif" ALT="Print Test Page" CLASS="button"></A>
+{?cupscommand=1?<A HREF="{printer_uri_supported}?op=clean-print-heads">
+<IMG SRC="/images/clean-print-heads.gif" ALT="Clean Print Heads" CLASS="button"></A>
+<A HREF="{printer_uri_supported}?op=print-self-test-page">
+<IMG SRC="/images/print-self-test-page.gif" ALT="Print Self Test Page" CLASS="button"></A>:}
 {printer_state=5?
 <A HREF="{admin_uri}?op=start-printer&amp;printer_name={printer_name}">
 <IMG SRC="/images/start-printer.gif" ALT="Start Printer" CLASS="button"></A>
index bbca2dcc9b6bc95efc7839fe8b2ea4f4015e4e7f..bf49994af4e6d180a1e4a59f7c06a8fd6e70de5b 100644 (file)
@@ -1,2 +1,2 @@
 <P>Test page sent; job ID is <A HREF="/{SECTION}/{printer_name}">
-{printer_name}-{job_id}</A>.
+{printer_name}-{job_id}</A>.</P>
index fdd0516ef1474516fb2fbb26f04da904c46f4abe..ff961efd78ae32cd0b7c105044a70a79baf32a48 100755 (executable)
@@ -43,7 +43,7 @@ svn export $url /tmp/cups-$version
 echo Updating version information...
 cd /tmp/cups-$version/config-scripts
 
-sed -e '1,$s/^CUPS_VERSION=.*/CUPS_VERSION='$fileversion'/' \
+sed -e '1,$s/^CUPS_VERSION=.*/CUPS_VERSION='$version'/' \
        -e '1,$s/^CUPS_REVISION=.*/CUPS_REVISION='$revision'/' \
        <cups-common.m4 >cups-common.m4.new
 mv cups-common.m4.new cups-common.m4