]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/dest-job.c
Merge changes from CUPS 1.6svn-r10390.
[thirdparty/cups.git] / cups / dest-job.c
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 *
40 * @since CUPS 1.6@
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".
56 * "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_OK@
57 * on success.
58 *
59 * @since CUPS 1.6@
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_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());
134 }
135
136
137 /*
138 * 'cupsCreateDestJob()' - Create a job on a destination.
139 *
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".
142 *
143 * @since CUPS 1.6@
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 {
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);
199 cupsEncodeOptions(request, num_options, options);
200
201 /*
202 * Send the request and get the job-id...
203 */
204
205 response = cupsDoRequest(http, request, info->resource);
206
207 if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
208 {
209 *job_id = attr->values[0].integer;
210 DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id));
211 }
212
213 ippDelete(response);
214
215 /*
216 * Return the status code from the Create-Job request...
217 */
218
219 DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()),
220 cupsLastErrorString()));
221
222 return (cupsLastError());
223 }
224
225
226 /*
227 * 'cupsFinishDestDocument()' - Finish the current document.
228 *
229 * Returns @code IPP_OK@ or @code IPP_OK_SUBST@ on success.
230 *
231 * @since CUPS 1.6@
232 */
233
234 ipp_status_t /* O - Status of document submission */
235 cupsFinishDestDocument(
236 http_t *http, /* I - Connection to destination */
237 cups_dest_t *dest, /* I - Destination */
238 cups_dinfo_t *info) /* I - Destination information */
239 {
240 DEBUG_printf(("cupsFinishDestDocument(http=%p, dest=%p(%s/%s), info=%p)",
241 http, dest, dest ? dest->name : NULL,
242 dest ? dest->instance : NULL, info));
243
244 /*
245 * Range check input...
246 */
247
248 if (!http || !dest || !info)
249 {
250 _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
251 DEBUG_puts("1cupsFinishDestDocument: Bad arguments.");
252 return (IPP_INTERNAL_ERROR);
253 }
254
255 /*
256 * Get the response at the end of the document and return it...
257 */
258
259 ippDelete(cupsGetResponse(http, info->resource));
260
261 DEBUG_printf(("1cupsFinishDestDocument: %s (%s)",
262 ippErrorString(cupsLastError()), cupsLastErrorString()));
263
264 return (cupsLastError());
265 }
266
267
268 /*
269 * 'cupsStartDestDocument()' - Start a new document.
270 *
271 * "job_id" is the job ID returned by cupsCreateDestJob. "docname" is the name
272 * of the document/file being printed, "format" is the MIME media type for the
273 * document (see CUPS_FORMAT_xxx constants), and "num_options" and "options"
274 * are the options do be applied to the document. "last_document" should be 1
275 * if this is the last document to be submitted in the job. Returns
276 * @code HTTP_CONTINUE@ on success.
277 *
278 * @since CUPS 1.6@
279 */
280
281 http_status_t /* O - Status of document creation */
282 cupsStartDestDocument(
283 http_t *http, /* I - Connection to destination */
284 cups_dest_t *dest, /* I - Destination */
285 cups_dinfo_t *info, /* I - Destination information */
286 int job_id, /* I - Job ID */
287 const char *docname, /* I - Document name */
288 const char *format, /* I - Document format */
289 int num_options, /* I - Number of document options */
290 cups_option_t *options, /* I - Document options */
291 int last_document) /* I - 1 if this is the last document */
292 {
293 ipp_t *request; /* Send-Document request */
294 http_status_t status; /* HTTP status */
295
296
297 DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, "
298 "job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, "
299 "options=%p, last_document=%d)",
300 http, dest, dest ? dest->name : NULL,
301 dest ? dest->instance : NULL, info, job_id, docname, format,
302 num_options, options, last_document));
303
304 /*
305 * Range check input...
306 */
307
308 if (!http || !dest || !info || job_id <= 0)
309 {
310 _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
311 DEBUG_puts("1cupsStartDestDocument: Bad arguments.");
312 return (HTTP_ERROR);
313 }
314
315 /*
316 * Create a Send-Document request...
317 */
318
319 if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL)
320 {
321 _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0);
322 DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document "
323 "request.");
324 return (HTTP_ERROR);
325 }
326
327 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
328 NULL, info->uri);
329 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
330 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
331 NULL, cupsUser());
332 if (docname)
333 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
334 NULL, docname);
335 if (format)
336 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
337 "document-format", NULL, format);
338 ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document);
339
340 cupsEncodeOptions2(request, num_options, options, IPP_TAG_DOCUMENT);
341
342 /*
343 * Send and delete the request, then return the status...
344 */
345
346 status = cupsSendRequest(http, request, info->resource, CUPS_LENGTH_VARIABLE);
347
348 ippDelete(request);
349
350 return (status);
351 }
352
353
354 /*
355 * End of "$Id$".
356 */