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