]>
Commit | Line | Data |
---|---|---|
dcb445bc | 1 | /* |
61515785 | 2 | * "$Id: dest-job.c 4274 2013-04-09 20:10:23Z msweet $" |
dcb445bc MS |
3 | * |
4 | * Destination job support for CUPS. | |
5 | * | |
cb7f98ee | 6 | * Copyright 2012-2013 by Apple Inc. |
dcb445bc MS |
7 | * |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Apple Inc. and are protected by Federal copyright | |
10 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
11 | * which should have been included with this file. If this file is | |
12 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
13 | * | |
14 | * This file is subject to the Apple OS-Developed Software exception. | |
15 | * | |
16 | * Contents: | |
17 | * | |
a469f8a5 | 18 | * cupsCancelDestJob() - Cancel a job on a destination. |
dcb445bc MS |
19 | * cupsCloseDestJob() - Close a job and start printing. |
20 | * cupsCreateDestJob() - Create a job on a destination. | |
21 | * cupsFinishDestDocument() - Finish the current document. | |
22 | * cupsStartDestDocument() - Start a new document. | |
23 | */ | |
24 | ||
25 | /* | |
26 | * Include necessary headers... | |
27 | */ | |
28 | ||
29 | #include "cups-private.h" | |
30 | ||
31 | ||
32 | /* | |
33 | * 'cupsCancelDestJob()' - Cancel a job on a destination. | |
34 | * | |
35 | * The "job_id" is the number returned by cupsCreateDestJob. | |
36 | * | |
cb7f98ee | 37 | * Returns IPP_STATUS_OK on success and IPP_NOT_AUTHORIZED or IPP_FORBIDDEN on |
dcb445bc MS |
38 | * failure. |
39 | * | |
f3c17241 | 40 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
41 | */ |
42 | ||
43 | ipp_status_t | |
44 | cupsCancelDestJob(http_t *http, /* I - Connection to destination */ | |
45 | cups_dest_t *dest, /* I - Destination */ | |
46 | int job_id) /* I - Job ID */ | |
47 | { | |
cb7f98ee | 48 | return (IPP_STATUS_ERROR_NOT_FOUND); |
dcb445bc MS |
49 | } |
50 | ||
51 | ||
52 | /* | |
53 | * 'cupsCloseDestJob()' - Close a job and start printing. | |
54 | * | |
55 | * Use when the last call to cupsStartDocument passed 0 for "last_document". | |
cb7f98ee | 56 | * "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_STATUS_OK@ |
82cc1f9a | 57 | * on success. |
dcb445bc | 58 | * |
f3c17241 | 59 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
60 | */ |
61 | ||
82cc1f9a | 62 | ipp_status_t /* O - IPP status code */ |
dcb445bc | 63 | cupsCloseDestJob( |
82cc1f9a MS |
64 | http_t *http, /* I - Connection to destination */ |
65 | cups_dest_t *dest, /* I - Destination */ | |
66 | cups_dinfo_t *info, /* I - Destination information */ | |
67 | int job_id) /* I - Job ID */ | |
dcb445bc | 68 | { |
82cc1f9a MS |
69 | int i; /* Looping var */ |
70 | ipp_t *request = NULL;/* Close-Job/Send-Document request */ | |
71 | ipp_attribute_t *attr; /* operations-supported attribute */ | |
72 | ||
73 | ||
74 | DEBUG_printf(("cupsCloseDestJob(http=%p, dest=%p(%s/%s), info=%p, job_id=%d)", | |
75 | http, dest, dest ? dest->name : NULL, | |
76 | dest ? dest->instance : NULL, info, job_id)); | |
77 | ||
78 | /* | |
79 | * Range check input... | |
80 | */ | |
81 | ||
82 | if (!http || !dest || !info || job_id <= 0) | |
83 | { | |
cb7f98ee | 84 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); |
82cc1f9a | 85 | DEBUG_puts("1cupsCloseDestJob: Bad arguments."); |
cb7f98ee | 86 | return (IPP_STATUS_ERROR_INTERNAL); |
82cc1f9a MS |
87 | } |
88 | ||
89 | /* | |
90 | * Build a Close-Job or empty Send-Document request... | |
91 | */ | |
92 | ||
93 | if ((attr = ippFindAttribute(info->attrs, "operations-supported", | |
94 | IPP_TAG_ENUM)) != NULL) | |
95 | { | |
96 | for (i = 0; i < attr->num_values; i ++) | |
cb7f98ee | 97 | if (attr->values[i].integer == IPP_OP_CLOSE_JOB) |
82cc1f9a | 98 | { |
cb7f98ee | 99 | request = ippNewRequest(IPP_OP_CLOSE_JOB); |
82cc1f9a MS |
100 | break; |
101 | } | |
102 | } | |
103 | ||
104 | if (!request) | |
cb7f98ee | 105 | request = ippNewRequest(IPP_OP_SEND_DOCUMENT); |
82cc1f9a MS |
106 | |
107 | if (!request) | |
108 | { | |
cb7f98ee | 109 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); |
82cc1f9a MS |
110 | DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document " |
111 | "request."); | |
cb7f98ee | 112 | return (IPP_STATUS_ERROR_INTERNAL); |
82cc1f9a MS |
113 | } |
114 | ||
6961465f MS |
115 | ippSetVersion(request, info->version / 10, info->version % 10); |
116 | ||
82cc1f9a MS |
117 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", |
118 | NULL, info->uri); | |
119 | ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", | |
120 | job_id); | |
121 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
122 | NULL, cupsUser()); | |
cb7f98ee | 123 | if (ippGetOperation(request) == IPP_OP_SEND_DOCUMENT) |
82cc1f9a MS |
124 | ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); |
125 | ||
126 | /* | |
127 | * Send the request and return the status... | |
128 | */ | |
129 | ||
130 | ippDelete(cupsDoRequest(http, request, info->resource)); | |
131 | ||
132 | DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()), | |
133 | cupsLastErrorString())); | |
134 | ||
135 | return (cupsLastError()); | |
dcb445bc MS |
136 | } |
137 | ||
138 | ||
139 | /* | |
140 | * 'cupsCreateDestJob()' - Create a job on a destination. | |
141 | * | |
cb7f98ee | 142 | * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success, saving the job ID |
82cc1f9a | 143 | * in the variable pointed to by "job_id". |
dcb445bc | 144 | * |
f3c17241 | 145 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
146 | */ |
147 | ||
148 | ipp_status_t /* O - IPP status code */ | |
149 | cupsCreateDestJob( | |
150 | http_t *http, /* I - Connection to destination */ | |
151 | cups_dest_t *dest, /* I - Destination */ | |
152 | cups_dinfo_t *info, /* I - Destination information */ | |
153 | int *job_id, /* O - Job ID or 0 on error */ | |
154 | const char *title, /* I - Job name */ | |
155 | int num_options, /* I - Number of job options */ | |
156 | cups_option_t *options) /* I - Job options */ | |
157 | { | |
82cc1f9a MS |
158 | ipp_t *request, /* Create-Job request */ |
159 | *response; /* Create-Job response */ | |
160 | ipp_attribute_t *attr; /* job-id attribute */ | |
161 | ||
162 | ||
163 | DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, " | |
164 | "job_id=%p, title=\"%s\", num_options=%d, options=%p)", | |
165 | http, dest, dest ? dest->name : NULL, | |
166 | dest ? dest->instance : NULL, info, job_id, title, num_options, | |
167 | options)); | |
168 | ||
169 | /* | |
170 | * Range check input... | |
171 | */ | |
172 | ||
173 | if (job_id) | |
174 | *job_id = 0; | |
175 | ||
176 | if (!http || !dest || !info || !job_id) | |
177 | { | |
cb7f98ee | 178 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); |
82cc1f9a | 179 | DEBUG_puts("1cupsCreateDestJob: Bad arguments."); |
cb7f98ee | 180 | return (IPP_STATUS_ERROR_INTERNAL); |
82cc1f9a MS |
181 | } |
182 | ||
183 | /* | |
184 | * Build a Create-Job request... | |
185 | */ | |
186 | ||
cb7f98ee | 187 | if ((request = ippNewRequest(IPP_OP_CREATE_JOB)) == NULL) |
82cc1f9a | 188 | { |
cb7f98ee | 189 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); |
82cc1f9a | 190 | DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request."); |
cb7f98ee | 191 | return (IPP_STATUS_ERROR_INTERNAL); |
82cc1f9a MS |
192 | } |
193 | ||
6961465f MS |
194 | ippSetVersion(request, info->version / 10, info->version % 10); |
195 | ||
82cc1f9a MS |
196 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", |
197 | NULL, info->uri); | |
198 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
199 | NULL, cupsUser()); | |
200 | if (title) | |
201 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, | |
202 | title); | |
a29fd7dd | 203 | |
a469f8a5 | 204 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); |
a29fd7dd MS |
205 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB); |
206 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION); | |
82cc1f9a MS |
207 | |
208 | /* | |
209 | * Send the request and get the job-id... | |
210 | */ | |
dcb445bc | 211 | |
82cc1f9a MS |
212 | response = cupsDoRequest(http, request, info->resource); |
213 | ||
214 | if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) | |
215 | { | |
216 | *job_id = attr->values[0].integer; | |
217 | DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id)); | |
218 | } | |
219 | ||
220 | ippDelete(response); | |
221 | ||
222 | /* | |
223 | * Return the status code from the Create-Job request... | |
224 | */ | |
225 | ||
226 | DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()), | |
227 | cupsLastErrorString())); | |
228 | ||
229 | return (cupsLastError()); | |
dcb445bc MS |
230 | } |
231 | ||
232 | ||
233 | /* | |
234 | * 'cupsFinishDestDocument()' - Finish the current document. | |
235 | * | |
cb7f98ee | 236 | * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success. |
dcb445bc | 237 | * |
f3c17241 | 238 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
239 | */ |
240 | ||
82cc1f9a | 241 | ipp_status_t /* O - Status of document submission */ |
dcb445bc | 242 | cupsFinishDestDocument( |
82cc1f9a MS |
243 | http_t *http, /* I - Connection to destination */ |
244 | cups_dest_t *dest, /* I - Destination */ | |
245 | cups_dinfo_t *info) /* I - Destination information */ | |
dcb445bc | 246 | { |
82cc1f9a MS |
247 | DEBUG_printf(("cupsFinishDestDocument(http=%p, dest=%p(%s/%s), info=%p)", |
248 | http, dest, dest ? dest->name : NULL, | |
249 | dest ? dest->instance : NULL, info)); | |
250 | ||
251 | /* | |
252 | * Range check input... | |
253 | */ | |
254 | ||
255 | if (!http || !dest || !info) | |
256 | { | |
cb7f98ee | 257 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); |
82cc1f9a | 258 | DEBUG_puts("1cupsFinishDestDocument: Bad arguments."); |
cb7f98ee | 259 | return (IPP_STATUS_ERROR_INTERNAL); |
82cc1f9a MS |
260 | } |
261 | ||
262 | /* | |
263 | * Get the response at the end of the document and return it... | |
264 | */ | |
265 | ||
266 | ippDelete(cupsGetResponse(http, info->resource)); | |
267 | ||
268 | DEBUG_printf(("1cupsFinishDestDocument: %s (%s)", | |
269 | ippErrorString(cupsLastError()), cupsLastErrorString())); | |
270 | ||
271 | return (cupsLastError()); | |
dcb445bc MS |
272 | } |
273 | ||
274 | ||
275 | /* | |
276 | * 'cupsStartDestDocument()' - Start a new document. | |
277 | * | |
278 | * "job_id" is the job ID returned by cupsCreateDestJob. "docname" is the name | |
279 | * of the document/file being printed, "format" is the MIME media type for the | |
280 | * document (see CUPS_FORMAT_xxx constants), and "num_options" and "options" | |
281 | * are the options do be applied to the document. "last_document" should be 1 | |
282 | * if this is the last document to be submitted in the job. Returns | |
82cc1f9a | 283 | * @code HTTP_CONTINUE@ on success. |
dcb445bc | 284 | * |
f3c17241 | 285 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
286 | */ |
287 | ||
82cc1f9a | 288 | http_status_t /* O - Status of document creation */ |
dcb445bc MS |
289 | cupsStartDestDocument( |
290 | http_t *http, /* I - Connection to destination */ | |
291 | cups_dest_t *dest, /* I - Destination */ | |
292 | cups_dinfo_t *info, /* I - Destination information */ | |
293 | int job_id, /* I - Job ID */ | |
294 | const char *docname, /* I - Document name */ | |
295 | const char *format, /* I - Document format */ | |
296 | int num_options, /* I - Number of document options */ | |
297 | cups_option_t *options, /* I - Document options */ | |
298 | int last_document) /* I - 1 if this is the last document */ | |
299 | { | |
82cc1f9a MS |
300 | ipp_t *request; /* Send-Document request */ |
301 | http_status_t status; /* HTTP status */ | |
302 | ||
303 | ||
304 | DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, " | |
305 | "job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, " | |
306 | "options=%p, last_document=%d)", | |
307 | http, dest, dest ? dest->name : NULL, | |
308 | dest ? dest->instance : NULL, info, job_id, docname, format, | |
309 | num_options, options, last_document)); | |
310 | ||
311 | /* | |
312 | * Range check input... | |
313 | */ | |
314 | ||
315 | if (!http || !dest || !info || job_id <= 0) | |
316 | { | |
cb7f98ee | 317 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); |
82cc1f9a | 318 | DEBUG_puts("1cupsStartDestDocument: Bad arguments."); |
cb7f98ee | 319 | return (HTTP_STATUS_ERROR); |
82cc1f9a MS |
320 | } |
321 | ||
322 | /* | |
323 | * Create a Send-Document request... | |
324 | */ | |
325 | ||
cb7f98ee | 326 | if ((request = ippNewRequest(IPP_OP_SEND_DOCUMENT)) == NULL) |
82cc1f9a | 327 | { |
cb7f98ee | 328 | _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); |
82cc1f9a MS |
329 | DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document " |
330 | "request."); | |
cb7f98ee | 331 | return (HTTP_STATUS_ERROR); |
82cc1f9a MS |
332 | } |
333 | ||
6961465f MS |
334 | ippSetVersion(request, info->version / 10, info->version % 10); |
335 | ||
82cc1f9a MS |
336 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", |
337 | NULL, info->uri); | |
338 | ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); | |
339 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
340 | NULL, cupsUser()); | |
341 | if (docname) | |
342 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", | |
343 | NULL, docname); | |
344 | if (format) | |
345 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, | |
346 | "document-format", NULL, format); | |
347 | ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document); | |
348 | ||
a469f8a5 | 349 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); |
82cc1f9a MS |
350 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_DOCUMENT); |
351 | ||
352 | /* | |
353 | * Send and delete the request, then return the status... | |
354 | */ | |
355 | ||
356 | status = cupsSendRequest(http, request, info->resource, CUPS_LENGTH_VARIABLE); | |
357 | ||
358 | ippDelete(request); | |
359 | ||
360 | return (status); | |
dcb445bc MS |
361 | } |
362 | ||
363 | ||
364 | /* | |
61515785 | 365 | * End of "$Id: dest-job.c 4274 2013-04-09 20:10:23Z msweet $". |
dcb445bc | 366 | */ |