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