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"
14 #include "debug-internal.h"
18 * 'cupsCancelDestJob()' - Cancel a job on a destination.
20 * The "job_id" is the number returned by cupsCreateDestJob.
22 * Returns @code IPP_STATUS_OK@ on success and
23 * @code IPP_STATUS_ERROR_NOT_AUTHORIZED@ or
24 * @code IPP_STATUS_ERROR_FORBIDDEN@ on failure.
26 * @since CUPS 1.6/macOS 10.8@
29 ipp_status_t
/* O - Status of cancel operation */
30 cupsCancelDestJob(http_t
*http
, /* I - Connection to destination */
31 cups_dest_t
*dest
, /* I - Destination */
32 int job_id
) /* I - Job ID */
34 cups_dinfo_t
*info
; /* Destination information */
37 if ((info
= cupsCopyDestInfo(http
, dest
)) != NULL
)
39 ipp_t
*request
; /* Cancel-Job request */
41 request
= ippNewRequest(IPP_OP_CANCEL_JOB
);
43 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
45 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri", NULL
, info
->uri
);
46 ippAddInteger(request
, IPP_TAG_OPERATION
, IPP_TAG_INTEGER
, "job-id", job_id
);
47 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name", NULL
, cupsUser());
49 ippDelete(cupsDoRequest(http
, request
, info
->resource
));
50 cupsFreeDestInfo(info
);
53 return (cupsLastError());
58 * 'cupsCloseDestJob()' - Close a job and start printing.
60 * Use when the last call to cupsStartDocument passed 0 for "last_document".
61 * "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_STATUS_OK@
64 * @since CUPS 1.6/macOS 10.8@
67 ipp_status_t
/* O - IPP status code */
69 http_t
*http
, /* I - Connection to destination */
70 cups_dest_t
*dest
, /* I - Destination */
71 cups_dinfo_t
*info
, /* I - Destination information */
72 int job_id
) /* I - Job ID */
74 int i
; /* Looping var */
75 ipp_t
*request
= NULL
;/* Close-Job/Send-Document request */
76 ipp_attribute_t
*attr
; /* operations-supported attribute */
79 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
));
82 * Get the default connection as needed...
86 http
= _cupsConnect();
89 * Range check input...
92 if (!http
|| !dest
|| !info
|| job_id
<= 0)
94 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
95 DEBUG_puts("1cupsCloseDestJob: Bad arguments.");
96 return (IPP_STATUS_ERROR_INTERNAL
);
100 * Build a Close-Job or empty Send-Document request...
103 if ((attr
= ippFindAttribute(info
->attrs
, "operations-supported",
104 IPP_TAG_ENUM
)) != NULL
)
106 for (i
= 0; i
< attr
->num_values
; i
++)
107 if (attr
->values
[i
].integer
== IPP_OP_CLOSE_JOB
)
109 request
= ippNewRequest(IPP_OP_CLOSE_JOB
);
115 request
= ippNewRequest(IPP_OP_SEND_DOCUMENT
);
119 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(ENOMEM
), 0);
120 DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document "
122 return (IPP_STATUS_ERROR_INTERNAL
);
125 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
127 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
129 ippAddInteger(request
, IPP_TAG_OPERATION
, IPP_TAG_INTEGER
, "job-id",
131 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
133 if (ippGetOperation(request
) == IPP_OP_SEND_DOCUMENT
)
134 ippAddBoolean(request
, IPP_TAG_OPERATION
, "last-document", 1);
137 * Send the request and return the status...
140 ippDelete(cupsDoRequest(http
, request
, info
->resource
));
142 DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()),
143 cupsLastErrorString()));
145 return (cupsLastError());
150 * 'cupsCreateDestJob()' - Create a job on a destination.
152 * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success, saving the job ID
153 * in the variable pointed to by "job_id".
155 * @since CUPS 1.6/macOS 10.8@
158 ipp_status_t
/* O - IPP status code */
160 http_t
*http
, /* I - Connection to destination */
161 cups_dest_t
*dest
, /* I - Destination */
162 cups_dinfo_t
*info
, /* I - Destination information */
163 int *job_id
, /* O - Job ID or 0 on error */
164 const char *title
, /* I - Job name */
165 int num_options
, /* I - Number of job options */
166 cups_option_t
*options
) /* I - Job options */
168 ipp_t
*request
, /* Create-Job request */
169 *response
; /* Create-Job response */
170 ipp_attribute_t
*attr
; /* job-id attribute */
173 DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, "
174 "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
));
177 * Get the default connection as needed...
181 http
= _cupsConnect();
184 * Range check input...
190 if (!http
|| !dest
|| !info
|| !job_id
)
192 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
193 DEBUG_puts("1cupsCreateDestJob: Bad arguments.");
194 return (IPP_STATUS_ERROR_INTERNAL
);
198 * Build a Create-Job request...
201 if ((request
= ippNewRequest(IPP_OP_CREATE_JOB
)) == NULL
)
203 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(ENOMEM
), 0);
204 DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request.");
205 return (IPP_STATUS_ERROR_INTERNAL
);
208 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
210 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
212 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
215 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "job-name", NULL
,
218 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_OPERATION
);
219 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_JOB
);
220 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_SUBSCRIPTION
);
223 * Send the request and get the job-id...
226 response
= cupsDoRequest(http
, request
, info
->resource
);
228 if ((attr
= ippFindAttribute(response
, "job-id", IPP_TAG_INTEGER
)) != NULL
)
230 *job_id
= attr
->values
[0].integer
;
231 DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id
));
237 * Return the status code from the Create-Job request...
240 DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()),
241 cupsLastErrorString()));
243 return (cupsLastError());
248 * 'cupsFinishDestDocument()' - Finish the current document.
250 * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success.
252 * @since CUPS 1.6/macOS 10.8@
255 ipp_status_t
/* O - Status of document submission */
256 cupsFinishDestDocument(
257 http_t
*http
, /* I - Connection to destination */
258 cups_dest_t
*dest
, /* I - Destination */
259 cups_dinfo_t
*info
) /* I - Destination information */
261 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
));
264 * Get the default connection as needed...
268 http
= _cupsConnect();
271 * Range check input...
274 if (!http
|| !dest
|| !info
)
276 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
277 DEBUG_puts("1cupsFinishDestDocument: Bad arguments.");
278 return (IPP_STATUS_ERROR_INTERNAL
);
282 * Get the response at the end of the document and return it...
285 ippDelete(cupsGetResponse(http
, info
->resource
));
287 DEBUG_printf(("1cupsFinishDestDocument: %s (%s)",
288 ippErrorString(cupsLastError()), cupsLastErrorString()));
290 return (cupsLastError());
295 * 'cupsStartDestDocument()' - Start a new document.
297 * "job_id" is the job ID returned by cupsCreateDestJob. "docname" is the name
298 * of the document/file being printed, "format" is the MIME media type for the
299 * document (see CUPS_FORMAT_xxx constants), and "num_options" and "options"
300 * are the options do be applied to the document. "last_document" should be 1
301 * if this is the last document to be submitted in the job. Returns
302 * @code HTTP_CONTINUE@ on success.
304 * @since CUPS 1.6/macOS 10.8@
307 http_status_t
/* O - Status of document creation */
308 cupsStartDestDocument(
309 http_t
*http
, /* I - Connection to destination */
310 cups_dest_t
*dest
, /* I - Destination */
311 cups_dinfo_t
*info
, /* I - Destination information */
312 int job_id
, /* I - Job ID */
313 const char *docname
, /* I - Document name */
314 const char *format
, /* I - Document format */
315 int num_options
, /* I - Number of document options */
316 cups_option_t
*options
, /* I - Document options */
317 int last_document
) /* I - 1 if this is the last document */
319 ipp_t
*request
; /* Send-Document request */
320 http_status_t status
; /* HTTP status */
323 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
));
326 * Get the default connection as needed...
330 http
= _cupsConnect();
333 * Range check input...
336 if (!http
|| !dest
|| !info
|| job_id
<= 0)
338 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(EINVAL
), 0);
339 DEBUG_puts("1cupsStartDestDocument: Bad arguments.");
340 return (HTTP_STATUS_ERROR
);
344 * Create a Send-Document request...
347 if ((request
= ippNewRequest(IPP_OP_SEND_DOCUMENT
)) == NULL
)
349 _cupsSetError(IPP_STATUS_ERROR_INTERNAL
, strerror(ENOMEM
), 0);
350 DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document "
352 return (HTTP_STATUS_ERROR
);
355 ippSetVersion(request
, info
->version
/ 10, info
->version
% 10);
357 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
359 ippAddInteger(request
, IPP_TAG_OPERATION
, IPP_TAG_INTEGER
, "job-id", job_id
);
360 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "requesting-user-name",
363 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
, "document-name",
366 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_MIMETYPE
,
367 "document-format", NULL
, format
);
368 ippAddBoolean(request
, IPP_TAG_OPERATION
, "last-document", (char)last_document
);
370 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_OPERATION
);
371 cupsEncodeOptions2(request
, num_options
, options
, IPP_TAG_DOCUMENT
);
374 * Send and delete the request, then return the status...
377 status
= cupsSendRequest(http
, request
, info
->resource
, CUPS_LENGTH_VARIABLE
);