Index: doc/help/spec-ipp.html
===================================================================
--- doc/help/spec-ipp.html	(revision 6878)
+++ doc/help/spec-ipp.html	(revision 6879)
@@ -39,7 +39,7 @@
 'fold',' trim', and 'bale' attribute values extension"
 specifications.</p>
 
-<p>CUPS also provides 15 new operations and many new attributes
+<p>CUPS also provides 16 new operations and many new attributes
 to support multiple IPP printers and printer classes on a single
 host.</p>
 
@@ -80,7 +80,7 @@
 
 <h3 class='title'><a name='IPP_OPERATIONS'>CUPS IPP Operations</a></h3>
 
-<p>CUPS provides 14 extension operations in addition to most of the
+<p>CUPS provides 16 extension operations in addition to most of the
 standard IPP and registered extension operations:
 
 <div class='table'><table align='center' border='1' width='80%'
@@ -328,6 +328,12 @@
 	<td>0x400F</td>
 	<td>Get a PPD file.</td>
 </tr>
+<tr>
+	<td><a href='#CUPS_GET_DOCUMENT'>CUPS-Get-Document</a></td>
+	<td>1.4</td>
+	<td>0x4027</td>
+	<td>Get a document file from a job.</td>
+</tr>
 </tbody>
 </table></div>
 
@@ -1786,7 +1792,91 @@
 <p>If the status code is <tt>successful-ok</tt>, the PPD file follows
 the end of the IPP response.</p>
 
+<h3 class='title'><span class='info'>CUPS 1.4</span><a name='CUPS_GET_DOCUMENT'>CUPS-Get-Document Operation</a></h3>
 
+<p>The CUPS-Get-Document operation (0x4027) gets a document file from a
+job on the server. The document file is specified using the
+<tt>document-number</tt> and either the <tt>job-uri</tt> or <tt>printer-uri</tt>
+and <tt>job-id</tt> identifying the job.</p>
+
+<p>If the document file is found, <tt>successful-ok</tt> is returned with
+the document file following the response data.</p>
+
+<p>If the document file does not exist, <tt>client-error-not-found</tt> is
+returned.</p>
+
+<p>If the requesting user does not have access to the document file,
+<tt>client-error-not-authorized</tt> is returned.
+
+<h4>CUPS-Get-Document Request</h4>
+
+<p>The following group of attributes is supplied as part of the
+CUPS-Get-Document request:
+
+<p>Group 1: Operation Attributes
+
+<dl>
+
+	<dt>Natural Language and Character Set:
+
+	<dd>The "attributes-charset" and "attributes-natural-language"
+	attributes as described in section 3.1.4.1 of the IPP Model and
+	Semantics document.
+
+	<dt>"printer-uri" (uri) and "job-id" (integer)
+	<br><i>OR</i>
+	<br>"job-uri" (uri):
+
+	<dd>The client MUST supply a printer URI and job ID or job URI.
+
+	<dt>"document-number" (integer(1:MAX)):
+
+	<dd>The client MUST supply a document number to retrieve. The
+	<tt>document-count</tt> attribute for the job defines the maximum
+	document number that can be specified. In the case of jobs with
+	banners (<tt>job-sheets</tt> is not "none"), document number 1
+	will typically contain the start banner and document number N
+	will typically contain the end banner.
+
+</dl>
+
+<h4>CUPS-Get-Document Response</h4>
+
+<p>The following group of attributes is sent as part of the
+CUPS-Get-Document Response:
+
+<p>Group 1: Operation Attributes
+
+<dl>
+
+	<dt>Status Message:
+
+	<dd>The standard response status message.
+
+	<dt>Natural Language and Character Set:
+
+	<dd>The "attributes-charset" and "attributes-natural-language"
+	attributes as described in section 3.1.4.2 of the IPP Model and
+	Semantics document.
+
+	<dt>"document-format" (mimeType):
+
+	<dd>The format of the document file.
+
+	<dt>"document-number" (integer(1:MAX)):
+
+	<dd>The requested document number.
+
+	<dt>"document-name" (name(MAX)):
+
+	<dd>The name that was supplied with the document, if any.
+
+</dl>
+
+<p>If the status code is <tt>successful-ok</tt>, the document file follows
+the end of the IPP response.</p>
+
+
 <h2 class='title'><a name='ATTRIBUTES'>Attributes</a></h2>
 
 <p>CUPS provides many extension attributes to support multiple
@@ -1914,6 +2004,11 @@
 printing text files. Only the values 10, 12, and 17 are currently
 supported. The default value is 10.
 
+<h4><a name="document-count">document-count (integer(1:MAX))</a></h4>
+
+<p>The document-count attribute specifies the number of documents that
+are present in the job.
+
 <h4><a name="fitplot">fitplot (boolean)</a></h4>
 
 <p>The fitplot attribute specifies whether to scale HP-GL/2 plot files to
Index: cups/ipp.h
===================================================================
--- cups/ipp.h	(revision 6878)
+++ cups/ipp.h	(revision 6879)
@@ -246,7 +246,8 @@
   CUPS_GET_PPDS,			/* Get a list of supported drivers */
   CUPS_MOVE_JOB,			/* Move a job to a different printer */
   CUPS_AUTHENTICATE_JOB,		/* Authenticate a job @since CUPS 1.2@ */
-  CUPS_GET_PPD				/* Get a PPD file @since CUPS 1.3@ */
+  CUPS_GET_PPD,				/* Get a PPD file @since CUPS 1.3@ */
+  CUPS_GET_DOCUMENT = 0x4027		/* Get a document file @since CUPS 1.4@ */
 } ipp_op_t;
 
 /* Old names for the operations */
Index: cups/ipp-support.c
===================================================================
--- cups/ipp-support.c	(revision 6878)
+++ cups/ipp-support.c	(revision 6879)
@@ -150,6 +150,10 @@
 		  "CUPS-Move-Job",
 		  "CUPS-Authenticate-Job",
 		  "CUPS-Get-PPD"
+		},
+		* const ipp_cups_ops2[] =
+		{
+		  "CUPS-Get-Document"
 		};
 
 
@@ -244,6 +248,8 @@
     return ("windows-ext");
   else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD)
     return (ipp_cups_ops[op - CUPS_GET_DEFAULT]);
+  else if (op == CUPS_GET_DOCUMENT)
+    return (ipp_cups_ops2[0]);
 
  /*
   * No, build an "unknown-xxxx" operation string...
@@ -278,6 +284,10 @@
     if (!strcasecmp(name, ipp_cups_ops[i]))
       return ((ipp_op_t)(i + 0x4001));
 
+  for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++)
+    if (!strcasecmp(name, ipp_cups_ops2[i]))
+      return ((ipp_op_t)(i + 0x4027));
+
   if (!strcasecmp(name, "CUPS-Add-Class"))
     return (CUPS_ADD_MODIFY_CLASS);
 
Index: cups/request.c
===================================================================
--- cups/request.c	(revision 6878)
+++ cups/request.c	(revision 6879)
@@ -17,6 +17,7 @@
  * Contents:
  *
  *   cupsDoFileRequest() - Do an IPP request with a file.
+ *   cupsDoIORequest()   - Do an IPP request with file descriptors.
  *   cupsDoRequest()     - Do an IPP request.
  *   _cupsSetError()     - Set the last IPP status code and status-message.
  *   _cupsSetHTTPError() - Set the last error using the HTTP status.
Index: man/cupsfilter.man
===================================================================
--- man/cupsfilter.man	(revision 6878)
+++ man/cupsfilter.man	(revision 6879)
@@ -11,14 +11,16 @@
 .\"   which should have been included with this file.  If this file is
 .\"   file is missing or damaged, see the license at "http://www.cups.org/".
 .\"
-.TH cupsfilter 8 "Common UNIX Printing System" "12 July 2007" "Apple Inc."
+.TH cupsfilter 8 "Common UNIX Printing System" "29 August 2007" "Apple Inc."
 .SH NAME
 cupsfilter \- convert a file to another format using cups filters
 .SH SYNOPSIS
 .B cupsfilter
 [ -c
 .I config-file
-] -m
+] -j
+.I job-id[,N]
+-m
 .I mime/type
 [ -n
 .I copies
@@ -40,6 +42,11 @@
 .br
 Uses the named cupsd.conf configuration file.
 .TP 5
+-j job-id[,N]
+.br
+Converts document N from the specified job. If N is omitted, document 1 is
+converted.
+.TP 5
 -m mime/type
 .br
 Specifies the destination file type.
Index: CHANGES.txt
===================================================================
--- CHANGES.txt	(revision 6878)
+++ CHANGES.txt	(revision 6879)
@@ -1,8 +1,12 @@
-CHANGES.txt - 2007-08-27
+CHANGES.txt - 2007-08-29
 ------------------------
 
 CHANGES IN CUPS V1.4b1
 
+	- The scheduler now supports a CUPS-Get-Document operation
+	  that returns the specified print job document (STR #118)
+	- The cupsfilter utility now supports a "-J jobid" option
+	  to filter the document from the specified job.
 	- The scheduler (cupsd) now supports a new option (-t) to
 	  do a syntax check of the cupsd.conf file (STR #2003)
 	- Added new cupsGetPPD3() API to allow applications to
Index: scheduler/cupsfilter.c
===================================================================
--- scheduler/cupsfilter.c	(revision 6878)
+++ scheduler/cupsfilter.c	(revision 6879)
@@ -19,6 +19,7 @@
  *   escape_options()  - Convert an options array to a string.
  *   exec_filter()     - Execute a single filter.
  *   exec_filters()    - Execute filters for the given file and options.
+ *   get_job_file()    - Get the specified job file.
  *   open_pipe()       - Create a pipe which is closed on exec.
  *   read_cupsd_conf() - Read the cupsd.conf file to get the filter settings.
  *   set_string()      - Copy and set a string.
@@ -35,8 +36,10 @@
 #include <errno.h>
 #include "mime.h"
 #include <stdlib.h>
+#include <limits.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <sys/wait.h>
 #if defined(__APPLE__)
 #  include <libgen.h>
@@ -64,6 +67,8 @@
 					/* CUPS_SERVERROOT environment variable */
 static char		*RIPCache = NULL;
 					/* RIP_CACHE environment variable */
+static char		TempFile[1024] = "";
+					/* Temporary file */
 
 
 /*
@@ -79,9 +84,11 @@
 			     const char *printer, const char *user,
 			     const char *title, int num_options,
 			     cups_option_t *options);
+static void	get_job_file(const char *job);
 static int	open_pipe(int *fds);
 static int	read_cupsd_conf(const char *filename);
 static void	set_string(char **s, const char *val);
+static void	sighandler(int sig);
 static void	usage(const char *command, const char *opt);
 
 
@@ -214,7 +221,21 @@
 	        usage(command, opt);
 	      break;
 
-          case 'j' : /* Specify destination MIME type... */
+          case 'j' : /* Get job file or specify destination MIME type... */
+              if (strcmp(command, "convert"))
+	      {
+	        i ++;
+		if (i < argc)
+		{
+		  get_job_file(argv[i]);
+		  infile = TempFile;
+		}
+		else
+		  usage(command, opt);
+
+                break;
+	      }
+
           case 'm' : /* Specify destination MIME type... */
 	      i ++;
 	      if (i < argc)
@@ -405,6 +426,9 @@
   * Remove files as needed, then exit...
   */
 
+  if (TempFile[0])
+    unlink(TempFile);
+
   if (removeppd && ppdfile)
     unlink(ppdfile);
 
@@ -811,10 +835,102 @@
 
 
 /*
+ * 'get_job_file()' - Get the specified job file.
+ */
+
+static void
+get_job_file(const char *job)		/* I - Job ID */
+{
+  long		jobid,			/* Job ID */
+		docnum;			/* Document number */
+  const char	*jobptr;		/* Pointer into job ID string */
+  char		uri[1024];		/* job-uri */
+  http_t	*http;			/* Connection to server */
+  ipp_t		*request;		/* Request data */
+  int		tempfd;			/* Temporary file */
+
+
+ /*
+  * Get the job ID and document number, if any...
+  */
+
+  if ((jobptr = strrchr(job, '-')) != NULL)
+    jobptr ++;
+  else
+    jobptr = job;
+
+  jobid = strtol(jobptr, (char **)&jobptr, 10);
+
+  if (*jobptr == ',')
+    docnum = strtol(jobptr + 1, NULL, 10);
+  else
+    docnum = 1;
+
+  if (jobid < 1 || jobid > INT_MAX)
+  {
+    _cupsLangPrintf(stderr, _("cupsfilter: Invalid job ID %d!\n"), (int)jobid);
+    exit(1);
+  }
+
+  if (docnum < 1 || docnum > INT_MAX)
+  {
+    _cupsLangPrintf(stderr, _("cupsfilter: Invalid document number %d!\n"),
+                    (int)docnum);
+    exit(1);
+  }
+
+ /*
+  * Ask the server for the document file...
+  */
+
+  if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+                                 cupsEncryption())) == NULL)
+  {
+    _cupsLangPrintf(stderr, _("%s: Unable to connect to server\n"),
+                    "cupsfilter");
+    exit(1);
+  }
+
+  request = ippNewRequest(CUPS_GET_DOCUMENT);
+
+  snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", (int)jobid);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
+  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "document-number",
+                (int)docnum);
+
+  if ((tempfd = cupsTempFd(TempFile, sizeof(TempFile))) == -1)
+  {
+    _cupsLangPrintf(stderr,
+                    _("cupsfilter: Unable to create temporary file: %s\n"),
+                    strerror(errno));
+    httpClose(http);
+    exit(1);
+  }
+
+  signal(SIGTERM, sighandler);
+
+  ippDelete(cupsDoIORequest(http, request, "/", -1, tempfd));
+
+  close(tempfd);
+
+  httpClose(http);
+
+  if (cupsLastError() != IPP_OK)
+  {
+    _cupsLangPrintf(stderr, _("cupsfilter: Unable to get job file - %s\n"),
+                    cupsLastErrorString());
+    unlink(TempFile);
+    exit(1);
+  }
+}
+
+
+/*
  * 'open_pipe()' - Create a pipe which is closed on exec.
  */
 
-int					/* O - 0 on success, -1 on error */
+static int				/* O - 0 on success, -1 on error */
 open_pipe(int *fds)			/* O - Pipe file descriptors (2) */
 {
  /*
@@ -948,6 +1064,28 @@
 
 
 /*
+ * 'sighandler()' - Signal catcher for when we print from stdin...
+ */
+
+static void
+sighandler(int s)			/* I - Signal number */
+{
+ /*
+  * Remove the temporary file we're using to print a job file...
+  */
+
+  if (TempFile[0])
+    unlink(TempFile);
+
+ /*
+  * Exit...
+  */
+
+  exit(s);
+}
+
+
+/*
  * 'usage()' - Show program usage...
  */
 
@@ -965,6 +1103,7 @@
 		    "Options:\n"
 		    "\n"
 		    "  -c cupsd.conf    Set cupsd.conf file to use\n"
+		    "  -j job-id[,N]    Filter file N from the specified job (default is file 1)\n"
 		    "  -n copies        Set number of copies\n"
 		    "  -o name=value    Set option(s)\n"
 		    "  -p filename.ppd  Set PPD file\n"
Index: scheduler/conf.c
===================================================================
--- scheduler/conf.c	(revision 6878)
+++ scheduler/conf.c	(revision 6879)
@@ -958,7 +958,7 @@
 		      "Renew-Subscription Cancel-Subscription "
 		      "Get-Notifications Reprocess-Job Cancel-Current-Job "
 		      "Suspend-Current-Job Resume-Job CUPS-Move-Job "
-		      "CUPS-Authenticate-Job>");
+		      "CUPS-Authenticate-Job CUPS-Get-Document>");
       cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
 
       po = cupsdAddPolicyOp(p, NULL, IPP_SEND_DOCUMENT);
@@ -986,6 +986,7 @@
       cupsdAddPolicyOp(p, po, IPP_RESUME_JOB);
       cupsdAddPolicyOp(p, po, CUPS_MOVE_JOB);
       cupsdAddPolicyOp(p, po, CUPS_AUTHENTICATE_JOB);
+      cupsdAddPolicyOp(p, po, CUPS_GET_DOCUMENT);
 
       cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
 
@@ -3245,6 +3246,36 @@
 	                "Missing </Limit> before </Policy> on line %d!",
 	                linenum);
 
+     /*
+      * Verify that we have an explicit policy for CUPS-Get-Document
+      * (ensures that upgrades do not introduce new security issues...)
+      */
+
+      for (i = 0; i < pol->num_ops; i ++)
+        if (pol->ops[i]->op == CUPS_GET_DOCUMENT)
+	  break;
+
+      if (i >= pol->num_ops)
+      {
+	for (i = 0; i < pol->num_ops; i ++)
+	  if (pol->ops[i]->op == IPP_SEND_DOCUMENT)
+            break;
+
+        if (i < pol->num_ops)
+	{
+	 /*
+	  * Add a new limit for CUPS-Get-Document using the Send-Document
+	  * limit as a template...
+	  */
+
+          cupsdLogMessage(CUPSD_LOG_WARN,
+	                  "No limit for CUPS-Get-Document defined in policy %s "
+			  "- using Send-Document's policy", pol->name);
+
+          cupsdAddPolicyOp(pol, pol->ops[i], CUPS_GET_DOCUMENT);
+	}
+      }
+
       return (linenum);
     }
     else if (!strcasecmp(line, "<Limit") && !op)
Index: scheduler/ipp.c
===================================================================
--- scheduler/ipp.c	(revision 6878)
+++ scheduler/ipp.c	(revision 6879)
@@ -54,6 +54,7 @@
  *   get_default()               - Get the default destination.
  *   get_devices()               - Get the list of available devices on the
  *                                 local system.
+ *   get_document()              - Get a copy of a job file.
  *   get_job_attrs()             - Get job attributes.
  *   get_jobs()                  - Get a list of jobs for the specified printer.
  *   get_notifications()         - Get events for a subscription.
@@ -169,6 +170,7 @@
 static void	delete_printer(cupsd_client_t *con, ipp_attribute_t *uri);
 static void	get_default(cupsd_client_t *con);
 static void	get_devices(cupsd_client_t *con);
+static void	get_document(cupsd_client_t *con, ipp_attribute_t *uri);
 static void	get_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
 static void	get_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
 static void	get_notifications(cupsd_client_t *con);
@@ -575,6 +577,10 @@
               get_devices(con);
               break;
 
+          case CUPS_GET_DOCUMENT :
+	      get_document(con, uri);
+	      break;
+
 	  case CUPS_GET_PPD :
               get_ppd(con, uri);
               break;
@@ -4535,6 +4541,10 @@
                    con->servername, con->serverport, "/jobs/%d",
         	   job->id);
 
+  if (!ra || cupsArrayFind(ra, "document-count"))
+    ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
+        	  "document-count", job->num_files);
+
   if (!ra || cupsArrayFind(ra, "job-more-info"))
     ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
         	 "job-more-info", NULL, job_uri);
@@ -5608,6 +5618,150 @@
 
 
 /*
+ * 'get_document()' - Get a copy of a job file.
+ */
+
+static void
+get_document(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 */
+  int		jobid;			/* Job ID */
+  int		docnum;			/* Document number */
+  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 */
+  char		filename[1024],		/* Filename for document */
+		format[1024];		/* Format for document */
+
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_document(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
+
+ /*
+  * See if we have a job URI or a printer URI...
+  */
+
+  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;
+    }
+
+    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;
+    }
+
+    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;
+  }
+
+ /*
+  * Check policy...
+  */
+
+  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+  {
+    send_http_error(con, status, NULL);
+    return;
+  }
+
+ /*
+  * Get the document number...
+  */
+
+  if ((attr = ippFindAttribute(con->request, "document-number",
+                               IPP_TAG_INTEGER)) == NULL)
+  {
+    send_ipp_status(con, IPP_BAD_REQUEST,
+                    _("Missing document-number attribute!"));
+    return;
+  }
+
+  if ((docnum = attr->values[0].integer) < 1 || docnum > job->num_files ||
+      attr->num_values > 1)
+  {
+    send_ipp_status(con, IPP_NOT_FOUND, _("Document %d not found in job %d."),
+                    docnum, jobid);
+    return;
+  }
+
+  snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, jobid,
+           docnum);
+  if ((con->file = open(filename, O_RDONLY)) == -1)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Unable to open document %d in job %d - %s", docnum, jobid,
+		    strerror(errno));
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("Unable to open document %d in job %d!"), docnum, jobid);
+    return;
+  }
+
+  fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
+
+  cupsdLoadJob(job);
+
+  snprintf(format, sizeof(format), "%s/%s", job->filetypes[docnum - 1]->super,
+           job->filetypes[docnum - 1]->type);
+
+  ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
+               NULL, format);
+  ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "document-number",
+                docnum);
+  if ((attr = ippFindAttribute(job->attrs, "document-name",
+                               IPP_TAG_NAME)) != NULL)
+    ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_NAME, "document-name",
+                 NULL, attr->values[0].string.text);
+}
+
+
+/*
  * 'get_job_attrs()' - Get job attributes.
  */
 
Index: scheduler/printers.c
===================================================================
--- scheduler/printers.c	(revision 6878)
+++ scheduler/printers.c	(revision 6879)
@@ -321,6 +321,8 @@
 		  CUPS_GET_PPDS,
 		  CUPS_MOVE_JOB,
 		  CUPS_AUTHENTICATE_JOB,
+		  CUPS_GET_PPD,
+		  CUPS_GET_DOCUMENT,
 		  IPP_RESTART_JOB
 		};
   static const char * const charsets[] =/* charset-supported values */
