xref: /aosp_15_r20/external/libcups/cups/util.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Printing utilities for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
17*5e7646d2SAndroid Build Coastguard Worker #include <fcntl.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <sys/stat.h>
19*5e7646d2SAndroid Build Coastguard Worker #if defined(_WIN32) || defined(__EMX__)
20*5e7646d2SAndroid Build Coastguard Worker #  include <io.h>
21*5e7646d2SAndroid Build Coastguard Worker #else
22*5e7646d2SAndroid Build Coastguard Worker #  include <unistd.h>
23*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 || __EMX__ */
24*5e7646d2SAndroid Build Coastguard Worker 
25*5e7646d2SAndroid Build Coastguard Worker 
26*5e7646d2SAndroid Build Coastguard Worker /*
27*5e7646d2SAndroid Build Coastguard Worker  * 'cupsCancelJob()' - Cancel a print job on the default server.
28*5e7646d2SAndroid Build Coastguard Worker  *
29*5e7646d2SAndroid Build Coastguard Worker  * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@
30*5e7646d2SAndroid Build Coastguard Worker  * to cancel the current job on the named destination.
31*5e7646d2SAndroid Build Coastguard Worker  *
32*5e7646d2SAndroid Build Coastguard Worker  * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get
33*5e7646d2SAndroid Build Coastguard Worker  * the cause of any failure.
34*5e7646d2SAndroid Build Coastguard Worker  *
35*5e7646d2SAndroid Build Coastguard Worker  * @exclude all@
36*5e7646d2SAndroid Build Coastguard Worker  */
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 on success, 0 on failure */
cupsCancelJob(const char * name,int job_id)39*5e7646d2SAndroid Build Coastguard Worker cupsCancelJob(const char *name,		/* I - Name of printer or class */
40*5e7646d2SAndroid Build Coastguard Worker               int        job_id)	/* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */
41*5e7646d2SAndroid Build Coastguard Worker {
42*5e7646d2SAndroid Build Coastguard Worker   return (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0)
43*5e7646d2SAndroid Build Coastguard Worker               < IPP_STATUS_REDIRECTION_OTHER_SITE);
44*5e7646d2SAndroid Build Coastguard Worker }
45*5e7646d2SAndroid Build Coastguard Worker 
46*5e7646d2SAndroid Build Coastguard Worker 
47*5e7646d2SAndroid Build Coastguard Worker /*
48*5e7646d2SAndroid Build Coastguard Worker  * 'cupsCancelJob2()' - Cancel or purge a print job.
49*5e7646d2SAndroid Build Coastguard Worker  *
50*5e7646d2SAndroid Build Coastguard Worker  * Canceled jobs remain in the job history while purged jobs are removed
51*5e7646d2SAndroid Build Coastguard Worker  * from the job history.
52*5e7646d2SAndroid Build Coastguard Worker  *
53*5e7646d2SAndroid Build Coastguard Worker  * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@
54*5e7646d2SAndroid Build Coastguard Worker  * to cancel the current job on the named destination.
55*5e7646d2SAndroid Build Coastguard Worker  *
56*5e7646d2SAndroid Build Coastguard Worker  * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get
57*5e7646d2SAndroid Build Coastguard Worker  * the cause of any failure.
58*5e7646d2SAndroid Build Coastguard Worker  *
59*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.4/macOS 10.6@ @exclude all@
60*5e7646d2SAndroid Build Coastguard Worker  */
61*5e7646d2SAndroid Build Coastguard Worker 
62*5e7646d2SAndroid Build Coastguard Worker ipp_status_t				/* O - IPP status */
cupsCancelJob2(http_t * http,const char * name,int job_id,int purge)63*5e7646d2SAndroid Build Coastguard Worker cupsCancelJob2(http_t     *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
64*5e7646d2SAndroid Build Coastguard Worker                const char *name,	/* I - Name of printer or class */
65*5e7646d2SAndroid Build Coastguard Worker                int        job_id,	/* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */
66*5e7646d2SAndroid Build Coastguard Worker 	       int        purge)	/* I - 1 to purge, 0 to cancel */
67*5e7646d2SAndroid Build Coastguard Worker {
68*5e7646d2SAndroid Build Coastguard Worker   char		uri[HTTP_MAX_URI];	/* Job/printer URI */
69*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request;		/* IPP request */
70*5e7646d2SAndroid Build Coastguard Worker 
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker  /*
73*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
74*5e7646d2SAndroid Build Coastguard Worker   */
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker   if (job_id < -1 || (!name && job_id == 0))
77*5e7646d2SAndroid Build Coastguard Worker   {
78*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
79*5e7646d2SAndroid Build Coastguard Worker     return (0);
80*5e7646d2SAndroid Build Coastguard Worker   }
81*5e7646d2SAndroid Build Coastguard Worker 
82*5e7646d2SAndroid Build Coastguard Worker  /*
83*5e7646d2SAndroid Build Coastguard Worker   * Connect to the default server as needed...
84*5e7646d2SAndroid Build Coastguard Worker   */
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker   if (!http)
87*5e7646d2SAndroid Build Coastguard Worker     if ((http = _cupsConnect()) == NULL)
88*5e7646d2SAndroid Build Coastguard Worker       return (IPP_STATUS_ERROR_SERVICE_UNAVAILABLE);
89*5e7646d2SAndroid Build Coastguard Worker 
90*5e7646d2SAndroid Build Coastguard Worker  /*
91*5e7646d2SAndroid Build Coastguard Worker   * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following
92*5e7646d2SAndroid Build Coastguard Worker   * attributes:
93*5e7646d2SAndroid Build Coastguard Worker   *
94*5e7646d2SAndroid Build Coastguard Worker   *    attributes-charset
95*5e7646d2SAndroid Build Coastguard Worker   *    attributes-natural-language
96*5e7646d2SAndroid Build Coastguard Worker   *    job-uri or printer-uri + job-id
97*5e7646d2SAndroid Build Coastguard Worker   *    requesting-user-name
98*5e7646d2SAndroid Build Coastguard Worker   *    [purge-job] or [purge-jobs]
99*5e7646d2SAndroid Build Coastguard Worker   */
100*5e7646d2SAndroid Build Coastguard Worker 
101*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(job_id < 0 ? IPP_OP_PURGE_JOBS : IPP_OP_CANCEL_JOB);
102*5e7646d2SAndroid Build Coastguard Worker 
103*5e7646d2SAndroid Build Coastguard Worker   if (name)
104*5e7646d2SAndroid Build Coastguard Worker   {
105*5e7646d2SAndroid Build Coastguard Worker     httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
106*5e7646d2SAndroid Build Coastguard Worker                      "localhost", ippPort(), "/printers/%s", name);
107*5e7646d2SAndroid Build Coastguard Worker 
108*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
109*5e7646d2SAndroid Build Coastguard Worker                  uri);
110*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
111*5e7646d2SAndroid Build Coastguard Worker                   job_id);
112*5e7646d2SAndroid Build Coastguard Worker   }
113*5e7646d2SAndroid Build Coastguard Worker   else if (job_id > 0)
114*5e7646d2SAndroid Build Coastguard Worker   {
115*5e7646d2SAndroid Build Coastguard Worker     snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
116*5e7646d2SAndroid Build Coastguard Worker 
117*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
118*5e7646d2SAndroid Build Coastguard Worker   }
119*5e7646d2SAndroid Build Coastguard Worker 
120*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
121*5e7646d2SAndroid Build Coastguard Worker                NULL, cupsUser());
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker   if (purge && job_id >= 0)
124*5e7646d2SAndroid Build Coastguard Worker     ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1);
125*5e7646d2SAndroid Build Coastguard Worker   else if (!purge && job_id < 0)
126*5e7646d2SAndroid Build Coastguard Worker     ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", 0);
127*5e7646d2SAndroid Build Coastguard Worker 
128*5e7646d2SAndroid Build Coastguard Worker  /*
129*5e7646d2SAndroid Build Coastguard Worker   * Do the request...
130*5e7646d2SAndroid Build Coastguard Worker   */
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker   ippDelete(cupsDoRequest(http, request, "/jobs/"));
133*5e7646d2SAndroid Build Coastguard Worker 
134*5e7646d2SAndroid Build Coastguard Worker   return (cupsLastError());
135*5e7646d2SAndroid Build Coastguard Worker }
136*5e7646d2SAndroid Build Coastguard Worker 
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker /*
139*5e7646d2SAndroid Build Coastguard Worker  * 'cupsCreateJob()' - Create an empty job for streaming.
140*5e7646d2SAndroid Build Coastguard Worker  *
141*5e7646d2SAndroid Build Coastguard Worker  * Use this function when you want to stream print data using the
142*5e7646d2SAndroid Build Coastguard Worker  * @link cupsStartDocument@, @link cupsWriteRequestData@, and
143*5e7646d2SAndroid Build Coastguard Worker  * @link cupsFinishDocument@ functions.  If you have one or more files to
144*5e7646d2SAndroid Build Coastguard Worker  * print, use the @link cupsPrintFile2@ or @link cupsPrintFiles2@ function
145*5e7646d2SAndroid Build Coastguard Worker  * instead.
146*5e7646d2SAndroid Build Coastguard Worker  *
147*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.4/macOS 10.6@ @exclude all@
148*5e7646d2SAndroid Build Coastguard Worker  */
149*5e7646d2SAndroid Build Coastguard Worker 
150*5e7646d2SAndroid Build Coastguard Worker int					/* O - Job ID or 0 on error */
cupsCreateJob(http_t * http,const char * name,const char * title,int num_options,cups_option_t * options)151*5e7646d2SAndroid Build Coastguard Worker cupsCreateJob(
152*5e7646d2SAndroid Build Coastguard Worker     http_t        *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
153*5e7646d2SAndroid Build Coastguard Worker     const char    *name,		/* I - Destination name */
154*5e7646d2SAndroid Build Coastguard Worker     const char    *title,		/* I - Title of job */
155*5e7646d2SAndroid Build Coastguard Worker     int           num_options,		/* I - Number of options */
156*5e7646d2SAndroid Build Coastguard Worker     cups_option_t *options)		/* I - Options */
157*5e7646d2SAndroid Build Coastguard Worker {
158*5e7646d2SAndroid Build Coastguard Worker   int		job_id = 0;		/* job-id value */
159*5e7646d2SAndroid Build Coastguard Worker   ipp_status_t  status;                 /* Create-Job status */
160*5e7646d2SAndroid Build Coastguard Worker   cups_dest_t	*dest;			/* Destination */
161*5e7646d2SAndroid Build Coastguard Worker   cups_dinfo_t  *info;                  /* Destination information */
162*5e7646d2SAndroid Build Coastguard Worker 
163*5e7646d2SAndroid Build Coastguard Worker 
164*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", num_options=%d, options=%p)", (void *)http, name, title, num_options, (void *)options));
165*5e7646d2SAndroid Build Coastguard Worker 
166*5e7646d2SAndroid Build Coastguard Worker  /*
167*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
168*5e7646d2SAndroid Build Coastguard Worker   */
169*5e7646d2SAndroid Build Coastguard Worker 
170*5e7646d2SAndroid Build Coastguard Worker   if (!name)
171*5e7646d2SAndroid Build Coastguard Worker   {
172*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
173*5e7646d2SAndroid Build Coastguard Worker     return (0);
174*5e7646d2SAndroid Build Coastguard Worker   }
175*5e7646d2SAndroid Build Coastguard Worker 
176*5e7646d2SAndroid Build Coastguard Worker  /*
177*5e7646d2SAndroid Build Coastguard Worker   * Lookup the destination...
178*5e7646d2SAndroid Build Coastguard Worker   */
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker   if ((dest = cupsGetNamedDest(http, name, NULL)) == NULL)
181*5e7646d2SAndroid Build Coastguard Worker   {
182*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1cupsCreateJob: Destination not found.");
183*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
184*5e7646d2SAndroid Build Coastguard Worker     return (0);
185*5e7646d2SAndroid Build Coastguard Worker   }
186*5e7646d2SAndroid Build Coastguard Worker 
187*5e7646d2SAndroid Build Coastguard Worker  /*
188*5e7646d2SAndroid Build Coastguard Worker   * Query dest information and create the job...
189*5e7646d2SAndroid Build Coastguard Worker   */
190*5e7646d2SAndroid Build Coastguard Worker 
191*5e7646d2SAndroid Build Coastguard Worker   DEBUG_puts("1cupsCreateJob: Querying destination info.");
192*5e7646d2SAndroid Build Coastguard Worker   if ((info = cupsCopyDestInfo(http, dest)) == NULL)
193*5e7646d2SAndroid Build Coastguard Worker   {
194*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1cupsCreateJob: Query failed.");
195*5e7646d2SAndroid Build Coastguard Worker     cupsFreeDests(1, dest);
196*5e7646d2SAndroid Build Coastguard Worker     return (0);
197*5e7646d2SAndroid Build Coastguard Worker   }
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker   status = cupsCreateDestJob(http, dest, info, &job_id, title, num_options, options);
200*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("1cupsCreateJob: cupsCreateDestJob returned %04x (%s)", status, ippErrorString(status)));
201*5e7646d2SAndroid Build Coastguard Worker 
202*5e7646d2SAndroid Build Coastguard Worker   cupsFreeDestInfo(info);
203*5e7646d2SAndroid Build Coastguard Worker   cupsFreeDests(1, dest);
204*5e7646d2SAndroid Build Coastguard Worker 
205*5e7646d2SAndroid Build Coastguard Worker  /*
206*5e7646d2SAndroid Build Coastguard Worker   * Return the job...
207*5e7646d2SAndroid Build Coastguard Worker   */
208*5e7646d2SAndroid Build Coastguard Worker 
209*5e7646d2SAndroid Build Coastguard Worker   if (status >= IPP_STATUS_REDIRECTION_OTHER_SITE)
210*5e7646d2SAndroid Build Coastguard Worker     return (0);
211*5e7646d2SAndroid Build Coastguard Worker   else
212*5e7646d2SAndroid Build Coastguard Worker     return (job_id);
213*5e7646d2SAndroid Build Coastguard Worker }
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker 
216*5e7646d2SAndroid Build Coastguard Worker /*
217*5e7646d2SAndroid Build Coastguard Worker  * 'cupsFinishDocument()' - Finish sending a document.
218*5e7646d2SAndroid Build Coastguard Worker  *
219*5e7646d2SAndroid Build Coastguard Worker  * The document must have been started using @link cupsStartDocument@.
220*5e7646d2SAndroid Build Coastguard Worker  *
221*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.4/macOS 10.6@ @exclude all@
222*5e7646d2SAndroid Build Coastguard Worker  */
223*5e7646d2SAndroid Build Coastguard Worker 
224*5e7646d2SAndroid Build Coastguard Worker ipp_status_t				/* O - Status of document submission */
cupsFinishDocument(http_t * http,const char * name)225*5e7646d2SAndroid Build Coastguard Worker cupsFinishDocument(http_t     *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
226*5e7646d2SAndroid Build Coastguard Worker                    const char *name)	/* I - Destination name */
227*5e7646d2SAndroid Build Coastguard Worker {
228*5e7646d2SAndroid Build Coastguard Worker   char	resource[1024];			/* Printer resource */
229*5e7646d2SAndroid Build Coastguard Worker 
230*5e7646d2SAndroid Build Coastguard Worker 
231*5e7646d2SAndroid Build Coastguard Worker   snprintf(resource, sizeof(resource), "/printers/%s", name);
232*5e7646d2SAndroid Build Coastguard Worker 
233*5e7646d2SAndroid Build Coastguard Worker   ippDelete(cupsGetResponse(http, resource));
234*5e7646d2SAndroid Build Coastguard Worker 
235*5e7646d2SAndroid Build Coastguard Worker   return (cupsLastError());
236*5e7646d2SAndroid Build Coastguard Worker }
237*5e7646d2SAndroid Build Coastguard Worker 
238*5e7646d2SAndroid Build Coastguard Worker 
239*5e7646d2SAndroid Build Coastguard Worker /*
240*5e7646d2SAndroid Build Coastguard Worker  * 'cupsFreeJobs()' - Free memory used by job data.
241*5e7646d2SAndroid Build Coastguard Worker  */
242*5e7646d2SAndroid Build Coastguard Worker 
243*5e7646d2SAndroid Build Coastguard Worker void
cupsFreeJobs(int num_jobs,cups_job_t * jobs)244*5e7646d2SAndroid Build Coastguard Worker cupsFreeJobs(int        num_jobs,	/* I - Number of jobs */
245*5e7646d2SAndroid Build Coastguard Worker              cups_job_t *jobs)		/* I - Jobs */
246*5e7646d2SAndroid Build Coastguard Worker {
247*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
248*5e7646d2SAndroid Build Coastguard Worker   cups_job_t	*job;			/* Current job */
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker 
251*5e7646d2SAndroid Build Coastguard Worker   if (num_jobs <= 0 || !jobs)
252*5e7646d2SAndroid Build Coastguard Worker     return;
253*5e7646d2SAndroid Build Coastguard Worker 
254*5e7646d2SAndroid Build Coastguard Worker   for (i = num_jobs, job = jobs; i > 0; i --, job ++)
255*5e7646d2SAndroid Build Coastguard Worker   {
256*5e7646d2SAndroid Build Coastguard Worker     _cupsStrFree(job->dest);
257*5e7646d2SAndroid Build Coastguard Worker     _cupsStrFree(job->user);
258*5e7646d2SAndroid Build Coastguard Worker     _cupsStrFree(job->format);
259*5e7646d2SAndroid Build Coastguard Worker     _cupsStrFree(job->title);
260*5e7646d2SAndroid Build Coastguard Worker   }
261*5e7646d2SAndroid Build Coastguard Worker 
262*5e7646d2SAndroid Build Coastguard Worker   free(jobs);
263*5e7646d2SAndroid Build Coastguard Worker }
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker 
266*5e7646d2SAndroid Build Coastguard Worker /*
267*5e7646d2SAndroid Build Coastguard Worker  * 'cupsGetClasses()' - Get a list of printer classes from the default server.
268*5e7646d2SAndroid Build Coastguard Worker  *
269*5e7646d2SAndroid Build Coastguard Worker  * This function is deprecated and no longer returns a list of printer
270*5e7646d2SAndroid Build Coastguard Worker  * classes - use @link cupsGetDests@ instead.
271*5e7646d2SAndroid Build Coastguard Worker  *
272*5e7646d2SAndroid Build Coastguard Worker  * @deprecated@ @exclude all@
273*5e7646d2SAndroid Build Coastguard Worker  */
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker int					/* O - Number of classes */
cupsGetClasses(char *** classes)276*5e7646d2SAndroid Build Coastguard Worker cupsGetClasses(char ***classes)		/* O - Classes */
277*5e7646d2SAndroid Build Coastguard Worker {
278*5e7646d2SAndroid Build Coastguard Worker   if (classes)
279*5e7646d2SAndroid Build Coastguard Worker     *classes = NULL;
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker   return (0);
282*5e7646d2SAndroid Build Coastguard Worker }
283*5e7646d2SAndroid Build Coastguard Worker 
284*5e7646d2SAndroid Build Coastguard Worker 
285*5e7646d2SAndroid Build Coastguard Worker /*
286*5e7646d2SAndroid Build Coastguard Worker  * 'cupsGetDefault()' - Get the default printer or class for the default server.
287*5e7646d2SAndroid Build Coastguard Worker  *
288*5e7646d2SAndroid Build Coastguard Worker  * This function returns the default printer or class as defined by
289*5e7646d2SAndroid Build Coastguard Worker  * the LPDEST or PRINTER environment variables. If these environment
290*5e7646d2SAndroid Build Coastguard Worker  * variables are not set, the server default destination is returned.
291*5e7646d2SAndroid Build Coastguard Worker  * Applications should use the @link cupsGetDests@ and @link cupsGetDest@
292*5e7646d2SAndroid Build Coastguard Worker  * functions to get the user-defined default printer, as this function does
293*5e7646d2SAndroid Build Coastguard Worker  * not support the lpoptions-defined default printer.
294*5e7646d2SAndroid Build Coastguard Worker  *
295*5e7646d2SAndroid Build Coastguard Worker  * @exclude all@
296*5e7646d2SAndroid Build Coastguard Worker  */
297*5e7646d2SAndroid Build Coastguard Worker 
298*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - Default printer or @code NULL@ */
cupsGetDefault(void)299*5e7646d2SAndroid Build Coastguard Worker cupsGetDefault(void)
300*5e7646d2SAndroid Build Coastguard Worker {
301*5e7646d2SAndroid Build Coastguard Worker  /*
302*5e7646d2SAndroid Build Coastguard Worker   * Return the default printer...
303*5e7646d2SAndroid Build Coastguard Worker   */
304*5e7646d2SAndroid Build Coastguard Worker 
305*5e7646d2SAndroid Build Coastguard Worker   return (cupsGetDefault2(CUPS_HTTP_DEFAULT));
306*5e7646d2SAndroid Build Coastguard Worker }
307*5e7646d2SAndroid Build Coastguard Worker 
308*5e7646d2SAndroid Build Coastguard Worker 
309*5e7646d2SAndroid Build Coastguard Worker /*
310*5e7646d2SAndroid Build Coastguard Worker  * 'cupsGetDefault2()' - Get the default printer or class for the specified server.
311*5e7646d2SAndroid Build Coastguard Worker  *
312*5e7646d2SAndroid Build Coastguard Worker  * This function returns the default printer or class as defined by
313*5e7646d2SAndroid Build Coastguard Worker  * the LPDEST or PRINTER environment variables. If these environment
314*5e7646d2SAndroid Build Coastguard Worker  * variables are not set, the server default destination is returned.
315*5e7646d2SAndroid Build Coastguard Worker  * Applications should use the @link cupsGetDests@ and @link cupsGetDest@
316*5e7646d2SAndroid Build Coastguard Worker  * functions to get the user-defined default printer, as this function does
317*5e7646d2SAndroid Build Coastguard Worker  * not support the lpoptions-defined default printer.
318*5e7646d2SAndroid Build Coastguard Worker  *
319*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.1.21/macOS 10.4@ @exclude all@
320*5e7646d2SAndroid Build Coastguard Worker  */
321*5e7646d2SAndroid Build Coastguard Worker 
322*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - Default printer or @code NULL@ */
cupsGetDefault2(http_t * http)323*5e7646d2SAndroid Build Coastguard Worker cupsGetDefault2(http_t *http)		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
324*5e7646d2SAndroid Build Coastguard Worker {
325*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request,		/* IPP Request */
326*5e7646d2SAndroid Build Coastguard Worker 		*response;		/* IPP Response */
327*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Current attribute */
328*5e7646d2SAndroid Build Coastguard Worker   _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */
329*5e7646d2SAndroid Build Coastguard Worker 
330*5e7646d2SAndroid Build Coastguard Worker 
331*5e7646d2SAndroid Build Coastguard Worker  /*
332*5e7646d2SAndroid Build Coastguard Worker   * See if we have a user default printer set...
333*5e7646d2SAndroid Build Coastguard Worker   */
334*5e7646d2SAndroid Build Coastguard Worker 
335*5e7646d2SAndroid Build Coastguard Worker   if (_cupsUserDefault(cg->def_printer, sizeof(cg->def_printer)))
336*5e7646d2SAndroid Build Coastguard Worker     return (cg->def_printer);
337*5e7646d2SAndroid Build Coastguard Worker 
338*5e7646d2SAndroid Build Coastguard Worker  /*
339*5e7646d2SAndroid Build Coastguard Worker   * Connect to the server as needed...
340*5e7646d2SAndroid Build Coastguard Worker   */
341*5e7646d2SAndroid Build Coastguard Worker 
342*5e7646d2SAndroid Build Coastguard Worker   if (!http)
343*5e7646d2SAndroid Build Coastguard Worker     if ((http = _cupsConnect()) == NULL)
344*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
345*5e7646d2SAndroid Build Coastguard Worker 
346*5e7646d2SAndroid Build Coastguard Worker  /*
347*5e7646d2SAndroid Build Coastguard Worker   * Build a CUPS_GET_DEFAULT request, which requires the following
348*5e7646d2SAndroid Build Coastguard Worker   * attributes:
349*5e7646d2SAndroid Build Coastguard Worker   *
350*5e7646d2SAndroid Build Coastguard Worker   *    attributes-charset
351*5e7646d2SAndroid Build Coastguard Worker   *    attributes-natural-language
352*5e7646d2SAndroid Build Coastguard Worker   */
353*5e7646d2SAndroid Build Coastguard Worker 
354*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_OP_CUPS_GET_DEFAULT);
355*5e7646d2SAndroid Build Coastguard Worker 
356*5e7646d2SAndroid Build Coastguard Worker  /*
357*5e7646d2SAndroid Build Coastguard Worker   * Do the request and get back a response...
358*5e7646d2SAndroid Build Coastguard Worker   */
359*5e7646d2SAndroid Build Coastguard Worker 
360*5e7646d2SAndroid Build Coastguard Worker   if ((response = cupsDoRequest(http, request, "/")) != NULL)
361*5e7646d2SAndroid Build Coastguard Worker   {
362*5e7646d2SAndroid Build Coastguard Worker     if ((attr = ippFindAttribute(response, "printer-name",
363*5e7646d2SAndroid Build Coastguard Worker                                  IPP_TAG_NAME)) != NULL)
364*5e7646d2SAndroid Build Coastguard Worker     {
365*5e7646d2SAndroid Build Coastguard Worker       strlcpy(cg->def_printer, attr->values[0].string.text,
366*5e7646d2SAndroid Build Coastguard Worker               sizeof(cg->def_printer));
367*5e7646d2SAndroid Build Coastguard Worker       ippDelete(response);
368*5e7646d2SAndroid Build Coastguard Worker       return (cg->def_printer);
369*5e7646d2SAndroid Build Coastguard Worker     }
370*5e7646d2SAndroid Build Coastguard Worker 
371*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
372*5e7646d2SAndroid Build Coastguard Worker   }
373*5e7646d2SAndroid Build Coastguard Worker 
374*5e7646d2SAndroid Build Coastguard Worker   return (NULL);
375*5e7646d2SAndroid Build Coastguard Worker }
376*5e7646d2SAndroid Build Coastguard Worker 
377*5e7646d2SAndroid Build Coastguard Worker 
378*5e7646d2SAndroid Build Coastguard Worker /*
379*5e7646d2SAndroid Build Coastguard Worker  * 'cupsGetJobs()' - Get the jobs from the default server.
380*5e7646d2SAndroid Build Coastguard Worker  *
381*5e7646d2SAndroid Build Coastguard Worker  * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless
382*5e7646d2SAndroid Build Coastguard Worker  * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are
383*5e7646d2SAndroid Build Coastguard Worker  * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns
384*5e7646d2SAndroid Build Coastguard Worker  * jobs that are stopped, canceled, aborted, or completed.
385*5e7646d2SAndroid Build Coastguard Worker  *
386*5e7646d2SAndroid Build Coastguard Worker  * @exclude all@
387*5e7646d2SAndroid Build Coastguard Worker  */
388*5e7646d2SAndroid Build Coastguard Worker 
389*5e7646d2SAndroid Build Coastguard Worker int					/* O - Number of jobs */
cupsGetJobs(cups_job_t ** jobs,const char * name,int myjobs,int whichjobs)390*5e7646d2SAndroid Build Coastguard Worker cupsGetJobs(cups_job_t **jobs,		/* O - Job data */
391*5e7646d2SAndroid Build Coastguard Worker             const char *name,		/* I - @code NULL@ = all destinations, otherwise show jobs for named destination */
392*5e7646d2SAndroid Build Coastguard Worker             int        myjobs,		/* I - 0 = all users, 1 = mine */
393*5e7646d2SAndroid Build Coastguard Worker 	    int        whichjobs)	/* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
394*5e7646d2SAndroid Build Coastguard Worker {
395*5e7646d2SAndroid Build Coastguard Worker  /*
396*5e7646d2SAndroid Build Coastguard Worker   * Return the jobs...
397*5e7646d2SAndroid Build Coastguard Worker   */
398*5e7646d2SAndroid Build Coastguard Worker 
399*5e7646d2SAndroid Build Coastguard Worker   return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, name, myjobs, whichjobs));
400*5e7646d2SAndroid Build Coastguard Worker }
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker 
403*5e7646d2SAndroid Build Coastguard Worker 
404*5e7646d2SAndroid Build Coastguard Worker /*
405*5e7646d2SAndroid Build Coastguard Worker  * 'cupsGetJobs2()' - Get the jobs from the specified server.
406*5e7646d2SAndroid Build Coastguard Worker  *
407*5e7646d2SAndroid Build Coastguard Worker  * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless
408*5e7646d2SAndroid Build Coastguard Worker  * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are
409*5e7646d2SAndroid Build Coastguard Worker  * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns
410*5e7646d2SAndroid Build Coastguard Worker  * jobs that are stopped, canceled, aborted, or completed.
411*5e7646d2SAndroid Build Coastguard Worker  *
412*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.1.21/macOS 10.4@
413*5e7646d2SAndroid Build Coastguard Worker  */
414*5e7646d2SAndroid Build Coastguard Worker 
415*5e7646d2SAndroid Build Coastguard Worker int					/* O - Number of jobs */
cupsGetJobs2(http_t * http,cups_job_t ** jobs,const char * name,int myjobs,int whichjobs)416*5e7646d2SAndroid Build Coastguard Worker cupsGetJobs2(http_t     *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
417*5e7646d2SAndroid Build Coastguard Worker              cups_job_t **jobs,		/* O - Job data */
418*5e7646d2SAndroid Build Coastguard Worker              const char *name,		/* I - @code NULL@ = all destinations, otherwise show jobs for named destination */
419*5e7646d2SAndroid Build Coastguard Worker              int        myjobs,		/* I - 0 = all users, 1 = mine */
420*5e7646d2SAndroid Build Coastguard Worker 	     int        whichjobs)	/* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
421*5e7646d2SAndroid Build Coastguard Worker {
422*5e7646d2SAndroid Build Coastguard Worker   int		n;			/* Number of jobs */
423*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request,		/* IPP Request */
424*5e7646d2SAndroid Build Coastguard Worker 		*response;		/* IPP Response */
425*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Current attribute */
426*5e7646d2SAndroid Build Coastguard Worker   cups_job_t	*temp;			/* Temporary pointer */
427*5e7646d2SAndroid Build Coastguard Worker   int		id,			/* job-id */
428*5e7646d2SAndroid Build Coastguard Worker 		priority,		/* job-priority */
429*5e7646d2SAndroid Build Coastguard Worker 		size;			/* job-k-octets */
430*5e7646d2SAndroid Build Coastguard Worker   ipp_jstate_t	state;			/* job-state */
431*5e7646d2SAndroid Build Coastguard Worker   time_t	completed_time,		/* time-at-completed */
432*5e7646d2SAndroid Build Coastguard Worker 		creation_time,		/* time-at-creation */
433*5e7646d2SAndroid Build Coastguard Worker 		processing_time;	/* time-at-processing */
434*5e7646d2SAndroid Build Coastguard Worker   const char	*dest,			/* job-printer-uri */
435*5e7646d2SAndroid Build Coastguard Worker 		*format,		/* document-format */
436*5e7646d2SAndroid Build Coastguard Worker 		*title,			/* job-name */
437*5e7646d2SAndroid Build Coastguard Worker 		*user;			/* job-originating-user-name */
438*5e7646d2SAndroid Build Coastguard Worker   char		uri[HTTP_MAX_URI];	/* URI for jobs */
439*5e7646d2SAndroid Build Coastguard Worker   _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */
440*5e7646d2SAndroid Build Coastguard Worker   static const char * const attrs[] =	/* Requested attributes */
441*5e7646d2SAndroid Build Coastguard Worker 		{
442*5e7646d2SAndroid Build Coastguard Worker 		  "document-format",
443*5e7646d2SAndroid Build Coastguard Worker 		  "job-id",
444*5e7646d2SAndroid Build Coastguard Worker 		  "job-k-octets",
445*5e7646d2SAndroid Build Coastguard Worker 		  "job-name",
446*5e7646d2SAndroid Build Coastguard Worker 		  "job-originating-user-name",
447*5e7646d2SAndroid Build Coastguard Worker 		  "job-printer-uri",
448*5e7646d2SAndroid Build Coastguard Worker 		  "job-priority",
449*5e7646d2SAndroid Build Coastguard Worker 		  "job-state",
450*5e7646d2SAndroid Build Coastguard Worker 		  "time-at-completed",
451*5e7646d2SAndroid Build Coastguard Worker 		  "time-at-creation",
452*5e7646d2SAndroid Build Coastguard Worker 		  "time-at-processing"
453*5e7646d2SAndroid Build Coastguard Worker 		};
454*5e7646d2SAndroid Build Coastguard Worker 
455*5e7646d2SAndroid Build Coastguard Worker 
456*5e7646d2SAndroid Build Coastguard Worker  /*
457*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
458*5e7646d2SAndroid Build Coastguard Worker   */
459*5e7646d2SAndroid Build Coastguard Worker 
460*5e7646d2SAndroid Build Coastguard Worker   if (!jobs)
461*5e7646d2SAndroid Build Coastguard Worker   {
462*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker     return (-1);
465*5e7646d2SAndroid Build Coastguard Worker   }
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker  /*
468*5e7646d2SAndroid Build Coastguard Worker   * Get the right URI...
469*5e7646d2SAndroid Build Coastguard Worker   */
470*5e7646d2SAndroid Build Coastguard Worker 
471*5e7646d2SAndroid Build Coastguard Worker   if (name)
472*5e7646d2SAndroid Build Coastguard Worker   {
473*5e7646d2SAndroid Build Coastguard Worker     if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
474*5e7646d2SAndroid Build Coastguard Worker                          "localhost", 0, "/printers/%s",
475*5e7646d2SAndroid Build Coastguard Worker                          name) < HTTP_URI_STATUS_OK)
476*5e7646d2SAndroid Build Coastguard Worker     {
477*5e7646d2SAndroid Build Coastguard Worker       _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
478*5e7646d2SAndroid Build Coastguard Worker                     _("Unable to create printer-uri"), 1);
479*5e7646d2SAndroid Build Coastguard Worker 
480*5e7646d2SAndroid Build Coastguard Worker       return (-1);
481*5e7646d2SAndroid Build Coastguard Worker     }
482*5e7646d2SAndroid Build Coastguard Worker   }
483*5e7646d2SAndroid Build Coastguard Worker   else
484*5e7646d2SAndroid Build Coastguard Worker     strlcpy(uri, "ipp://localhost/", sizeof(uri));
485*5e7646d2SAndroid Build Coastguard Worker 
486*5e7646d2SAndroid Build Coastguard Worker   if (!http)
487*5e7646d2SAndroid Build Coastguard Worker     if ((http = _cupsConnect()) == NULL)
488*5e7646d2SAndroid Build Coastguard Worker       return (-1);
489*5e7646d2SAndroid Build Coastguard Worker 
490*5e7646d2SAndroid Build Coastguard Worker  /*
491*5e7646d2SAndroid Build Coastguard Worker   * Build an IPP_GET_JOBS request, which requires the following
492*5e7646d2SAndroid Build Coastguard Worker   * attributes:
493*5e7646d2SAndroid Build Coastguard Worker   *
494*5e7646d2SAndroid Build Coastguard Worker   *    attributes-charset
495*5e7646d2SAndroid Build Coastguard Worker   *    attributes-natural-language
496*5e7646d2SAndroid Build Coastguard Worker   *    printer-uri
497*5e7646d2SAndroid Build Coastguard Worker   *    requesting-user-name
498*5e7646d2SAndroid Build Coastguard Worker   *    which-jobs
499*5e7646d2SAndroid Build Coastguard Worker   *    my-jobs
500*5e7646d2SAndroid Build Coastguard Worker   *    requested-attributes
501*5e7646d2SAndroid Build Coastguard Worker   */
502*5e7646d2SAndroid Build Coastguard Worker 
503*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_OP_GET_JOBS);
504*5e7646d2SAndroid Build Coastguard Worker 
505*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
506*5e7646d2SAndroid Build Coastguard Worker                "printer-uri", NULL, uri);
507*5e7646d2SAndroid Build Coastguard Worker 
508*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
509*5e7646d2SAndroid Build Coastguard Worker                "requesting-user-name", NULL, cupsUser());
510*5e7646d2SAndroid Build Coastguard Worker 
511*5e7646d2SAndroid Build Coastguard Worker   if (myjobs)
512*5e7646d2SAndroid Build Coastguard Worker     ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
513*5e7646d2SAndroid Build Coastguard Worker 
514*5e7646d2SAndroid Build Coastguard Worker   if (whichjobs == CUPS_WHICHJOBS_COMPLETED)
515*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
516*5e7646d2SAndroid Build Coastguard Worker                  "which-jobs", NULL, "completed");
517*5e7646d2SAndroid Build Coastguard Worker   else if (whichjobs == CUPS_WHICHJOBS_ALL)
518*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
519*5e7646d2SAndroid Build Coastguard Worker                  "which-jobs", NULL, "all");
520*5e7646d2SAndroid Build Coastguard Worker 
521*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
522*5e7646d2SAndroid Build Coastguard Worker                 "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
523*5e7646d2SAndroid Build Coastguard Worker 		NULL, attrs);
524*5e7646d2SAndroid Build Coastguard Worker 
525*5e7646d2SAndroid Build Coastguard Worker  /*
526*5e7646d2SAndroid Build Coastguard Worker   * Do the request and get back a response...
527*5e7646d2SAndroid Build Coastguard Worker   */
528*5e7646d2SAndroid Build Coastguard Worker 
529*5e7646d2SAndroid Build Coastguard Worker   n     = 0;
530*5e7646d2SAndroid Build Coastguard Worker   *jobs = NULL;
531*5e7646d2SAndroid Build Coastguard Worker 
532*5e7646d2SAndroid Build Coastguard Worker   if ((response = cupsDoRequest(http, request, "/")) != NULL)
533*5e7646d2SAndroid Build Coastguard Worker   {
534*5e7646d2SAndroid Build Coastguard Worker     for (attr = response->attrs; attr; attr = attr->next)
535*5e7646d2SAndroid Build Coastguard Worker     {
536*5e7646d2SAndroid Build Coastguard Worker      /*
537*5e7646d2SAndroid Build Coastguard Worker       * Skip leading attributes until we hit a job...
538*5e7646d2SAndroid Build Coastguard Worker       */
539*5e7646d2SAndroid Build Coastguard Worker 
540*5e7646d2SAndroid Build Coastguard Worker       while (attr && attr->group_tag != IPP_TAG_JOB)
541*5e7646d2SAndroid Build Coastguard Worker         attr = attr->next;
542*5e7646d2SAndroid Build Coastguard Worker 
543*5e7646d2SAndroid Build Coastguard Worker       if (!attr)
544*5e7646d2SAndroid Build Coastguard Worker         break;
545*5e7646d2SAndroid Build Coastguard Worker 
546*5e7646d2SAndroid Build Coastguard Worker      /*
547*5e7646d2SAndroid Build Coastguard Worker       * Pull the needed attributes from this job...
548*5e7646d2SAndroid Build Coastguard Worker       */
549*5e7646d2SAndroid Build Coastguard Worker 
550*5e7646d2SAndroid Build Coastguard Worker       id              = 0;
551*5e7646d2SAndroid Build Coastguard Worker       size            = 0;
552*5e7646d2SAndroid Build Coastguard Worker       priority        = 50;
553*5e7646d2SAndroid Build Coastguard Worker       state           = IPP_JSTATE_PENDING;
554*5e7646d2SAndroid Build Coastguard Worker       user            = "unknown";
555*5e7646d2SAndroid Build Coastguard Worker       dest            = NULL;
556*5e7646d2SAndroid Build Coastguard Worker       format          = "application/octet-stream";
557*5e7646d2SAndroid Build Coastguard Worker       title           = "untitled";
558*5e7646d2SAndroid Build Coastguard Worker       creation_time   = 0;
559*5e7646d2SAndroid Build Coastguard Worker       completed_time  = 0;
560*5e7646d2SAndroid Build Coastguard Worker       processing_time = 0;
561*5e7646d2SAndroid Build Coastguard Worker 
562*5e7646d2SAndroid Build Coastguard Worker       while (attr && attr->group_tag == IPP_TAG_JOB)
563*5e7646d2SAndroid Build Coastguard Worker       {
564*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(attr->name, "job-id") &&
565*5e7646d2SAndroid Build Coastguard Worker 	    attr->value_tag == IPP_TAG_INTEGER)
566*5e7646d2SAndroid Build Coastguard Worker 	  id = attr->values[0].integer;
567*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "job-state") &&
568*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_ENUM)
569*5e7646d2SAndroid Build Coastguard Worker 	  state = (ipp_jstate_t)attr->values[0].integer;
570*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "job-priority") &&
571*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_INTEGER)
572*5e7646d2SAndroid Build Coastguard Worker 	  priority = attr->values[0].integer;
573*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "job-k-octets") &&
574*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_INTEGER)
575*5e7646d2SAndroid Build Coastguard Worker 	  size = attr->values[0].integer;
576*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "time-at-completed") &&
577*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_INTEGER)
578*5e7646d2SAndroid Build Coastguard Worker 	  completed_time = attr->values[0].integer;
579*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "time-at-creation") &&
580*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_INTEGER)
581*5e7646d2SAndroid Build Coastguard Worker 	  creation_time = attr->values[0].integer;
582*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "time-at-processing") &&
583*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_INTEGER)
584*5e7646d2SAndroid Build Coastguard Worker 	  processing_time = attr->values[0].integer;
585*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "job-printer-uri") &&
586*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_URI)
587*5e7646d2SAndroid Build Coastguard Worker 	{
588*5e7646d2SAndroid Build Coastguard Worker 	  if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL)
589*5e7646d2SAndroid Build Coastguard Worker 	    dest ++;
590*5e7646d2SAndroid Build Coastguard Worker         }
591*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "job-originating-user-name") &&
592*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_NAME)
593*5e7646d2SAndroid Build Coastguard Worker 	  user = attr->values[0].string.text;
594*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "document-format") &&
595*5e7646d2SAndroid Build Coastguard Worker 	         attr->value_tag == IPP_TAG_MIMETYPE)
596*5e7646d2SAndroid Build Coastguard Worker 	  format = attr->values[0].string.text;
597*5e7646d2SAndroid Build Coastguard Worker         else if (!strcmp(attr->name, "job-name") &&
598*5e7646d2SAndroid Build Coastguard Worker 	         (attr->value_tag == IPP_TAG_TEXT ||
599*5e7646d2SAndroid Build Coastguard Worker 		  attr->value_tag == IPP_TAG_NAME))
600*5e7646d2SAndroid Build Coastguard Worker 	  title = attr->values[0].string.text;
601*5e7646d2SAndroid Build Coastguard Worker 
602*5e7646d2SAndroid Build Coastguard Worker         attr = attr->next;
603*5e7646d2SAndroid Build Coastguard Worker       }
604*5e7646d2SAndroid Build Coastguard Worker 
605*5e7646d2SAndroid Build Coastguard Worker      /*
606*5e7646d2SAndroid Build Coastguard Worker       * See if we have everything needed...
607*5e7646d2SAndroid Build Coastguard Worker       */
608*5e7646d2SAndroid Build Coastguard Worker 
609*5e7646d2SAndroid Build Coastguard Worker       if (!dest || !id)
610*5e7646d2SAndroid Build Coastguard Worker       {
611*5e7646d2SAndroid Build Coastguard Worker         if (!attr)
612*5e7646d2SAndroid Build Coastguard Worker 	  break;
613*5e7646d2SAndroid Build Coastguard Worker 	else
614*5e7646d2SAndroid Build Coastguard Worker           continue;
615*5e7646d2SAndroid Build Coastguard Worker       }
616*5e7646d2SAndroid Build Coastguard Worker 
617*5e7646d2SAndroid Build Coastguard Worker      /*
618*5e7646d2SAndroid Build Coastguard Worker       * Allocate memory for the job...
619*5e7646d2SAndroid Build Coastguard Worker       */
620*5e7646d2SAndroid Build Coastguard Worker 
621*5e7646d2SAndroid Build Coastguard Worker       if (n == 0)
622*5e7646d2SAndroid Build Coastguard Worker         temp = malloc(sizeof(cups_job_t));
623*5e7646d2SAndroid Build Coastguard Worker       else
624*5e7646d2SAndroid Build Coastguard Worker 	temp = realloc(*jobs, sizeof(cups_job_t) * (size_t)(n + 1));
625*5e7646d2SAndroid Build Coastguard Worker 
626*5e7646d2SAndroid Build Coastguard Worker       if (!temp)
627*5e7646d2SAndroid Build Coastguard Worker       {
628*5e7646d2SAndroid Build Coastguard Worker        /*
629*5e7646d2SAndroid Build Coastguard Worker         * Ran out of memory!
630*5e7646d2SAndroid Build Coastguard Worker         */
631*5e7646d2SAndroid Build Coastguard Worker 
632*5e7646d2SAndroid Build Coastguard Worker         _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
633*5e7646d2SAndroid Build Coastguard Worker 
634*5e7646d2SAndroid Build Coastguard Worker 	cupsFreeJobs(n, *jobs);
635*5e7646d2SAndroid Build Coastguard Worker 	*jobs = NULL;
636*5e7646d2SAndroid Build Coastguard Worker 
637*5e7646d2SAndroid Build Coastguard Worker         ippDelete(response);
638*5e7646d2SAndroid Build Coastguard Worker 
639*5e7646d2SAndroid Build Coastguard Worker 	return (-1);
640*5e7646d2SAndroid Build Coastguard Worker       }
641*5e7646d2SAndroid Build Coastguard Worker 
642*5e7646d2SAndroid Build Coastguard Worker       *jobs = temp;
643*5e7646d2SAndroid Build Coastguard Worker       temp  += n;
644*5e7646d2SAndroid Build Coastguard Worker       n ++;
645*5e7646d2SAndroid Build Coastguard Worker 
646*5e7646d2SAndroid Build Coastguard Worker      /*
647*5e7646d2SAndroid Build Coastguard Worker       * Copy the data over...
648*5e7646d2SAndroid Build Coastguard Worker       */
649*5e7646d2SAndroid Build Coastguard Worker 
650*5e7646d2SAndroid Build Coastguard Worker       temp->dest            = _cupsStrAlloc(dest);
651*5e7646d2SAndroid Build Coastguard Worker       temp->user            = _cupsStrAlloc(user);
652*5e7646d2SAndroid Build Coastguard Worker       temp->format          = _cupsStrAlloc(format);
653*5e7646d2SAndroid Build Coastguard Worker       temp->title           = _cupsStrAlloc(title);
654*5e7646d2SAndroid Build Coastguard Worker       temp->id              = id;
655*5e7646d2SAndroid Build Coastguard Worker       temp->priority        = priority;
656*5e7646d2SAndroid Build Coastguard Worker       temp->state           = state;
657*5e7646d2SAndroid Build Coastguard Worker       temp->size            = size;
658*5e7646d2SAndroid Build Coastguard Worker       temp->completed_time  = completed_time;
659*5e7646d2SAndroid Build Coastguard Worker       temp->creation_time   = creation_time;
660*5e7646d2SAndroid Build Coastguard Worker       temp->processing_time = processing_time;
661*5e7646d2SAndroid Build Coastguard Worker 
662*5e7646d2SAndroid Build Coastguard Worker       if (!attr)
663*5e7646d2SAndroid Build Coastguard Worker         break;
664*5e7646d2SAndroid Build Coastguard Worker     }
665*5e7646d2SAndroid Build Coastguard Worker 
666*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
667*5e7646d2SAndroid Build Coastguard Worker   }
668*5e7646d2SAndroid Build Coastguard Worker 
669*5e7646d2SAndroid Build Coastguard Worker   if (n == 0 && cg->last_error >= IPP_STATUS_ERROR_BAD_REQUEST)
670*5e7646d2SAndroid Build Coastguard Worker     return (-1);
671*5e7646d2SAndroid Build Coastguard Worker   else
672*5e7646d2SAndroid Build Coastguard Worker     return (n);
673*5e7646d2SAndroid Build Coastguard Worker }
674*5e7646d2SAndroid Build Coastguard Worker 
675*5e7646d2SAndroid Build Coastguard Worker 
676*5e7646d2SAndroid Build Coastguard Worker /*
677*5e7646d2SAndroid Build Coastguard Worker  * 'cupsGetPrinters()' - Get a list of printers from the default server.
678*5e7646d2SAndroid Build Coastguard Worker  *
679*5e7646d2SAndroid Build Coastguard Worker  * This function is deprecated and no longer returns a list of printers - use
680*5e7646d2SAndroid Build Coastguard Worker  * @link cupsGetDests@ instead.
681*5e7646d2SAndroid Build Coastguard Worker  *
682*5e7646d2SAndroid Build Coastguard Worker  * @deprecated@ @exclude all@
683*5e7646d2SAndroid Build Coastguard Worker  */
684*5e7646d2SAndroid Build Coastguard Worker 
685*5e7646d2SAndroid Build Coastguard Worker int					/* O - Number of printers */
cupsGetPrinters(char *** printers)686*5e7646d2SAndroid Build Coastguard Worker cupsGetPrinters(char ***printers)	/* O - Printers */
687*5e7646d2SAndroid Build Coastguard Worker {
688*5e7646d2SAndroid Build Coastguard Worker   if (printers)
689*5e7646d2SAndroid Build Coastguard Worker     *printers = NULL;
690*5e7646d2SAndroid Build Coastguard Worker 
691*5e7646d2SAndroid Build Coastguard Worker   return (0);
692*5e7646d2SAndroid Build Coastguard Worker }
693*5e7646d2SAndroid Build Coastguard Worker 
694*5e7646d2SAndroid Build Coastguard Worker 
695*5e7646d2SAndroid Build Coastguard Worker /*
696*5e7646d2SAndroid Build Coastguard Worker  * 'cupsPrintFile()' - Print a file to a printer or class on the default server.
697*5e7646d2SAndroid Build Coastguard Worker  *
698*5e7646d2SAndroid Build Coastguard Worker  * @exclude all@
699*5e7646d2SAndroid Build Coastguard Worker  */
700*5e7646d2SAndroid Build Coastguard Worker 
701*5e7646d2SAndroid Build Coastguard Worker int					/* O - Job ID or 0 on error */
cupsPrintFile(const char * name,const char * filename,const char * title,int num_options,cups_option_t * options)702*5e7646d2SAndroid Build Coastguard Worker cupsPrintFile(const char    *name,	/* I - Destination name */
703*5e7646d2SAndroid Build Coastguard Worker               const char    *filename,	/* I - File to print */
704*5e7646d2SAndroid Build Coastguard Worker 	      const char    *title,	/* I - Title of job */
705*5e7646d2SAndroid Build Coastguard Worker               int           num_options,/* I - Number of options */
706*5e7646d2SAndroid Build Coastguard Worker 	      cups_option_t *options)	/* I - Options */
707*5e7646d2SAndroid Build Coastguard Worker {
708*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("cupsPrintFile(name=\"%s\", filename=\"%s\", title=\"%s\", num_options=%d, options=%p)", name, filename, title, num_options, (void *)options));
709*5e7646d2SAndroid Build Coastguard Worker 
710*5e7646d2SAndroid Build Coastguard Worker   return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, 1, &filename, title,
711*5e7646d2SAndroid Build Coastguard Worker                           num_options, options));
712*5e7646d2SAndroid Build Coastguard Worker }
713*5e7646d2SAndroid Build Coastguard Worker 
714*5e7646d2SAndroid Build Coastguard Worker 
715*5e7646d2SAndroid Build Coastguard Worker /*
716*5e7646d2SAndroid Build Coastguard Worker  * 'cupsPrintFile2()' - Print a file to a printer or class on the specified
717*5e7646d2SAndroid Build Coastguard Worker  *                      server.
718*5e7646d2SAndroid Build Coastguard Worker  *
719*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.1.21/macOS 10.4@ @exclude all@
720*5e7646d2SAndroid Build Coastguard Worker  */
721*5e7646d2SAndroid Build Coastguard Worker 
722*5e7646d2SAndroid Build Coastguard Worker int					/* O - Job ID or 0 on error */
cupsPrintFile2(http_t * http,const char * name,const char * filename,const char * title,int num_options,cups_option_t * options)723*5e7646d2SAndroid Build Coastguard Worker cupsPrintFile2(
724*5e7646d2SAndroid Build Coastguard Worker     http_t        *http,		/* I - Connection to server */
725*5e7646d2SAndroid Build Coastguard Worker     const char    *name,		/* I - Destination name */
726*5e7646d2SAndroid Build Coastguard Worker     const char    *filename,		/* I - File to print */
727*5e7646d2SAndroid Build Coastguard Worker     const char    *title,		/* I - Title of job */
728*5e7646d2SAndroid Build Coastguard Worker     int           num_options,		/* I - Number of options */
729*5e7646d2SAndroid Build Coastguard Worker     cups_option_t *options)		/* I - Options */
730*5e7646d2SAndroid Build Coastguard Worker {
731*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("cupsPrintFile2(http=%p, name=\"%s\", filename=\"%s\",  title=\"%s\", num_options=%d, options=%p)", (void *)http, name, filename, title, num_options, (void *)options));
732*5e7646d2SAndroid Build Coastguard Worker 
733*5e7646d2SAndroid Build Coastguard Worker   return (cupsPrintFiles2(http, name, 1, &filename, title, num_options,
734*5e7646d2SAndroid Build Coastguard Worker                           options));
735*5e7646d2SAndroid Build Coastguard Worker }
736*5e7646d2SAndroid Build Coastguard Worker 
737*5e7646d2SAndroid Build Coastguard Worker 
738*5e7646d2SAndroid Build Coastguard Worker /*
739*5e7646d2SAndroid Build Coastguard Worker  * 'cupsPrintFiles()' - Print one or more files to a printer or class on the
740*5e7646d2SAndroid Build Coastguard Worker  *                      default server.
741*5e7646d2SAndroid Build Coastguard Worker  *
742*5e7646d2SAndroid Build Coastguard Worker  * @exclude all@
743*5e7646d2SAndroid Build Coastguard Worker  */
744*5e7646d2SAndroid Build Coastguard Worker 
745*5e7646d2SAndroid Build Coastguard Worker int					/* O - Job ID or 0 on error */
cupsPrintFiles(const char * name,int num_files,const char ** files,const char * title,int num_options,cups_option_t * options)746*5e7646d2SAndroid Build Coastguard Worker cupsPrintFiles(
747*5e7646d2SAndroid Build Coastguard Worker     const char    *name,		/* I - Destination name */
748*5e7646d2SAndroid Build Coastguard Worker     int           num_files,		/* I - Number of files */
749*5e7646d2SAndroid Build Coastguard Worker     const char    **files,		/* I - File(s) to print */
750*5e7646d2SAndroid Build Coastguard Worker     const char    *title,		/* I - Title of job */
751*5e7646d2SAndroid Build Coastguard Worker     int           num_options,		/* I - Number of options */
752*5e7646d2SAndroid Build Coastguard Worker     cups_option_t *options)		/* I - Options */
753*5e7646d2SAndroid Build Coastguard Worker {
754*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("cupsPrintFiles(name=\"%s\", num_files=%d, files=%p, title=\"%s\", num_options=%d, options=%p)", name, num_files, (void *)files, title, num_options, (void *)options));
755*5e7646d2SAndroid Build Coastguard Worker 
756*5e7646d2SAndroid Build Coastguard Worker  /*
757*5e7646d2SAndroid Build Coastguard Worker   * Print the file(s)...
758*5e7646d2SAndroid Build Coastguard Worker   */
759*5e7646d2SAndroid Build Coastguard Worker 
760*5e7646d2SAndroid Build Coastguard Worker   return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, num_files, files, title,
761*5e7646d2SAndroid Build Coastguard Worker                           num_options, options));
762*5e7646d2SAndroid Build Coastguard Worker }
763*5e7646d2SAndroid Build Coastguard Worker 
764*5e7646d2SAndroid Build Coastguard Worker 
765*5e7646d2SAndroid Build Coastguard Worker /*
766*5e7646d2SAndroid Build Coastguard Worker  * 'cupsPrintFiles2()' - Print one or more files to a printer or class on the
767*5e7646d2SAndroid Build Coastguard Worker  *                       specified server.
768*5e7646d2SAndroid Build Coastguard Worker  *
769*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.1.21/macOS 10.4@ @exclude all@
770*5e7646d2SAndroid Build Coastguard Worker  */
771*5e7646d2SAndroid Build Coastguard Worker 
772*5e7646d2SAndroid Build Coastguard Worker int					/* O - Job ID or 0 on error */
cupsPrintFiles2(http_t * http,const char * name,int num_files,const char ** files,const char * title,int num_options,cups_option_t * options)773*5e7646d2SAndroid Build Coastguard Worker cupsPrintFiles2(
774*5e7646d2SAndroid Build Coastguard Worker     http_t        *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
775*5e7646d2SAndroid Build Coastguard Worker     const char    *name,		/* I - Destination name */
776*5e7646d2SAndroid Build Coastguard Worker     int           num_files,		/* I - Number of files */
777*5e7646d2SAndroid Build Coastguard Worker     const char    **files,		/* I - File(s) to print */
778*5e7646d2SAndroid Build Coastguard Worker     const char    *title,		/* I - Title of job */
779*5e7646d2SAndroid Build Coastguard Worker     int           num_options,		/* I - Number of options */
780*5e7646d2SAndroid Build Coastguard Worker     cups_option_t *options)		/* I - Options */
781*5e7646d2SAndroid Build Coastguard Worker {
782*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
783*5e7646d2SAndroid Build Coastguard Worker   int		job_id;			/* New job ID */
784*5e7646d2SAndroid Build Coastguard Worker   const char	*docname;		/* Basename of current filename */
785*5e7646d2SAndroid Build Coastguard Worker   const char	*format;		/* Document format */
786*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* Current file */
787*5e7646d2SAndroid Build Coastguard Worker   char		buffer[8192];		/* Copy buffer */
788*5e7646d2SAndroid Build Coastguard Worker   ssize_t	bytes;			/* Bytes in buffer */
789*5e7646d2SAndroid Build Coastguard Worker   http_status_t	status;			/* Status of write */
790*5e7646d2SAndroid Build Coastguard Worker   _cups_globals_t *cg = _cupsGlobals();	/* Global data */
791*5e7646d2SAndroid Build Coastguard Worker   ipp_status_t	cancel_status;		/* Status code to preserve */
792*5e7646d2SAndroid Build Coastguard Worker   char		*cancel_message;	/* Error message to preserve */
793*5e7646d2SAndroid Build Coastguard Worker 
794*5e7646d2SAndroid Build Coastguard Worker 
795*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("cupsPrintFiles2(http=%p, name=\"%s\", num_files=%d, files=%p, title=\"%s\", num_options=%d, options=%p)", (void *)http, name, num_files, (void *)files, title, num_options, (void *)options));
796*5e7646d2SAndroid Build Coastguard Worker 
797*5e7646d2SAndroid Build Coastguard Worker  /*
798*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
799*5e7646d2SAndroid Build Coastguard Worker   */
800*5e7646d2SAndroid Build Coastguard Worker 
801*5e7646d2SAndroid Build Coastguard Worker   if (!name || num_files < 1 || !files)
802*5e7646d2SAndroid Build Coastguard Worker   {
803*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
804*5e7646d2SAndroid Build Coastguard Worker 
805*5e7646d2SAndroid Build Coastguard Worker     return (0);
806*5e7646d2SAndroid Build Coastguard Worker   }
807*5e7646d2SAndroid Build Coastguard Worker 
808*5e7646d2SAndroid Build Coastguard Worker  /*
809*5e7646d2SAndroid Build Coastguard Worker   * Create the print job...
810*5e7646d2SAndroid Build Coastguard Worker   */
811*5e7646d2SAndroid Build Coastguard Worker 
812*5e7646d2SAndroid Build Coastguard Worker   if ((job_id = cupsCreateJob(http, name, title, num_options, options)) == 0)
813*5e7646d2SAndroid Build Coastguard Worker     return (0);
814*5e7646d2SAndroid Build Coastguard Worker 
815*5e7646d2SAndroid Build Coastguard Worker  /*
816*5e7646d2SAndroid Build Coastguard Worker   * Send each of the files...
817*5e7646d2SAndroid Build Coastguard Worker   */
818*5e7646d2SAndroid Build Coastguard Worker 
819*5e7646d2SAndroid Build Coastguard Worker   if (cupsGetOption("raw", num_options, options))
820*5e7646d2SAndroid Build Coastguard Worker     format = CUPS_FORMAT_RAW;
821*5e7646d2SAndroid Build Coastguard Worker   else if ((format = cupsGetOption("document-format", num_options,
822*5e7646d2SAndroid Build Coastguard Worker 				   options)) == NULL)
823*5e7646d2SAndroid Build Coastguard Worker     format = CUPS_FORMAT_AUTO;
824*5e7646d2SAndroid Build Coastguard Worker 
825*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; i < num_files; i ++)
826*5e7646d2SAndroid Build Coastguard Worker   {
827*5e7646d2SAndroid Build Coastguard Worker    /*
828*5e7646d2SAndroid Build Coastguard Worker     * Start the next file...
829*5e7646d2SAndroid Build Coastguard Worker     */
830*5e7646d2SAndroid Build Coastguard Worker 
831*5e7646d2SAndroid Build Coastguard Worker     if ((docname = strrchr(files[i], '/')) != NULL)
832*5e7646d2SAndroid Build Coastguard Worker       docname ++;
833*5e7646d2SAndroid Build Coastguard Worker     else
834*5e7646d2SAndroid Build Coastguard Worker       docname = files[i];
835*5e7646d2SAndroid Build Coastguard Worker 
836*5e7646d2SAndroid Build Coastguard Worker     if ((fp = cupsFileOpen(files[i], "rb")) == NULL)
837*5e7646d2SAndroid Build Coastguard Worker     {
838*5e7646d2SAndroid Build Coastguard Worker      /*
839*5e7646d2SAndroid Build Coastguard Worker       * Unable to open print file, cancel the job and return...
840*5e7646d2SAndroid Build Coastguard Worker       */
841*5e7646d2SAndroid Build Coastguard Worker 
842*5e7646d2SAndroid Build Coastguard Worker       _cupsSetError(IPP_STATUS_ERROR_DOCUMENT_ACCESS, NULL, 0);
843*5e7646d2SAndroid Build Coastguard Worker       goto cancel_job;
844*5e7646d2SAndroid Build Coastguard Worker     }
845*5e7646d2SAndroid Build Coastguard Worker 
846*5e7646d2SAndroid Build Coastguard Worker     status = cupsStartDocument(http, name, job_id, docname, format,
847*5e7646d2SAndroid Build Coastguard Worker 			       i == (num_files - 1));
848*5e7646d2SAndroid Build Coastguard Worker 
849*5e7646d2SAndroid Build Coastguard Worker     while (status == HTTP_STATUS_CONTINUE &&
850*5e7646d2SAndroid Build Coastguard Worker 	   (bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
851*5e7646d2SAndroid Build Coastguard Worker       status = cupsWriteRequestData(http, buffer, (size_t)bytes);
852*5e7646d2SAndroid Build Coastguard Worker 
853*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(fp);
854*5e7646d2SAndroid Build Coastguard Worker 
855*5e7646d2SAndroid Build Coastguard Worker     if (status != HTTP_STATUS_CONTINUE || cupsFinishDocument(http, name) != IPP_STATUS_OK)
856*5e7646d2SAndroid Build Coastguard Worker     {
857*5e7646d2SAndroid Build Coastguard Worker      /*
858*5e7646d2SAndroid Build Coastguard Worker       * Unable to queue, cancel the job and return...
859*5e7646d2SAndroid Build Coastguard Worker       */
860*5e7646d2SAndroid Build Coastguard Worker 
861*5e7646d2SAndroid Build Coastguard Worker       goto cancel_job;
862*5e7646d2SAndroid Build Coastguard Worker     }
863*5e7646d2SAndroid Build Coastguard Worker   }
864*5e7646d2SAndroid Build Coastguard Worker 
865*5e7646d2SAndroid Build Coastguard Worker   return (job_id);
866*5e7646d2SAndroid Build Coastguard Worker 
867*5e7646d2SAndroid Build Coastguard Worker  /*
868*5e7646d2SAndroid Build Coastguard Worker   * If we get here, something happened while sending the print job so we need
869*5e7646d2SAndroid Build Coastguard Worker   * to cancel the job without setting the last error (since we need to preserve
870*5e7646d2SAndroid Build Coastguard Worker   * the current error...
871*5e7646d2SAndroid Build Coastguard Worker   */
872*5e7646d2SAndroid Build Coastguard Worker 
873*5e7646d2SAndroid Build Coastguard Worker   cancel_job:
874*5e7646d2SAndroid Build Coastguard Worker 
875*5e7646d2SAndroid Build Coastguard Worker   cancel_status  = cg->last_error;
876*5e7646d2SAndroid Build Coastguard Worker   cancel_message = cg->last_status_message ?
877*5e7646d2SAndroid Build Coastguard Worker                        _cupsStrRetain(cg->last_status_message) : NULL;
878*5e7646d2SAndroid Build Coastguard Worker 
879*5e7646d2SAndroid Build Coastguard Worker   cupsCancelJob2(http, name, job_id, 0);
880*5e7646d2SAndroid Build Coastguard Worker 
881*5e7646d2SAndroid Build Coastguard Worker   cg->last_error          = cancel_status;
882*5e7646d2SAndroid Build Coastguard Worker   cg->last_status_message = cancel_message;
883*5e7646d2SAndroid Build Coastguard Worker 
884*5e7646d2SAndroid Build Coastguard Worker   return (0);
885*5e7646d2SAndroid Build Coastguard Worker }
886*5e7646d2SAndroid Build Coastguard Worker 
887*5e7646d2SAndroid Build Coastguard Worker 
888*5e7646d2SAndroid Build Coastguard Worker /*
889*5e7646d2SAndroid Build Coastguard Worker  * 'cupsStartDocument()' - Add a document to a job created with cupsCreateJob().
890*5e7646d2SAndroid Build Coastguard Worker  *
891*5e7646d2SAndroid Build Coastguard Worker  * Use @link cupsWriteRequestData@ to write data for the document and
892*5e7646d2SAndroid Build Coastguard Worker  * @link cupsFinishDocument@ to finish the document and get the submission status.
893*5e7646d2SAndroid Build Coastguard Worker  *
894*5e7646d2SAndroid Build Coastguard Worker  * The MIME type constants @code CUPS_FORMAT_AUTO@, @code CUPS_FORMAT_PDF@,
895*5e7646d2SAndroid Build Coastguard Worker  * @code CUPS_FORMAT_POSTSCRIPT@, @code CUPS_FORMAT_RAW@, and
896*5e7646d2SAndroid Build Coastguard Worker  * @code CUPS_FORMAT_TEXT@ are provided for the "format" argument, although
897*5e7646d2SAndroid Build Coastguard Worker  * any supported MIME type string can be supplied.
898*5e7646d2SAndroid Build Coastguard Worker  *
899*5e7646d2SAndroid Build Coastguard Worker  * @since CUPS 1.4/macOS 10.6@ @exclude all@
900*5e7646d2SAndroid Build Coastguard Worker  */
901*5e7646d2SAndroid Build Coastguard Worker 
902*5e7646d2SAndroid Build Coastguard Worker http_status_t				/* O - HTTP status of request */
cupsStartDocument(http_t * http,const char * name,int job_id,const char * docname,const char * format,int last_document)903*5e7646d2SAndroid Build Coastguard Worker cupsStartDocument(
904*5e7646d2SAndroid Build Coastguard Worker     http_t     *http,			/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
905*5e7646d2SAndroid Build Coastguard Worker     const char *name,			/* I - Destination name */
906*5e7646d2SAndroid Build Coastguard Worker     int        job_id,			/* I - Job ID from @link cupsCreateJob@ */
907*5e7646d2SAndroid Build Coastguard Worker     const char *docname,		/* I - Name of document */
908*5e7646d2SAndroid Build Coastguard Worker     const char *format,			/* I - MIME type or @code CUPS_FORMAT_foo@ */
909*5e7646d2SAndroid Build Coastguard Worker     int        last_document)		/* I - 1 for last document in job, 0 otherwise */
910*5e7646d2SAndroid Build Coastguard Worker {
911*5e7646d2SAndroid Build Coastguard Worker   char		resource[1024],		/* Resource for destinatio */
912*5e7646d2SAndroid Build Coastguard Worker 		printer_uri[1024];	/* Printer URI */
913*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request;		/* Send-Document request */
914*5e7646d2SAndroid Build Coastguard Worker   http_status_t	status;			/* HTTP status */
915*5e7646d2SAndroid Build Coastguard Worker 
916*5e7646d2SAndroid Build Coastguard Worker 
917*5e7646d2SAndroid Build Coastguard Worker  /*
918*5e7646d2SAndroid Build Coastguard Worker   * Create a Send-Document request...
919*5e7646d2SAndroid Build Coastguard Worker   */
920*5e7646d2SAndroid Build Coastguard Worker 
921*5e7646d2SAndroid Build Coastguard Worker   if ((request = ippNewRequest(IPP_OP_SEND_DOCUMENT)) == NULL)
922*5e7646d2SAndroid Build Coastguard Worker   {
923*5e7646d2SAndroid Build Coastguard Worker     _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
924*5e7646d2SAndroid Build Coastguard Worker     return (HTTP_STATUS_ERROR);
925*5e7646d2SAndroid Build Coastguard Worker   }
926*5e7646d2SAndroid Build Coastguard Worker 
927*5e7646d2SAndroid Build Coastguard Worker   httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp",
928*5e7646d2SAndroid Build Coastguard Worker                    NULL, "localhost", ippPort(), "/printers/%s", name);
929*5e7646d2SAndroid Build Coastguard Worker   snprintf(resource, sizeof(resource), "/printers/%s", name);
930*5e7646d2SAndroid Build Coastguard Worker 
931*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
932*5e7646d2SAndroid Build Coastguard Worker                NULL, printer_uri);
933*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
934*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
935*5e7646d2SAndroid Build Coastguard Worker                NULL, cupsUser());
936*5e7646d2SAndroid Build Coastguard Worker   if (docname)
937*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
938*5e7646d2SAndroid Build Coastguard Worker                  NULL, docname);
939*5e7646d2SAndroid Build Coastguard Worker   if (format)
940*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
941*5e7646d2SAndroid Build Coastguard Worker                  "document-format", NULL, format);
942*5e7646d2SAndroid Build Coastguard Worker   ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", (char)last_document);
943*5e7646d2SAndroid Build Coastguard Worker 
944*5e7646d2SAndroid Build Coastguard Worker  /*
945*5e7646d2SAndroid Build Coastguard Worker   * Send and delete the request, then return the status...
946*5e7646d2SAndroid Build Coastguard Worker   */
947*5e7646d2SAndroid Build Coastguard Worker 
948*5e7646d2SAndroid Build Coastguard Worker   status = cupsSendRequest(http, request, resource, CUPS_LENGTH_VARIABLE);
949*5e7646d2SAndroid Build Coastguard Worker 
950*5e7646d2SAndroid Build Coastguard Worker   ippDelete(request);
951*5e7646d2SAndroid Build Coastguard Worker 
952*5e7646d2SAndroid Build Coastguard Worker   return (status);
953*5e7646d2SAndroid Build Coastguard Worker }
954*5e7646d2SAndroid Build Coastguard Worker 
955