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