]>
Commit | Line | Data |
---|---|---|
dcb445bc MS |
1 | /* |
2 | * "$Id$" | |
3 | * | |
4 | * Destination job support for CUPS. | |
5 | * | |
6 | * Copyright 2012 by Apple Inc. | |
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 | * | |
18 | * cupsCancelDestJob() - Cancel a job on a destination. | |
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 | * | |
37 | * Returns IPP_OK on success and IPP_NOT_AUTHORIZED or IPP_FORBIDDEN on | |
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 | { | |
48 | return (IPP_NOT_FOUND); | |
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". | |
82cc1f9a MS |
56 | * "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_OK@ |
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 | { | |
84 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); | |
85 | DEBUG_puts("1cupsCloseDestJob: Bad arguments."); | |
86 | return (IPP_INTERNAL_ERROR); | |
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 ++) | |
97 | if (attr->values[i].integer == IPP_CLOSE_JOB) | |
98 | { | |
99 | request = ippNewRequest(IPP_CLOSE_JOB); | |
100 | break; | |
101 | } | |
102 | } | |
103 | ||
104 | if (!request) | |
105 | request = ippNewRequest(IPP_SEND_DOCUMENT); | |
106 | ||
107 | if (!request) | |
108 | { | |
109 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); | |
110 | DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document " | |
111 | "request."); | |
112 | return (IPP_INTERNAL_ERROR); | |
113 | } | |
114 | ||
115 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", | |
116 | NULL, info->uri); | |
117 | ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", | |
118 | job_id); | |
119 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
120 | NULL, cupsUser()); | |
121 | if (ippGetOperation(request) == IPP_SEND_DOCUMENT) | |
122 | ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); | |
123 | ||
124 | /* | |
125 | * Send the request and return the status... | |
126 | */ | |
127 | ||
128 | ippDelete(cupsDoRequest(http, request, info->resource)); | |
129 | ||
130 | DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()), | |
131 | cupsLastErrorString())); | |
132 | ||
133 | return (cupsLastError()); | |
dcb445bc MS |
134 | } |
135 | ||
136 | ||
137 | /* | |
138 | * 'cupsCreateDestJob()' - Create a job on a destination. | |
139 | * | |
82cc1f9a MS |
140 | * Returns @code IPP_OK@ or @code IPP_OK_SUBST@ on success, saving the job ID |
141 | * in the variable pointed to by "job_id". | |
dcb445bc | 142 | * |
f3c17241 | 143 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
144 | */ |
145 | ||
146 | ipp_status_t /* O - IPP status code */ | |
147 | cupsCreateDestJob( | |
148 | http_t *http, /* I - Connection to destination */ | |
149 | cups_dest_t *dest, /* I - Destination */ | |
150 | cups_dinfo_t *info, /* I - Destination information */ | |
151 | int *job_id, /* O - Job ID or 0 on error */ | |
152 | const char *title, /* I - Job name */ | |
153 | int num_options, /* I - Number of job options */ | |
154 | cups_option_t *options) /* I - Job options */ | |
155 | { | |
82cc1f9a MS |
156 | ipp_t *request, /* Create-Job request */ |
157 | *response; /* Create-Job response */ | |
158 | ipp_attribute_t *attr; /* job-id attribute */ | |
159 | ||
160 | ||
161 | DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, " | |
162 | "job_id=%p, title=\"%s\", num_options=%d, options=%p)", | |
163 | http, dest, dest ? dest->name : NULL, | |
164 | dest ? dest->instance : NULL, info, job_id, title, num_options, | |
165 | options)); | |
166 | ||
167 | /* | |
168 | * Range check input... | |
169 | */ | |
170 | ||
171 | if (job_id) | |
172 | *job_id = 0; | |
173 | ||
174 | if (!http || !dest || !info || !job_id) | |
175 | { | |
176 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); | |
177 | DEBUG_puts("1cupsCreateDestJob: Bad arguments."); | |
178 | return (IPP_INTERNAL_ERROR); | |
179 | } | |
180 | ||
181 | /* | |
182 | * Build a Create-Job request... | |
183 | */ | |
184 | ||
185 | if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL) | |
186 | { | |
187 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); | |
188 | DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request."); | |
189 | return (IPP_INTERNAL_ERROR); | |
190 | } | |
191 | ||
192 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", | |
193 | NULL, info->uri); | |
194 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
195 | NULL, cupsUser()); | |
196 | if (title) | |
197 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, | |
198 | title); | |
a29fd7dd MS |
199 | |
200 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB); | |
201 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION); | |
82cc1f9a MS |
202 | |
203 | /* | |
204 | * Send the request and get the job-id... | |
205 | */ | |
dcb445bc | 206 | |
82cc1f9a MS |
207 | response = cupsDoRequest(http, request, info->resource); |
208 | ||
209 | if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) | |
210 | { | |
211 | *job_id = attr->values[0].integer; | |
212 | DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id)); | |
213 | } | |
214 | ||
215 | ippDelete(response); | |
216 | ||
217 | /* | |
218 | * Return the status code from the Create-Job request... | |
219 | */ | |
220 | ||
221 | DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()), | |
222 | cupsLastErrorString())); | |
223 | ||
224 | return (cupsLastError()); | |
dcb445bc MS |
225 | } |
226 | ||
227 | ||
228 | /* | |
229 | * 'cupsFinishDestDocument()' - Finish the current document. | |
230 | * | |
82cc1f9a | 231 | * Returns @code IPP_OK@ or @code IPP_OK_SUBST@ on success. |
dcb445bc | 232 | * |
f3c17241 | 233 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
234 | */ |
235 | ||
82cc1f9a | 236 | ipp_status_t /* O - Status of document submission */ |
dcb445bc | 237 | cupsFinishDestDocument( |
82cc1f9a MS |
238 | http_t *http, /* I - Connection to destination */ |
239 | cups_dest_t *dest, /* I - Destination */ | |
240 | cups_dinfo_t *info) /* I - Destination information */ | |
dcb445bc | 241 | { |
82cc1f9a MS |
242 | DEBUG_printf(("cupsFinishDestDocument(http=%p, dest=%p(%s/%s), info=%p)", |
243 | http, dest, dest ? dest->name : NULL, | |
244 | dest ? dest->instance : NULL, info)); | |
245 | ||
246 | /* | |
247 | * Range check input... | |
248 | */ | |
249 | ||
250 | if (!http || !dest || !info) | |
251 | { | |
252 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); | |
253 | DEBUG_puts("1cupsFinishDestDocument: Bad arguments."); | |
254 | return (IPP_INTERNAL_ERROR); | |
255 | } | |
256 | ||
257 | /* | |
258 | * Get the response at the end of the document and return it... | |
259 | */ | |
260 | ||
261 | ippDelete(cupsGetResponse(http, info->resource)); | |
262 | ||
263 | DEBUG_printf(("1cupsFinishDestDocument: %s (%s)", | |
264 | ippErrorString(cupsLastError()), cupsLastErrorString())); | |
265 | ||
266 | return (cupsLastError()); | |
dcb445bc MS |
267 | } |
268 | ||
269 | ||
270 | /* | |
271 | * 'cupsStartDestDocument()' - Start a new document. | |
272 | * | |
273 | * "job_id" is the job ID returned by cupsCreateDestJob. "docname" is the name | |
274 | * of the document/file being printed, "format" is the MIME media type for the | |
275 | * document (see CUPS_FORMAT_xxx constants), and "num_options" and "options" | |
276 | * are the options do be applied to the document. "last_document" should be 1 | |
277 | * if this is the last document to be submitted in the job. Returns | |
82cc1f9a | 278 | * @code HTTP_CONTINUE@ on success. |
dcb445bc | 279 | * |
f3c17241 | 280 | * @since CUPS 1.6/OS X 10.8@ |
dcb445bc MS |
281 | */ |
282 | ||
82cc1f9a | 283 | http_status_t /* O - Status of document creation */ |
dcb445bc MS |
284 | cupsStartDestDocument( |
285 | http_t *http, /* I - Connection to destination */ | |
286 | cups_dest_t *dest, /* I - Destination */ | |
287 | cups_dinfo_t *info, /* I - Destination information */ | |
288 | int job_id, /* I - Job ID */ | |
289 | const char *docname, /* I - Document name */ | |
290 | const char *format, /* I - Document format */ | |
291 | int num_options, /* I - Number of document options */ | |
292 | cups_option_t *options, /* I - Document options */ | |
293 | int last_document) /* I - 1 if this is the last document */ | |
294 | { | |
82cc1f9a MS |
295 | ipp_t *request; /* Send-Document request */ |
296 | http_status_t status; /* HTTP status */ | |
297 | ||
298 | ||
299 | DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, " | |
300 | "job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, " | |
301 | "options=%p, last_document=%d)", | |
302 | http, dest, dest ? dest->name : NULL, | |
303 | dest ? dest->instance : NULL, info, job_id, docname, format, | |
304 | num_options, options, last_document)); | |
305 | ||
306 | /* | |
307 | * Range check input... | |
308 | */ | |
309 | ||
310 | if (!http || !dest || !info || job_id <= 0) | |
311 | { | |
312 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); | |
313 | DEBUG_puts("1cupsStartDestDocument: Bad arguments."); | |
314 | return (HTTP_ERROR); | |
315 | } | |
316 | ||
317 | /* | |
318 | * Create a Send-Document request... | |
319 | */ | |
320 | ||
321 | if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL) | |
322 | { | |
323 | _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); | |
324 | DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document " | |
325 | "request."); | |
326 | return (HTTP_ERROR); | |
327 | } | |
328 | ||
329 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", | |
330 | NULL, info->uri); | |
331 | ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); | |
332 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
333 | NULL, cupsUser()); | |
334 | if (docname) | |
335 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", | |
336 | NULL, docname); | |
337 | if (format) | |
338 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, | |
339 | "document-format", NULL, format); | |
340 | ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document); | |
341 | ||
342 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_DOCUMENT); | |
343 | ||
344 | /* | |
345 | * Send and delete the request, then return the status... | |
346 | */ | |
347 | ||
348 | status = cupsSendRequest(http, request, info->resource, CUPS_LENGTH_VARIABLE); | |
349 | ||
350 | ippDelete(request); | |
351 | ||
352 | return (status); | |
dcb445bc MS |
353 | } |
354 | ||
355 | ||
356 | /* | |
357 | * End of "$Id$". | |
358 | */ |