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