]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/dest-job.c
Merge changes from CUPS 1.7b1-r10947.
[thirdparty/cups.git] / cups / dest-job.c
1 /*
2 * "$Id$"
3 *
4 * Destination job support for CUPS.
5 *
6 * Copyright 2012-2013 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_STATUS_OK on success and IPP_NOT_AUTHORIZED or IPP_FORBIDDEN on
38 * failure.
39 *
40 * @since CUPS 1.6/OS X 10.8@
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_STATUS_ERROR_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".
56 * "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_STATUS_OK@
57 * on success.
58 *
59 * @since CUPS 1.6/OS X 10.8@
60 */
61
62 ipp_status_t /* O - IPP status code */
63 cupsCloseDestJob(
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 */
68 {
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_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
85 DEBUG_puts("1cupsCloseDestJob: Bad arguments.");
86 return (IPP_STATUS_ERROR_INTERNAL);
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_OP_CLOSE_JOB)
98 {
99 request = ippNewRequest(IPP_OP_CLOSE_JOB);
100 break;
101 }
102 }
103
104 if (!request)
105 request = ippNewRequest(IPP_OP_SEND_DOCUMENT);
106
107 if (!request)
108 {
109 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
110 DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document "
111 "request.");
112 return (IPP_STATUS_ERROR_INTERNAL);
113 }
114
115 ippSetVersion(request, info->version / 10, info->version % 10);
116
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());
123 if (ippGetOperation(request) == IPP_OP_SEND_DOCUMENT)
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());
136 }
137
138
139 /*
140 * 'cupsCreateDestJob()' - Create a job on a destination.
141 *
142 * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success, saving the job ID
143 * in the variable pointed to by "job_id".
144 *
145 * @since CUPS 1.6/OS X 10.8@
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 {
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 {
178 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
179 DEBUG_puts("1cupsCreateDestJob: Bad arguments.");
180 return (IPP_STATUS_ERROR_INTERNAL);
181 }
182
183 /*
184 * Build a Create-Job request...
185 */
186
187 if ((request = ippNewRequest(IPP_OP_CREATE_JOB)) == NULL)
188 {
189 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
190 DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request.");
191 return (IPP_STATUS_ERROR_INTERNAL);
192 }
193
194 ippSetVersion(request, info->version / 10, info->version % 10);
195
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);
203
204 cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
205 cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB);
206 cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION);
207
208 /*
209 * Send the request and get the job-id...
210 */
211
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());
230 }
231
232
233 /*
234 * 'cupsFinishDestDocument()' - Finish the current document.
235 *
236 * Returns @code IPP_STATUS_OK@ or @code IPP_STATUS_OK_SUBST@ on success.
237 *
238 * @since CUPS 1.6/OS X 10.8@
239 */
240
241 ipp_status_t /* O - Status of document submission */
242 cupsFinishDestDocument(
243 http_t *http, /* I - Connection to destination */
244 cups_dest_t *dest, /* I - Destination */
245 cups_dinfo_t *info) /* I - Destination information */
246 {
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 {
257 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
258 DEBUG_puts("1cupsFinishDestDocument: Bad arguments.");
259 return (IPP_STATUS_ERROR_INTERNAL);
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());
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
283 * @code HTTP_CONTINUE@ on success.
284 *
285 * @since CUPS 1.6/OS X 10.8@
286 */
287
288 http_status_t /* O - Status of document creation */
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 {
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 {
317 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
318 DEBUG_puts("1cupsStartDestDocument: Bad arguments.");
319 return (HTTP_STATUS_ERROR);
320 }
321
322 /*
323 * Create a Send-Document request...
324 */
325
326 if ((request = ippNewRequest(IPP_OP_SEND_DOCUMENT)) == NULL)
327 {
328 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
329 DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document "
330 "request.");
331 return (HTTP_STATUS_ERROR);
332 }
333
334 ippSetVersion(request, info->version / 10, info->version % 10);
335
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
349 cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
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);
361 }
362
363
364 /*
365 * End of "$Id$".
366 */