xref: /aosp_15_r20/external/libcups/cups/dest-job.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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