]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
The scheduler now supports the Hold-New-Jobs and Release-Held-New-Jobs
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Fri, 10 Oct 2008 05:28:15 +0000 (05:28 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Fri, 10 Oct 2008 05:28:15 +0000 (05:28 +0000)
operations; these are exposed via the cupsdisable and cupsenable commands
(STR #2332)

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@8044 7a7537e8-13f0-0310-91df-b6672ffda945

CHANGES.txt
doc/help/whatsnew.html
man/cupsenable.man
scheduler/ipp.c
scheduler/job.c
scheduler/printers.c
scheduler/printers.h
systemv/cupsaccept.c

index ceffb881a8bb8bc49cdd4002529fae2cc72101e7..9377c2f53546b2e10019b76085c5ec9e29b891e6 100644 (file)
@@ -4,6 +4,9 @@ CHANGES.txt - 2008-10-09
 CHANGES IN CUPS V1.4b1
 
        - Documentation updates (STR #2567)
+       - The scheduler now supports the Hold-New-Jobs and
+         Release-Held-New-Jobs operations; these are exposed via the
+         cupsdisable and cupsenable commands (STR #2332)
        - The lpstat command is now much faster when displaying the
          status of a single printer (STR #2843)
        - The scheduler now caches information from PPD files to provide
index 8d9b1c0b57d30f0b601d6951d59574db37646165..db179ac7f1435f85c3793ea9164c2f87a280d796 100644 (file)
@@ -5,7 +5,7 @@
 </HEAD>
 <BODY>
 
-<P>CUPS 1.4 adds over 64 changes and new features to CUPS 1.3.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the <A HREF="overview.html">"Overview of CUPS"</A> document instead.</P>
+<P>CUPS 1.4 adds over 65 changes and new features to CUPS 1.3.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the <A HREF="overview.html">"Overview of CUPS"</A> document instead.</P>
 
 <H2 CLASS="title"><A NAME="COMMANDS">Commands</A></H2>
 
@@ -13,6 +13,8 @@
 
        <LI><EM>accept and reject;</EM> the accept and reject commands have been officially renamed to cupsaccess and cupsreject. The old names are still supported via symlinks.</LI>
 
+       <LI><EM>cupsdisable and cupsenable;</EM> the cupsdisable command now supports a --hold option to stop printing after the current job and the cupsenable command now supports a --release option to release pending jobs for printing.</LI>
+
        <LI><EM>cupsfilter;</EM> the cupsfilter program now supports filtering of already-queued print job files and can also run printer-specific filters specified in the PPD file.</LI>
 
        <LI><EM>cupstestdsc;</EM> the cupstestdsc utility has been improved to better detect problems with PostScript print files.</LI>
@@ -32,7 +34,7 @@
 
 <H2 CLASS="title"><A NAME="WEBIF">Web Interface</A></H2>
 
-<OL START="9">
+<OL START="10">
 
        <LI><EM>Look-n-feel;</EM> the web interface has been given a new look.</LI>
 
@@ -53,7 +55,7 @@
 
 <H2 CLASS="title"><A NAME="NETWORKING">Networking</A></H2>
 
-<OL START="16">
+<OL START="17">
 
        <LI><EM>Bonjour (DNS-SD) printing support;</EM> a new mdns backend provides Bonjour-based printer discovery and the ipp, lpd, and socket backends now support Bonjour address resolution.</LI>
 
@@ -72,7 +74,7 @@
 
 <H2 CLASS="title"><A NAME="IPP">IPP Support</A></H2>
 
-<OL START="22">
+<OL START="23">
 
        <LI><EM>CUPS-Add-Modify-Printer operation;</EM> the scheduler now supports setting the printer-state-reasons attribute using this operation.</LI>
 
@@ -87,7 +89,7 @@
 
 <H2 CLASS="title"><A NAME="SCHEDULER">Scheduler</A></H2>
 
-<OL START="26">
+<OL START="27">
 
        <LI><EM>Access control;</EM> the scheduler now supports multiple addresses in Allow and Deny lines. It also now returns a HTTP 403 (forbidden) status when a user authenticates successfully but is not allowed to perform an operation.</LI>
 
 
 <H2 CLASS="title"><A NAME="DRIVERS">Printer Drivers</A></H2>
 
-<OL START="47">
+<OL START="48">
 
        <LI><EM>Device discovery;</EM> the cups-deviced helper now runs backends in parallel for faster discovery and streams the results of discovery as the backends provide them.</LI>
 
 
 <H2 CLASS="title"><A NAME="FILTERS">Print Filters</A></H2>
 
-<OL START="56">
+<OL START="57">
 
        <LI><EM>Banner filter;</EM> the bundled banner ("job-sheets") pages are now generated using a new banner filter provides easier customization and better support for UTF-8 text.</LI>
 
 
 <H2 CLASS="title"><A NAME="CUPSAPI">CUPS API</A></H2>
 
-<OL START="59">
+<OL START="60">
 
        <LI><EM>Backend API;</EM> a new cupsBackendReport function is provided to report a device from a backend and handles any needed quoting of the make-and-model, info, device-id, and location strings.</LI>
 
index 9231f993522ce3adb29c69c392cf12b5e023ff50..9c1315afb5b847713064648e67f5f2cde7ca5f34 100644 (file)
@@ -4,7 +4,7 @@
 .\"   cupsenable/cupsdisable man page for the Common UNIX Printing System
 .\"   (CUPS).
 .\"
-.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 2007-2008 by Apple Inc.
 .\"   Copyright 1997-2006 by Easy Software Products.
 .\"
 .\"   These coded instructions, statements, and computer programs are the
@@ -13,7 +13,7 @@
 .\"   which should have been included with this file.  If this file is
 .\"   file is missing or damaged, see the license at "http://www.cups.org/".
 .\"
-.TH cupsenable 8 "Common UNIX Printing System" "12 February 2006" "Apple Inc."
+.TH cupsenable 8 "Common UNIX Printing System" "9 October 2008" "Apple Inc."
 .SH NAME
 cupsdisable, cupsenable \- stop/start printers and classes
 .SH SYNOPSIS
@@ -24,14 +24,14 @@ cupsdisable, cupsenable \- stop/start printers and classes
 .I server[:port]
 ] [ -r
 .I reason
-] destination(s)
+] [ --hold ] destination(s)
 .br
 .B cupsenable
 [ -E ] [-U
 .I username
 ] [ -c ] [ -h
 .I server[:port]
-] destination(s)
+] [ --release ] destination(s)
 .SH DESCRIPTION
 \fIcupsenable\fR starts the named printers or classes.
 .LP
@@ -54,10 +54,20 @@ Cancels all jobs on the named destination.
 .br
 Uses the specified server and port.
 .TP 5
+--hold
+.br
+Holds remaining jobs on the named printer.  Useful for allowing the current
+job to complete before performing maintenance.
+.TP 5
 -r "reason"
 .br
 Sets the message associated with the stopped state. If no reason is specified
 then the message is set to "Reason Unknown".
+.TP 5
+--release
+.br
+Releases pending jobs for printing. Use after running \fIcupsdisable\fR with
+the \fI--hold\fR option to resume printing.
 .SH COMPATIBILITY
 Unlike the System V printing system, CUPS allows printer names to
 contain any printable character except SPACE, TAB, "/", or "#".
@@ -65,19 +75,19 @@ Also, printer and class names are \fInot\fR case-sensitive.
 .LP
 The System V versions of these commands are \fIdisable\fR and
 \fIenable\fR. They have been renamed to avoid conflicts with the
-\fIbash(1)\fR build-in command of the same name.
+\fIbash(1)\fR build-in commands of the same name.
 .LP
 The CUPS versions of \fIdisable\fR and \fIenable\fR may ask the
 user for an access password depending on the printing system
 configuration.  This differs from the System V versions which
 require the root user to execute these commands.
 .SH SEE ALSO
-\fIaccept(8)\fR, \fIcancel(1)\fR, \fIlp(1)\fR, \fIlpadmin(8)\fR,
-\fIlpstat(1)\fR,
+\fIcupsaccept(8)\fR, \fIcupsreject(8)\fR, \fIcancel(1)\fR, \fIlp(1)\fR,
+\fIlpadmin(8)\fR, \fIlpstat(1)\fR,
 .br
 http://localhost:631/help
 .SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
 
 .\"
 .\" End of "$Id$".
index 580e8428ed21ed0f5e2e5238f3c91838855d4907..bfc3ab2f9918adf442b930a1937107f2abc6c522 100644 (file)
@@ -197,12 +197,15 @@ static void       get_subscription_attrs(cupsd_client_t *con, int sub_id);
 static void    get_subscriptions(cupsd_client_t *con, ipp_attribute_t *uri);
 static const char *get_username(cupsd_client_t *con);
 static void    hold_job(cupsd_client_t *con, ipp_attribute_t *uri);
+static void    hold_new_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    move_job(cupsd_client_t *con, ipp_attribute_t *uri);
 static int     ppd_parse_line(const char *line, char *option, int olen,
                               char *choice, int clen);
 static void    print_job(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    read_job_ticket(cupsd_client_t *con);
 static void    reject_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
+static void    release_held_new_jobs(cupsd_client_t *con,
+                                     ipp_attribute_t *uri);
 static void    release_job(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    renew_subscription(cupsd_client_t *con, int sub_id);
 static void    restart_job(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -564,6 +567,14 @@ cupsdProcessIPPRequest(
               set_job_attrs(con, uri);
               break;
 
+         case IPP_HOLD_NEW_JOBS :
+              hold_new_jobs(con, uri);
+              break;
+
+         case IPP_RELEASE_HELD_NEW_JOBS :
+              release_held_new_jobs(con, uri);
+              break;
+
          case CUPS_GET_DEFAULT :
               get_default(con);
               break;
@@ -898,7 +909,7 @@ add_class(cupsd_client_t  *con,             /* I - Client connection */
 {
   http_status_t        status;                 /* Policy status */
   int          i;                      /* Looping var */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+  char         scheme[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 */
@@ -919,8 +930,8 @@ add_class(cupsd_client_t  *con,             /* I - Client connection */
   * Do we have a valid URI?
   */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method,
-                  sizeof(method), username, sizeof(username), host,
+  httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                  sizeof(scheme), username, sizeof(username), host,
                  sizeof(host), &port, resource, sizeof(resource));
 
 
@@ -3570,7 +3581,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
                        *auth_info;     /* auth-info attribute */
   int                  jobid;          /* Job ID */
   cupsd_job_t          *job;           /* Current job */
-  char                 method[HTTP_MAX_URI],
+  char                 scheme[HTTP_MAX_URI],
                                        /* Method portion of URI */
                        username[HTTP_MAX_URI],
                                        /* Username portion of URI */
@@ -3616,8 +3627,8 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -6503,7 +6514,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
   int          jobid;                  /* Job ID */
   int          docnum;                 /* Document number */
   cupsd_job_t  *job;                   /* Current job */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+  char         scheme[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 */
@@ -6541,8 +6552,8 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -6646,7 +6657,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
   ipp_attribute_t *attr;               /* Current attribute */
   int          jobid;                  /* Job ID */
   cupsd_job_t  *job;                   /* Current job */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+  char         scheme[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 */
@@ -6683,8 +6694,8 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -7827,7 +7838,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
   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 */
+  char         scheme[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 */
@@ -7864,8 +7875,8 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -7960,6 +7971,73 @@ hold_job(cupsd_client_t  *con,           /* I - Client connection */
 }
 
 
+/*
+ * 'hold_new_jobs()' - Hold pending/new jobs on a printer or class.
+ */
+
+static void
+hold_new_jobs(cupsd_client_t  *con,    /* I - Connection */
+              ipp_attribute_t *uri)    /* I - Printer URI */
+{
+  http_status_t                status;         /* Policy status */
+  cups_ptype_t         dtype;          /* Destination type (printer/class) */
+  cupsd_printer_t      *printer;       /* Printer data */
+
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_new_jobs(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
+
+ /*
+  * Is the destination valid?
+  */
+
+  if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer))
+  {
+   /*
+    * 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, printer);
+    return;
+  }
+
+ /*
+  * Hold pending/new jobs sent to the printer...
+  */
+
+  printer->holding_new_jobs = 1;
+
+  cupsdSetPrinterReasons(printer, "+hold-new-jobs");
+  cupsdAddPrinterHistory(printer);
+
+  if (dtype & CUPS_PRINTER_CLASS)
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Class \"%s\" now holding pending/new jobs (\"%s\").",
+                    printer->name, get_username(con));
+  else
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Printer \"%s\" now holding pending/new jobs (\"%s\").",
+                    printer->name, get_username(con));
+
+ /*
+  * Everything was ok, so return OK status...
+  */
+
+  con->response->request.status.status_code = IPP_OK;
+}
+
+
 /*
  * 'move_job()' - Move a job to a new destination.
  */
@@ -8806,6 +8884,74 @@ reject_jobs(cupsd_client_t  *con,        /* I - Client connection */
 }
 
 
+/*
+ * 'release_held_new_jobs()' - Release pending/new jobs on a printer or class.
+ */
+
+static void
+release_held_new_jobs(
+    cupsd_client_t  *con,              /* I - Connection */
+    ipp_attribute_t *uri)              /* I - Printer URI */
+{
+  http_status_t                status;         /* Policy status */
+  cups_ptype_t         dtype;          /* Destination type (printer/class) */
+  cupsd_printer_t      *printer;       /* Printer data */
+
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_held_new_jobs(%p[%d], %s)", con,
+                  con->http.fd, uri->values[0].string.text);
+
+ /*
+  * Is the destination valid?
+  */
+
+  if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer))
+  {
+   /*
+    * 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, printer);
+    return;
+  }
+
+ /*
+  * Hold pending/new jobs sent to the printer...
+  */
+
+  printer->holding_new_jobs = 0;
+
+  cupsdSetPrinterReasons(printer, "-hold-new-jobs");
+  cupsdAddPrinterHistory(printer);
+
+  if (dtype & CUPS_PRINTER_CLASS)
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Class \"%s\" now printing pending/new jobs (\"%s\").",
+                    printer->name, get_username(con));
+  else
+    cupsdLogMessage(CUPSD_LOG_INFO,
+                    "Printer \"%s\" now printing pending/new jobs (\"%s\").",
+                    printer->name, get_username(con));
+
+ /*
+  * Everything was ok, so return OK status...
+  */
+
+  con->response->request.status.status_code = IPP_OK;
+}
+
+
 /*
  * 'release_job()' - Release a held print job.
  */
@@ -8816,7 +8962,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
 {
   ipp_attribute_t *attr;               /* Current attribute */
   int          jobid;                  /* Job ID */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+  char         scheme[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 */
@@ -8853,8 +8999,8 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -9041,7 +9187,7 @@ restart_job(cupsd_client_t  *con, /* I - Client connection */
 {
   ipp_attribute_t *attr;               /* Current attribute */
   int          jobid;                  /* Job ID */
-  char         method[HTTP_MAX_URI],   /* Method portion of URI */
+  char         scheme[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 */
@@ -9078,8 +9224,8 @@ restart_job(cupsd_client_t  *con, /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -9442,7 +9588,7 @@ send_document(cupsd_client_t  *con,       /* I - Client connection */
   cupsd_job_t          *job;           /* Current job */
   char                 job_uri[HTTP_MAX_URI],
                                        /* Job URI */
-                       method[HTTP_MAX_URI],
+                       scheme[HTTP_MAX_URI],
                                        /* Method portion of URI */
                        username[HTTP_MAX_URI],
                                        /* Username portion of URI */
@@ -9495,8 +9641,8 @@ send_document(cupsd_client_t  *con,       /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
@@ -10022,7 +10168,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
                        *attr2;         /* Job attribute */
   int                  jobid;          /* Job ID */
   cupsd_job_t          *job;           /* Current job */
-  char                 method[HTTP_MAX_URI],
+  char                 scheme[HTTP_MAX_URI],
                                        /* Method portion of URI */
                        username[HTTP_MAX_URI],
                                        /* Username portion of URI */
@@ -10070,8 +10216,8 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
     * 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,
+    httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
+                    sizeof(scheme), username, sizeof(username), host,
                    sizeof(host), &port, resource, sizeof(resource));
 
     if (strncmp(resource, "/jobs/", 6))
index b80241b9972512a4200b472f43655c92b1d5acae..990eaa87b4c297f0c1131d230de99f3a1b5a6b54 100644 (file)
@@ -447,7 +447,7 @@ cupsdCheckJobs(void)
 
         cupsdCancelJob(job, 1, IPP_JOB_ABORTED);
       }
-      else if (printer)
+      else if (printer && !printer->holding_new_jobs)
       {
        /*
         * See if the printer is available or remote and not printing a job;
@@ -473,7 +473,7 @@ cupsdCheckJobs(void)
        }
 
         if ((!(printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is local */
-            printer->state == IPP_PRINTER_IDLE) ||     /* and idle */
+            printer->state == IPP_PRINTER_IDLE) ||     /* and idle, OR */
            ((printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is remote */
             !printer->job))                            /* and not printing */
         {
index b87d309f6610bd3d94ec22f744b567fa4dacb0dd..c4ccec34f8cb4e6383cb9200d204572fb45d41ef 100644 (file)
@@ -316,6 +316,8 @@ cupsdCreateCommonData(void)
                  IPP_GET_NOTIFICATIONS,
                  IPP_ENABLE_PRINTER,
                  IPP_DISABLE_PRINTER,
+                 IPP_HOLD_NEW_JOBS,
+                 IPP_RELEASE_HELD_NEW_JOBS,
                  CUPS_GET_DEFAULT,
                  CUPS_GET_PRINTERS,
                  CUPS_ADD_PRINTER,
index d038c282db38d0ea5f4a88cefcc4b89b047231a0..6fab77351c64dc23f1354600955cb598f33ee52a 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Printer definitions for the Common UNIX Printing System (CUPS) scheduler.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -47,6 +47,7 @@ typedef struct cupsd_printer_s
   cupsd_policy_t *op_policy_ptr;       /* Pointer to operation policy */
   int          shared;                 /* Shared? */
   int          accepting;              /* Accepting jobs? */
+  int          holding_new_jobs;       /* Holding new jobs for printing? */
   int          in_implicit_class;      /* In an implicit class? */
   ipp_pstate_t state;                  /* Printer state */
   char         state_message[1024];    /* Printer state message */
index 3c4f838cb1562bb104037dede1633105808a823f..d92f184330dc6a03528fe4b415cf810f057d9fa0 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * "$Id$"
  *
- *   "accept", "disable", "enable", and "reject" commands for the Common
- *   UNIX Printing System (CUPS).
+ *   "cupsaccept", "cupsdisable", "cupsenable", and "cupsreject" commands for
+ *   the Common UNIX Printing System (CUPS).
  *
  *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
@@ -38,13 +38,11 @@ int                                 /* O - Exit status */
 main(int  argc,                                /* I - Number of command-line arguments */
      char *argv[])                     /* I - Command-line arguments */
 {
-  http_t       *http;                  /* HTTP connection to server */
   int          i;                      /* Looping var */
   char         *command,               /* Command to do */
                uri[1024],              /* Printer URI */
                *reason;                /* Reason for reject/disable */
   ipp_t                *request;               /* IPP request */
-  ipp_t                *response;              /* IPP response */
   ipp_op_t     op;                     /* Operation */
   int          cancel;                 /* Cancel jobs? */
 
@@ -77,7 +75,6 @@ main(int  argc,                               /* I - Number of command-line arguments */
     return (1);
   }
 
-  http   = NULL;
   reason = NULL;
 
  /*
@@ -86,14 +83,12 @@ main(int  argc,                             /* I - Number of command-line arguments */
 
   for (i = 1; i < argc; i ++)
     if (argv[i][0] == '-')
+    {
       switch (argv[i][1])
       {
         case 'E' : /* Encrypt */
 #ifdef HAVE_SSL
            cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
-
-           if (http)
-             httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
 #else
             _cupsLangPrintf(stderr,
                            _("%s: Sorry, no encryption support compiled in!\n"),
@@ -125,12 +120,6 @@ main(int  argc,                            /* I - Number of command-line arguments */
            break;
 
         case 'h' : /* Connect to host */
-           if (http)
-           {
-             httpClose(http);
-             http = NULL;
-           }
-
            if (argv[i][2] != '\0')
              cupsSetServer(argv[i] + 2);
            else
@@ -168,38 +157,31 @@ main(int  argc,                           /* I - Number of command-line arguments */
            }
            break;
 
+        case '-' :
+           if (!strcmp(argv[i], "--hold"))
+             op = IPP_HOLD_NEW_JOBS;
+           else if (!strcmp(argv[i], "--release"))
+             op = IPP_RELEASE_HELD_NEW_JOBS;
+           else
+           {
+             _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%s\'!\n"),
+                             command, argv[i]);
+             return (1);
+           }
+           break;
+
        default :
            _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"),
                            command, argv[i][1]);
            return (1);
       }
+    }
     else
     {
      /*
       * Accept/disable/enable/reject a destination...
       */
 
-      if (http == NULL)
-        http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-
-      if (http == NULL)
-      {
-       _cupsLangPrintf(stderr,
-                       _("%s: Unable to connect to server: %s\n"),
-                       command, strerror(errno));
-       return (1);
-      }
-
-     /*
-      * Build an IPP request, which requires the following
-      * attributes:
-      *
-      *    attributes-charset
-      *    attributes-natural-language
-      *    printer-uri
-      *    printer-state-message [optional]
-      */
-
       request = ippNewRequest(op);
 
       httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
@@ -218,21 +200,13 @@ main(int  argc,                           /* I - Number of command-line arguments */
       * Do the request and get back a response...
       */
 
-      if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
-      {
-        if (response->request.status.status_code > IPP_OK_CONFLICT)
-       {
-          _cupsLangPrintf(stderr,
-                         _("%s: Operation failed: %s\n"),
-                         command, ippErrorString(cupsLastError()));
-         return (1);
-       }
-       
-        ippDelete(response);
-      }
-      else
+      ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/"));
+
+      if (cupsLastError() > IPP_OK_CONFLICT)
       {
-        _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString());
+       _cupsLangPrintf(stderr,
+                       _("%s: Operation failed: %s\n"),
+                       command, ippErrorString(cupsLastError()));
        return (1);
       }
 
@@ -256,27 +230,16 @@ main(int  argc,                           /* I - Number of command-line arguments */
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
                      "printer-uri", NULL, uri);
 
-       if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
-       {
-          if (response->request.status.status_code > IPP_OK_CONFLICT)
-         {
-            _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString());
-           return (1);
-         }
+       ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/"));
 
-          ippDelete(response);
-       }
-       else
+        if (cupsLastError() > IPP_OK_CONFLICT)
        {
-          _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString());
+         _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString());
          return (1);
        }
       }
     }
 
-  if (http != NULL)
-    httpClose(http);
-
   return (0);
 }