2 * Destination job support for CUPS.
4 * Copyright 2012-2017 by Apple Inc.
6 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
10 * Include necessary headers...
13 #include "cups-private.h"
17 * 'cupsCancelDestJob()' - Cancel a job on a destination.
19 * The "job_id" is the number returned by cupsCreateDestJob.
21 * Returns @code IPP_STATUS_OK@ on success and
22 * @code IPP_STATUS_ERROR_NOT_AUTHORIZED@ or
23 * @code IPP_STATUS_ERROR_FORBIDDEN@ on failure.
25 * @since CUPS 1.6/macOS 10.8@
28 ipp_status_t
/* O - Status of cancel operation */
29 cupsCancelDestJob(http_t
*http
, /* I - Connection to destination */
30 cups_dest_t
*dest
, /* I - Destination */
31 int job_id
) /* I - Job ID */
33 cups_dinfo_t
*info
; /* Destination information */
36 if ((info
= cupsCopyDestInfo(http
, dest
)) != NULL
)
38 ipp_t
*request
; /* Cancel-Job request */
40 request
= ippNewRequest(IPP_OP_CANCEL_JOB
);
42 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
44 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri", NULL
, info
->uri
);
45 ippAddInteger(request
, IPP_TAG_OPERATION
, IPP_TAG_INTEGER
, "job-id", job_id
);
46 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name", NULL
, cupsUser());
48 ippDelete(cupsDoRequest(http
, request
, info
->resource
));
49 cupsFreeDestInfo(info
);
52 return (cupsLastError());
57 * 'cupsCloseDestJob()' - Close a job and start printing.
59 * Use when the last call to cupsStartDocument passed 0 for "last_document".
60 * "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_STATUS_OK@
63 * @since CUPS 1.6/macOS 10.8@
66 ipp_status_t
/* O - IPP status code */
68 http_t
*http
, /* I - Connection to destination */
69 cups_dest_t
*dest
, /* I - Destination */
70 cups_dinfo_t
*info
, /* I - Destination information */
71 int job_id
) /* I - Job ID */
73 int i
; /* Looping var */
74 ipp_t
*request
= NULL
;/* Close-Job/Send-Document request */
75 ipp_attribute_t
*attr
; /* operations-supported attribute */
78 DEBUG_printf(("cupsCloseDestJob(http=%p, dest=%p(%s/%s), info=%p, job_id=%d)", (void *)http
, (void *)dest
, dest
? dest
->name
: NULL
, dest
? dest
->instance
: NULL
, (void *)info
, job_id
));
81 * Get the default connection as needed...
85 http
= _cupsConnect();
88 * Range check input...
91 if (!http
|| !dest
|| !info
|| job_id
<= 0)
93 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
94 DEBUG_puts("1cupsCloseDestJob: Bad arguments.");
95 return (IPP_STATUS_ERROR_INTERNAL
);
99 * Build a Close-Job or empty Send-Document request...
102 if ((attr
= ippFindAttribute(info
->attrs
, "operations-supported",
103 IPP_TAG_ENUM
)) != NULL
)
105 for (i
= 0; i
< attr
->num_values
; i
++)
106 if (attr
->values
[i
].integer
== IPP_OP_CLOSE_JOB
)
108 request
= ippNewRequest(IPP_OP_CLOSE_JOB
);
114 request
= ippNewRequest(IPP_OP_SEND_DOCUMENT
);
118 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(ENOMEM
), 0);
119 DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document "
121 return (IPP_STATUS_ERROR_INTERNAL
);
124 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
126 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
128 ippAddInteger(request
, IPP_TAG_OPERATION
, IPP_TAG_INTEGER
, "job-id",
130 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
132 if (ippGetOperation(request
) == IPP_OP_SEND_DOCUMENT
)
133 ippAddBoolean(request
, IPP_TAG_OPERATION
, "last-document", 1);
136 * Send the request and return the status...
139 ippDelete(cupsDoRequest(http
, request
, info
->resource
));
141 DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()),
142 cupsLastErrorString()));
144 return (cupsLastError());
149 * 'cupsCreateDestJob()' - Create a job on a destination.
151 * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success, saving the job ID
152 * in the variable pointed to by "job_id".
154 * @since CUPS 1.6/macOS 10.8@
157 ipp_status_t
/* O - IPP status code */
159 http_t
*http
, /* I - Connection to destination */
160 cups_dest_t
*dest
, /* I - Destination */
161 cups_dinfo_t
*info
, /* I - Destination information */
162 int *job_id
, /* O - Job ID or 0 on error */
163 const char *title
, /* I - Job name */
164 int num_options
, /* I - Number of job options */
165 cups_option_t
*options
) /* I - Job options */
167 ipp_t
*request
, /* Create-Job request */
168 *response
; /* Create-Job response */
169 ipp_attribute_t
*attr
; /* job-id attribute */
172 DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, "
173 "job_id=%p, title=\"%s\", num_options=%d, options=%p)", (void *)http
, (void *)dest
, dest
? dest
->name
: NULL
, dest
? dest
->instance
: NULL
, (void *)info
, (void *)job_id
, title
, num_options
, (void *)options
));
176 * Get the default connection as needed...
180 http
= _cupsConnect();
183 * Range check input...
189 if (!http
|| !dest
|| !info
|| !job_id
)
191 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
192 DEBUG_puts("1cupsCreateDestJob: Bad arguments.");
193 return (IPP_STATUS_ERROR_INTERNAL
);
197 * Build a Create-Job request...
200 if ((request
= ippNewRequest(IPP_OP_CREATE_JOB
)) == NULL
)
202 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(ENOMEM
), 0);
203 DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request.");
204 return (IPP_STATUS_ERROR_INTERNAL
);
207 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
209 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
211 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
214 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "job-name", NULL
,
217 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_OPERATION
);
218 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_JOB
);
219 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_SUBSCRIPTION
);
222 * Send the request and get the job-id...
225 response
= cupsDoRequest(http
, request
, info
->resource
);
227 if ((attr
= ippFindAttribute(response
, "job-id", IPP_TAG_INTEGER
)) != NULL
)
229 *job_id
= attr
->values
[0].integer
;
230 DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id
));
236 * Return the status code from the Create-Job request...
239 DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()),
240 cupsLastErrorString()));
242 return (cupsLastError());
247 * 'cupsFinishDestDocument()' - Finish the current document.
249 * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success.
251 * @since CUPS 1.6/macOS 10.8@
254 ipp_status_t
/* O - Status of document submission */
255 cupsFinishDestDocument(
256 http_t
*http
, /* I - Connection to destination */
257 cups_dest_t
*dest
, /* I - Destination */
258 cups_dinfo_t
*info
) /* I - Destination information */
260 DEBUG_printf(("cupsFinishDestDocument(http=%p, dest=%p(%s/%s), info=%p)", (void *)http
, (void *)dest
, dest
? dest
->name
: NULL
, dest
? dest
->instance
: NULL
, (void *)info
));
263 * Get the default connection as needed...
267 http
= _cupsConnect();
270 * Range check input...
273 if (!http
|| !dest
|| !info
)
275 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
276 DEBUG_puts("1cupsFinishDestDocument: Bad arguments.");
277 return (IPP_STATUS_ERROR_INTERNAL
);
281 * Get the response at the end of the document and return it...
284 ippDelete(cupsGetResponse(http
, info
->resource
));
286 DEBUG_printf(("1cupsFinishDestDocument: %s (%s)",
287 ippErrorString(cupsLastError()), cupsLastErrorString()));
289 return (cupsLastError());
294 * 'cupsStartDestDocument()' - Start a new document.
296 * "job_id" is the job ID returned by cupsCreateDestJob. "docname" is the name
297 * of the document/file being printed, "format" is the MIME media type for the
298 * document (see CUPS_FORMAT_xxx constants), and "num_options" and "options"
299 * are the options do be applied to the document. "last_document" should be 1
300 * if this is the last document to be submitted in the job. Returns
301 * @code HTTP_CONTINUE@ on success.
303 * @since CUPS 1.6/macOS 10.8@
306 http_status_t
/* O - Status of document creation */
307 cupsStartDestDocument(
308 http_t
*http
, /* I - Connection to destination */
309 cups_dest_t
*dest
, /* I - Destination */
310 cups_dinfo_t
*info
, /* I - Destination information */
311 int job_id
, /* I - Job ID */
312 const char *docname
, /* I - Document name */
313 const char *format
, /* I - Document format */
314 int num_options
, /* I - Number of document options */
315 cups_option_t
*options
, /* I - Document options */
316 int last_document
) /* I - 1 if this is the last document */
318 ipp_t
*request
; /* Send-Document request */
319 http_status_t status
; /* HTTP status */
322 DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, options=%p, last_document=%d)", (void *)http
, (void *)dest
, dest
? dest
->name
: NULL
, dest
? dest
->instance
: NULL
, (void *)info
, job_id
, docname
, format
, num_options
, (void *)options
, last_document
));
325 * Get the default connection as needed...
329 http
= _cupsConnect();
332 * Range check input...
335 if (!http
|| !dest
|| !info
|| job_id
<= 0)
337 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
338 DEBUG_puts("1cupsStartDestDocument: Bad arguments.");
339 return (HTTP_STATUS_ERROR
);
343 * Create a Send-Document request...
346 if ((request
= ippNewRequest(IPP_OP_SEND_DOCUMENT
)) == NULL
)
348 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(ENOMEM
), 0);
349 DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document "
351 return (HTTP_STATUS_ERROR
);
354 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
356 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
358 ippAddInteger(request
, IPP_TAG_OPERATION
, IPP_TAG_INTEGER
, "job-id", job_id
);
359 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
362 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "document-name",
365 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_MIMETYPE
,
366 "document-format", NULL
, format
);
367 ippAddBoolean(request
, IPP_TAG_OPERATION
, "last-document", (char)last_document
);
369 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_OPERATION
);
370 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_DOCUMENT
);
373 * Send and delete the request, then return the status...
376 status
= cupsSendRequest(http
, request
, info
->resource
, CUPS_LENGTH_VARIABLE
);