1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Job management routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
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 "cupsd.h"
16*5e7646d2SAndroid Build Coastguard Worker #include <grp.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <cups/backend.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <cups/dir.h>
19*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
20*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/pwr_mgt/IOPMLib.h>
21*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H
22*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/pwr_mgt/IOPMLibPrivate.h>
23*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
24*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker /*
28*5e7646d2SAndroid Build Coastguard Worker * Design Notes for Job Management
29*5e7646d2SAndroid Build Coastguard Worker * -------------------------------
30*5e7646d2SAndroid Build Coastguard Worker *
31*5e7646d2SAndroid Build Coastguard Worker * STATE CHANGES
32*5e7646d2SAndroid Build Coastguard Worker *
33*5e7646d2SAndroid Build Coastguard Worker * pending Do nothing/check jobs
34*5e7646d2SAndroid Build Coastguard Worker * pending-held Send SIGTERM to filters and backend
35*5e7646d2SAndroid Build Coastguard Worker * processing Do nothing/start job
36*5e7646d2SAndroid Build Coastguard Worker * stopped Send SIGKILL to filters and backend
37*5e7646d2SAndroid Build Coastguard Worker * canceled Send SIGTERM to filters and backend
38*5e7646d2SAndroid Build Coastguard Worker * aborted Finalize
39*5e7646d2SAndroid Build Coastguard Worker * completed Finalize
40*5e7646d2SAndroid Build Coastguard Worker *
41*5e7646d2SAndroid Build Coastguard Worker * Finalize clears the printer <-> job association, deletes the status
42*5e7646d2SAndroid Build Coastguard Worker * buffer, closes all of the pipes, etc. and doesn't get run until all of
43*5e7646d2SAndroid Build Coastguard Worker * the print processes are finished.
44*5e7646d2SAndroid Build Coastguard Worker *
45*5e7646d2SAndroid Build Coastguard Worker * UNLOADING OF JOBS (cupsdUnloadCompletedJobs)
46*5e7646d2SAndroid Build Coastguard Worker *
47*5e7646d2SAndroid Build Coastguard Worker * We unload the job attributes when they are not needed to reduce overall
48*5e7646d2SAndroid Build Coastguard Worker * memory consumption. We don't unload jobs where job->state_value <
49*5e7646d2SAndroid Build Coastguard Worker * IPP_JOB_STOPPED, job->printer != NULL, or job->access_time is recent.
50*5e7646d2SAndroid Build Coastguard Worker *
51*5e7646d2SAndroid Build Coastguard Worker * STARTING OF JOBS (start_job)
52*5e7646d2SAndroid Build Coastguard Worker *
53*5e7646d2SAndroid Build Coastguard Worker * When a job is started, a status buffer, several pipes, a security
54*5e7646d2SAndroid Build Coastguard Worker * profile, and a backend process are created for the life of that job.
55*5e7646d2SAndroid Build Coastguard Worker * These are shared for every file in a job. For remote print jobs, the
56*5e7646d2SAndroid Build Coastguard Worker * IPP backend is provided with every file in the job and no filters are
57*5e7646d2SAndroid Build Coastguard Worker * run.
58*5e7646d2SAndroid Build Coastguard Worker *
59*5e7646d2SAndroid Build Coastguard Worker * The job->printer member tracks which printer is printing a job, which
60*5e7646d2SAndroid Build Coastguard Worker * can be different than the destination in job->dest for classes. The
61*5e7646d2SAndroid Build Coastguard Worker * printer object also has a job pointer to track which job is being
62*5e7646d2SAndroid Build Coastguard Worker * printed.
63*5e7646d2SAndroid Build Coastguard Worker *
64*5e7646d2SAndroid Build Coastguard Worker * PRINTING OF JOB FILES (cupsdContinueJob)
65*5e7646d2SAndroid Build Coastguard Worker *
66*5e7646d2SAndroid Build Coastguard Worker * Each file in a job is filtered by 0 or more programs. After getting the
67*5e7646d2SAndroid Build Coastguard Worker * list of filters needed and the total cost, the job is either passed or
68*5e7646d2SAndroid Build Coastguard Worker * put back to the processing state until the current FilterLevel comes down
69*5e7646d2SAndroid Build Coastguard Worker * enough to allow printing.
70*5e7646d2SAndroid Build Coastguard Worker *
71*5e7646d2SAndroid Build Coastguard Worker * If we can print, we build a string for the print options and run each of
72*5e7646d2SAndroid Build Coastguard Worker * the filters, piping the output from one into the next.
73*5e7646d2SAndroid Build Coastguard Worker *
74*5e7646d2SAndroid Build Coastguard Worker * JOB STATUS UPDATES (update_job)
75*5e7646d2SAndroid Build Coastguard Worker *
76*5e7646d2SAndroid Build Coastguard Worker * The update_job function gets called whenever there are pending messages
77*5e7646d2SAndroid Build Coastguard Worker * on the status pipe. These generally are updates to the marker-*,
78*5e7646d2SAndroid Build Coastguard Worker * printer-state-message, or printer-state-reasons attributes. On EOF,
79*5e7646d2SAndroid Build Coastguard Worker * finalize_job is called to clean up.
80*5e7646d2SAndroid Build Coastguard Worker *
81*5e7646d2SAndroid Build Coastguard Worker * FINALIZING JOBS (finalize_job)
82*5e7646d2SAndroid Build Coastguard Worker *
83*5e7646d2SAndroid Build Coastguard Worker * When all filters and the backend are done, we set the job state to
84*5e7646d2SAndroid Build Coastguard Worker * completed (no errors), aborted (filter errors or abort-job policy),
85*5e7646d2SAndroid Build Coastguard Worker * pending-held (auth required or retry-job policy), or pending
86*5e7646d2SAndroid Build Coastguard Worker * (retry-current-job or stop-printer policies) as appropriate.
87*5e7646d2SAndroid Build Coastguard Worker *
88*5e7646d2SAndroid Build Coastguard Worker * Then we close the pipes and free the status buffers and profiles.
89*5e7646d2SAndroid Build Coastguard Worker *
90*5e7646d2SAndroid Build Coastguard Worker * JOB FILE COMPLETION (process_children in main.c)
91*5e7646d2SAndroid Build Coastguard Worker *
92*5e7646d2SAndroid Build Coastguard Worker * For multiple-file jobs, process_children (in main.c) sees that all
93*5e7646d2SAndroid Build Coastguard Worker * filters have exited and calls in to print the next file if there are
94*5e7646d2SAndroid Build Coastguard Worker * more files in the job, otherwise it waits for the backend to exit and
95*5e7646d2SAndroid Build Coastguard Worker * update_job to do the cleanup.
96*5e7646d2SAndroid Build Coastguard Worker */
97*5e7646d2SAndroid Build Coastguard Worker
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker /*
100*5e7646d2SAndroid Build Coastguard Worker * Local globals...
101*5e7646d2SAndroid Build Coastguard Worker */
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker static mime_filter_t gziptoany_filter =
104*5e7646d2SAndroid Build Coastguard Worker {
105*5e7646d2SAndroid Build Coastguard Worker NULL, /* Source type */
106*5e7646d2SAndroid Build Coastguard Worker NULL, /* Destination type */
107*5e7646d2SAndroid Build Coastguard Worker 0, /* Cost */
108*5e7646d2SAndroid Build Coastguard Worker "gziptoany" /* Filter program to run */
109*5e7646d2SAndroid Build Coastguard Worker };
110*5e7646d2SAndroid Build Coastguard Worker
111*5e7646d2SAndroid Build Coastguard Worker
112*5e7646d2SAndroid Build Coastguard Worker /*
113*5e7646d2SAndroid Build Coastguard Worker * Local functions...
114*5e7646d2SAndroid Build Coastguard Worker */
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker static int compare_active_jobs(void *first, void *second, void *data);
117*5e7646d2SAndroid Build Coastguard Worker static int compare_completed_jobs(void *first, void *second, void *data);
118*5e7646d2SAndroid Build Coastguard Worker static int compare_jobs(void *first, void *second, void *data);
119*5e7646d2SAndroid Build Coastguard Worker static void dump_job_history(cupsd_job_t *job);
120*5e7646d2SAndroid Build Coastguard Worker static void finalize_job(cupsd_job_t *job, int set_job_state);
121*5e7646d2SAndroid Build Coastguard Worker static void free_job_history(cupsd_job_t *job);
122*5e7646d2SAndroid Build Coastguard Worker static char *get_options(cupsd_job_t *job, int banner_page, char *copies,
123*5e7646d2SAndroid Build Coastguard Worker size_t copies_size, char *title,
124*5e7646d2SAndroid Build Coastguard Worker size_t title_size);
125*5e7646d2SAndroid Build Coastguard Worker static size_t ipp_length(ipp_t *ipp);
126*5e7646d2SAndroid Build Coastguard Worker static void load_job_cache(const char *filename);
127*5e7646d2SAndroid Build Coastguard Worker static void load_next_job_id(const char *filename);
128*5e7646d2SAndroid Build Coastguard Worker static void load_request_root(void);
129*5e7646d2SAndroid Build Coastguard Worker static void remove_job_files(cupsd_job_t *job);
130*5e7646d2SAndroid Build Coastguard Worker static void remove_job_history(cupsd_job_t *job);
131*5e7646d2SAndroid Build Coastguard Worker static void set_time(cupsd_job_t *job, const char *name);
132*5e7646d2SAndroid Build Coastguard Worker static void start_job(cupsd_job_t *job, cupsd_printer_t *printer);
133*5e7646d2SAndroid Build Coastguard Worker static void stop_job(cupsd_job_t *job, cupsd_jobaction_t action);
134*5e7646d2SAndroid Build Coastguard Worker static void unload_job(cupsd_job_t *job);
135*5e7646d2SAndroid Build Coastguard Worker static void update_job(cupsd_job_t *job);
136*5e7646d2SAndroid Build Coastguard Worker static void update_job_attrs(cupsd_job_t *job, int do_message);
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker
139*5e7646d2SAndroid Build Coastguard Worker /*
140*5e7646d2SAndroid Build Coastguard Worker * 'cupsdAddJob()' - Add a new job to the job queue.
141*5e7646d2SAndroid Build Coastguard Worker */
142*5e7646d2SAndroid Build Coastguard Worker
143*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t * /* O - New job record */
cupsdAddJob(int priority,const char * dest)144*5e7646d2SAndroid Build Coastguard Worker cupsdAddJob(int priority, /* I - Job priority */
145*5e7646d2SAndroid Build Coastguard Worker const char *dest) /* I - Job destination */
146*5e7646d2SAndroid Build Coastguard Worker {
147*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* New job record */
148*5e7646d2SAndroid Build Coastguard Worker
149*5e7646d2SAndroid Build Coastguard Worker
150*5e7646d2SAndroid Build Coastguard Worker if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL)
151*5e7646d2SAndroid Build Coastguard Worker return (NULL);
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker job->id = NextJobId ++;
154*5e7646d2SAndroid Build Coastguard Worker job->priority = priority;
155*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[0] = -1;
156*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[1] = -1;
157*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[0] = -1;
158*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = -1;
159*5e7646d2SAndroid Build Coastguard Worker job->side_pipes[0] = -1;
160*5e7646d2SAndroid Build Coastguard Worker job->side_pipes[1] = -1;
161*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[0] = -1;
162*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[1] = -1;
163*5e7646d2SAndroid Build Coastguard Worker
164*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->dest, dest);
165*5e7646d2SAndroid Build Coastguard Worker
166*5e7646d2SAndroid Build Coastguard Worker /*
167*5e7646d2SAndroid Build Coastguard Worker * Add the new job to the "all jobs" and "active jobs" lists...
168*5e7646d2SAndroid Build Coastguard Worker */
169*5e7646d2SAndroid Build Coastguard Worker
170*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(Jobs, job);
171*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ActiveJobs, job);
172*5e7646d2SAndroid Build Coastguard Worker
173*5e7646d2SAndroid Build Coastguard Worker return (job);
174*5e7646d2SAndroid Build Coastguard Worker }
175*5e7646d2SAndroid Build Coastguard Worker
176*5e7646d2SAndroid Build Coastguard Worker
177*5e7646d2SAndroid Build Coastguard Worker /*
178*5e7646d2SAndroid Build Coastguard Worker * 'cupsdCancelJobs()' - Cancel all jobs for the given destination/user.
179*5e7646d2SAndroid Build Coastguard Worker */
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker void
cupsdCancelJobs(const char * dest,const char * username,int purge)182*5e7646d2SAndroid Build Coastguard Worker cupsdCancelJobs(const char *dest, /* I - Destination to cancel */
183*5e7646d2SAndroid Build Coastguard Worker const char *username, /* I - Username or NULL */
184*5e7646d2SAndroid Build Coastguard Worker int purge) /* I - Purge jobs? */
185*5e7646d2SAndroid Build Coastguard Worker {
186*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
187*5e7646d2SAndroid Build Coastguard Worker
188*5e7646d2SAndroid Build Coastguard Worker
189*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
190*5e7646d2SAndroid Build Coastguard Worker job;
191*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
192*5e7646d2SAndroid Build Coastguard Worker {
193*5e7646d2SAndroid Build Coastguard Worker if ((!job->dest || !job->username) && !cupsdLoadJob(job))
194*5e7646d2SAndroid Build Coastguard Worker continue;
195*5e7646d2SAndroid Build Coastguard Worker
196*5e7646d2SAndroid Build Coastguard Worker if ((!dest || !strcmp(job->dest, dest)) &&
197*5e7646d2SAndroid Build Coastguard Worker (!username || !strcmp(job->username, username)))
198*5e7646d2SAndroid Build Coastguard Worker {
199*5e7646d2SAndroid Build Coastguard Worker /*
200*5e7646d2SAndroid Build Coastguard Worker * Cancel all jobs matching this destination/user...
201*5e7646d2SAndroid Build Coastguard Worker */
202*5e7646d2SAndroid Build Coastguard Worker
203*5e7646d2SAndroid Build Coastguard Worker if (purge)
204*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_PURGE,
205*5e7646d2SAndroid Build Coastguard Worker "Job purged by user.");
206*5e7646d2SAndroid Build Coastguard Worker else if (job->state_value < IPP_JOB_CANCELED)
207*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT,
208*5e7646d2SAndroid Build Coastguard Worker "Job canceled by user.");
209*5e7646d2SAndroid Build Coastguard Worker }
210*5e7646d2SAndroid Build Coastguard Worker }
211*5e7646d2SAndroid Build Coastguard Worker }
212*5e7646d2SAndroid Build Coastguard Worker
213*5e7646d2SAndroid Build Coastguard Worker
214*5e7646d2SAndroid Build Coastguard Worker /*
215*5e7646d2SAndroid Build Coastguard Worker * 'cupsdCheckJobs()' - Check the pending jobs and start any if the destination
216*5e7646d2SAndroid Build Coastguard Worker * is available.
217*5e7646d2SAndroid Build Coastguard Worker */
218*5e7646d2SAndroid Build Coastguard Worker
219*5e7646d2SAndroid Build Coastguard Worker void
cupsdCheckJobs(void)220*5e7646d2SAndroid Build Coastguard Worker cupsdCheckJobs(void)
221*5e7646d2SAndroid Build Coastguard Worker {
222*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job in queue */
223*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *printer, /* Printer destination */
224*5e7646d2SAndroid Build Coastguard Worker *pclass; /* Printer class destination */
225*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Job attribute */
226*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time */
227*5e7646d2SAndroid Build Coastguard Worker const char *reasons; /* job-state-reasons value */
228*5e7646d2SAndroid Build Coastguard Worker
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker curtime = time(NULL);
231*5e7646d2SAndroid Build Coastguard Worker
232*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckJobs: %d active jobs, sleeping=%d, ac-power=%d, reload=%d, curtime=%ld", cupsArrayCount(ActiveJobs), Sleeping, ACPower, NeedReload, (long)curtime);
233*5e7646d2SAndroid Build Coastguard Worker
234*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
235*5e7646d2SAndroid Build Coastguard Worker job;
236*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
237*5e7646d2SAndroid Build Coastguard Worker {
238*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2,
239*5e7646d2SAndroid Build Coastguard Worker "cupsdCheckJobs: Job %d - dest=\"%s\", printer=%p, "
240*5e7646d2SAndroid Build Coastguard Worker "state=%d, cancel_time=%ld, hold_until=%ld, kill_time=%ld, "
241*5e7646d2SAndroid Build Coastguard Worker "pending_cost=%d, pending_timeout=%ld", job->id, job->dest,
242*5e7646d2SAndroid Build Coastguard Worker job->printer, job->state_value, (long)job->cancel_time,
243*5e7646d2SAndroid Build Coastguard Worker (long)job->hold_until, (long)job->kill_time,
244*5e7646d2SAndroid Build Coastguard Worker job->pending_cost, (long)job->pending_timeout);
245*5e7646d2SAndroid Build Coastguard Worker
246*5e7646d2SAndroid Build Coastguard Worker /*
247*5e7646d2SAndroid Build Coastguard Worker * Kill jobs if they are unresponsive...
248*5e7646d2SAndroid Build Coastguard Worker */
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker if (job->kill_time && job->kill_time <= curtime)
251*5e7646d2SAndroid Build Coastguard Worker {
252*5e7646d2SAndroid Build Coastguard Worker if (!job->completed)
253*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "Stopping unresponsive job.");
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker stop_job(job, CUPSD_JOB_FORCE);
256*5e7646d2SAndroid Build Coastguard Worker continue;
257*5e7646d2SAndroid Build Coastguard Worker }
258*5e7646d2SAndroid Build Coastguard Worker
259*5e7646d2SAndroid Build Coastguard Worker /*
260*5e7646d2SAndroid Build Coastguard Worker * Cancel stuck jobs...
261*5e7646d2SAndroid Build Coastguard Worker */
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker if (job->cancel_time && job->cancel_time <= curtime)
264*5e7646d2SAndroid Build Coastguard Worker {
265*5e7646d2SAndroid Build Coastguard Worker int cancel_after; /* job-cancel-after value */
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(job->attrs, "job-cancel-after", IPP_TAG_INTEGER);
268*5e7646d2SAndroid Build Coastguard Worker cancel_after = attr ? ippGetInteger(attr, 0) : MaxJobTime;
269*5e7646d2SAndroid Build Coastguard Worker
270*5e7646d2SAndroid Build Coastguard Worker if (job->completed)
271*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_FORCE, "Marking stuck job as completed after %d seconds.", cancel_after);
272*5e7646d2SAndroid Build Coastguard Worker else
273*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT, "Canceling stuck job after %d seconds.", cancel_after);
274*5e7646d2SAndroid Build Coastguard Worker continue;
275*5e7646d2SAndroid Build Coastguard Worker }
276*5e7646d2SAndroid Build Coastguard Worker
277*5e7646d2SAndroid Build Coastguard Worker /*
278*5e7646d2SAndroid Build Coastguard Worker * Start held jobs if they are ready...
279*5e7646d2SAndroid Build Coastguard Worker */
280*5e7646d2SAndroid Build Coastguard Worker
281*5e7646d2SAndroid Build Coastguard Worker if (job->state_value == IPP_JOB_HELD &&
282*5e7646d2SAndroid Build Coastguard Worker job->hold_until &&
283*5e7646d2SAndroid Build Coastguard Worker job->hold_until < curtime)
284*5e7646d2SAndroid Build Coastguard Worker {
285*5e7646d2SAndroid Build Coastguard Worker if (job->pending_timeout)
286*5e7646d2SAndroid Build Coastguard Worker {
287*5e7646d2SAndroid Build Coastguard Worker /*
288*5e7646d2SAndroid Build Coastguard Worker * This job is pending; check that we don't have an active Send-Document
289*5e7646d2SAndroid Build Coastguard Worker * operation in progress on any of the client connections, then timeout
290*5e7646d2SAndroid Build Coastguard Worker * the job so we can start printing...
291*5e7646d2SAndroid Build Coastguard Worker */
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker cupsd_client_t *con; /* Current client connection */
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
296*5e7646d2SAndroid Build Coastguard Worker con;
297*5e7646d2SAndroid Build Coastguard Worker con = (cupsd_client_t *)cupsArrayNext(Clients))
298*5e7646d2SAndroid Build Coastguard Worker if (con->request &&
299*5e7646d2SAndroid Build Coastguard Worker con->request->request.op.operation_id == IPP_SEND_DOCUMENT)
300*5e7646d2SAndroid Build Coastguard Worker break;
301*5e7646d2SAndroid Build Coastguard Worker
302*5e7646d2SAndroid Build Coastguard Worker if (con)
303*5e7646d2SAndroid Build Coastguard Worker continue;
304*5e7646d2SAndroid Build Coastguard Worker
305*5e7646d2SAndroid Build Coastguard Worker if (cupsdTimeoutJob(job))
306*5e7646d2SAndroid Build Coastguard Worker continue;
307*5e7646d2SAndroid Build Coastguard Worker
308*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, "Job submission timed out.");
309*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "Job submission timed out.");
310*5e7646d2SAndroid Build Coastguard Worker }
311*5e7646d2SAndroid Build Coastguard Worker else
312*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, "Job hold expired.");
313*5e7646d2SAndroid Build Coastguard Worker }
314*5e7646d2SAndroid Build Coastguard Worker
315*5e7646d2SAndroid Build Coastguard Worker /*
316*5e7646d2SAndroid Build Coastguard Worker * Continue jobs that are waiting on the FilterLimit...
317*5e7646d2SAndroid Build Coastguard Worker */
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker if (job->pending_cost > 0 &&
320*5e7646d2SAndroid Build Coastguard Worker ((FilterLevel + job->pending_cost) < FilterLimit || FilterLevel == 0))
321*5e7646d2SAndroid Build Coastguard Worker cupsdContinueJob(job);
322*5e7646d2SAndroid Build Coastguard Worker
323*5e7646d2SAndroid Build Coastguard Worker /*
324*5e7646d2SAndroid Build Coastguard Worker * Skip jobs that where held-on-create
325*5e7646d2SAndroid Build Coastguard Worker */
326*5e7646d2SAndroid Build Coastguard Worker
327*5e7646d2SAndroid Build Coastguard Worker reasons = ippGetString(job->reasons, 0, NULL);
328*5e7646d2SAndroid Build Coastguard Worker if (reasons && !strcmp(reasons, "job-held-on-create"))
329*5e7646d2SAndroid Build Coastguard Worker {
330*5e7646d2SAndroid Build Coastguard Worker /*
331*5e7646d2SAndroid Build Coastguard Worker * Check whether the printer is still holding new jobs...
332*5e7646d2SAndroid Build Coastguard Worker */
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker printer = cupsdFindDest(job->dest);
335*5e7646d2SAndroid Build Coastguard Worker
336*5e7646d2SAndroid Build Coastguard Worker if (printer->holding_new_jobs)
337*5e7646d2SAndroid Build Coastguard Worker continue;
338*5e7646d2SAndroid Build Coastguard Worker
339*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "none");
340*5e7646d2SAndroid Build Coastguard Worker }
341*5e7646d2SAndroid Build Coastguard Worker
342*5e7646d2SAndroid Build Coastguard Worker /*
343*5e7646d2SAndroid Build Coastguard Worker * Start pending jobs if the destination is available...
344*5e7646d2SAndroid Build Coastguard Worker */
345*5e7646d2SAndroid Build Coastguard Worker
346*5e7646d2SAndroid Build Coastguard Worker if (job->state_value == IPP_JOB_PENDING && !NeedReload &&
347*5e7646d2SAndroid Build Coastguard Worker (!Sleeping || ACPower) && !DoingShutdown && !job->printer)
348*5e7646d2SAndroid Build Coastguard Worker {
349*5e7646d2SAndroid Build Coastguard Worker printer = cupsdFindDest(job->dest);
350*5e7646d2SAndroid Build Coastguard Worker pclass = NULL;
351*5e7646d2SAndroid Build Coastguard Worker
352*5e7646d2SAndroid Build Coastguard Worker while (printer && (printer->type & CUPS_PRINTER_CLASS))
353*5e7646d2SAndroid Build Coastguard Worker {
354*5e7646d2SAndroid Build Coastguard Worker /*
355*5e7646d2SAndroid Build Coastguard Worker * If the class is remote, just pass it to the remote server...
356*5e7646d2SAndroid Build Coastguard Worker */
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker pclass = printer;
359*5e7646d2SAndroid Build Coastguard Worker
360*5e7646d2SAndroid Build Coastguard Worker if (pclass->state == IPP_PRINTER_STOPPED)
361*5e7646d2SAndroid Build Coastguard Worker printer = NULL;
362*5e7646d2SAndroid Build Coastguard Worker else if (pclass->type & CUPS_PRINTER_REMOTE)
363*5e7646d2SAndroid Build Coastguard Worker break;
364*5e7646d2SAndroid Build Coastguard Worker else
365*5e7646d2SAndroid Build Coastguard Worker printer = cupsdFindAvailablePrinter(printer->name);
366*5e7646d2SAndroid Build Coastguard Worker }
367*5e7646d2SAndroid Build Coastguard Worker
368*5e7646d2SAndroid Build Coastguard Worker if (!printer && !pclass)
369*5e7646d2SAndroid Build Coastguard Worker {
370*5e7646d2SAndroid Build Coastguard Worker /*
371*5e7646d2SAndroid Build Coastguard Worker * Whoa, the printer and/or class for this destination went away;
372*5e7646d2SAndroid Build Coastguard Worker * cancel the job...
373*5e7646d2SAndroid Build Coastguard Worker */
374*5e7646d2SAndroid Build Coastguard Worker
375*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_PURGE,
376*5e7646d2SAndroid Build Coastguard Worker "Job aborted because the destination printer/class "
377*5e7646d2SAndroid Build Coastguard Worker "has gone away.");
378*5e7646d2SAndroid Build Coastguard Worker }
379*5e7646d2SAndroid Build Coastguard Worker else if (printer)
380*5e7646d2SAndroid Build Coastguard Worker {
381*5e7646d2SAndroid Build Coastguard Worker /*
382*5e7646d2SAndroid Build Coastguard Worker * See if the printer is available or remote and not printing a job;
383*5e7646d2SAndroid Build Coastguard Worker * if so, start the job...
384*5e7646d2SAndroid Build Coastguard Worker */
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker if (pclass)
387*5e7646d2SAndroid Build Coastguard Worker {
388*5e7646d2SAndroid Build Coastguard Worker /*
389*5e7646d2SAndroid Build Coastguard Worker * Add/update a job-printer-uri-actual attribute for this job
390*5e7646d2SAndroid Build Coastguard Worker * so that we know which printer actually printed the job...
391*5e7646d2SAndroid Build Coastguard Worker */
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-printer-uri-actual", IPP_TAG_URI)) != NULL)
394*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &attr, 0, printer->uri);
395*5e7646d2SAndroid Build Coastguard Worker else
396*5e7646d2SAndroid Build Coastguard Worker ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri-actual", NULL, printer->uri);
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
399*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
400*5e7646d2SAndroid Build Coastguard Worker }
401*5e7646d2SAndroid Build Coastguard Worker
402*5e7646d2SAndroid Build Coastguard Worker if (!printer->job && printer->state == IPP_PRINTER_IDLE)
403*5e7646d2SAndroid Build Coastguard Worker {
404*5e7646d2SAndroid Build Coastguard Worker /*
405*5e7646d2SAndroid Build Coastguard Worker * Start the job...
406*5e7646d2SAndroid Build Coastguard Worker */
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ActiveJobs);
409*5e7646d2SAndroid Build Coastguard Worker start_job(job, printer);
410*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ActiveJobs);
411*5e7646d2SAndroid Build Coastguard Worker }
412*5e7646d2SAndroid Build Coastguard Worker }
413*5e7646d2SAndroid Build Coastguard Worker }
414*5e7646d2SAndroid Build Coastguard Worker }
415*5e7646d2SAndroid Build Coastguard Worker }
416*5e7646d2SAndroid Build Coastguard Worker
417*5e7646d2SAndroid Build Coastguard Worker
418*5e7646d2SAndroid Build Coastguard Worker /*
419*5e7646d2SAndroid Build Coastguard Worker * 'cupsdCleanJobs()' - Clean out old jobs.
420*5e7646d2SAndroid Build Coastguard Worker */
421*5e7646d2SAndroid Build Coastguard Worker
422*5e7646d2SAndroid Build Coastguard Worker void
cupsdCleanJobs(void)423*5e7646d2SAndroid Build Coastguard Worker cupsdCleanJobs(void)
424*5e7646d2SAndroid Build Coastguard Worker {
425*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
426*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time */
427*5e7646d2SAndroid Build Coastguard Worker
428*5e7646d2SAndroid Build Coastguard Worker
429*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2,
430*5e7646d2SAndroid Build Coastguard Worker "cupsdCleanJobs: MaxJobs=%d, JobHistory=%d, JobFiles=%d",
431*5e7646d2SAndroid Build Coastguard Worker MaxJobs, JobHistory, JobFiles);
432*5e7646d2SAndroid Build Coastguard Worker
433*5e7646d2SAndroid Build Coastguard Worker if (MaxJobs <= 0 && JobHistory == INT_MAX && JobFiles == INT_MAX)
434*5e7646d2SAndroid Build Coastguard Worker return;
435*5e7646d2SAndroid Build Coastguard Worker
436*5e7646d2SAndroid Build Coastguard Worker curtime = time(NULL);
437*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = 0;
438*5e7646d2SAndroid Build Coastguard Worker
439*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCleanJobs: curtime=%d", (int)curtime);
440*5e7646d2SAndroid Build Coastguard Worker
441*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
442*5e7646d2SAndroid Build Coastguard Worker job;
443*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
444*5e7646d2SAndroid Build Coastguard Worker {
445*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCleanJobs: Job %d, state=%d, printer=%p, history_time=%d, file_time=%d", job->id, (int)job->state_value, (void *)job->printer, (int)job->history_time, (int)job->file_time);
446*5e7646d2SAndroid Build Coastguard Worker
447*5e7646d2SAndroid Build Coastguard Worker if ((job->history_time && job->history_time < JobHistoryUpdate) || !JobHistoryUpdate)
448*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->history_time;
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker if ((job->file_time && job->file_time < JobHistoryUpdate) || !JobHistoryUpdate)
451*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->file_time;
452*5e7646d2SAndroid Build Coastguard Worker
453*5e7646d2SAndroid Build Coastguard Worker if (job->state_value >= IPP_JOB_CANCELED && !job->printer)
454*5e7646d2SAndroid Build Coastguard Worker {
455*5e7646d2SAndroid Build Coastguard Worker /*
456*5e7646d2SAndroid Build Coastguard Worker * Expire old jobs (or job files)...
457*5e7646d2SAndroid Build Coastguard Worker */
458*5e7646d2SAndroid Build Coastguard Worker
459*5e7646d2SAndroid Build Coastguard Worker if ((MaxJobs > 0 && cupsArrayCount(Jobs) >= MaxJobs) ||
460*5e7646d2SAndroid Build Coastguard Worker (job->history_time && job->history_time <= curtime))
461*5e7646d2SAndroid Build Coastguard Worker {
462*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing from history.");
463*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteJob(job, CUPSD_JOB_PURGE);
464*5e7646d2SAndroid Build Coastguard Worker }
465*5e7646d2SAndroid Build Coastguard Worker else if (job->file_time && job->file_time <= curtime && job->num_files > 0)
466*5e7646d2SAndroid Build Coastguard Worker {
467*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing document files.");
468*5e7646d2SAndroid Build Coastguard Worker remove_job_files(job);
469*5e7646d2SAndroid Build Coastguard Worker
470*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
471*5e7646d2SAndroid Build Coastguard Worker }
472*5e7646d2SAndroid Build Coastguard Worker }
473*5e7646d2SAndroid Build Coastguard Worker }
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCleanJobs: JobHistoryUpdate=%ld",
476*5e7646d2SAndroid Build Coastguard Worker (long)JobHistoryUpdate);
477*5e7646d2SAndroid Build Coastguard Worker }
478*5e7646d2SAndroid Build Coastguard Worker
479*5e7646d2SAndroid Build Coastguard Worker
480*5e7646d2SAndroid Build Coastguard Worker /*
481*5e7646d2SAndroid Build Coastguard Worker * 'cupsdContinueJob()' - Continue printing with the next file in a job.
482*5e7646d2SAndroid Build Coastguard Worker */
483*5e7646d2SAndroid Build Coastguard Worker
484*5e7646d2SAndroid Build Coastguard Worker void
cupsdContinueJob(cupsd_job_t * job)485*5e7646d2SAndroid Build Coastguard Worker cupsdContinueJob(cupsd_job_t *job) /* I - Job */
486*5e7646d2SAndroid Build Coastguard Worker {
487*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
488*5e7646d2SAndroid Build Coastguard Worker int slot; /* Pipe slot */
489*5e7646d2SAndroid Build Coastguard Worker cups_array_t *filters = NULL,/* Filters for job */
490*5e7646d2SAndroid Build Coastguard Worker *prefilters; /* Filters with prefilters */
491*5e7646d2SAndroid Build Coastguard Worker mime_filter_t *filter, /* Current filter */
492*5e7646d2SAndroid Build Coastguard Worker *prefilter, /* Prefilter */
493*5e7646d2SAndroid Build Coastguard Worker port_monitor; /* Port monitor filter */
494*5e7646d2SAndroid Build Coastguard Worker char scheme[255]; /* Device URI scheme */
495*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
496*5e7646d2SAndroid Build Coastguard Worker const char *ptr, /* Pointer into value */
497*5e7646d2SAndroid Build Coastguard Worker *abort_message; /* Abort message */
498*5e7646d2SAndroid Build Coastguard Worker ipp_jstate_t abort_state = IPP_JOB_STOPPED;
499*5e7646d2SAndroid Build Coastguard Worker /* New job state on abort */
500*5e7646d2SAndroid Build Coastguard Worker struct stat backinfo; /* Backend file information */
501*5e7646d2SAndroid Build Coastguard Worker int backroot; /* Run backend as root? */
502*5e7646d2SAndroid Build Coastguard Worker int pid; /* Process ID of new filter process */
503*5e7646d2SAndroid Build Coastguard Worker int banner_page; /* 1 if banner page, 0 otherwise */
504*5e7646d2SAndroid Build Coastguard Worker int filterfds[2][2] = { { -1, -1 }, { -1, -1 } };
505*5e7646d2SAndroid Build Coastguard Worker /* Pipes used between filters */
506*5e7646d2SAndroid Build Coastguard Worker int envc; /* Number of environment variables */
507*5e7646d2SAndroid Build Coastguard Worker struct stat fileinfo; /* Job file information */
508*5e7646d2SAndroid Build Coastguard Worker int argc = 0; /* Number of arguments */
509*5e7646d2SAndroid Build Coastguard Worker char **argv = NULL, /* Filter command-line arguments */
510*5e7646d2SAndroid Build Coastguard Worker filename[1024], /* Job filename */
511*5e7646d2SAndroid Build Coastguard Worker command[1024], /* Full path to command */
512*5e7646d2SAndroid Build Coastguard Worker jobid[255], /* Job ID string */
513*5e7646d2SAndroid Build Coastguard Worker title[IPP_MAX_NAME],
514*5e7646d2SAndroid Build Coastguard Worker /* Job title string */
515*5e7646d2SAndroid Build Coastguard Worker copies[255], /* # copies string */
516*5e7646d2SAndroid Build Coastguard Worker *options, /* Options string */
517*5e7646d2SAndroid Build Coastguard Worker *envp[MAX_ENV + 21],
518*5e7646d2SAndroid Build Coastguard Worker /* Environment variables */
519*5e7646d2SAndroid Build Coastguard Worker charset[255], /* CHARSET env variable */
520*5e7646d2SAndroid Build Coastguard Worker class_name[255],/* CLASS env variable */
521*5e7646d2SAndroid Build Coastguard Worker classification[1024],
522*5e7646d2SAndroid Build Coastguard Worker /* CLASSIFICATION env variable */
523*5e7646d2SAndroid Build Coastguard Worker content_type[1024],
524*5e7646d2SAndroid Build Coastguard Worker /* CONTENT_TYPE env variable */
525*5e7646d2SAndroid Build Coastguard Worker device_uri[1024],
526*5e7646d2SAndroid Build Coastguard Worker /* DEVICE_URI env variable */
527*5e7646d2SAndroid Build Coastguard Worker final_content_type[1024] = "",
528*5e7646d2SAndroid Build Coastguard Worker /* FINAL_CONTENT_TYPE env variable */
529*5e7646d2SAndroid Build Coastguard Worker lang[255], /* LANG env variable */
530*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
531*5e7646d2SAndroid Build Coastguard Worker apple_language[255],
532*5e7646d2SAndroid Build Coastguard Worker /* APPLE_LANGUAGE env variable */
533*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
534*5e7646d2SAndroid Build Coastguard Worker auth_info_required[255],
535*5e7646d2SAndroid Build Coastguard Worker /* AUTH_INFO_REQUIRED env variable */
536*5e7646d2SAndroid Build Coastguard Worker ppd[1024], /* PPD env variable */
537*5e7646d2SAndroid Build Coastguard Worker printer_info[255],
538*5e7646d2SAndroid Build Coastguard Worker /* PRINTER_INFO env variable */
539*5e7646d2SAndroid Build Coastguard Worker printer_location[255],
540*5e7646d2SAndroid Build Coastguard Worker /* PRINTER_LOCATION env variable */
541*5e7646d2SAndroid Build Coastguard Worker printer_name[255],
542*5e7646d2SAndroid Build Coastguard Worker /* PRINTER env variable */
543*5e7646d2SAndroid Build Coastguard Worker *printer_state_reasons = NULL,
544*5e7646d2SAndroid Build Coastguard Worker /* PRINTER_STATE_REASONS env var */
545*5e7646d2SAndroid Build Coastguard Worker rip_max_cache[255];
546*5e7646d2SAndroid Build Coastguard Worker /* RIP_MAX_CACHE env variable */
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker
549*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2,
550*5e7646d2SAndroid Build Coastguard Worker "cupsdContinueJob(job=%p(%d)): current_file=%d, num_files=%d",
551*5e7646d2SAndroid Build Coastguard Worker job, job->id, job->current_file, job->num_files);
552*5e7646d2SAndroid Build Coastguard Worker
553*5e7646d2SAndroid Build Coastguard Worker /*
554*5e7646d2SAndroid Build Coastguard Worker * Figure out what filters are required to convert from
555*5e7646d2SAndroid Build Coastguard Worker * the source to the destination type...
556*5e7646d2SAndroid Build Coastguard Worker */
557*5e7646d2SAndroid Build Coastguard Worker
558*5e7646d2SAndroid Build Coastguard Worker FilterLevel -= job->cost;
559*5e7646d2SAndroid Build Coastguard Worker
560*5e7646d2SAndroid Build Coastguard Worker job->cost = 0;
561*5e7646d2SAndroid Build Coastguard Worker job->pending_cost = 0;
562*5e7646d2SAndroid Build Coastguard Worker
563*5e7646d2SAndroid Build Coastguard Worker memset(job->filters, 0, sizeof(job->filters));
564*5e7646d2SAndroid Build Coastguard Worker
565*5e7646d2SAndroid Build Coastguard Worker if (job->printer->raw)
566*5e7646d2SAndroid Build Coastguard Worker {
567*5e7646d2SAndroid Build Coastguard Worker /*
568*5e7646d2SAndroid Build Coastguard Worker * Remote jobs and raw queues go directly to the printer without
569*5e7646d2SAndroid Build Coastguard Worker * filtering...
570*5e7646d2SAndroid Build Coastguard Worker */
571*5e7646d2SAndroid Build Coastguard Worker
572*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Sending job to queue tagged as raw...");
573*5e7646d2SAndroid Build Coastguard Worker }
574*5e7646d2SAndroid Build Coastguard Worker else
575*5e7646d2SAndroid Build Coastguard Worker {
576*5e7646d2SAndroid Build Coastguard Worker /*
577*5e7646d2SAndroid Build Coastguard Worker * Local jobs get filtered...
578*5e7646d2SAndroid Build Coastguard Worker */
579*5e7646d2SAndroid Build Coastguard Worker
580*5e7646d2SAndroid Build Coastguard Worker mime_type_t *dst = job->printer->filetype;
581*5e7646d2SAndroid Build Coastguard Worker /* Destination file type */
582*5e7646d2SAndroid Build Coastguard Worker
583*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
584*5e7646d2SAndroid Build Coastguard Worker job->id, job->current_file + 1);
585*5e7646d2SAndroid Build Coastguard Worker if (stat(filename, &fileinfo))
586*5e7646d2SAndroid Build Coastguard Worker fileinfo.st_size = 0;
587*5e7646d2SAndroid Build Coastguard Worker
588*5e7646d2SAndroid Build Coastguard Worker if (job->retry_as_raster)
589*5e7646d2SAndroid Build Coastguard Worker {
590*5e7646d2SAndroid Build Coastguard Worker /*
591*5e7646d2SAndroid Build Coastguard Worker * Need to figure out whether the printer supports image/pwg-raster or
592*5e7646d2SAndroid Build Coastguard Worker * image/urf, and use the corresponding type...
593*5e7646d2SAndroid Build Coastguard Worker */
594*5e7646d2SAndroid Build Coastguard Worker
595*5e7646d2SAndroid Build Coastguard Worker char type[MIME_MAX_TYPE]; /* MIME media type for printer */
596*5e7646d2SAndroid Build Coastguard Worker
597*5e7646d2SAndroid Build Coastguard Worker snprintf(type, sizeof(type), "%s/image/urf", job->printer->name);
598*5e7646d2SAndroid Build Coastguard Worker if ((dst = mimeType(MimeDatabase, "printer", type)) == NULL)
599*5e7646d2SAndroid Build Coastguard Worker {
600*5e7646d2SAndroid Build Coastguard Worker snprintf(type, sizeof(type), "%s/image/pwg-raster", job->printer->name);
601*5e7646d2SAndroid Build Coastguard Worker dst = mimeType(MimeDatabase, "printer", type);
602*5e7646d2SAndroid Build Coastguard Worker }
603*5e7646d2SAndroid Build Coastguard Worker
604*5e7646d2SAndroid Build Coastguard Worker if (dst)
605*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Retrying job as \"%s\".", strchr(dst->type, '/') + 1);
606*5e7646d2SAndroid Build Coastguard Worker else
607*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to retry job using a supported raster format.");
608*5e7646d2SAndroid Build Coastguard Worker }
609*5e7646d2SAndroid Build Coastguard Worker
610*5e7646d2SAndroid Build Coastguard Worker filters = mimeFilter2(MimeDatabase, job->filetypes[job->current_file], (size_t)fileinfo.st_size, dst, &(job->cost));
611*5e7646d2SAndroid Build Coastguard Worker
612*5e7646d2SAndroid Build Coastguard Worker if (!filters)
613*5e7646d2SAndroid Build Coastguard Worker {
614*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
615*5e7646d2SAndroid Build Coastguard Worker "Unable to convert file %d to printable format.",
616*5e7646d2SAndroid Build Coastguard Worker job->current_file);
617*5e7646d2SAndroid Build Coastguard Worker
618*5e7646d2SAndroid Build Coastguard Worker abort_message = "Aborting job because it cannot be printed.";
619*5e7646d2SAndroid Build Coastguard Worker abort_state = IPP_JOB_ABORTED;
620*5e7646d2SAndroid Build Coastguard Worker
621*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "document-unprintable-error");
622*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
623*5e7646d2SAndroid Build Coastguard Worker }
624*5e7646d2SAndroid Build Coastguard Worker
625*5e7646d2SAndroid Build Coastguard Worker /*
626*5e7646d2SAndroid Build Coastguard Worker * Figure out the final content type...
627*5e7646d2SAndroid Build Coastguard Worker */
628*5e7646d2SAndroid Build Coastguard Worker
629*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "%d filters for job:",
630*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(filters));
631*5e7646d2SAndroid Build Coastguard Worker for (filter = (mime_filter_t *)cupsArrayFirst(filters);
632*5e7646d2SAndroid Build Coastguard Worker filter;
633*5e7646d2SAndroid Build Coastguard Worker filter = (mime_filter_t *)cupsArrayNext(filters))
634*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s (%s/%s to %s/%s, cost %d)",
635*5e7646d2SAndroid Build Coastguard Worker filter->filter,
636*5e7646d2SAndroid Build Coastguard Worker filter->src ? filter->src->super : "???",
637*5e7646d2SAndroid Build Coastguard Worker filter->src ? filter->src->type : "???",
638*5e7646d2SAndroid Build Coastguard Worker filter->dst ? filter->dst->super : "???",
639*5e7646d2SAndroid Build Coastguard Worker filter->dst ? filter->dst->type : "???",
640*5e7646d2SAndroid Build Coastguard Worker filter->cost);
641*5e7646d2SAndroid Build Coastguard Worker
642*5e7646d2SAndroid Build Coastguard Worker if (!job->printer->remote)
643*5e7646d2SAndroid Build Coastguard Worker {
644*5e7646d2SAndroid Build Coastguard Worker for (filter = (mime_filter_t *)cupsArrayLast(filters);
645*5e7646d2SAndroid Build Coastguard Worker filter && filter->dst;
646*5e7646d2SAndroid Build Coastguard Worker filter = (mime_filter_t *)cupsArrayPrev(filters))
647*5e7646d2SAndroid Build Coastguard Worker if (strcmp(filter->dst->super, "printer") ||
648*5e7646d2SAndroid Build Coastguard Worker strcmp(filter->dst->type, job->printer->name))
649*5e7646d2SAndroid Build Coastguard Worker break;
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker if (filter && filter->dst)
652*5e7646d2SAndroid Build Coastguard Worker {
653*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strchr(filter->dst->type, '/')) != NULL)
654*5e7646d2SAndroid Build Coastguard Worker snprintf(final_content_type, sizeof(final_content_type),
655*5e7646d2SAndroid Build Coastguard Worker "FINAL_CONTENT_TYPE=%s", ptr + 1);
656*5e7646d2SAndroid Build Coastguard Worker else
657*5e7646d2SAndroid Build Coastguard Worker snprintf(final_content_type, sizeof(final_content_type),
658*5e7646d2SAndroid Build Coastguard Worker "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super,
659*5e7646d2SAndroid Build Coastguard Worker filter->dst->type);
660*5e7646d2SAndroid Build Coastguard Worker }
661*5e7646d2SAndroid Build Coastguard Worker else
662*5e7646d2SAndroid Build Coastguard Worker snprintf(final_content_type, sizeof(final_content_type),
663*5e7646d2SAndroid Build Coastguard Worker "FINAL_CONTENT_TYPE=printer/%s", job->printer->name);
664*5e7646d2SAndroid Build Coastguard Worker }
665*5e7646d2SAndroid Build Coastguard Worker
666*5e7646d2SAndroid Build Coastguard Worker /*
667*5e7646d2SAndroid Build Coastguard Worker * Remove NULL ("-") filters...
668*5e7646d2SAndroid Build Coastguard Worker */
669*5e7646d2SAndroid Build Coastguard Worker
670*5e7646d2SAndroid Build Coastguard Worker for (filter = (mime_filter_t *)cupsArrayFirst(filters);
671*5e7646d2SAndroid Build Coastguard Worker filter;
672*5e7646d2SAndroid Build Coastguard Worker filter = (mime_filter_t *)cupsArrayNext(filters))
673*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(filter->filter, "-"))
674*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(filters, filter);
675*5e7646d2SAndroid Build Coastguard Worker
676*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(filters) == 0)
677*5e7646d2SAndroid Build Coastguard Worker {
678*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(filters);
679*5e7646d2SAndroid Build Coastguard Worker filters = NULL;
680*5e7646d2SAndroid Build Coastguard Worker }
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker /*
683*5e7646d2SAndroid Build Coastguard Worker * If this printer has any pre-filters, insert the required pre-filter
684*5e7646d2SAndroid Build Coastguard Worker * in the filters array...
685*5e7646d2SAndroid Build Coastguard Worker */
686*5e7646d2SAndroid Build Coastguard Worker
687*5e7646d2SAndroid Build Coastguard Worker if (job->printer->prefiltertype && filters)
688*5e7646d2SAndroid Build Coastguard Worker {
689*5e7646d2SAndroid Build Coastguard Worker prefilters = cupsArrayNew(NULL, NULL);
690*5e7646d2SAndroid Build Coastguard Worker
691*5e7646d2SAndroid Build Coastguard Worker for (filter = (mime_filter_t *)cupsArrayFirst(filters);
692*5e7646d2SAndroid Build Coastguard Worker filter;
693*5e7646d2SAndroid Build Coastguard Worker filter = (mime_filter_t *)cupsArrayNext(filters))
694*5e7646d2SAndroid Build Coastguard Worker {
695*5e7646d2SAndroid Build Coastguard Worker if ((prefilter = mimeFilterLookup(MimeDatabase, filter->src,
696*5e7646d2SAndroid Build Coastguard Worker job->printer->prefiltertype)))
697*5e7646d2SAndroid Build Coastguard Worker {
698*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(prefilters, prefilter);
699*5e7646d2SAndroid Build Coastguard Worker job->cost += prefilter->cost;
700*5e7646d2SAndroid Build Coastguard Worker }
701*5e7646d2SAndroid Build Coastguard Worker
702*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(prefilters, filter);
703*5e7646d2SAndroid Build Coastguard Worker }
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(filters);
706*5e7646d2SAndroid Build Coastguard Worker filters = prefilters;
707*5e7646d2SAndroid Build Coastguard Worker }
708*5e7646d2SAndroid Build Coastguard Worker }
709*5e7646d2SAndroid Build Coastguard Worker
710*5e7646d2SAndroid Build Coastguard Worker /*
711*5e7646d2SAndroid Build Coastguard Worker * Set a minimum cost of 100 for all jobs so that FilterLimit
712*5e7646d2SAndroid Build Coastguard Worker * works with raw queues and other low-cost paths.
713*5e7646d2SAndroid Build Coastguard Worker */
714*5e7646d2SAndroid Build Coastguard Worker
715*5e7646d2SAndroid Build Coastguard Worker if (job->cost < 100)
716*5e7646d2SAndroid Build Coastguard Worker job->cost = 100;
717*5e7646d2SAndroid Build Coastguard Worker
718*5e7646d2SAndroid Build Coastguard Worker /*
719*5e7646d2SAndroid Build Coastguard Worker * See if the filter cost is too high...
720*5e7646d2SAndroid Build Coastguard Worker */
721*5e7646d2SAndroid Build Coastguard Worker
722*5e7646d2SAndroid Build Coastguard Worker if ((FilterLevel + job->cost) > FilterLimit && FilterLevel > 0 &&
723*5e7646d2SAndroid Build Coastguard Worker FilterLimit > 0)
724*5e7646d2SAndroid Build Coastguard Worker {
725*5e7646d2SAndroid Build Coastguard Worker /*
726*5e7646d2SAndroid Build Coastguard Worker * Don't print this job quite yet...
727*5e7646d2SAndroid Build Coastguard Worker */
728*5e7646d2SAndroid Build Coastguard Worker
729*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(filters);
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_INFO,
732*5e7646d2SAndroid Build Coastguard Worker "Holding because filter limit has been reached.");
733*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2,
734*5e7646d2SAndroid Build Coastguard Worker "cupsdContinueJob: file=%d, cost=%d, level=%d, limit=%d",
735*5e7646d2SAndroid Build Coastguard Worker job->current_file, job->cost, FilterLevel,
736*5e7646d2SAndroid Build Coastguard Worker FilterLimit);
737*5e7646d2SAndroid Build Coastguard Worker
738*5e7646d2SAndroid Build Coastguard Worker job->pending_cost = job->cost;
739*5e7646d2SAndroid Build Coastguard Worker job->cost = 0;
740*5e7646d2SAndroid Build Coastguard Worker return;
741*5e7646d2SAndroid Build Coastguard Worker }
742*5e7646d2SAndroid Build Coastguard Worker
743*5e7646d2SAndroid Build Coastguard Worker FilterLevel += job->cost;
744*5e7646d2SAndroid Build Coastguard Worker
745*5e7646d2SAndroid Build Coastguard Worker /*
746*5e7646d2SAndroid Build Coastguard Worker * Add decompression/raw filter as needed...
747*5e7646d2SAndroid Build Coastguard Worker */
748*5e7646d2SAndroid Build Coastguard Worker
749*5e7646d2SAndroid Build Coastguard Worker if ((job->compressions[job->current_file] && (!job->printer->remote || job->num_files == 1)) ||
750*5e7646d2SAndroid Build Coastguard Worker (!job->printer->remote && job->printer->raw && job->num_files > 1))
751*5e7646d2SAndroid Build Coastguard Worker {
752*5e7646d2SAndroid Build Coastguard Worker /*
753*5e7646d2SAndroid Build Coastguard Worker * Add gziptoany filter to the front of the list...
754*5e7646d2SAndroid Build Coastguard Worker */
755*5e7646d2SAndroid Build Coastguard Worker
756*5e7646d2SAndroid Build Coastguard Worker if (!filters)
757*5e7646d2SAndroid Build Coastguard Worker filters = cupsArrayNew(NULL, NULL);
758*5e7646d2SAndroid Build Coastguard Worker
759*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayInsert(filters, &gziptoany_filter))
760*5e7646d2SAndroid Build Coastguard Worker {
761*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
762*5e7646d2SAndroid Build Coastguard Worker "Unable to add decompression filter - %s", strerror(errno));
763*5e7646d2SAndroid Build Coastguard Worker
764*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(filters);
765*5e7646d2SAndroid Build Coastguard Worker
766*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler ran out of memory.";
767*5e7646d2SAndroid Build Coastguard Worker
768*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
769*5e7646d2SAndroid Build Coastguard Worker }
770*5e7646d2SAndroid Build Coastguard Worker }
771*5e7646d2SAndroid Build Coastguard Worker
772*5e7646d2SAndroid Build Coastguard Worker /*
773*5e7646d2SAndroid Build Coastguard Worker * Add port monitor, if any...
774*5e7646d2SAndroid Build Coastguard Worker */
775*5e7646d2SAndroid Build Coastguard Worker
776*5e7646d2SAndroid Build Coastguard Worker if (job->printer->port_monitor)
777*5e7646d2SAndroid Build Coastguard Worker {
778*5e7646d2SAndroid Build Coastguard Worker /*
779*5e7646d2SAndroid Build Coastguard Worker * Add port monitor to the end of the list...
780*5e7646d2SAndroid Build Coastguard Worker */
781*5e7646d2SAndroid Build Coastguard Worker
782*5e7646d2SAndroid Build Coastguard Worker if (!filters)
783*5e7646d2SAndroid Build Coastguard Worker filters = cupsArrayNew(NULL, NULL);
784*5e7646d2SAndroid Build Coastguard Worker
785*5e7646d2SAndroid Build Coastguard Worker port_monitor.src = NULL;
786*5e7646d2SAndroid Build Coastguard Worker port_monitor.dst = NULL;
787*5e7646d2SAndroid Build Coastguard Worker port_monitor.cost = 0;
788*5e7646d2SAndroid Build Coastguard Worker
789*5e7646d2SAndroid Build Coastguard Worker snprintf(port_monitor.filter, sizeof(port_monitor.filter),
790*5e7646d2SAndroid Build Coastguard Worker "%s/monitor/%s", ServerBin, job->printer->port_monitor);
791*5e7646d2SAndroid Build Coastguard Worker
792*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayAdd(filters, &port_monitor))
793*5e7646d2SAndroid Build Coastguard Worker {
794*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
795*5e7646d2SAndroid Build Coastguard Worker "Unable to add port monitor - %s", strerror(errno));
796*5e7646d2SAndroid Build Coastguard Worker
797*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler ran out of memory.";
798*5e7646d2SAndroid Build Coastguard Worker
799*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
800*5e7646d2SAndroid Build Coastguard Worker }
801*5e7646d2SAndroid Build Coastguard Worker }
802*5e7646d2SAndroid Build Coastguard Worker
803*5e7646d2SAndroid Build Coastguard Worker /*
804*5e7646d2SAndroid Build Coastguard Worker * Make sure we don't go over the "MAX_FILTERS" limit...
805*5e7646d2SAndroid Build Coastguard Worker */
806*5e7646d2SAndroid Build Coastguard Worker
807*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(filters) > MAX_FILTERS)
808*5e7646d2SAndroid Build Coastguard Worker {
809*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
810*5e7646d2SAndroid Build Coastguard Worker "Too many filters (%d > %d), unable to print.",
811*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(filters), MAX_FILTERS);
812*5e7646d2SAndroid Build Coastguard Worker
813*5e7646d2SAndroid Build Coastguard Worker abort_message = "Aborting job because it needs too many filters to print.";
814*5e7646d2SAndroid Build Coastguard Worker abort_state = IPP_JOB_ABORTED;
815*5e7646d2SAndroid Build Coastguard Worker
816*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "document-unprintable-error");
817*5e7646d2SAndroid Build Coastguard Worker
818*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
819*5e7646d2SAndroid Build Coastguard Worker }
820*5e7646d2SAndroid Build Coastguard Worker
821*5e7646d2SAndroid Build Coastguard Worker /*
822*5e7646d2SAndroid Build Coastguard Worker * Determine if we are printing a banner page or not...
823*5e7646d2SAndroid Build Coastguard Worker */
824*5e7646d2SAndroid Build Coastguard Worker
825*5e7646d2SAndroid Build Coastguard Worker if (job->job_sheets == NULL)
826*5e7646d2SAndroid Build Coastguard Worker {
827*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "No job-sheets attribute.");
828*5e7646d2SAndroid Build Coastguard Worker if ((job->job_sheets =
829*5e7646d2SAndroid Build Coastguard Worker ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL)
830*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
831*5e7646d2SAndroid Build Coastguard Worker "... but someone added one without setting job_sheets.");
832*5e7646d2SAndroid Build Coastguard Worker }
833*5e7646d2SAndroid Build Coastguard Worker else if (job->job_sheets->num_values == 1)
834*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s",
835*5e7646d2SAndroid Build Coastguard Worker job->job_sheets->values[0].string.text);
836*5e7646d2SAndroid Build Coastguard Worker else
837*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s,%s",
838*5e7646d2SAndroid Build Coastguard Worker job->job_sheets->values[0].string.text,
839*5e7646d2SAndroid Build Coastguard Worker job->job_sheets->values[1].string.text);
840*5e7646d2SAndroid Build Coastguard Worker
841*5e7646d2SAndroid Build Coastguard Worker if (job->printer->type & CUPS_PRINTER_REMOTE)
842*5e7646d2SAndroid Build Coastguard Worker banner_page = 0;
843*5e7646d2SAndroid Build Coastguard Worker else if (job->job_sheets == NULL)
844*5e7646d2SAndroid Build Coastguard Worker banner_page = 0;
845*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(job->job_sheets->values[0].string.text, "none") != 0 &&
846*5e7646d2SAndroid Build Coastguard Worker job->current_file == 0)
847*5e7646d2SAndroid Build Coastguard Worker banner_page = 1;
848*5e7646d2SAndroid Build Coastguard Worker else if (job->job_sheets->num_values > 1 &&
849*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(job->job_sheets->values[1].string.text, "none") != 0 &&
850*5e7646d2SAndroid Build Coastguard Worker job->current_file == (job->num_files - 1))
851*5e7646d2SAndroid Build Coastguard Worker banner_page = 1;
852*5e7646d2SAndroid Build Coastguard Worker else
853*5e7646d2SAndroid Build Coastguard Worker banner_page = 0;
854*5e7646d2SAndroid Build Coastguard Worker
855*5e7646d2SAndroid Build Coastguard Worker if ((options = get_options(job, banner_page, copies, sizeof(copies), title,
856*5e7646d2SAndroid Build Coastguard Worker sizeof(title))) == NULL)
857*5e7646d2SAndroid Build Coastguard Worker {
858*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler ran out of memory.";
859*5e7646d2SAndroid Build Coastguard Worker
860*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
861*5e7646d2SAndroid Build Coastguard Worker }
862*5e7646d2SAndroid Build Coastguard Worker
863*5e7646d2SAndroid Build Coastguard Worker /*
864*5e7646d2SAndroid Build Coastguard Worker * Build the command-line arguments for the filters. Each filter
865*5e7646d2SAndroid Build Coastguard Worker * has 6 or 7 arguments:
866*5e7646d2SAndroid Build Coastguard Worker *
867*5e7646d2SAndroid Build Coastguard Worker * argv[0] = printer
868*5e7646d2SAndroid Build Coastguard Worker * argv[1] = job ID
869*5e7646d2SAndroid Build Coastguard Worker * argv[2] = username
870*5e7646d2SAndroid Build Coastguard Worker * argv[3] = title
871*5e7646d2SAndroid Build Coastguard Worker * argv[4] = # copies
872*5e7646d2SAndroid Build Coastguard Worker * argv[5] = options
873*5e7646d2SAndroid Build Coastguard Worker * argv[6] = filename (optional; normally stdin)
874*5e7646d2SAndroid Build Coastguard Worker *
875*5e7646d2SAndroid Build Coastguard Worker * This allows legacy printer drivers that use the old System V
876*5e7646d2SAndroid Build Coastguard Worker * printing interface to be used by CUPS.
877*5e7646d2SAndroid Build Coastguard Worker *
878*5e7646d2SAndroid Build Coastguard Worker * For remote jobs, we send all of the files in the argument list.
879*5e7646d2SAndroid Build Coastguard Worker */
880*5e7646d2SAndroid Build Coastguard Worker
881*5e7646d2SAndroid Build Coastguard Worker if (job->printer->remote)
882*5e7646d2SAndroid Build Coastguard Worker argc = 6 + job->num_files;
883*5e7646d2SAndroid Build Coastguard Worker else
884*5e7646d2SAndroid Build Coastguard Worker argc = 7;
885*5e7646d2SAndroid Build Coastguard Worker
886*5e7646d2SAndroid Build Coastguard Worker if ((argv = calloc((size_t)argc + 1, sizeof(char *))) == NULL)
887*5e7646d2SAndroid Build Coastguard Worker {
888*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Unable to allocate argument array - %s",
889*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
890*5e7646d2SAndroid Build Coastguard Worker
891*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler ran out of memory.";
892*5e7646d2SAndroid Build Coastguard Worker
893*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
894*5e7646d2SAndroid Build Coastguard Worker }
895*5e7646d2SAndroid Build Coastguard Worker
896*5e7646d2SAndroid Build Coastguard Worker snprintf(jobid, sizeof(jobid), "%d", job->id);
897*5e7646d2SAndroid Build Coastguard Worker
898*5e7646d2SAndroid Build Coastguard Worker argv[0] = job->printer->name;
899*5e7646d2SAndroid Build Coastguard Worker argv[1] = jobid;
900*5e7646d2SAndroid Build Coastguard Worker argv[2] = job->username;
901*5e7646d2SAndroid Build Coastguard Worker argv[3] = title;
902*5e7646d2SAndroid Build Coastguard Worker argv[4] = copies;
903*5e7646d2SAndroid Build Coastguard Worker argv[5] = options;
904*5e7646d2SAndroid Build Coastguard Worker
905*5e7646d2SAndroid Build Coastguard Worker if (job->printer->remote && job->num_files > 1)
906*5e7646d2SAndroid Build Coastguard Worker {
907*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < job->num_files; i ++)
908*5e7646d2SAndroid Build Coastguard Worker {
909*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
910*5e7646d2SAndroid Build Coastguard Worker job->id, i + 1);
911*5e7646d2SAndroid Build Coastguard Worker argv[6 + i] = strdup(filename);
912*5e7646d2SAndroid Build Coastguard Worker }
913*5e7646d2SAndroid Build Coastguard Worker }
914*5e7646d2SAndroid Build Coastguard Worker else
915*5e7646d2SAndroid Build Coastguard Worker {
916*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
917*5e7646d2SAndroid Build Coastguard Worker job->id, job->current_file + 1);
918*5e7646d2SAndroid Build Coastguard Worker argv[6] = strdup(filename);
919*5e7646d2SAndroid Build Coastguard Worker }
920*5e7646d2SAndroid Build Coastguard Worker
921*5e7646d2SAndroid Build Coastguard Worker for (i = 0; argv[i]; i ++)
922*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "argv[%d]=\"%s\"", i, argv[i]);
923*5e7646d2SAndroid Build Coastguard Worker
924*5e7646d2SAndroid Build Coastguard Worker /*
925*5e7646d2SAndroid Build Coastguard Worker * Create environment variable strings for the filters...
926*5e7646d2SAndroid Build Coastguard Worker */
927*5e7646d2SAndroid Build Coastguard Worker
928*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(job->attrs, "attributes-natural-language",
929*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_LANGUAGE);
930*5e7646d2SAndroid Build Coastguard Worker
931*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
932*5e7646d2SAndroid Build Coastguard Worker strlcpy(apple_language, "APPLE_LANGUAGE=", sizeof(apple_language));
933*5e7646d2SAndroid Build Coastguard Worker _cupsAppleLanguage(attr->values[0].string.text,
934*5e7646d2SAndroid Build Coastguard Worker apple_language + 15, sizeof(apple_language) - 15);
935*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
936*5e7646d2SAndroid Build Coastguard Worker
937*5e7646d2SAndroid Build Coastguard Worker switch (strlen(attr->values[0].string.text))
938*5e7646d2SAndroid Build Coastguard Worker {
939*5e7646d2SAndroid Build Coastguard Worker default :
940*5e7646d2SAndroid Build Coastguard Worker /*
941*5e7646d2SAndroid Build Coastguard Worker * This is an unknown or badly formatted language code; use
942*5e7646d2SAndroid Build Coastguard Worker * the POSIX locale...
943*5e7646d2SAndroid Build Coastguard Worker */
944*5e7646d2SAndroid Build Coastguard Worker
945*5e7646d2SAndroid Build Coastguard Worker strlcpy(lang, "LANG=C", sizeof(lang));
946*5e7646d2SAndroid Build Coastguard Worker break;
947*5e7646d2SAndroid Build Coastguard Worker
948*5e7646d2SAndroid Build Coastguard Worker case 2 :
949*5e7646d2SAndroid Build Coastguard Worker /*
950*5e7646d2SAndroid Build Coastguard Worker * Just the language code (ll)...
951*5e7646d2SAndroid Build Coastguard Worker */
952*5e7646d2SAndroid Build Coastguard Worker
953*5e7646d2SAndroid Build Coastguard Worker snprintf(lang, sizeof(lang), "LANG=%s.UTF-8",
954*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text);
955*5e7646d2SAndroid Build Coastguard Worker break;
956*5e7646d2SAndroid Build Coastguard Worker
957*5e7646d2SAndroid Build Coastguard Worker case 5 :
958*5e7646d2SAndroid Build Coastguard Worker /*
959*5e7646d2SAndroid Build Coastguard Worker * Language and country code (ll-cc)...
960*5e7646d2SAndroid Build Coastguard Worker */
961*5e7646d2SAndroid Build Coastguard Worker
962*5e7646d2SAndroid Build Coastguard Worker snprintf(lang, sizeof(lang), "LANG=%c%c_%c%c.UTF-8",
963*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text[0],
964*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text[1],
965*5e7646d2SAndroid Build Coastguard Worker toupper(attr->values[0].string.text[3] & 255),
966*5e7646d2SAndroid Build Coastguard Worker toupper(attr->values[0].string.text[4] & 255));
967*5e7646d2SAndroid Build Coastguard Worker break;
968*5e7646d2SAndroid Build Coastguard Worker }
969*5e7646d2SAndroid Build Coastguard Worker
970*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "document-format",
971*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_MIMETYPE)) != NULL &&
972*5e7646d2SAndroid Build Coastguard Worker (ptr = strstr(attr->values[0].string.text, "charset=")) != NULL)
973*5e7646d2SAndroid Build Coastguard Worker snprintf(charset, sizeof(charset), "CHARSET=%s", ptr + 8);
974*5e7646d2SAndroid Build Coastguard Worker else
975*5e7646d2SAndroid Build Coastguard Worker strlcpy(charset, "CHARSET=utf-8", sizeof(charset));
976*5e7646d2SAndroid Build Coastguard Worker
977*5e7646d2SAndroid Build Coastguard Worker snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s",
978*5e7646d2SAndroid Build Coastguard Worker job->filetypes[job->current_file]->super,
979*5e7646d2SAndroid Build Coastguard Worker job->filetypes[job->current_file]->type);
980*5e7646d2SAndroid Build Coastguard Worker snprintf(device_uri, sizeof(device_uri), "DEVICE_URI=%s",
981*5e7646d2SAndroid Build Coastguard Worker job->printer->device_uri);
982*5e7646d2SAndroid Build Coastguard Worker snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", ServerRoot,
983*5e7646d2SAndroid Build Coastguard Worker job->printer->name);
984*5e7646d2SAndroid Build Coastguard Worker snprintf(printer_info, sizeof(printer_name), "PRINTER_INFO=%s",
985*5e7646d2SAndroid Build Coastguard Worker job->printer->info ? job->printer->info : "");
986*5e7646d2SAndroid Build Coastguard Worker snprintf(printer_location, sizeof(printer_name), "PRINTER_LOCATION=%s",
987*5e7646d2SAndroid Build Coastguard Worker job->printer->location ? job->printer->location : "");
988*5e7646d2SAndroid Build Coastguard Worker snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", job->printer->name);
989*5e7646d2SAndroid Build Coastguard Worker if (job->printer->num_reasons > 0)
990*5e7646d2SAndroid Build Coastguard Worker {
991*5e7646d2SAndroid Build Coastguard Worker char *psrptr; /* Pointer into PRINTER_STATE_REASONS */
992*5e7646d2SAndroid Build Coastguard Worker size_t psrlen; /* Size of PRINTER_STATE_REASONS */
993*5e7646d2SAndroid Build Coastguard Worker
994*5e7646d2SAndroid Build Coastguard Worker for (psrlen = 22, i = 0; i < job->printer->num_reasons; i ++)
995*5e7646d2SAndroid Build Coastguard Worker psrlen += strlen(job->printer->reasons[i]) + 1;
996*5e7646d2SAndroid Build Coastguard Worker
997*5e7646d2SAndroid Build Coastguard Worker if ((printer_state_reasons = malloc(psrlen)) != NULL)
998*5e7646d2SAndroid Build Coastguard Worker {
999*5e7646d2SAndroid Build Coastguard Worker /*
1000*5e7646d2SAndroid Build Coastguard Worker * All of these strcpy's are safe because we allocated the psr string...
1001*5e7646d2SAndroid Build Coastguard Worker */
1002*5e7646d2SAndroid Build Coastguard Worker
1003*5e7646d2SAndroid Build Coastguard Worker strlcpy(printer_state_reasons, "PRINTER_STATE_REASONS=", psrlen);
1004*5e7646d2SAndroid Build Coastguard Worker for (psrptr = printer_state_reasons + 22, i = 0;
1005*5e7646d2SAndroid Build Coastguard Worker i < job->printer->num_reasons;
1006*5e7646d2SAndroid Build Coastguard Worker i ++)
1007*5e7646d2SAndroid Build Coastguard Worker {
1008*5e7646d2SAndroid Build Coastguard Worker if (i)
1009*5e7646d2SAndroid Build Coastguard Worker *psrptr++ = ',';
1010*5e7646d2SAndroid Build Coastguard Worker strlcpy(psrptr, job->printer->reasons[i], psrlen - (size_t)(psrptr - printer_state_reasons));
1011*5e7646d2SAndroid Build Coastguard Worker psrptr += strlen(psrptr);
1012*5e7646d2SAndroid Build Coastguard Worker }
1013*5e7646d2SAndroid Build Coastguard Worker }
1014*5e7646d2SAndroid Build Coastguard Worker }
1015*5e7646d2SAndroid Build Coastguard Worker snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache);
1016*5e7646d2SAndroid Build Coastguard Worker
1017*5e7646d2SAndroid Build Coastguard Worker if (job->printer->num_auth_info_required == 1)
1018*5e7646d2SAndroid Build Coastguard Worker snprintf(auth_info_required, sizeof(auth_info_required),
1019*5e7646d2SAndroid Build Coastguard Worker "AUTH_INFO_REQUIRED=%s",
1020*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[0]);
1021*5e7646d2SAndroid Build Coastguard Worker else if (job->printer->num_auth_info_required == 2)
1022*5e7646d2SAndroid Build Coastguard Worker snprintf(auth_info_required, sizeof(auth_info_required),
1023*5e7646d2SAndroid Build Coastguard Worker "AUTH_INFO_REQUIRED=%s,%s",
1024*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[0],
1025*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[1]);
1026*5e7646d2SAndroid Build Coastguard Worker else if (job->printer->num_auth_info_required == 3)
1027*5e7646d2SAndroid Build Coastguard Worker snprintf(auth_info_required, sizeof(auth_info_required),
1028*5e7646d2SAndroid Build Coastguard Worker "AUTH_INFO_REQUIRED=%s,%s,%s",
1029*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[0],
1030*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[1],
1031*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[2]);
1032*5e7646d2SAndroid Build Coastguard Worker else if (job->printer->num_auth_info_required == 4)
1033*5e7646d2SAndroid Build Coastguard Worker snprintf(auth_info_required, sizeof(auth_info_required),
1034*5e7646d2SAndroid Build Coastguard Worker "AUTH_INFO_REQUIRED=%s,%s,%s,%s",
1035*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[0],
1036*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[1],
1037*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[2],
1038*5e7646d2SAndroid Build Coastguard Worker job->printer->auth_info_required[3]);
1039*5e7646d2SAndroid Build Coastguard Worker else
1040*5e7646d2SAndroid Build Coastguard Worker strlcpy(auth_info_required, "AUTH_INFO_REQUIRED=none",
1041*5e7646d2SAndroid Build Coastguard Worker sizeof(auth_info_required));
1042*5e7646d2SAndroid Build Coastguard Worker
1043*5e7646d2SAndroid Build Coastguard Worker envc = cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
1044*5e7646d2SAndroid Build Coastguard Worker
1045*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = charset;
1046*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = lang;
1047*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
1048*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = apple_language;
1049*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
1050*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = ppd;
1051*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = rip_max_cache;
1052*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = content_type;
1053*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = device_uri;
1054*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = printer_info;
1055*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = printer_location;
1056*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = printer_name;
1057*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = printer_state_reasons ? printer_state_reasons :
1058*5e7646d2SAndroid Build Coastguard Worker "PRINTER_STATE_REASONS=none";
1059*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = banner_page ? "CUPS_FILETYPE=job-sheet" :
1060*5e7646d2SAndroid Build Coastguard Worker "CUPS_FILETYPE=document";
1061*5e7646d2SAndroid Build Coastguard Worker
1062*5e7646d2SAndroid Build Coastguard Worker if (final_content_type[0])
1063*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = final_content_type;
1064*5e7646d2SAndroid Build Coastguard Worker
1065*5e7646d2SAndroid Build Coastguard Worker if (Classification && !banner_page)
1066*5e7646d2SAndroid Build Coastguard Worker {
1067*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-sheets",
1068*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_NAME)) == NULL)
1069*5e7646d2SAndroid Build Coastguard Worker snprintf(classification, sizeof(classification), "CLASSIFICATION=%s",
1070*5e7646d2SAndroid Build Coastguard Worker Classification);
1071*5e7646d2SAndroid Build Coastguard Worker else if (attr->num_values > 1 &&
1072*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->values[1].string.text, "none") != 0)
1073*5e7646d2SAndroid Build Coastguard Worker snprintf(classification, sizeof(classification), "CLASSIFICATION=%s",
1074*5e7646d2SAndroid Build Coastguard Worker attr->values[1].string.text);
1075*5e7646d2SAndroid Build Coastguard Worker else
1076*5e7646d2SAndroid Build Coastguard Worker snprintf(classification, sizeof(classification), "CLASSIFICATION=%s",
1077*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text);
1078*5e7646d2SAndroid Build Coastguard Worker
1079*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = classification;
1080*5e7646d2SAndroid Build Coastguard Worker }
1081*5e7646d2SAndroid Build Coastguard Worker
1082*5e7646d2SAndroid Build Coastguard Worker if (job->dtype & CUPS_PRINTER_CLASS)
1083*5e7646d2SAndroid Build Coastguard Worker {
1084*5e7646d2SAndroid Build Coastguard Worker snprintf(class_name, sizeof(class_name), "CLASS=%s", job->dest);
1085*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = class_name;
1086*5e7646d2SAndroid Build Coastguard Worker }
1087*5e7646d2SAndroid Build Coastguard Worker
1088*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = auth_info_required;
1089*5e7646d2SAndroid Build Coastguard Worker
1090*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
1091*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
1092*5e7646d2SAndroid Build Coastguard Worker i ++)
1093*5e7646d2SAndroid Build Coastguard Worker if (job->auth_env[i])
1094*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = job->auth_env[i];
1095*5e7646d2SAndroid Build Coastguard Worker else
1096*5e7646d2SAndroid Build Coastguard Worker break;
1097*5e7646d2SAndroid Build Coastguard Worker
1098*5e7646d2SAndroid Build Coastguard Worker if (job->auth_uid)
1099*5e7646d2SAndroid Build Coastguard Worker envp[envc ++] = job->auth_uid;
1100*5e7646d2SAndroid Build Coastguard Worker
1101*5e7646d2SAndroid Build Coastguard Worker envp[envc] = NULL;
1102*5e7646d2SAndroid Build Coastguard Worker
1103*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < envc; i ++)
1104*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(envp[i], "AUTH_", 5))
1105*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"AUTH_%c****\"", i,
1106*5e7646d2SAndroid Build Coastguard Worker envp[i][5]);
1107*5e7646d2SAndroid Build Coastguard Worker else if (strncmp(envp[i], "DEVICE_URI=", 11))
1108*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"%s\"", i, envp[i]);
1109*5e7646d2SAndroid Build Coastguard Worker else
1110*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"DEVICE_URI=%s\"", i,
1111*5e7646d2SAndroid Build Coastguard Worker job->printer->sanitized_device_uri);
1112*5e7646d2SAndroid Build Coastguard Worker
1113*5e7646d2SAndroid Build Coastguard Worker if (job->printer->remote)
1114*5e7646d2SAndroid Build Coastguard Worker job->current_file = job->num_files;
1115*5e7646d2SAndroid Build Coastguard Worker else
1116*5e7646d2SAndroid Build Coastguard Worker job->current_file ++;
1117*5e7646d2SAndroid Build Coastguard Worker
1118*5e7646d2SAndroid Build Coastguard Worker /*
1119*5e7646d2SAndroid Build Coastguard Worker * Now create processes for all of the filters...
1120*5e7646d2SAndroid Build Coastguard Worker */
1121*5e7646d2SAndroid Build Coastguard Worker
1122*5e7646d2SAndroid Build Coastguard Worker for (i = 0, slot = 0, filter = (mime_filter_t *)cupsArrayFirst(filters);
1123*5e7646d2SAndroid Build Coastguard Worker filter;
1124*5e7646d2SAndroid Build Coastguard Worker i ++, filter = (mime_filter_t *)cupsArrayNext(filters))
1125*5e7646d2SAndroid Build Coastguard Worker {
1126*5e7646d2SAndroid Build Coastguard Worker if (filter->filter[0] != '/')
1127*5e7646d2SAndroid Build Coastguard Worker snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
1128*5e7646d2SAndroid Build Coastguard Worker filter->filter);
1129*5e7646d2SAndroid Build Coastguard Worker else
1130*5e7646d2SAndroid Build Coastguard Worker strlcpy(command, filter->filter, sizeof(command));
1131*5e7646d2SAndroid Build Coastguard Worker
1132*5e7646d2SAndroid Build Coastguard Worker if (i < (cupsArrayCount(filters) - 1))
1133*5e7646d2SAndroid Build Coastguard Worker {
1134*5e7646d2SAndroid Build Coastguard Worker if (cupsdOpenPipe(filterfds[slot]))
1135*5e7646d2SAndroid Build Coastguard Worker {
1136*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler could not create "
1137*5e7646d2SAndroid Build Coastguard Worker "the filter pipes.";
1138*5e7646d2SAndroid Build Coastguard Worker
1139*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
1140*5e7646d2SAndroid Build Coastguard Worker }
1141*5e7646d2SAndroid Build Coastguard Worker }
1142*5e7646d2SAndroid Build Coastguard Worker else
1143*5e7646d2SAndroid Build Coastguard Worker {
1144*5e7646d2SAndroid Build Coastguard Worker if (job->current_file == 1 ||
1145*5e7646d2SAndroid Build Coastguard Worker (job->printer->pc && job->printer->pc->single_file))
1146*5e7646d2SAndroid Build Coastguard Worker {
1147*5e7646d2SAndroid Build Coastguard Worker if (strncmp(job->printer->device_uri, "file:", 5) != 0)
1148*5e7646d2SAndroid Build Coastguard Worker {
1149*5e7646d2SAndroid Build Coastguard Worker if (cupsdOpenPipe(job->print_pipes))
1150*5e7646d2SAndroid Build Coastguard Worker {
1151*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler could not "
1152*5e7646d2SAndroid Build Coastguard Worker "create the backend pipes.";
1153*5e7646d2SAndroid Build Coastguard Worker
1154*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
1155*5e7646d2SAndroid Build Coastguard Worker }
1156*5e7646d2SAndroid Build Coastguard Worker }
1157*5e7646d2SAndroid Build Coastguard Worker else
1158*5e7646d2SAndroid Build Coastguard Worker {
1159*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[0] = -1;
1160*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(job->printer->device_uri, "file:/dev/null") ||
1161*5e7646d2SAndroid Build Coastguard Worker !strcmp(job->printer->device_uri, "file:///dev/null"))
1162*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = -1;
1163*5e7646d2SAndroid Build Coastguard Worker else
1164*5e7646d2SAndroid Build Coastguard Worker {
1165*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(job->printer->device_uri, "file:/dev/", 10))
1166*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = open(job->printer->device_uri + 5,
1167*5e7646d2SAndroid Build Coastguard Worker O_WRONLY | O_EXCL);
1168*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(job->printer->device_uri, "file:///dev/", 12))
1169*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = open(job->printer->device_uri + 7,
1170*5e7646d2SAndroid Build Coastguard Worker O_WRONLY | O_EXCL);
1171*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(job->printer->device_uri, "file:///", 8))
1172*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = open(job->printer->device_uri + 7,
1173*5e7646d2SAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_TRUNC, 0600);
1174*5e7646d2SAndroid Build Coastguard Worker else
1175*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = open(job->printer->device_uri + 5,
1176*5e7646d2SAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_TRUNC, 0600);
1177*5e7646d2SAndroid Build Coastguard Worker
1178*5e7646d2SAndroid Build Coastguard Worker if (job->print_pipes[1] < 0)
1179*5e7646d2SAndroid Build Coastguard Worker {
1180*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler could not "
1181*5e7646d2SAndroid Build Coastguard Worker "open the output file.";
1182*5e7646d2SAndroid Build Coastguard Worker
1183*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
1184*5e7646d2SAndroid Build Coastguard Worker }
1185*5e7646d2SAndroid Build Coastguard Worker
1186*5e7646d2SAndroid Build Coastguard Worker fcntl(job->print_pipes[1], F_SETFD,
1187*5e7646d2SAndroid Build Coastguard Worker fcntl(job->print_pipes[1], F_GETFD) | FD_CLOEXEC);
1188*5e7646d2SAndroid Build Coastguard Worker }
1189*5e7646d2SAndroid Build Coastguard Worker }
1190*5e7646d2SAndroid Build Coastguard Worker }
1191*5e7646d2SAndroid Build Coastguard Worker
1192*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][0] = job->print_pipes[0];
1193*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][1] = job->print_pipes[1];
1194*5e7646d2SAndroid Build Coastguard Worker }
1195*5e7646d2SAndroid Build Coastguard Worker
1196*5e7646d2SAndroid Build Coastguard Worker pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0],
1197*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][1], job->status_pipes[1],
1198*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[0], job->side_pipes[0], 0,
1199*5e7646d2SAndroid Build Coastguard Worker job->profile, job, job->filters + i);
1200*5e7646d2SAndroid Build Coastguard Worker
1201*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(filterfds[!slot]);
1202*5e7646d2SAndroid Build Coastguard Worker
1203*5e7646d2SAndroid Build Coastguard Worker if (pid == 0)
1204*5e7646d2SAndroid Build Coastguard Worker {
1205*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to start filter \"%s\" - %s.",
1206*5e7646d2SAndroid Build Coastguard Worker filter->filter, strerror(errno));
1207*5e7646d2SAndroid Build Coastguard Worker
1208*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the scheduler could not execute a "
1209*5e7646d2SAndroid Build Coastguard Worker "filter.";
1210*5e7646d2SAndroid Build Coastguard Worker
1211*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
1212*5e7646d2SAndroid Build Coastguard Worker }
1213*5e7646d2SAndroid Build Coastguard Worker
1214*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_INFO, "Started filter %s (PID %d)", command,
1215*5e7646d2SAndroid Build Coastguard Worker pid);
1216*5e7646d2SAndroid Build Coastguard Worker
1217*5e7646d2SAndroid Build Coastguard Worker if (argv[6])
1218*5e7646d2SAndroid Build Coastguard Worker {
1219*5e7646d2SAndroid Build Coastguard Worker free(argv[6]);
1220*5e7646d2SAndroid Build Coastguard Worker argv[6] = NULL;
1221*5e7646d2SAndroid Build Coastguard Worker }
1222*5e7646d2SAndroid Build Coastguard Worker
1223*5e7646d2SAndroid Build Coastguard Worker slot = !slot;
1224*5e7646d2SAndroid Build Coastguard Worker }
1225*5e7646d2SAndroid Build Coastguard Worker
1226*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(filters);
1227*5e7646d2SAndroid Build Coastguard Worker filters = NULL;
1228*5e7646d2SAndroid Build Coastguard Worker
1229*5e7646d2SAndroid Build Coastguard Worker /*
1230*5e7646d2SAndroid Build Coastguard Worker * Finally, pipe the final output into a backend process if needed...
1231*5e7646d2SAndroid Build Coastguard Worker */
1232*5e7646d2SAndroid Build Coastguard Worker
1233*5e7646d2SAndroid Build Coastguard Worker if (strncmp(job->printer->device_uri, "file:", 5) != 0)
1234*5e7646d2SAndroid Build Coastguard Worker {
1235*5e7646d2SAndroid Build Coastguard Worker if (job->current_file == 1 || job->printer->remote ||
1236*5e7646d2SAndroid Build Coastguard Worker (job->printer->pc && job->printer->pc->single_file))
1237*5e7646d2SAndroid Build Coastguard Worker {
1238*5e7646d2SAndroid Build Coastguard Worker sscanf(job->printer->device_uri, "%254[^:]", scheme);
1239*5e7646d2SAndroid Build Coastguard Worker snprintf(command, sizeof(command), "%s/backend/%s", ServerBin, scheme);
1240*5e7646d2SAndroid Build Coastguard Worker
1241*5e7646d2SAndroid Build Coastguard Worker /*
1242*5e7646d2SAndroid Build Coastguard Worker * See if the backend needs to run as root...
1243*5e7646d2SAndroid Build Coastguard Worker */
1244*5e7646d2SAndroid Build Coastguard Worker
1245*5e7646d2SAndroid Build Coastguard Worker if (RunUser)
1246*5e7646d2SAndroid Build Coastguard Worker backroot = 0;
1247*5e7646d2SAndroid Build Coastguard Worker else if (stat(command, &backinfo))
1248*5e7646d2SAndroid Build Coastguard Worker backroot = 0;
1249*5e7646d2SAndroid Build Coastguard Worker else
1250*5e7646d2SAndroid Build Coastguard Worker backroot = !(backinfo.st_mode & (S_IWGRP | S_IWOTH | S_IXOTH));
1251*5e7646d2SAndroid Build Coastguard Worker
1252*5e7646d2SAndroid Build Coastguard Worker argv[0] = job->printer->sanitized_device_uri;
1253*5e7646d2SAndroid Build Coastguard Worker
1254*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][0] = -1;
1255*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][1] = -1;
1256*5e7646d2SAndroid Build Coastguard Worker
1257*5e7646d2SAndroid Build Coastguard Worker pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0],
1258*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][1], job->status_pipes[1],
1259*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[1], job->side_pipes[1],
1260*5e7646d2SAndroid Build Coastguard Worker backroot, job->bprofile, job, &(job->backend));
1261*5e7646d2SAndroid Build Coastguard Worker
1262*5e7646d2SAndroid Build Coastguard Worker if (pid == 0)
1263*5e7646d2SAndroid Build Coastguard Worker {
1264*5e7646d2SAndroid Build Coastguard Worker abort_message = "Stopping job because the sheduler could not execute "
1265*5e7646d2SAndroid Build Coastguard Worker "the backend.";
1266*5e7646d2SAndroid Build Coastguard Worker
1267*5e7646d2SAndroid Build Coastguard Worker goto abort_job;
1268*5e7646d2SAndroid Build Coastguard Worker }
1269*5e7646d2SAndroid Build Coastguard Worker else
1270*5e7646d2SAndroid Build Coastguard Worker {
1271*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_INFO, "Started backend %s (PID %d)",
1272*5e7646d2SAndroid Build Coastguard Worker command, pid);
1273*5e7646d2SAndroid Build Coastguard Worker }
1274*5e7646d2SAndroid Build Coastguard Worker }
1275*5e7646d2SAndroid Build Coastguard Worker
1276*5e7646d2SAndroid Build Coastguard Worker if (job->current_file == job->num_files ||
1277*5e7646d2SAndroid Build Coastguard Worker (job->printer->pc && job->printer->pc->single_file))
1278*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->print_pipes);
1279*5e7646d2SAndroid Build Coastguard Worker
1280*5e7646d2SAndroid Build Coastguard Worker if (job->current_file == job->num_files)
1281*5e7646d2SAndroid Build Coastguard Worker {
1282*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->back_pipes);
1283*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->side_pipes);
1284*5e7646d2SAndroid Build Coastguard Worker
1285*5e7646d2SAndroid Build Coastguard Worker close(job->status_pipes[1]);
1286*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[1] = -1;
1287*5e7646d2SAndroid Build Coastguard Worker }
1288*5e7646d2SAndroid Build Coastguard Worker }
1289*5e7646d2SAndroid Build Coastguard Worker else
1290*5e7646d2SAndroid Build Coastguard Worker {
1291*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][0] = -1;
1292*5e7646d2SAndroid Build Coastguard Worker filterfds[slot][1] = -1;
1293*5e7646d2SAndroid Build Coastguard Worker
1294*5e7646d2SAndroid Build Coastguard Worker if (job->current_file == job->num_files ||
1295*5e7646d2SAndroid Build Coastguard Worker (job->printer->pc && job->printer->pc->single_file))
1296*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->print_pipes);
1297*5e7646d2SAndroid Build Coastguard Worker
1298*5e7646d2SAndroid Build Coastguard Worker if (job->current_file == job->num_files)
1299*5e7646d2SAndroid Build Coastguard Worker {
1300*5e7646d2SAndroid Build Coastguard Worker close(job->status_pipes[1]);
1301*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[1] = -1;
1302*5e7646d2SAndroid Build Coastguard Worker }
1303*5e7646d2SAndroid Build Coastguard Worker }
1304*5e7646d2SAndroid Build Coastguard Worker
1305*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(filterfds[slot]);
1306*5e7646d2SAndroid Build Coastguard Worker
1307*5e7646d2SAndroid Build Coastguard Worker for (i = 6; i < argc; i ++)
1308*5e7646d2SAndroid Build Coastguard Worker free(argv[i]);
1309*5e7646d2SAndroid Build Coastguard Worker free(argv);
1310*5e7646d2SAndroid Build Coastguard Worker
1311*5e7646d2SAndroid Build Coastguard Worker if (printer_state_reasons)
1312*5e7646d2SAndroid Build Coastguard Worker free(printer_state_reasons);
1313*5e7646d2SAndroid Build Coastguard Worker
1314*5e7646d2SAndroid Build Coastguard Worker cupsdAddSelect(job->status_buffer->fd, (cupsd_selfunc_t)update_job, NULL,
1315*5e7646d2SAndroid Build Coastguard Worker job);
1316*5e7646d2SAndroid Build Coastguard Worker
1317*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "Job #%d started.",
1318*5e7646d2SAndroid Build Coastguard Worker job->id);
1319*5e7646d2SAndroid Build Coastguard Worker
1320*5e7646d2SAndroid Build Coastguard Worker return;
1321*5e7646d2SAndroid Build Coastguard Worker
1322*5e7646d2SAndroid Build Coastguard Worker
1323*5e7646d2SAndroid Build Coastguard Worker /*
1324*5e7646d2SAndroid Build Coastguard Worker * If we get here, we need to abort the current job and close out all
1325*5e7646d2SAndroid Build Coastguard Worker * files and pipes...
1326*5e7646d2SAndroid Build Coastguard Worker */
1327*5e7646d2SAndroid Build Coastguard Worker
1328*5e7646d2SAndroid Build Coastguard Worker abort_job:
1329*5e7646d2SAndroid Build Coastguard Worker
1330*5e7646d2SAndroid Build Coastguard Worker FilterLevel -= job->cost;
1331*5e7646d2SAndroid Build Coastguard Worker job->cost = 0;
1332*5e7646d2SAndroid Build Coastguard Worker
1333*5e7646d2SAndroid Build Coastguard Worker for (slot = 0; slot < 2; slot ++)
1334*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(filterfds[slot]);
1335*5e7646d2SAndroid Build Coastguard Worker
1336*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(filters);
1337*5e7646d2SAndroid Build Coastguard Worker
1338*5e7646d2SAndroid Build Coastguard Worker if (argv)
1339*5e7646d2SAndroid Build Coastguard Worker {
1340*5e7646d2SAndroid Build Coastguard Worker for (i = 6; i < argc; i ++)
1341*5e7646d2SAndroid Build Coastguard Worker free(argv[i]);
1342*5e7646d2SAndroid Build Coastguard Worker
1343*5e7646d2SAndroid Build Coastguard Worker free(argv);
1344*5e7646d2SAndroid Build Coastguard Worker }
1345*5e7646d2SAndroid Build Coastguard Worker
1346*5e7646d2SAndroid Build Coastguard Worker if (printer_state_reasons)
1347*5e7646d2SAndroid Build Coastguard Worker free(printer_state_reasons);
1348*5e7646d2SAndroid Build Coastguard Worker
1349*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->print_pipes);
1350*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->back_pipes);
1351*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->side_pipes);
1352*5e7646d2SAndroid Build Coastguard Worker
1353*5e7646d2SAndroid Build Coastguard Worker cupsdRemoveSelect(job->status_pipes[0]);
1354*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->status_pipes);
1355*5e7646d2SAndroid Build Coastguard Worker cupsdStatBufDelete(job->status_buffer);
1356*5e7646d2SAndroid Build Coastguard Worker job->status_buffer = NULL;
1357*5e7646d2SAndroid Build Coastguard Worker
1358*5e7646d2SAndroid Build Coastguard Worker /*
1359*5e7646d2SAndroid Build Coastguard Worker * Update the printer and job state.
1360*5e7646d2SAndroid Build Coastguard Worker */
1361*5e7646d2SAndroid Build Coastguard Worker
1362*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, abort_state, CUPSD_JOB_DEFAULT, "%s", abort_message);
1363*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterState(job->printer, IPP_PRINTER_IDLE, 0);
1364*5e7646d2SAndroid Build Coastguard Worker update_job_attrs(job, 0);
1365*5e7646d2SAndroid Build Coastguard Worker
1366*5e7646d2SAndroid Build Coastguard Worker if (job->history)
1367*5e7646d2SAndroid Build Coastguard Worker free_job_history(job);
1368*5e7646d2SAndroid Build Coastguard Worker
1369*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(PrintingJobs, job);
1370*5e7646d2SAndroid Build Coastguard Worker
1371*5e7646d2SAndroid Build Coastguard Worker /*
1372*5e7646d2SAndroid Build Coastguard Worker * Clear the printer <-> job association...
1373*5e7646d2SAndroid Build Coastguard Worker */
1374*5e7646d2SAndroid Build Coastguard Worker
1375*5e7646d2SAndroid Build Coastguard Worker job->printer->job = NULL;
1376*5e7646d2SAndroid Build Coastguard Worker job->printer = NULL;
1377*5e7646d2SAndroid Build Coastguard Worker }
1378*5e7646d2SAndroid Build Coastguard Worker
1379*5e7646d2SAndroid Build Coastguard Worker
1380*5e7646d2SAndroid Build Coastguard Worker /*
1381*5e7646d2SAndroid Build Coastguard Worker * 'cupsdDeleteJob()' - Free all memory used by a job.
1382*5e7646d2SAndroid Build Coastguard Worker */
1383*5e7646d2SAndroid Build Coastguard Worker
1384*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeleteJob(cupsd_job_t * job,cupsd_jobaction_t action)1385*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteJob(cupsd_job_t *job, /* I - Job */
1386*5e7646d2SAndroid Build Coastguard Worker cupsd_jobaction_t action)/* I - Action */
1387*5e7646d2SAndroid Build Coastguard Worker {
1388*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1389*5e7646d2SAndroid Build Coastguard Worker
1390*5e7646d2SAndroid Build Coastguard Worker
1391*5e7646d2SAndroid Build Coastguard Worker if (job->printer)
1392*5e7646d2SAndroid Build Coastguard Worker finalize_job(job, 1);
1393*5e7646d2SAndroid Build Coastguard Worker
1394*5e7646d2SAndroid Build Coastguard Worker if (action == CUPSD_JOB_PURGE)
1395*5e7646d2SAndroid Build Coastguard Worker remove_job_history(job);
1396*5e7646d2SAndroid Build Coastguard Worker
1397*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(&job->username);
1398*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(&job->dest);
1399*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
1400*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
1401*5e7646d2SAndroid Build Coastguard Worker i ++)
1402*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(job->auth_env + i);
1403*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(&job->auth_uid);
1404*5e7646d2SAndroid Build Coastguard Worker
1405*5e7646d2SAndroid Build Coastguard Worker if (action == CUPSD_JOB_PURGE)
1406*5e7646d2SAndroid Build Coastguard Worker remove_job_files(job);
1407*5e7646d2SAndroid Build Coastguard Worker else if (job->num_files > 0)
1408*5e7646d2SAndroid Build Coastguard Worker {
1409*5e7646d2SAndroid Build Coastguard Worker free(job->compressions);
1410*5e7646d2SAndroid Build Coastguard Worker free(job->filetypes);
1411*5e7646d2SAndroid Build Coastguard Worker
1412*5e7646d2SAndroid Build Coastguard Worker job->num_files = 0;
1413*5e7646d2SAndroid Build Coastguard Worker }
1414*5e7646d2SAndroid Build Coastguard Worker
1415*5e7646d2SAndroid Build Coastguard Worker if (job->history)
1416*5e7646d2SAndroid Build Coastguard Worker free_job_history(job);
1417*5e7646d2SAndroid Build Coastguard Worker
1418*5e7646d2SAndroid Build Coastguard Worker unload_job(job);
1419*5e7646d2SAndroid Build Coastguard Worker
1420*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(Jobs, job);
1421*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ActiveJobs, job);
1422*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(PrintingJobs, job);
1423*5e7646d2SAndroid Build Coastguard Worker
1424*5e7646d2SAndroid Build Coastguard Worker free(job);
1425*5e7646d2SAndroid Build Coastguard Worker }
1426*5e7646d2SAndroid Build Coastguard Worker
1427*5e7646d2SAndroid Build Coastguard Worker
1428*5e7646d2SAndroid Build Coastguard Worker /*
1429*5e7646d2SAndroid Build Coastguard Worker * 'cupsdFreeAllJobs()' - Free all jobs from memory.
1430*5e7646d2SAndroid Build Coastguard Worker */
1431*5e7646d2SAndroid Build Coastguard Worker
1432*5e7646d2SAndroid Build Coastguard Worker void
cupsdFreeAllJobs(void)1433*5e7646d2SAndroid Build Coastguard Worker cupsdFreeAllJobs(void)
1434*5e7646d2SAndroid Build Coastguard Worker {
1435*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
1436*5e7646d2SAndroid Build Coastguard Worker
1437*5e7646d2SAndroid Build Coastguard Worker
1438*5e7646d2SAndroid Build Coastguard Worker if (!Jobs)
1439*5e7646d2SAndroid Build Coastguard Worker return;
1440*5e7646d2SAndroid Build Coastguard Worker
1441*5e7646d2SAndroid Build Coastguard Worker cupsdHoldSignals();
1442*5e7646d2SAndroid Build Coastguard Worker
1443*5e7646d2SAndroid Build Coastguard Worker cupsdStopAllJobs(CUPSD_JOB_FORCE, 0);
1444*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllJobs();
1445*5e7646d2SAndroid Build Coastguard Worker
1446*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
1447*5e7646d2SAndroid Build Coastguard Worker job;
1448*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
1449*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteJob(job, CUPSD_JOB_DEFAULT);
1450*5e7646d2SAndroid Build Coastguard Worker
1451*5e7646d2SAndroid Build Coastguard Worker cupsdReleaseSignals();
1452*5e7646d2SAndroid Build Coastguard Worker }
1453*5e7646d2SAndroid Build Coastguard Worker
1454*5e7646d2SAndroid Build Coastguard Worker
1455*5e7646d2SAndroid Build Coastguard Worker /*
1456*5e7646d2SAndroid Build Coastguard Worker * 'cupsdFindJob()' - Find the specified job.
1457*5e7646d2SAndroid Build Coastguard Worker */
1458*5e7646d2SAndroid Build Coastguard Worker
1459*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t * /* O - Job data */
cupsdFindJob(int id)1460*5e7646d2SAndroid Build Coastguard Worker cupsdFindJob(int id) /* I - Job ID */
1461*5e7646d2SAndroid Build Coastguard Worker {
1462*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t key; /* Search key */
1463*5e7646d2SAndroid Build Coastguard Worker
1464*5e7646d2SAndroid Build Coastguard Worker
1465*5e7646d2SAndroid Build Coastguard Worker key.id = id;
1466*5e7646d2SAndroid Build Coastguard Worker
1467*5e7646d2SAndroid Build Coastguard Worker return ((cupsd_job_t *)cupsArrayFind(Jobs, &key));
1468*5e7646d2SAndroid Build Coastguard Worker }
1469*5e7646d2SAndroid Build Coastguard Worker
1470*5e7646d2SAndroid Build Coastguard Worker
1471*5e7646d2SAndroid Build Coastguard Worker /*
1472*5e7646d2SAndroid Build Coastguard Worker * 'cupsdGetCompletedJobs()'- Generate a completed jobs list.
1473*5e7646d2SAndroid Build Coastguard Worker */
1474*5e7646d2SAndroid Build Coastguard Worker
1475*5e7646d2SAndroid Build Coastguard Worker cups_array_t * /* O - Array of jobs */
cupsdGetCompletedJobs(cupsd_printer_t * p)1476*5e7646d2SAndroid Build Coastguard Worker cupsdGetCompletedJobs(
1477*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p) /* I - Printer */
1478*5e7646d2SAndroid Build Coastguard Worker {
1479*5e7646d2SAndroid Build Coastguard Worker cups_array_t *list; /* Array of jobs */
1480*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
1481*5e7646d2SAndroid Build Coastguard Worker
1482*5e7646d2SAndroid Build Coastguard Worker
1483*5e7646d2SAndroid Build Coastguard Worker list = cupsArrayNew(compare_completed_jobs, NULL);
1484*5e7646d2SAndroid Build Coastguard Worker
1485*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
1486*5e7646d2SAndroid Build Coastguard Worker job;
1487*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
1488*5e7646d2SAndroid Build Coastguard Worker if ((!p || !_cups_strcasecmp(p->name, job->dest)) && job->state_value >= IPP_JOB_STOPPED && job->completed_time)
1489*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(list, job);
1490*5e7646d2SAndroid Build Coastguard Worker
1491*5e7646d2SAndroid Build Coastguard Worker return (list);
1492*5e7646d2SAndroid Build Coastguard Worker }
1493*5e7646d2SAndroid Build Coastguard Worker
1494*5e7646d2SAndroid Build Coastguard Worker
1495*5e7646d2SAndroid Build Coastguard Worker /*
1496*5e7646d2SAndroid Build Coastguard Worker * 'cupsdGetPrinterJobCount()' - Get the number of pending, processing,
1497*5e7646d2SAndroid Build Coastguard Worker * or held jobs in a printer or class.
1498*5e7646d2SAndroid Build Coastguard Worker */
1499*5e7646d2SAndroid Build Coastguard Worker
1500*5e7646d2SAndroid Build Coastguard Worker int /* O - Job count */
cupsdGetPrinterJobCount(const char * dest)1501*5e7646d2SAndroid Build Coastguard Worker cupsdGetPrinterJobCount(
1502*5e7646d2SAndroid Build Coastguard Worker const char *dest) /* I - Printer or class name */
1503*5e7646d2SAndroid Build Coastguard Worker {
1504*5e7646d2SAndroid Build Coastguard Worker int count; /* Job count */
1505*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
1506*5e7646d2SAndroid Build Coastguard Worker
1507*5e7646d2SAndroid Build Coastguard Worker
1508*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0;
1509*5e7646d2SAndroid Build Coastguard Worker job;
1510*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
1511*5e7646d2SAndroid Build Coastguard Worker if (job->dest && !_cups_strcasecmp(job->dest, dest))
1512*5e7646d2SAndroid Build Coastguard Worker count ++;
1513*5e7646d2SAndroid Build Coastguard Worker
1514*5e7646d2SAndroid Build Coastguard Worker return (count);
1515*5e7646d2SAndroid Build Coastguard Worker }
1516*5e7646d2SAndroid Build Coastguard Worker
1517*5e7646d2SAndroid Build Coastguard Worker
1518*5e7646d2SAndroid Build Coastguard Worker /*
1519*5e7646d2SAndroid Build Coastguard Worker * 'cupsdGetUserJobCount()' - Get the number of pending, processing,
1520*5e7646d2SAndroid Build Coastguard Worker * or held jobs for a user.
1521*5e7646d2SAndroid Build Coastguard Worker */
1522*5e7646d2SAndroid Build Coastguard Worker
1523*5e7646d2SAndroid Build Coastguard Worker int /* O - Job count */
cupsdGetUserJobCount(const char * username)1524*5e7646d2SAndroid Build Coastguard Worker cupsdGetUserJobCount(
1525*5e7646d2SAndroid Build Coastguard Worker const char *username) /* I - Username */
1526*5e7646d2SAndroid Build Coastguard Worker {
1527*5e7646d2SAndroid Build Coastguard Worker int count; /* Job count */
1528*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
1529*5e7646d2SAndroid Build Coastguard Worker
1530*5e7646d2SAndroid Build Coastguard Worker
1531*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0;
1532*5e7646d2SAndroid Build Coastguard Worker job;
1533*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
1534*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(job->username, username))
1535*5e7646d2SAndroid Build Coastguard Worker count ++;
1536*5e7646d2SAndroid Build Coastguard Worker
1537*5e7646d2SAndroid Build Coastguard Worker return (count);
1538*5e7646d2SAndroid Build Coastguard Worker }
1539*5e7646d2SAndroid Build Coastguard Worker
1540*5e7646d2SAndroid Build Coastguard Worker
1541*5e7646d2SAndroid Build Coastguard Worker /*
1542*5e7646d2SAndroid Build Coastguard Worker * 'cupsdLoadAllJobs()' - Load all jobs from disk.
1543*5e7646d2SAndroid Build Coastguard Worker */
1544*5e7646d2SAndroid Build Coastguard Worker
1545*5e7646d2SAndroid Build Coastguard Worker void
cupsdLoadAllJobs(void)1546*5e7646d2SAndroid Build Coastguard Worker cupsdLoadAllJobs(void)
1547*5e7646d2SAndroid Build Coastguard Worker {
1548*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Full filename of job.cache file */
1549*5e7646d2SAndroid Build Coastguard Worker struct stat fileinfo; /* Information on job.cache file */
1550*5e7646d2SAndroid Build Coastguard Worker cups_dir_t *dir; /* RequestRoot dir */
1551*5e7646d2SAndroid Build Coastguard Worker cups_dentry_t *dent; /* Entry in RequestRoot */
1552*5e7646d2SAndroid Build Coastguard Worker int load_cache = 1; /* Load the job.cache file? */
1553*5e7646d2SAndroid Build Coastguard Worker
1554*5e7646d2SAndroid Build Coastguard Worker
1555*5e7646d2SAndroid Build Coastguard Worker /*
1556*5e7646d2SAndroid Build Coastguard Worker * Create the job arrays as needed...
1557*5e7646d2SAndroid Build Coastguard Worker */
1558*5e7646d2SAndroid Build Coastguard Worker
1559*5e7646d2SAndroid Build Coastguard Worker if (!Jobs)
1560*5e7646d2SAndroid Build Coastguard Worker Jobs = cupsArrayNew(compare_jobs, NULL);
1561*5e7646d2SAndroid Build Coastguard Worker
1562*5e7646d2SAndroid Build Coastguard Worker if (!ActiveJobs)
1563*5e7646d2SAndroid Build Coastguard Worker ActiveJobs = cupsArrayNew(compare_active_jobs, NULL);
1564*5e7646d2SAndroid Build Coastguard Worker
1565*5e7646d2SAndroid Build Coastguard Worker if (!PrintingJobs)
1566*5e7646d2SAndroid Build Coastguard Worker PrintingJobs = cupsArrayNew(compare_jobs, NULL);
1567*5e7646d2SAndroid Build Coastguard Worker
1568*5e7646d2SAndroid Build Coastguard Worker /*
1569*5e7646d2SAndroid Build Coastguard Worker * See whether the job.cache file is older than the RequestRoot directory...
1570*5e7646d2SAndroid Build Coastguard Worker */
1571*5e7646d2SAndroid Build Coastguard Worker
1572*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/job.cache", CacheDir);
1573*5e7646d2SAndroid Build Coastguard Worker
1574*5e7646d2SAndroid Build Coastguard Worker if (stat(filename, &fileinfo))
1575*5e7646d2SAndroid Build Coastguard Worker {
1576*5e7646d2SAndroid Build Coastguard Worker /*
1577*5e7646d2SAndroid Build Coastguard Worker * No job.cache file...
1578*5e7646d2SAndroid Build Coastguard Worker */
1579*5e7646d2SAndroid Build Coastguard Worker
1580*5e7646d2SAndroid Build Coastguard Worker load_cache = 0;
1581*5e7646d2SAndroid Build Coastguard Worker
1582*5e7646d2SAndroid Build Coastguard Worker if (errno != ENOENT)
1583*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
1584*5e7646d2SAndroid Build Coastguard Worker "Unable to get file information for \"%s\" - %s",
1585*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
1586*5e7646d2SAndroid Build Coastguard Worker }
1587*5e7646d2SAndroid Build Coastguard Worker else if ((dir = cupsDirOpen(RequestRoot)) == NULL)
1588*5e7646d2SAndroid Build Coastguard Worker {
1589*5e7646d2SAndroid Build Coastguard Worker /*
1590*5e7646d2SAndroid Build Coastguard Worker * No spool directory...
1591*5e7646d2SAndroid Build Coastguard Worker */
1592*5e7646d2SAndroid Build Coastguard Worker
1593*5e7646d2SAndroid Build Coastguard Worker load_cache = 0;
1594*5e7646d2SAndroid Build Coastguard Worker }
1595*5e7646d2SAndroid Build Coastguard Worker else
1596*5e7646d2SAndroid Build Coastguard Worker {
1597*5e7646d2SAndroid Build Coastguard Worker while ((dent = cupsDirRead(dir)) != NULL)
1598*5e7646d2SAndroid Build Coastguard Worker {
1599*5e7646d2SAndroid Build Coastguard Worker if (strlen(dent->filename) >= 6 && dent->filename[0] == 'c' && dent->fileinfo.st_mtime > fileinfo.st_mtime)
1600*5e7646d2SAndroid Build Coastguard Worker {
1601*5e7646d2SAndroid Build Coastguard Worker /*
1602*5e7646d2SAndroid Build Coastguard Worker * Job history file is newer than job.cache file...
1603*5e7646d2SAndroid Build Coastguard Worker */
1604*5e7646d2SAndroid Build Coastguard Worker
1605*5e7646d2SAndroid Build Coastguard Worker load_cache = 0;
1606*5e7646d2SAndroid Build Coastguard Worker break;
1607*5e7646d2SAndroid Build Coastguard Worker }
1608*5e7646d2SAndroid Build Coastguard Worker }
1609*5e7646d2SAndroid Build Coastguard Worker
1610*5e7646d2SAndroid Build Coastguard Worker cupsDirClose(dir);
1611*5e7646d2SAndroid Build Coastguard Worker }
1612*5e7646d2SAndroid Build Coastguard Worker
1613*5e7646d2SAndroid Build Coastguard Worker /*
1614*5e7646d2SAndroid Build Coastguard Worker * Load the most recent source for job data...
1615*5e7646d2SAndroid Build Coastguard Worker */
1616*5e7646d2SAndroid Build Coastguard Worker
1617*5e7646d2SAndroid Build Coastguard Worker if (load_cache)
1618*5e7646d2SAndroid Build Coastguard Worker {
1619*5e7646d2SAndroid Build Coastguard Worker /*
1620*5e7646d2SAndroid Build Coastguard Worker * Load the job.cache file...
1621*5e7646d2SAndroid Build Coastguard Worker */
1622*5e7646d2SAndroid Build Coastguard Worker
1623*5e7646d2SAndroid Build Coastguard Worker load_job_cache(filename);
1624*5e7646d2SAndroid Build Coastguard Worker }
1625*5e7646d2SAndroid Build Coastguard Worker else
1626*5e7646d2SAndroid Build Coastguard Worker {
1627*5e7646d2SAndroid Build Coastguard Worker /*
1628*5e7646d2SAndroid Build Coastguard Worker * Load the job history files...
1629*5e7646d2SAndroid Build Coastguard Worker */
1630*5e7646d2SAndroid Build Coastguard Worker
1631*5e7646d2SAndroid Build Coastguard Worker load_request_root();
1632*5e7646d2SAndroid Build Coastguard Worker
1633*5e7646d2SAndroid Build Coastguard Worker load_next_job_id(filename);
1634*5e7646d2SAndroid Build Coastguard Worker }
1635*5e7646d2SAndroid Build Coastguard Worker
1636*5e7646d2SAndroid Build Coastguard Worker /*
1637*5e7646d2SAndroid Build Coastguard Worker * Clean out old jobs as needed...
1638*5e7646d2SAndroid Build Coastguard Worker */
1639*5e7646d2SAndroid Build Coastguard Worker
1640*5e7646d2SAndroid Build Coastguard Worker if (MaxJobs > 0 && cupsArrayCount(Jobs) >= MaxJobs)
1641*5e7646d2SAndroid Build Coastguard Worker cupsdCleanJobs();
1642*5e7646d2SAndroid Build Coastguard Worker }
1643*5e7646d2SAndroid Build Coastguard Worker
1644*5e7646d2SAndroid Build Coastguard Worker
1645*5e7646d2SAndroid Build Coastguard Worker /*
1646*5e7646d2SAndroid Build Coastguard Worker * 'cupsdLoadJob()' - Load a single job.
1647*5e7646d2SAndroid Build Coastguard Worker */
1648*5e7646d2SAndroid Build Coastguard Worker
1649*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
cupsdLoadJob(cupsd_job_t * job)1650*5e7646d2SAndroid Build Coastguard Worker cupsdLoadJob(cupsd_job_t *job) /* I - Job */
1651*5e7646d2SAndroid Build Coastguard Worker {
1652*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1653*5e7646d2SAndroid Build Coastguard Worker char jobfile[1024]; /* Job filename */
1654*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* Job file */
1655*5e7646d2SAndroid Build Coastguard Worker int fileid; /* Current file ID */
1656*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Job attribute */
1657*5e7646d2SAndroid Build Coastguard Worker const char *dest; /* Destination name */
1658*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *destptr; /* Pointer to destination */
1659*5e7646d2SAndroid Build Coastguard Worker mime_type_t **filetypes; /* New filetypes array */
1660*5e7646d2SAndroid Build Coastguard Worker int *compressions; /* New compressions array */
1661*5e7646d2SAndroid Build Coastguard Worker
1662*5e7646d2SAndroid Build Coastguard Worker
1663*5e7646d2SAndroid Build Coastguard Worker if (job->attrs)
1664*5e7646d2SAndroid Build Coastguard Worker {
1665*5e7646d2SAndroid Build Coastguard Worker if (job->state_value > IPP_JOB_STOPPED)
1666*5e7646d2SAndroid Build Coastguard Worker job->access_time = time(NULL);
1667*5e7646d2SAndroid Build Coastguard Worker
1668*5e7646d2SAndroid Build Coastguard Worker return (1);
1669*5e7646d2SAndroid Build Coastguard Worker }
1670*5e7646d2SAndroid Build Coastguard Worker
1671*5e7646d2SAndroid Build Coastguard Worker if ((job->attrs = ippNew()) == NULL)
1672*5e7646d2SAndroid Build Coastguard Worker {
1673*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "Ran out of memory for job attributes.");
1674*5e7646d2SAndroid Build Coastguard Worker return (0);
1675*5e7646d2SAndroid Build Coastguard Worker }
1676*5e7646d2SAndroid Build Coastguard Worker
1677*5e7646d2SAndroid Build Coastguard Worker /*
1678*5e7646d2SAndroid Build Coastguard Worker * Load job attributes...
1679*5e7646d2SAndroid Build Coastguard Worker */
1680*5e7646d2SAndroid Build Coastguard Worker
1681*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading attributes...");
1682*5e7646d2SAndroid Build Coastguard Worker
1683*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id);
1684*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsdOpenConfFile(jobfile)) == NULL)
1685*5e7646d2SAndroid Build Coastguard Worker goto error;
1686*5e7646d2SAndroid Build Coastguard Worker
1687*5e7646d2SAndroid Build Coastguard Worker if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA)
1688*5e7646d2SAndroid Build Coastguard Worker {
1689*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1690*5e7646d2SAndroid Build Coastguard Worker "Unable to read job control file \"%s\".", jobfile);
1691*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
1692*5e7646d2SAndroid Build Coastguard Worker goto error;
1693*5e7646d2SAndroid Build Coastguard Worker }
1694*5e7646d2SAndroid Build Coastguard Worker
1695*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
1696*5e7646d2SAndroid Build Coastguard Worker
1697*5e7646d2SAndroid Build Coastguard Worker /*
1698*5e7646d2SAndroid Build Coastguard Worker * Copy attribute data to the job object...
1699*5e7646d2SAndroid Build Coastguard Worker */
1700*5e7646d2SAndroid Build Coastguard Worker
1701*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER))
1702*5e7646d2SAndroid Build Coastguard Worker {
1703*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1704*5e7646d2SAndroid Build Coastguard Worker "Missing or bad time-at-creation attribute in control file.");
1705*5e7646d2SAndroid Build Coastguard Worker goto error;
1706*5e7646d2SAndroid Build Coastguard Worker }
1707*5e7646d2SAndroid Build Coastguard Worker
1708*5e7646d2SAndroid Build Coastguard Worker if ((job->state = ippFindAttribute(job->attrs, "job-state",
1709*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ENUM)) == NULL)
1710*5e7646d2SAndroid Build Coastguard Worker {
1711*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1712*5e7646d2SAndroid Build Coastguard Worker "Missing or bad job-state attribute in control file.");
1713*5e7646d2SAndroid Build Coastguard Worker goto error;
1714*5e7646d2SAndroid Build Coastguard Worker }
1715*5e7646d2SAndroid Build Coastguard Worker
1716*5e7646d2SAndroid Build Coastguard Worker job->state_value = (ipp_jstate_t)job->state->values[0].integer;
1717*5e7646d2SAndroid Build Coastguard Worker job->file_time = 0;
1718*5e7646d2SAndroid Build Coastguard Worker job->history_time = 0;
1719*5e7646d2SAndroid Build Coastguard Worker
1720*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) != NULL)
1721*5e7646d2SAndroid Build Coastguard Worker job->creation_time = attr->values[0].integer;
1722*5e7646d2SAndroid Build Coastguard Worker
1723*5e7646d2SAndroid Build Coastguard Worker if (job->state_value >= IPP_JOB_CANCELED && (attr = ippFindAttribute(job->attrs, "time-at-completed", IPP_TAG_INTEGER)) != NULL)
1724*5e7646d2SAndroid Build Coastguard Worker {
1725*5e7646d2SAndroid Build Coastguard Worker job->completed_time = attr->values[0].integer;
1726*5e7646d2SAndroid Build Coastguard Worker
1727*5e7646d2SAndroid Build Coastguard Worker if (JobHistory < INT_MAX)
1728*5e7646d2SAndroid Build Coastguard Worker job->history_time = job->completed_time + JobHistory;
1729*5e7646d2SAndroid Build Coastguard Worker else
1730*5e7646d2SAndroid Build Coastguard Worker job->history_time = INT_MAX;
1731*5e7646d2SAndroid Build Coastguard Worker
1732*5e7646d2SAndroid Build Coastguard Worker if (job->history_time < time(NULL))
1733*5e7646d2SAndroid Build Coastguard Worker goto error; /* Expired, remove from history */
1734*5e7646d2SAndroid Build Coastguard Worker
1735*5e7646d2SAndroid Build Coastguard Worker if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
1736*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->history_time;
1737*5e7646d2SAndroid Build Coastguard Worker
1738*5e7646d2SAndroid Build Coastguard Worker if (JobFiles < INT_MAX)
1739*5e7646d2SAndroid Build Coastguard Worker job->file_time = job->completed_time + JobFiles;
1740*5e7646d2SAndroid Build Coastguard Worker else
1741*5e7646d2SAndroid Build Coastguard Worker job->file_time = INT_MAX;
1742*5e7646d2SAndroid Build Coastguard Worker
1743*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "cupsdLoadJob: job->file_time=%ld, time-at-completed=%ld, JobFiles=%d", (long)job->file_time, (long)attr->values[0].integer, JobFiles);
1744*5e7646d2SAndroid Build Coastguard Worker
1745*5e7646d2SAndroid Build Coastguard Worker if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
1746*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->file_time;
1747*5e7646d2SAndroid Build Coastguard Worker
1748*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdLoadJob: JobHistoryUpdate=%ld",
1749*5e7646d2SAndroid Build Coastguard Worker (long)JobHistoryUpdate);
1750*5e7646d2SAndroid Build Coastguard Worker }
1751*5e7646d2SAndroid Build Coastguard Worker
1752*5e7646d2SAndroid Build Coastguard Worker if (!job->dest)
1753*5e7646d2SAndroid Build Coastguard Worker {
1754*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
1755*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_URI)) == NULL)
1756*5e7646d2SAndroid Build Coastguard Worker {
1757*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1758*5e7646d2SAndroid Build Coastguard Worker "No job-printer-uri attribute in control file.");
1759*5e7646d2SAndroid Build Coastguard Worker goto error;
1760*5e7646d2SAndroid Build Coastguard Worker }
1761*5e7646d2SAndroid Build Coastguard Worker
1762*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype),
1763*5e7646d2SAndroid Build Coastguard Worker &destptr)) == NULL)
1764*5e7646d2SAndroid Build Coastguard Worker {
1765*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1766*5e7646d2SAndroid Build Coastguard Worker "Unable to queue job for destination \"%s\".",
1767*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text);
1768*5e7646d2SAndroid Build Coastguard Worker goto error;
1769*5e7646d2SAndroid Build Coastguard Worker }
1770*5e7646d2SAndroid Build Coastguard Worker
1771*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->dest, dest);
1772*5e7646d2SAndroid Build Coastguard Worker }
1773*5e7646d2SAndroid Build Coastguard Worker else if ((destptr = cupsdFindDest(job->dest)) == NULL)
1774*5e7646d2SAndroid Build Coastguard Worker {
1775*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1776*5e7646d2SAndroid Build Coastguard Worker "Unable to queue job for destination \"%s\".",
1777*5e7646d2SAndroid Build Coastguard Worker job->dest);
1778*5e7646d2SAndroid Build Coastguard Worker goto error;
1779*5e7646d2SAndroid Build Coastguard Worker }
1780*5e7646d2SAndroid Build Coastguard Worker
1781*5e7646d2SAndroid Build Coastguard Worker if ((job->reasons = ippFindAttribute(job->attrs, "job-state-reasons",
1782*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) == NULL)
1783*5e7646d2SAndroid Build Coastguard Worker {
1784*5e7646d2SAndroid Build Coastguard Worker const char *reason; /* job-state-reason keyword */
1785*5e7646d2SAndroid Build Coastguard Worker
1786*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
1787*5e7646d2SAndroid Build Coastguard Worker "Adding missing job-state-reasons attribute to control file.");
1788*5e7646d2SAndroid Build Coastguard Worker
1789*5e7646d2SAndroid Build Coastguard Worker switch (job->state_value)
1790*5e7646d2SAndroid Build Coastguard Worker {
1791*5e7646d2SAndroid Build Coastguard Worker default :
1792*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PENDING :
1793*5e7646d2SAndroid Build Coastguard Worker if (destptr->state == IPP_PRINTER_STOPPED)
1794*5e7646d2SAndroid Build Coastguard Worker reason = "printer-stopped";
1795*5e7646d2SAndroid Build Coastguard Worker else
1796*5e7646d2SAndroid Build Coastguard Worker reason = "none";
1797*5e7646d2SAndroid Build Coastguard Worker break;
1798*5e7646d2SAndroid Build Coastguard Worker
1799*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_HELD :
1800*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
1801*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO)) != NULL &&
1802*5e7646d2SAndroid Build Coastguard Worker (attr->value_tag == IPP_TAG_NAME ||
1803*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_NAMELANG ||
1804*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_KEYWORD) &&
1805*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->values[0].string.text, "no-hold"))
1806*5e7646d2SAndroid Build Coastguard Worker reason = "job-hold-until-specified";
1807*5e7646d2SAndroid Build Coastguard Worker else
1808*5e7646d2SAndroid Build Coastguard Worker reason = "job-incoming";
1809*5e7646d2SAndroid Build Coastguard Worker break;
1810*5e7646d2SAndroid Build Coastguard Worker
1811*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PROCESSING :
1812*5e7646d2SAndroid Build Coastguard Worker reason = "job-printing";
1813*5e7646d2SAndroid Build Coastguard Worker break;
1814*5e7646d2SAndroid Build Coastguard Worker
1815*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_STOPPED :
1816*5e7646d2SAndroid Build Coastguard Worker reason = "job-stopped";
1817*5e7646d2SAndroid Build Coastguard Worker break;
1818*5e7646d2SAndroid Build Coastguard Worker
1819*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_CANCELED :
1820*5e7646d2SAndroid Build Coastguard Worker reason = "job-canceled-by-user";
1821*5e7646d2SAndroid Build Coastguard Worker break;
1822*5e7646d2SAndroid Build Coastguard Worker
1823*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_ABORTED :
1824*5e7646d2SAndroid Build Coastguard Worker reason = "aborted-by-system";
1825*5e7646d2SAndroid Build Coastguard Worker break;
1826*5e7646d2SAndroid Build Coastguard Worker
1827*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_COMPLETED :
1828*5e7646d2SAndroid Build Coastguard Worker reason = "job-completed-successfully";
1829*5e7646d2SAndroid Build Coastguard Worker break;
1830*5e7646d2SAndroid Build Coastguard Worker }
1831*5e7646d2SAndroid Build Coastguard Worker
1832*5e7646d2SAndroid Build Coastguard Worker job->reasons = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
1833*5e7646d2SAndroid Build Coastguard Worker "job-state-reasons", NULL, reason);
1834*5e7646d2SAndroid Build Coastguard Worker }
1835*5e7646d2SAndroid Build Coastguard Worker else if (job->state_value == IPP_JOB_PENDING)
1836*5e7646d2SAndroid Build Coastguard Worker {
1837*5e7646d2SAndroid Build Coastguard Worker if (destptr->state == IPP_PRINTER_STOPPED)
1838*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "printer-stopped");
1839*5e7646d2SAndroid Build Coastguard Worker else
1840*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "none");
1841*5e7646d2SAndroid Build Coastguard Worker }
1842*5e7646d2SAndroid Build Coastguard Worker
1843*5e7646d2SAndroid Build Coastguard Worker job->impressions = ippFindAttribute(job->attrs, "job-impressions-completed", IPP_TAG_INTEGER);
1844*5e7646d2SAndroid Build Coastguard Worker job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed", IPP_TAG_INTEGER);
1845*5e7646d2SAndroid Build Coastguard Worker job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
1846*5e7646d2SAndroid Build Coastguard Worker
1847*5e7646d2SAndroid Build Coastguard Worker if (!job->impressions)
1848*5e7646d2SAndroid Build Coastguard Worker job->impressions = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-impressions-completed", 0);
1849*5e7646d2SAndroid Build Coastguard Worker if (!job->sheets)
1850*5e7646d2SAndroid Build Coastguard Worker job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-media-sheets-completed", 0);
1851*5e7646d2SAndroid Build Coastguard Worker
1852*5e7646d2SAndroid Build Coastguard Worker if (!job->priority)
1853*5e7646d2SAndroid Build Coastguard Worker {
1854*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-priority",
1855*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_INTEGER)) == NULL)
1856*5e7646d2SAndroid Build Coastguard Worker {
1857*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1858*5e7646d2SAndroid Build Coastguard Worker "Missing or bad job-priority attribute in control file.");
1859*5e7646d2SAndroid Build Coastguard Worker goto error;
1860*5e7646d2SAndroid Build Coastguard Worker }
1861*5e7646d2SAndroid Build Coastguard Worker
1862*5e7646d2SAndroid Build Coastguard Worker job->priority = attr->values[0].integer;
1863*5e7646d2SAndroid Build Coastguard Worker }
1864*5e7646d2SAndroid Build Coastguard Worker
1865*5e7646d2SAndroid Build Coastguard Worker if (!job->username)
1866*5e7646d2SAndroid Build Coastguard Worker {
1867*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-originating-user-name",
1868*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_NAME)) == NULL)
1869*5e7646d2SAndroid Build Coastguard Worker {
1870*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1871*5e7646d2SAndroid Build Coastguard Worker "Missing or bad job-originating-user-name "
1872*5e7646d2SAndroid Build Coastguard Worker "attribute in control file.");
1873*5e7646d2SAndroid Build Coastguard Worker goto error;
1874*5e7646d2SAndroid Build Coastguard Worker }
1875*5e7646d2SAndroid Build Coastguard Worker
1876*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->username, attr->values[0].string.text);
1877*5e7646d2SAndroid Build Coastguard Worker }
1878*5e7646d2SAndroid Build Coastguard Worker
1879*5e7646d2SAndroid Build Coastguard Worker if (!job->name)
1880*5e7646d2SAndroid Build Coastguard Worker {
1881*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL)
1882*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->name, attr->values[0].string.text);
1883*5e7646d2SAndroid Build Coastguard Worker }
1884*5e7646d2SAndroid Build Coastguard Worker
1885*5e7646d2SAndroid Build Coastguard Worker /*
1886*5e7646d2SAndroid Build Coastguard Worker * Set the job hold-until time and state...
1887*5e7646d2SAndroid Build Coastguard Worker */
1888*5e7646d2SAndroid Build Coastguard Worker
1889*5e7646d2SAndroid Build Coastguard Worker if (job->state_value == IPP_JOB_HELD)
1890*5e7646d2SAndroid Build Coastguard Worker {
1891*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
1892*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) == NULL)
1893*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
1894*5e7646d2SAndroid Build Coastguard Worker
1895*5e7646d2SAndroid Build Coastguard Worker if (attr)
1896*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, attr->values[0].string.text, CUPSD_JOB_DEFAULT);
1897*5e7646d2SAndroid Build Coastguard Worker else
1898*5e7646d2SAndroid Build Coastguard Worker {
1899*5e7646d2SAndroid Build Coastguard Worker job->state->values[0].integer = IPP_JOB_PENDING;
1900*5e7646d2SAndroid Build Coastguard Worker job->state_value = IPP_JOB_PENDING;
1901*5e7646d2SAndroid Build Coastguard Worker }
1902*5e7646d2SAndroid Build Coastguard Worker }
1903*5e7646d2SAndroid Build Coastguard Worker else if (job->state_value == IPP_JOB_PROCESSING)
1904*5e7646d2SAndroid Build Coastguard Worker {
1905*5e7646d2SAndroid Build Coastguard Worker job->state->values[0].integer = IPP_JOB_PENDING;
1906*5e7646d2SAndroid Build Coastguard Worker job->state_value = IPP_JOB_PENDING;
1907*5e7646d2SAndroid Build Coastguard Worker }
1908*5e7646d2SAndroid Build Coastguard Worker
1909*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
1910*5e7646d2SAndroid Build Coastguard Worker job->koctets = attr->values[0].integer;
1911*5e7646d2SAndroid Build Coastguard Worker
1912*5e7646d2SAndroid Build Coastguard Worker if (!job->num_files)
1913*5e7646d2SAndroid Build Coastguard Worker {
1914*5e7646d2SAndroid Build Coastguard Worker /*
1915*5e7646d2SAndroid Build Coastguard Worker * Find all the d##### files...
1916*5e7646d2SAndroid Build Coastguard Worker */
1917*5e7646d2SAndroid Build Coastguard Worker
1918*5e7646d2SAndroid Build Coastguard Worker for (fileid = 1; fileid < 10000; fileid ++)
1919*5e7646d2SAndroid Build Coastguard Worker {
1920*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot,
1921*5e7646d2SAndroid Build Coastguard Worker job->id, fileid);
1922*5e7646d2SAndroid Build Coastguard Worker
1923*5e7646d2SAndroid Build Coastguard Worker if (access(jobfile, 0))
1924*5e7646d2SAndroid Build Coastguard Worker break;
1925*5e7646d2SAndroid Build Coastguard Worker
1926*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
1927*5e7646d2SAndroid Build Coastguard Worker "Auto-typing document file \"%s\"...", jobfile);
1928*5e7646d2SAndroid Build Coastguard Worker
1929*5e7646d2SAndroid Build Coastguard Worker if (fileid > job->num_files)
1930*5e7646d2SAndroid Build Coastguard Worker {
1931*5e7646d2SAndroid Build Coastguard Worker if (job->num_files == 0)
1932*5e7646d2SAndroid Build Coastguard Worker {
1933*5e7646d2SAndroid Build Coastguard Worker compressions = (int *)calloc((size_t)fileid, sizeof(int));
1934*5e7646d2SAndroid Build Coastguard Worker filetypes = (mime_type_t **)calloc((size_t)fileid, sizeof(mime_type_t *));
1935*5e7646d2SAndroid Build Coastguard Worker }
1936*5e7646d2SAndroid Build Coastguard Worker else
1937*5e7646d2SAndroid Build Coastguard Worker {
1938*5e7646d2SAndroid Build Coastguard Worker compressions = (int *)realloc(job->compressions, sizeof(int) * (size_t)fileid);
1939*5e7646d2SAndroid Build Coastguard Worker filetypes = (mime_type_t **)realloc(job->filetypes, sizeof(mime_type_t *) * (size_t)fileid);
1940*5e7646d2SAndroid Build Coastguard Worker }
1941*5e7646d2SAndroid Build Coastguard Worker
1942*5e7646d2SAndroid Build Coastguard Worker if (compressions)
1943*5e7646d2SAndroid Build Coastguard Worker job->compressions = compressions;
1944*5e7646d2SAndroid Build Coastguard Worker
1945*5e7646d2SAndroid Build Coastguard Worker if (filetypes)
1946*5e7646d2SAndroid Build Coastguard Worker job->filetypes = filetypes;
1947*5e7646d2SAndroid Build Coastguard Worker
1948*5e7646d2SAndroid Build Coastguard Worker if (!compressions || !filetypes)
1949*5e7646d2SAndroid Build Coastguard Worker {
1950*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
1951*5e7646d2SAndroid Build Coastguard Worker "Ran out of memory for job file types.");
1952*5e7646d2SAndroid Build Coastguard Worker
1953*5e7646d2SAndroid Build Coastguard Worker ippDelete(job->attrs);
1954*5e7646d2SAndroid Build Coastguard Worker job->attrs = NULL;
1955*5e7646d2SAndroid Build Coastguard Worker
1956*5e7646d2SAndroid Build Coastguard Worker if (job->compressions)
1957*5e7646d2SAndroid Build Coastguard Worker {
1958*5e7646d2SAndroid Build Coastguard Worker free(job->compressions);
1959*5e7646d2SAndroid Build Coastguard Worker job->compressions = NULL;
1960*5e7646d2SAndroid Build Coastguard Worker }
1961*5e7646d2SAndroid Build Coastguard Worker
1962*5e7646d2SAndroid Build Coastguard Worker if (job->filetypes)
1963*5e7646d2SAndroid Build Coastguard Worker {
1964*5e7646d2SAndroid Build Coastguard Worker free(job->filetypes);
1965*5e7646d2SAndroid Build Coastguard Worker job->filetypes = NULL;
1966*5e7646d2SAndroid Build Coastguard Worker }
1967*5e7646d2SAndroid Build Coastguard Worker
1968*5e7646d2SAndroid Build Coastguard Worker job->num_files = 0;
1969*5e7646d2SAndroid Build Coastguard Worker return (0);
1970*5e7646d2SAndroid Build Coastguard Worker }
1971*5e7646d2SAndroid Build Coastguard Worker
1972*5e7646d2SAndroid Build Coastguard Worker job->num_files = fileid;
1973*5e7646d2SAndroid Build Coastguard Worker }
1974*5e7646d2SAndroid Build Coastguard Worker
1975*5e7646d2SAndroid Build Coastguard Worker job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, jobfile, NULL,
1976*5e7646d2SAndroid Build Coastguard Worker job->compressions + fileid - 1);
1977*5e7646d2SAndroid Build Coastguard Worker
1978*5e7646d2SAndroid Build Coastguard Worker if (!job->filetypes[fileid - 1])
1979*5e7646d2SAndroid Build Coastguard Worker job->filetypes[fileid - 1] = mimeType(MimeDatabase, "application",
1980*5e7646d2SAndroid Build Coastguard Worker "vnd.cups-raw");
1981*5e7646d2SAndroid Build Coastguard Worker }
1982*5e7646d2SAndroid Build Coastguard Worker }
1983*5e7646d2SAndroid Build Coastguard Worker
1984*5e7646d2SAndroid Build Coastguard Worker /*
1985*5e7646d2SAndroid Build Coastguard Worker * Load authentication information as needed...
1986*5e7646d2SAndroid Build Coastguard Worker */
1987*5e7646d2SAndroid Build Coastguard Worker
1988*5e7646d2SAndroid Build Coastguard Worker if (job->state_value < IPP_JOB_STOPPED)
1989*5e7646d2SAndroid Build Coastguard Worker {
1990*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/a%05d", RequestRoot, job->id);
1991*5e7646d2SAndroid Build Coastguard Worker
1992*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
1993*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
1994*5e7646d2SAndroid Build Coastguard Worker i ++)
1995*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(job->auth_env + i);
1996*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(&job->auth_uid);
1997*5e7646d2SAndroid Build Coastguard Worker
1998*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpen(jobfile, "r")) != NULL)
1999*5e7646d2SAndroid Build Coastguard Worker {
2000*5e7646d2SAndroid Build Coastguard Worker int bytes, /* Size of auth data */
2001*5e7646d2SAndroid Build Coastguard Worker linenum = 1; /* Current line number */
2002*5e7646d2SAndroid Build Coastguard Worker char line[65536], /* Line from file */
2003*5e7646d2SAndroid Build Coastguard Worker *value, /* Value from line */
2004*5e7646d2SAndroid Build Coastguard Worker data[65536]; /* Decoded data */
2005*5e7646d2SAndroid Build Coastguard Worker
2006*5e7646d2SAndroid Build Coastguard Worker
2007*5e7646d2SAndroid Build Coastguard Worker if (cupsFileGets(fp, line, sizeof(line)) &&
2008*5e7646d2SAndroid Build Coastguard Worker !strcmp(line, "CUPSD-AUTH-V3"))
2009*5e7646d2SAndroid Build Coastguard Worker {
2010*5e7646d2SAndroid Build Coastguard Worker i = 0;
2011*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
2012*5e7646d2SAndroid Build Coastguard Worker {
2013*5e7646d2SAndroid Build Coastguard Worker /*
2014*5e7646d2SAndroid Build Coastguard Worker * Decode value...
2015*5e7646d2SAndroid Build Coastguard Worker */
2016*5e7646d2SAndroid Build Coastguard Worker
2017*5e7646d2SAndroid Build Coastguard Worker if (strcmp(line, "negotiate") && strcmp(line, "uid"))
2018*5e7646d2SAndroid Build Coastguard Worker {
2019*5e7646d2SAndroid Build Coastguard Worker bytes = sizeof(data);
2020*5e7646d2SAndroid Build Coastguard Worker httpDecode64_2(data, &bytes, value);
2021*5e7646d2SAndroid Build Coastguard Worker }
2022*5e7646d2SAndroid Build Coastguard Worker
2023*5e7646d2SAndroid Build Coastguard Worker /*
2024*5e7646d2SAndroid Build Coastguard Worker * Assign environment variables...
2025*5e7646d2SAndroid Build Coastguard Worker */
2026*5e7646d2SAndroid Build Coastguard Worker
2027*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(line, "uid"))
2028*5e7646d2SAndroid Build Coastguard Worker {
2029*5e7646d2SAndroid Build Coastguard Worker cupsdSetStringf(&job->auth_uid, "AUTH_UID=%s", value);
2030*5e7646d2SAndroid Build Coastguard Worker continue;
2031*5e7646d2SAndroid Build Coastguard Worker }
2032*5e7646d2SAndroid Build Coastguard Worker else if (i >= (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])))
2033*5e7646d2SAndroid Build Coastguard Worker break;
2034*5e7646d2SAndroid Build Coastguard Worker
2035*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(line, "username"))
2036*5e7646d2SAndroid Build Coastguard Worker cupsdSetStringf(job->auth_env + i, "AUTH_USERNAME=%s", data);
2037*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(line, "domain"))
2038*5e7646d2SAndroid Build Coastguard Worker cupsdSetStringf(job->auth_env + i, "AUTH_DOMAIN=%s", data);
2039*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(line, "password"))
2040*5e7646d2SAndroid Build Coastguard Worker cupsdSetStringf(job->auth_env + i, "AUTH_PASSWORD=%s", data);
2041*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(line, "negotiate"))
2042*5e7646d2SAndroid Build Coastguard Worker cupsdSetStringf(job->auth_env + i, "AUTH_NEGOTIATE=%s", value);
2043*5e7646d2SAndroid Build Coastguard Worker else
2044*5e7646d2SAndroid Build Coastguard Worker continue;
2045*5e7646d2SAndroid Build Coastguard Worker
2046*5e7646d2SAndroid Build Coastguard Worker i ++;
2047*5e7646d2SAndroid Build Coastguard Worker }
2048*5e7646d2SAndroid Build Coastguard Worker }
2049*5e7646d2SAndroid Build Coastguard Worker
2050*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
2051*5e7646d2SAndroid Build Coastguard Worker }
2052*5e7646d2SAndroid Build Coastguard Worker }
2053*5e7646d2SAndroid Build Coastguard Worker
2054*5e7646d2SAndroid Build Coastguard Worker job->access_time = time(NULL);
2055*5e7646d2SAndroid Build Coastguard Worker return (1);
2056*5e7646d2SAndroid Build Coastguard Worker
2057*5e7646d2SAndroid Build Coastguard Worker /*
2058*5e7646d2SAndroid Build Coastguard Worker * If we get here then something bad happened...
2059*5e7646d2SAndroid Build Coastguard Worker */
2060*5e7646d2SAndroid Build Coastguard Worker
2061*5e7646d2SAndroid Build Coastguard Worker error:
2062*5e7646d2SAndroid Build Coastguard Worker
2063*5e7646d2SAndroid Build Coastguard Worker ippDelete(job->attrs);
2064*5e7646d2SAndroid Build Coastguard Worker job->attrs = NULL;
2065*5e7646d2SAndroid Build Coastguard Worker
2066*5e7646d2SAndroid Build Coastguard Worker remove_job_history(job);
2067*5e7646d2SAndroid Build Coastguard Worker remove_job_files(job);
2068*5e7646d2SAndroid Build Coastguard Worker
2069*5e7646d2SAndroid Build Coastguard Worker return (0);
2070*5e7646d2SAndroid Build Coastguard Worker }
2071*5e7646d2SAndroid Build Coastguard Worker
2072*5e7646d2SAndroid Build Coastguard Worker
2073*5e7646d2SAndroid Build Coastguard Worker /*
2074*5e7646d2SAndroid Build Coastguard Worker * 'cupsdMoveJob()' - Move the specified job to a different destination.
2075*5e7646d2SAndroid Build Coastguard Worker */
2076*5e7646d2SAndroid Build Coastguard Worker
2077*5e7646d2SAndroid Build Coastguard Worker void
cupsdMoveJob(cupsd_job_t * job,cupsd_printer_t * p)2078*5e7646d2SAndroid Build Coastguard Worker cupsdMoveJob(cupsd_job_t *job, /* I - Job */
2079*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p) /* I - Destination printer or class */
2080*5e7646d2SAndroid Build Coastguard Worker {
2081*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* job-printer-uri attribute */
2082*5e7646d2SAndroid Build Coastguard Worker const char *olddest; /* Old destination */
2083*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *oldp; /* Old pointer */
2084*5e7646d2SAndroid Build Coastguard Worker
2085*5e7646d2SAndroid Build Coastguard Worker
2086*5e7646d2SAndroid Build Coastguard Worker /*
2087*5e7646d2SAndroid Build Coastguard Worker * Don't move completed jobs...
2088*5e7646d2SAndroid Build Coastguard Worker */
2089*5e7646d2SAndroid Build Coastguard Worker
2090*5e7646d2SAndroid Build Coastguard Worker if (job->state_value > IPP_JOB_STOPPED)
2091*5e7646d2SAndroid Build Coastguard Worker return;
2092*5e7646d2SAndroid Build Coastguard Worker
2093*5e7646d2SAndroid Build Coastguard Worker /*
2094*5e7646d2SAndroid Build Coastguard Worker * Get the old destination...
2095*5e7646d2SAndroid Build Coastguard Worker */
2096*5e7646d2SAndroid Build Coastguard Worker
2097*5e7646d2SAndroid Build Coastguard Worker olddest = job->dest;
2098*5e7646d2SAndroid Build Coastguard Worker
2099*5e7646d2SAndroid Build Coastguard Worker if (job->printer)
2100*5e7646d2SAndroid Build Coastguard Worker oldp = job->printer;
2101*5e7646d2SAndroid Build Coastguard Worker else
2102*5e7646d2SAndroid Build Coastguard Worker oldp = cupsdFindDest(olddest);
2103*5e7646d2SAndroid Build Coastguard Worker
2104*5e7646d2SAndroid Build Coastguard Worker /*
2105*5e7646d2SAndroid Build Coastguard Worker * Change the destination information...
2106*5e7646d2SAndroid Build Coastguard Worker */
2107*5e7646d2SAndroid Build Coastguard Worker
2108*5e7646d2SAndroid Build Coastguard Worker if (job->state_value > IPP_JOB_HELD)
2109*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT,
2110*5e7646d2SAndroid Build Coastguard Worker "Stopping job prior to move.");
2111*5e7646d2SAndroid Build Coastguard Worker
2112*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, oldp, job,
2113*5e7646d2SAndroid Build Coastguard Worker "Job #%d moved from %s to %s.", job->id, olddest,
2114*5e7646d2SAndroid Build Coastguard Worker p->name);
2115*5e7646d2SAndroid Build Coastguard Worker
2116*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->dest, p->name);
2117*5e7646d2SAndroid Build Coastguard Worker job->dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
2118*5e7646d2SAndroid Build Coastguard Worker
2119*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
2120*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_URI)) != NULL)
2121*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &attr, 0, p->uri);
2122*5e7646d2SAndroid Build Coastguard Worker
2123*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job,
2124*5e7646d2SAndroid Build Coastguard Worker "Job #%d moved from %s to %s.", job->id, olddest,
2125*5e7646d2SAndroid Build Coastguard Worker p->name);
2126*5e7646d2SAndroid Build Coastguard Worker
2127*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
2128*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
2129*5e7646d2SAndroid Build Coastguard Worker }
2130*5e7646d2SAndroid Build Coastguard Worker
2131*5e7646d2SAndroid Build Coastguard Worker
2132*5e7646d2SAndroid Build Coastguard Worker /*
2133*5e7646d2SAndroid Build Coastguard Worker * 'cupsdReleaseJob()' - Release the specified job.
2134*5e7646d2SAndroid Build Coastguard Worker */
2135*5e7646d2SAndroid Build Coastguard Worker
2136*5e7646d2SAndroid Build Coastguard Worker void
cupsdReleaseJob(cupsd_job_t * job)2137*5e7646d2SAndroid Build Coastguard Worker cupsdReleaseJob(cupsd_job_t *job) /* I - Job */
2138*5e7646d2SAndroid Build Coastguard Worker {
2139*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReleaseJob(job=%p(%d))", job,
2140*5e7646d2SAndroid Build Coastguard Worker job->id);
2141*5e7646d2SAndroid Build Coastguard Worker
2142*5e7646d2SAndroid Build Coastguard Worker if (job->state_value == IPP_JOB_HELD)
2143*5e7646d2SAndroid Build Coastguard Worker {
2144*5e7646d2SAndroid Build Coastguard Worker /*
2145*5e7646d2SAndroid Build Coastguard Worker * Add trailing banner as needed...
2146*5e7646d2SAndroid Build Coastguard Worker */
2147*5e7646d2SAndroid Build Coastguard Worker
2148*5e7646d2SAndroid Build Coastguard Worker if (job->pending_timeout)
2149*5e7646d2SAndroid Build Coastguard Worker cupsdTimeoutJob(job);
2150*5e7646d2SAndroid Build Coastguard Worker
2151*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT,
2152*5e7646d2SAndroid Build Coastguard Worker "Job released by user.");
2153*5e7646d2SAndroid Build Coastguard Worker }
2154*5e7646d2SAndroid Build Coastguard Worker }
2155*5e7646d2SAndroid Build Coastguard Worker
2156*5e7646d2SAndroid Build Coastguard Worker
2157*5e7646d2SAndroid Build Coastguard Worker /*
2158*5e7646d2SAndroid Build Coastguard Worker * 'cupsdRestartJob()' - Restart the specified job.
2159*5e7646d2SAndroid Build Coastguard Worker */
2160*5e7646d2SAndroid Build Coastguard Worker
2161*5e7646d2SAndroid Build Coastguard Worker void
cupsdRestartJob(cupsd_job_t * job)2162*5e7646d2SAndroid Build Coastguard Worker cupsdRestartJob(cupsd_job_t *job) /* I - Job */
2163*5e7646d2SAndroid Build Coastguard Worker {
2164*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdRestartJob(job=%p(%d))", job,
2165*5e7646d2SAndroid Build Coastguard Worker job->id);
2166*5e7646d2SAndroid Build Coastguard Worker
2167*5e7646d2SAndroid Build Coastguard Worker if (job->state_value == IPP_JOB_STOPPED || job->num_files)
2168*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT,
2169*5e7646d2SAndroid Build Coastguard Worker "Job restarted by user.");
2170*5e7646d2SAndroid Build Coastguard Worker }
2171*5e7646d2SAndroid Build Coastguard Worker
2172*5e7646d2SAndroid Build Coastguard Worker
2173*5e7646d2SAndroid Build Coastguard Worker /*
2174*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSaveAllJobs()' - Save a summary of all jobs to disk.
2175*5e7646d2SAndroid Build Coastguard Worker */
2176*5e7646d2SAndroid Build Coastguard Worker
2177*5e7646d2SAndroid Build Coastguard Worker void
cupsdSaveAllJobs(void)2178*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllJobs(void)
2179*5e7646d2SAndroid Build Coastguard Worker {
2180*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2181*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* job.cache file */
2182*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* job.cache filename */
2183*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
2184*5e7646d2SAndroid Build Coastguard Worker
2185*5e7646d2SAndroid Build Coastguard Worker
2186*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/job.cache", CacheDir);
2187*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
2188*5e7646d2SAndroid Build Coastguard Worker return;
2189*5e7646d2SAndroid Build Coastguard Worker
2190*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_INFO, "Saving job.cache...");
2191*5e7646d2SAndroid Build Coastguard Worker
2192*5e7646d2SAndroid Build Coastguard Worker /*
2193*5e7646d2SAndroid Build Coastguard Worker * Write a small header to the file...
2194*5e7646d2SAndroid Build Coastguard Worker */
2195*5e7646d2SAndroid Build Coastguard Worker
2196*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "# Job cache file for " CUPS_SVERSION "\n");
2197*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "# Written by cupsd\n");
2198*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "NextJobId %d\n", NextJobId);
2199*5e7646d2SAndroid Build Coastguard Worker
2200*5e7646d2SAndroid Build Coastguard Worker /*
2201*5e7646d2SAndroid Build Coastguard Worker * Write each job known to the system...
2202*5e7646d2SAndroid Build Coastguard Worker */
2203*5e7646d2SAndroid Build Coastguard Worker
2204*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
2205*5e7646d2SAndroid Build Coastguard Worker job;
2206*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
2207*5e7646d2SAndroid Build Coastguard Worker {
2208*5e7646d2SAndroid Build Coastguard Worker if (job->printer && job->printer->temporary)
2209*5e7646d2SAndroid Build Coastguard Worker {
2210*5e7646d2SAndroid Build Coastguard Worker /*
2211*5e7646d2SAndroid Build Coastguard Worker * Don't save jobs on temporary printers...
2212*5e7646d2SAndroid Build Coastguard Worker */
2213*5e7646d2SAndroid Build Coastguard Worker
2214*5e7646d2SAndroid Build Coastguard Worker continue;
2215*5e7646d2SAndroid Build Coastguard Worker }
2216*5e7646d2SAndroid Build Coastguard Worker
2217*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "<Job %d>\n", job->id);
2218*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "State %d\n", job->state_value);
2219*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Created %ld\n", (long)job->creation_time);
2220*5e7646d2SAndroid Build Coastguard Worker if (job->completed_time)
2221*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Completed %ld\n", (long)job->completed_time);
2222*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Priority %d\n", job->priority);
2223*5e7646d2SAndroid Build Coastguard Worker if (job->hold_until)
2224*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "HoldUntil %ld\n", (long)job->hold_until);
2225*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Username %s\n", job->username);
2226*5e7646d2SAndroid Build Coastguard Worker if (job->name)
2227*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Name", job->name);
2228*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Destination %s\n", job->dest);
2229*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "DestType %d\n", job->dtype);
2230*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "KOctets %d\n", job->koctets);
2231*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "NumFiles %d\n", job->num_files);
2232*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < job->num_files; i ++)
2233*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "File %d %s/%s %d\n", i + 1, job->filetypes[i]->super,
2234*5e7646d2SAndroid Build Coastguard Worker job->filetypes[i]->type, job->compressions[i]);
2235*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "</Job>\n");
2236*5e7646d2SAndroid Build Coastguard Worker }
2237*5e7646d2SAndroid Build Coastguard Worker
2238*5e7646d2SAndroid Build Coastguard Worker cupsdCloseCreatedConfFile(fp, filename);
2239*5e7646d2SAndroid Build Coastguard Worker }
2240*5e7646d2SAndroid Build Coastguard Worker
2241*5e7646d2SAndroid Build Coastguard Worker
2242*5e7646d2SAndroid Build Coastguard Worker /*
2243*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSaveJob()' - Save a job to disk.
2244*5e7646d2SAndroid Build Coastguard Worker */
2245*5e7646d2SAndroid Build Coastguard Worker
2246*5e7646d2SAndroid Build Coastguard Worker void
cupsdSaveJob(cupsd_job_t * job)2247*5e7646d2SAndroid Build Coastguard Worker cupsdSaveJob(cupsd_job_t *job) /* I - Job */
2248*5e7646d2SAndroid Build Coastguard Worker {
2249*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Job control filename */
2250*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* Job file */
2251*5e7646d2SAndroid Build Coastguard Worker
2252*5e7646d2SAndroid Build Coastguard Worker
2253*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
2254*5e7646d2SAndroid Build Coastguard Worker job, job->id, job->attrs);
2255*5e7646d2SAndroid Build Coastguard Worker
2256*5e7646d2SAndroid Build Coastguard Worker if (job->printer && job->printer->temporary)
2257*5e7646d2SAndroid Build Coastguard Worker {
2258*5e7646d2SAndroid Build Coastguard Worker /*
2259*5e7646d2SAndroid Build Coastguard Worker * Don't save jobs on temporary printers...
2260*5e7646d2SAndroid Build Coastguard Worker */
2261*5e7646d2SAndroid Build Coastguard Worker
2262*5e7646d2SAndroid Build Coastguard Worker job->dirty = 0;
2263*5e7646d2SAndroid Build Coastguard Worker return;
2264*5e7646d2SAndroid Build Coastguard Worker }
2265*5e7646d2SAndroid Build Coastguard Worker
2266*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
2267*5e7646d2SAndroid Build Coastguard Worker
2268*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm & 0600)) == NULL)
2269*5e7646d2SAndroid Build Coastguard Worker return;
2270*5e7646d2SAndroid Build Coastguard Worker
2271*5e7646d2SAndroid Build Coastguard Worker fchown(cupsFileNumber(fp), RunUser, Group);
2272*5e7646d2SAndroid Build Coastguard Worker
2273*5e7646d2SAndroid Build Coastguard Worker job->attrs->state = IPP_IDLE;
2274*5e7646d2SAndroid Build Coastguard Worker
2275*5e7646d2SAndroid Build Coastguard Worker if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
2276*5e7646d2SAndroid Build Coastguard Worker job->attrs) != IPP_DATA)
2277*5e7646d2SAndroid Build Coastguard Worker {
2278*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to write job control file.");
2279*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
2280*5e7646d2SAndroid Build Coastguard Worker return;
2281*5e7646d2SAndroid Build Coastguard Worker }
2282*5e7646d2SAndroid Build Coastguard Worker
2283*5e7646d2SAndroid Build Coastguard Worker if (!cupsdCloseCreatedConfFile(fp, filename))
2284*5e7646d2SAndroid Build Coastguard Worker {
2285*5e7646d2SAndroid Build Coastguard Worker /*
2286*5e7646d2SAndroid Build Coastguard Worker * Remove backup file and mark this job as clean...
2287*5e7646d2SAndroid Build Coastguard Worker */
2288*5e7646d2SAndroid Build Coastguard Worker
2289*5e7646d2SAndroid Build Coastguard Worker strlcat(filename, ".O", sizeof(filename));
2290*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
2291*5e7646d2SAndroid Build Coastguard Worker
2292*5e7646d2SAndroid Build Coastguard Worker job->dirty = 0;
2293*5e7646d2SAndroid Build Coastguard Worker }
2294*5e7646d2SAndroid Build Coastguard Worker }
2295*5e7646d2SAndroid Build Coastguard Worker
2296*5e7646d2SAndroid Build Coastguard Worker
2297*5e7646d2SAndroid Build Coastguard Worker /*
2298*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSetJobHoldUntil()' - Set the hold time for a job.
2299*5e7646d2SAndroid Build Coastguard Worker */
2300*5e7646d2SAndroid Build Coastguard Worker
2301*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetJobHoldUntil(cupsd_job_t * job,const char * when,int update)2302*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
2303*5e7646d2SAndroid Build Coastguard Worker const char *when, /* I - When to resume */
2304*5e7646d2SAndroid Build Coastguard Worker int update)/* I - Update job-hold-until attr? */
2305*5e7646d2SAndroid Build Coastguard Worker {
2306*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time */
2307*5e7646d2SAndroid Build Coastguard Worker struct tm curdate; /* Current date */
2308*5e7646d2SAndroid Build Coastguard Worker int hour; /* Hold hour */
2309*5e7646d2SAndroid Build Coastguard Worker int minute; /* Hold minute */
2310*5e7646d2SAndroid Build Coastguard Worker int second = 0; /* Hold second */
2311*5e7646d2SAndroid Build Coastguard Worker
2312*5e7646d2SAndroid Build Coastguard Worker
2313*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2,
2314*5e7646d2SAndroid Build Coastguard Worker "cupsdSetJobHoldUntil(job=%p(%d), when=\"%s\", update=%d)",
2315*5e7646d2SAndroid Build Coastguard Worker job, job->id, when, update);
2316*5e7646d2SAndroid Build Coastguard Worker
2317*5e7646d2SAndroid Build Coastguard Worker if (update)
2318*5e7646d2SAndroid Build Coastguard Worker {
2319*5e7646d2SAndroid Build Coastguard Worker /*
2320*5e7646d2SAndroid Build Coastguard Worker * Update the job-hold-until attribute...
2321*5e7646d2SAndroid Build Coastguard Worker */
2322*5e7646d2SAndroid Build Coastguard Worker
2323*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* job-hold-until attribute */
2324*5e7646d2SAndroid Build Coastguard Worker
2325*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
2326*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) == NULL)
2327*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
2328*5e7646d2SAndroid Build Coastguard Worker
2329*5e7646d2SAndroid Build Coastguard Worker if (attr)
2330*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &attr, 0, when);
2331*5e7646d2SAndroid Build Coastguard Worker else
2332*5e7646d2SAndroid Build Coastguard Worker attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
2333*5e7646d2SAndroid Build Coastguard Worker "job-hold-until", NULL, when);
2334*5e7646d2SAndroid Build Coastguard Worker
2335*5e7646d2SAndroid Build Coastguard Worker if (attr)
2336*5e7646d2SAndroid Build Coastguard Worker {
2337*5e7646d2SAndroid Build Coastguard Worker if (isdigit(when[0] & 255))
2338*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = IPP_TAG_NAME;
2339*5e7646d2SAndroid Build Coastguard Worker else
2340*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = IPP_TAG_KEYWORD;
2341*5e7646d2SAndroid Build Coastguard Worker
2342*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
2343*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
2344*5e7646d2SAndroid Build Coastguard Worker }
2345*5e7646d2SAndroid Build Coastguard Worker
2346*5e7646d2SAndroid Build Coastguard Worker }
2347*5e7646d2SAndroid Build Coastguard Worker
2348*5e7646d2SAndroid Build Coastguard Worker if (strcmp(when, "no-hold"))
2349*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
2350*5e7646d2SAndroid Build Coastguard Worker else
2351*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "none");
2352*5e7646d2SAndroid Build Coastguard Worker
2353*5e7646d2SAndroid Build Coastguard Worker /*
2354*5e7646d2SAndroid Build Coastguard Worker * Update the hold time...
2355*5e7646d2SAndroid Build Coastguard Worker */
2356*5e7646d2SAndroid Build Coastguard Worker
2357*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = 0;
2358*5e7646d2SAndroid Build Coastguard Worker
2359*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(when, "indefinite") || !strcmp(when, "auth-info-required"))
2360*5e7646d2SAndroid Build Coastguard Worker {
2361*5e7646d2SAndroid Build Coastguard Worker /*
2362*5e7646d2SAndroid Build Coastguard Worker * Hold indefinitely...
2363*5e7646d2SAndroid Build Coastguard Worker */
2364*5e7646d2SAndroid Build Coastguard Worker
2365*5e7646d2SAndroid Build Coastguard Worker job->hold_until = 0;
2366*5e7646d2SAndroid Build Coastguard Worker
2367*5e7646d2SAndroid Build Coastguard Worker if (MaxHoldTime > 0)
2368*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + MaxHoldTime;
2369*5e7646d2SAndroid Build Coastguard Worker }
2370*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(when, "day-time"))
2371*5e7646d2SAndroid Build Coastguard Worker {
2372*5e7646d2SAndroid Build Coastguard Worker /*
2373*5e7646d2SAndroid Build Coastguard Worker * Hold to 6am the next morning unless local time is < 6pm.
2374*5e7646d2SAndroid Build Coastguard Worker */
2375*5e7646d2SAndroid Build Coastguard Worker
2376*5e7646d2SAndroid Build Coastguard Worker time(&curtime);
2377*5e7646d2SAndroid Build Coastguard Worker localtime_r(&curtime, &curdate);
2378*5e7646d2SAndroid Build Coastguard Worker
2379*5e7646d2SAndroid Build Coastguard Worker if (curdate.tm_hour < 18)
2380*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime;
2381*5e7646d2SAndroid Build Coastguard Worker else
2382*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime +
2383*5e7646d2SAndroid Build Coastguard Worker ((29 - curdate.tm_hour) * 60 + 59 -
2384*5e7646d2SAndroid Build Coastguard Worker curdate.tm_min) * 60 + 60 - curdate.tm_sec;
2385*5e7646d2SAndroid Build Coastguard Worker }
2386*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(when, "evening") || !strcmp(when, "night"))
2387*5e7646d2SAndroid Build Coastguard Worker {
2388*5e7646d2SAndroid Build Coastguard Worker /*
2389*5e7646d2SAndroid Build Coastguard Worker * Hold to 6pm unless local time is > 6pm or < 6am.
2390*5e7646d2SAndroid Build Coastguard Worker */
2391*5e7646d2SAndroid Build Coastguard Worker
2392*5e7646d2SAndroid Build Coastguard Worker time(&curtime);
2393*5e7646d2SAndroid Build Coastguard Worker localtime_r(&curtime, &curdate);
2394*5e7646d2SAndroid Build Coastguard Worker
2395*5e7646d2SAndroid Build Coastguard Worker if (curdate.tm_hour < 6 || curdate.tm_hour >= 18)
2396*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime;
2397*5e7646d2SAndroid Build Coastguard Worker else
2398*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime +
2399*5e7646d2SAndroid Build Coastguard Worker ((17 - curdate.tm_hour) * 60 + 59 -
2400*5e7646d2SAndroid Build Coastguard Worker curdate.tm_min) * 60 + 60 - curdate.tm_sec;
2401*5e7646d2SAndroid Build Coastguard Worker }
2402*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(when, "second-shift"))
2403*5e7646d2SAndroid Build Coastguard Worker {
2404*5e7646d2SAndroid Build Coastguard Worker /*
2405*5e7646d2SAndroid Build Coastguard Worker * Hold to 4pm unless local time is > 4pm.
2406*5e7646d2SAndroid Build Coastguard Worker */
2407*5e7646d2SAndroid Build Coastguard Worker
2408*5e7646d2SAndroid Build Coastguard Worker time(&curtime);
2409*5e7646d2SAndroid Build Coastguard Worker localtime_r(&curtime, &curdate);
2410*5e7646d2SAndroid Build Coastguard Worker
2411*5e7646d2SAndroid Build Coastguard Worker if (curdate.tm_hour >= 16)
2412*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime;
2413*5e7646d2SAndroid Build Coastguard Worker else
2414*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime +
2415*5e7646d2SAndroid Build Coastguard Worker ((15 - curdate.tm_hour) * 60 + 59 -
2416*5e7646d2SAndroid Build Coastguard Worker curdate.tm_min) * 60 + 60 - curdate.tm_sec;
2417*5e7646d2SAndroid Build Coastguard Worker }
2418*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(when, "third-shift"))
2419*5e7646d2SAndroid Build Coastguard Worker {
2420*5e7646d2SAndroid Build Coastguard Worker /*
2421*5e7646d2SAndroid Build Coastguard Worker * Hold to 12am unless local time is < 8am.
2422*5e7646d2SAndroid Build Coastguard Worker */
2423*5e7646d2SAndroid Build Coastguard Worker
2424*5e7646d2SAndroid Build Coastguard Worker time(&curtime);
2425*5e7646d2SAndroid Build Coastguard Worker localtime_r(&curtime, &curdate);
2426*5e7646d2SAndroid Build Coastguard Worker
2427*5e7646d2SAndroid Build Coastguard Worker if (curdate.tm_hour < 8)
2428*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime;
2429*5e7646d2SAndroid Build Coastguard Worker else
2430*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime +
2431*5e7646d2SAndroid Build Coastguard Worker ((23 - curdate.tm_hour) * 60 + 59 -
2432*5e7646d2SAndroid Build Coastguard Worker curdate.tm_min) * 60 + 60 - curdate.tm_sec;
2433*5e7646d2SAndroid Build Coastguard Worker }
2434*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(when, "weekend"))
2435*5e7646d2SAndroid Build Coastguard Worker {
2436*5e7646d2SAndroid Build Coastguard Worker /*
2437*5e7646d2SAndroid Build Coastguard Worker * Hold to weekend unless we are in the weekend.
2438*5e7646d2SAndroid Build Coastguard Worker */
2439*5e7646d2SAndroid Build Coastguard Worker
2440*5e7646d2SAndroid Build Coastguard Worker time(&curtime);
2441*5e7646d2SAndroid Build Coastguard Worker localtime_r(&curtime, &curdate);
2442*5e7646d2SAndroid Build Coastguard Worker
2443*5e7646d2SAndroid Build Coastguard Worker if (curdate.tm_wday == 0 || curdate.tm_wday == 6)
2444*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime;
2445*5e7646d2SAndroid Build Coastguard Worker else
2446*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime +
2447*5e7646d2SAndroid Build Coastguard Worker (((5 - curdate.tm_wday) * 24 +
2448*5e7646d2SAndroid Build Coastguard Worker (17 - curdate.tm_hour)) * 60 + 59 -
2449*5e7646d2SAndroid Build Coastguard Worker curdate.tm_min) * 60 + 60 - curdate.tm_sec;
2450*5e7646d2SAndroid Build Coastguard Worker }
2451*5e7646d2SAndroid Build Coastguard Worker else if (sscanf(when, "%d:%d:%d", &hour, &minute, &second) >= 2)
2452*5e7646d2SAndroid Build Coastguard Worker {
2453*5e7646d2SAndroid Build Coastguard Worker /*
2454*5e7646d2SAndroid Build Coastguard Worker * Hold to specified GMT time (HH:MM or HH:MM:SS)...
2455*5e7646d2SAndroid Build Coastguard Worker */
2456*5e7646d2SAndroid Build Coastguard Worker
2457*5e7646d2SAndroid Build Coastguard Worker time(&curtime);
2458*5e7646d2SAndroid Build Coastguard Worker gmtime_r(&curtime, &curdate);
2459*5e7646d2SAndroid Build Coastguard Worker
2460*5e7646d2SAndroid Build Coastguard Worker job->hold_until = curtime +
2461*5e7646d2SAndroid Build Coastguard Worker ((hour - curdate.tm_hour) * 60 + minute -
2462*5e7646d2SAndroid Build Coastguard Worker curdate.tm_min) * 60 + second - curdate.tm_sec;
2463*5e7646d2SAndroid Build Coastguard Worker
2464*5e7646d2SAndroid Build Coastguard Worker /*
2465*5e7646d2SAndroid Build Coastguard Worker * Hold until next day as needed...
2466*5e7646d2SAndroid Build Coastguard Worker */
2467*5e7646d2SAndroid Build Coastguard Worker
2468*5e7646d2SAndroid Build Coastguard Worker if (job->hold_until < curtime)
2469*5e7646d2SAndroid Build Coastguard Worker job->hold_until += 24 * 60 * 60;
2470*5e7646d2SAndroid Build Coastguard Worker }
2471*5e7646d2SAndroid Build Coastguard Worker
2472*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSetJobHoldUntil: hold_until=%d",
2473*5e7646d2SAndroid Build Coastguard Worker (int)job->hold_until);
2474*5e7646d2SAndroid Build Coastguard Worker }
2475*5e7646d2SAndroid Build Coastguard Worker
2476*5e7646d2SAndroid Build Coastguard Worker
2477*5e7646d2SAndroid Build Coastguard Worker /*
2478*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSetJobPriority()' - Set the priority of a job, moving it up/down in
2479*5e7646d2SAndroid Build Coastguard Worker * the list as needed.
2480*5e7646d2SAndroid Build Coastguard Worker */
2481*5e7646d2SAndroid Build Coastguard Worker
2482*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetJobPriority(cupsd_job_t * job,int priority)2483*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobPriority(
2484*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job, /* I - Job ID */
2485*5e7646d2SAndroid Build Coastguard Worker int priority) /* I - New priority (0 to 100) */
2486*5e7646d2SAndroid Build Coastguard Worker {
2487*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Job attribute */
2488*5e7646d2SAndroid Build Coastguard Worker
2489*5e7646d2SAndroid Build Coastguard Worker
2490*5e7646d2SAndroid Build Coastguard Worker /*
2491*5e7646d2SAndroid Build Coastguard Worker * Don't change completed jobs...
2492*5e7646d2SAndroid Build Coastguard Worker */
2493*5e7646d2SAndroid Build Coastguard Worker
2494*5e7646d2SAndroid Build Coastguard Worker if (job->state_value >= IPP_JOB_PROCESSING)
2495*5e7646d2SAndroid Build Coastguard Worker return;
2496*5e7646d2SAndroid Build Coastguard Worker
2497*5e7646d2SAndroid Build Coastguard Worker /*
2498*5e7646d2SAndroid Build Coastguard Worker * Set the new priority and re-add the job into the active list...
2499*5e7646d2SAndroid Build Coastguard Worker */
2500*5e7646d2SAndroid Build Coastguard Worker
2501*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ActiveJobs, job);
2502*5e7646d2SAndroid Build Coastguard Worker
2503*5e7646d2SAndroid Build Coastguard Worker job->priority = priority;
2504*5e7646d2SAndroid Build Coastguard Worker
2505*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-priority",
2506*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_INTEGER)) != NULL)
2507*5e7646d2SAndroid Build Coastguard Worker attr->values[0].integer = priority;
2508*5e7646d2SAndroid Build Coastguard Worker else
2509*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
2510*5e7646d2SAndroid Build Coastguard Worker priority);
2511*5e7646d2SAndroid Build Coastguard Worker
2512*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ActiveJobs, job);
2513*5e7646d2SAndroid Build Coastguard Worker
2514*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
2515*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
2516*5e7646d2SAndroid Build Coastguard Worker }
2517*5e7646d2SAndroid Build Coastguard Worker
2518*5e7646d2SAndroid Build Coastguard Worker
2519*5e7646d2SAndroid Build Coastguard Worker /*
2520*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSetJobState()' - Set the state of the specified print job.
2521*5e7646d2SAndroid Build Coastguard Worker */
2522*5e7646d2SAndroid Build Coastguard Worker
2523*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetJobState(cupsd_job_t * job,ipp_jstate_t newstate,cupsd_jobaction_t action,const char * message,...)2524*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(
2525*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job, /* I - Job to cancel */
2526*5e7646d2SAndroid Build Coastguard Worker ipp_jstate_t newstate, /* I - New job state */
2527*5e7646d2SAndroid Build Coastguard Worker cupsd_jobaction_t action, /* I - Action to take */
2528*5e7646d2SAndroid Build Coastguard Worker const char *message, /* I - Message to log */
2529*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
2530*5e7646d2SAndroid Build Coastguard Worker {
2531*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2532*5e7646d2SAndroid Build Coastguard Worker ipp_jstate_t oldstate; /* Old state */
2533*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Job filename */
2534*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Job attribute */
2535*5e7646d2SAndroid Build Coastguard Worker
2536*5e7646d2SAndroid Build Coastguard Worker
2537*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2,
2538*5e7646d2SAndroid Build Coastguard Worker "cupsdSetJobState(job=%p(%d), state=%d, newstate=%d, "
2539*5e7646d2SAndroid Build Coastguard Worker "action=%d, message=\"%s\")", job, job->id, job->state_value,
2540*5e7646d2SAndroid Build Coastguard Worker newstate, action, message ? message : "(null)");
2541*5e7646d2SAndroid Build Coastguard Worker
2542*5e7646d2SAndroid Build Coastguard Worker
2543*5e7646d2SAndroid Build Coastguard Worker /*
2544*5e7646d2SAndroid Build Coastguard Worker * Make sure we have the job attributes...
2545*5e7646d2SAndroid Build Coastguard Worker */
2546*5e7646d2SAndroid Build Coastguard Worker
2547*5e7646d2SAndroid Build Coastguard Worker if (!cupsdLoadJob(job))
2548*5e7646d2SAndroid Build Coastguard Worker return;
2549*5e7646d2SAndroid Build Coastguard Worker
2550*5e7646d2SAndroid Build Coastguard Worker /*
2551*5e7646d2SAndroid Build Coastguard Worker * Don't do anything if the state is unchanged and we aren't purging the
2552*5e7646d2SAndroid Build Coastguard Worker * job...
2553*5e7646d2SAndroid Build Coastguard Worker */
2554*5e7646d2SAndroid Build Coastguard Worker
2555*5e7646d2SAndroid Build Coastguard Worker oldstate = job->state_value;
2556*5e7646d2SAndroid Build Coastguard Worker if (newstate == oldstate && action != CUPSD_JOB_PURGE)
2557*5e7646d2SAndroid Build Coastguard Worker return;
2558*5e7646d2SAndroid Build Coastguard Worker
2559*5e7646d2SAndroid Build Coastguard Worker /*
2560*5e7646d2SAndroid Build Coastguard Worker * Stop any processes that are working on the current job...
2561*5e7646d2SAndroid Build Coastguard Worker */
2562*5e7646d2SAndroid Build Coastguard Worker
2563*5e7646d2SAndroid Build Coastguard Worker if (oldstate == IPP_JOB_PROCESSING)
2564*5e7646d2SAndroid Build Coastguard Worker stop_job(job, action);
2565*5e7646d2SAndroid Build Coastguard Worker
2566*5e7646d2SAndroid Build Coastguard Worker /*
2567*5e7646d2SAndroid Build Coastguard Worker * Set the new job state...
2568*5e7646d2SAndroid Build Coastguard Worker */
2569*5e7646d2SAndroid Build Coastguard Worker
2570*5e7646d2SAndroid Build Coastguard Worker job->state_value = newstate;
2571*5e7646d2SAndroid Build Coastguard Worker
2572*5e7646d2SAndroid Build Coastguard Worker if (job->state)
2573*5e7646d2SAndroid Build Coastguard Worker job->state->values[0].integer = (int)newstate;
2574*5e7646d2SAndroid Build Coastguard Worker
2575*5e7646d2SAndroid Build Coastguard Worker switch (newstate)
2576*5e7646d2SAndroid Build Coastguard Worker {
2577*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PENDING :
2578*5e7646d2SAndroid Build Coastguard Worker /*
2579*5e7646d2SAndroid Build Coastguard Worker * Update job-hold-until as needed...
2580*5e7646d2SAndroid Build Coastguard Worker */
2581*5e7646d2SAndroid Build Coastguard Worker
2582*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
2583*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) == NULL)
2584*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
2585*5e7646d2SAndroid Build Coastguard Worker
2586*5e7646d2SAndroid Build Coastguard Worker if (attr)
2587*5e7646d2SAndroid Build Coastguard Worker {
2588*5e7646d2SAndroid Build Coastguard Worker ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
2589*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &attr, 0, "no-hold");
2590*5e7646d2SAndroid Build Coastguard Worker }
2591*5e7646d2SAndroid Build Coastguard Worker
2592*5e7646d2SAndroid Build Coastguard Worker default :
2593*5e7646d2SAndroid Build Coastguard Worker break;
2594*5e7646d2SAndroid Build Coastguard Worker
2595*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_ABORTED :
2596*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_CANCELED :
2597*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_COMPLETED :
2598*5e7646d2SAndroid Build Coastguard Worker set_time(job, "time-at-completed");
2599*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "processing-to-stop-point");
2600*5e7646d2SAndroid Build Coastguard Worker break;
2601*5e7646d2SAndroid Build Coastguard Worker }
2602*5e7646d2SAndroid Build Coastguard Worker
2603*5e7646d2SAndroid Build Coastguard Worker /*
2604*5e7646d2SAndroid Build Coastguard Worker * Log message as needed...
2605*5e7646d2SAndroid Build Coastguard Worker */
2606*5e7646d2SAndroid Build Coastguard Worker
2607*5e7646d2SAndroid Build Coastguard Worker if (message)
2608*5e7646d2SAndroid Build Coastguard Worker {
2609*5e7646d2SAndroid Build Coastguard Worker char buffer[2048]; /* Message buffer */
2610*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Pointer to additional arguments */
2611*5e7646d2SAndroid Build Coastguard Worker
2612*5e7646d2SAndroid Build Coastguard Worker va_start(ap, message);
2613*5e7646d2SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), message, ap);
2614*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
2615*5e7646d2SAndroid Build Coastguard Worker
2616*5e7646d2SAndroid Build Coastguard Worker if (newstate > IPP_JOB_STOPPED)
2617*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, "%s", buffer);
2618*5e7646d2SAndroid Build Coastguard Worker else
2619*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "%s", buffer);
2620*5e7646d2SAndroid Build Coastguard Worker
2621*5e7646d2SAndroid Build Coastguard Worker if (newstate == IPP_JOB_STOPPED || newstate == IPP_JOB_ABORTED)
2622*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR, "%s", buffer);
2623*5e7646d2SAndroid Build Coastguard Worker else
2624*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_INFO, "%s", buffer);
2625*5e7646d2SAndroid Build Coastguard Worker }
2626*5e7646d2SAndroid Build Coastguard Worker
2627*5e7646d2SAndroid Build Coastguard Worker /*
2628*5e7646d2SAndroid Build Coastguard Worker * Handle post-state-change actions...
2629*5e7646d2SAndroid Build Coastguard Worker */
2630*5e7646d2SAndroid Build Coastguard Worker
2631*5e7646d2SAndroid Build Coastguard Worker switch (newstate)
2632*5e7646d2SAndroid Build Coastguard Worker {
2633*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PROCESSING :
2634*5e7646d2SAndroid Build Coastguard Worker /*
2635*5e7646d2SAndroid Build Coastguard Worker * Add the job to the "printing" list...
2636*5e7646d2SAndroid Build Coastguard Worker */
2637*5e7646d2SAndroid Build Coastguard Worker
2638*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(PrintingJobs, job))
2639*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(PrintingJobs, job);
2640*5e7646d2SAndroid Build Coastguard Worker
2641*5e7646d2SAndroid Build Coastguard Worker /*
2642*5e7646d2SAndroid Build Coastguard Worker * Set the processing time...
2643*5e7646d2SAndroid Build Coastguard Worker */
2644*5e7646d2SAndroid Build Coastguard Worker
2645*5e7646d2SAndroid Build Coastguard Worker set_time(job, "time-at-processing");
2646*5e7646d2SAndroid Build Coastguard Worker
2647*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PENDING :
2648*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_HELD :
2649*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_STOPPED :
2650*5e7646d2SAndroid Build Coastguard Worker /*
2651*5e7646d2SAndroid Build Coastguard Worker * Make sure the job is in the active list...
2652*5e7646d2SAndroid Build Coastguard Worker */
2653*5e7646d2SAndroid Build Coastguard Worker
2654*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(ActiveJobs, job))
2655*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ActiveJobs, job);
2656*5e7646d2SAndroid Build Coastguard Worker
2657*5e7646d2SAndroid Build Coastguard Worker /*
2658*5e7646d2SAndroid Build Coastguard Worker * Save the job state to disk...
2659*5e7646d2SAndroid Build Coastguard Worker */
2660*5e7646d2SAndroid Build Coastguard Worker
2661*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
2662*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
2663*5e7646d2SAndroid Build Coastguard Worker break;
2664*5e7646d2SAndroid Build Coastguard Worker
2665*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_ABORTED :
2666*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_CANCELED :
2667*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_COMPLETED :
2668*5e7646d2SAndroid Build Coastguard Worker if (newstate == IPP_JOB_CANCELED)
2669*5e7646d2SAndroid Build Coastguard Worker {
2670*5e7646d2SAndroid Build Coastguard Worker /*
2671*5e7646d2SAndroid Build Coastguard Worker * Remove the job from the active list if there are no processes still
2672*5e7646d2SAndroid Build Coastguard Worker * running for it...
2673*5e7646d2SAndroid Build Coastguard Worker */
2674*5e7646d2SAndroid Build Coastguard Worker
2675*5e7646d2SAndroid Build Coastguard Worker for (i = 0; job->filters[i] < 0; i++);
2676*5e7646d2SAndroid Build Coastguard Worker
2677*5e7646d2SAndroid Build Coastguard Worker if (!job->filters[i] && job->backend <= 0)
2678*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ActiveJobs, job);
2679*5e7646d2SAndroid Build Coastguard Worker }
2680*5e7646d2SAndroid Build Coastguard Worker else
2681*5e7646d2SAndroid Build Coastguard Worker {
2682*5e7646d2SAndroid Build Coastguard Worker /*
2683*5e7646d2SAndroid Build Coastguard Worker * Otherwise just remove the job from the active list immediately...
2684*5e7646d2SAndroid Build Coastguard Worker */
2685*5e7646d2SAndroid Build Coastguard Worker
2686*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ActiveJobs, job);
2687*5e7646d2SAndroid Build Coastguard Worker }
2688*5e7646d2SAndroid Build Coastguard Worker
2689*5e7646d2SAndroid Build Coastguard Worker /*
2690*5e7646d2SAndroid Build Coastguard Worker * Expire job subscriptions since the job is now "completed"...
2691*5e7646d2SAndroid Build Coastguard Worker */
2692*5e7646d2SAndroid Build Coastguard Worker
2693*5e7646d2SAndroid Build Coastguard Worker cupsdExpireSubscriptions(NULL, job);
2694*5e7646d2SAndroid Build Coastguard Worker
2695*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
2696*5e7646d2SAndroid Build Coastguard Worker /*
2697*5e7646d2SAndroid Build Coastguard Worker * If we are going to sleep and the PrintingJobs count is now 0, allow the
2698*5e7646d2SAndroid Build Coastguard Worker * sleep to happen immediately...
2699*5e7646d2SAndroid Build Coastguard Worker */
2700*5e7646d2SAndroid Build Coastguard Worker
2701*5e7646d2SAndroid Build Coastguard Worker if (Sleeping && cupsArrayCount(PrintingJobs) == 0)
2702*5e7646d2SAndroid Build Coastguard Worker cupsdAllowSleep();
2703*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
2704*5e7646d2SAndroid Build Coastguard Worker
2705*5e7646d2SAndroid Build Coastguard Worker /*
2706*5e7646d2SAndroid Build Coastguard Worker * Remove any authentication data...
2707*5e7646d2SAndroid Build Coastguard Worker */
2708*5e7646d2SAndroid Build Coastguard Worker
2709*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/a%05d", RequestRoot, job->id);
2710*5e7646d2SAndroid Build Coastguard Worker if (cupsdRemoveFile(filename) && errno != ENOENT)
2711*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
2712*5e7646d2SAndroid Build Coastguard Worker "Unable to remove authentication cache: %s",
2713*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
2714*5e7646d2SAndroid Build Coastguard Worker
2715*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
2716*5e7646d2SAndroid Build Coastguard Worker i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
2717*5e7646d2SAndroid Build Coastguard Worker i ++)
2718*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(job->auth_env + i);
2719*5e7646d2SAndroid Build Coastguard Worker
2720*5e7646d2SAndroid Build Coastguard Worker cupsdClearString(&job->auth_uid);
2721*5e7646d2SAndroid Build Coastguard Worker
2722*5e7646d2SAndroid Build Coastguard Worker /*
2723*5e7646d2SAndroid Build Coastguard Worker * Remove the print file for good if we aren't preserving jobs or
2724*5e7646d2SAndroid Build Coastguard Worker * files...
2725*5e7646d2SAndroid Build Coastguard Worker */
2726*5e7646d2SAndroid Build Coastguard Worker
2727*5e7646d2SAndroid Build Coastguard Worker if (!JobHistory || !JobFiles || action == CUPSD_JOB_PURGE)
2728*5e7646d2SAndroid Build Coastguard Worker remove_job_files(job);
2729*5e7646d2SAndroid Build Coastguard Worker
2730*5e7646d2SAndroid Build Coastguard Worker if (JobHistory && action != CUPSD_JOB_PURGE)
2731*5e7646d2SAndroid Build Coastguard Worker {
2732*5e7646d2SAndroid Build Coastguard Worker /*
2733*5e7646d2SAndroid Build Coastguard Worker * Save job state info...
2734*5e7646d2SAndroid Build Coastguard Worker */
2735*5e7646d2SAndroid Build Coastguard Worker
2736*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
2737*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
2738*5e7646d2SAndroid Build Coastguard Worker }
2739*5e7646d2SAndroid Build Coastguard Worker else if (!job->printer)
2740*5e7646d2SAndroid Build Coastguard Worker {
2741*5e7646d2SAndroid Build Coastguard Worker /*
2742*5e7646d2SAndroid Build Coastguard Worker * Delete the job immediately if not actively printing...
2743*5e7646d2SAndroid Build Coastguard Worker */
2744*5e7646d2SAndroid Build Coastguard Worker
2745*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteJob(job, CUPSD_JOB_PURGE);
2746*5e7646d2SAndroid Build Coastguard Worker job = NULL;
2747*5e7646d2SAndroid Build Coastguard Worker }
2748*5e7646d2SAndroid Build Coastguard Worker break;
2749*5e7646d2SAndroid Build Coastguard Worker }
2750*5e7646d2SAndroid Build Coastguard Worker
2751*5e7646d2SAndroid Build Coastguard Worker /*
2752*5e7646d2SAndroid Build Coastguard Worker * Finalize the job immediately if we forced things...
2753*5e7646d2SAndroid Build Coastguard Worker */
2754*5e7646d2SAndroid Build Coastguard Worker
2755*5e7646d2SAndroid Build Coastguard Worker if (action >= CUPSD_JOB_FORCE && job && job->printer)
2756*5e7646d2SAndroid Build Coastguard Worker finalize_job(job, 0);
2757*5e7646d2SAndroid Build Coastguard Worker
2758*5e7646d2SAndroid Build Coastguard Worker /*
2759*5e7646d2SAndroid Build Coastguard Worker * Update the server "busy" state...
2760*5e7646d2SAndroid Build Coastguard Worker */
2761*5e7646d2SAndroid Build Coastguard Worker
2762*5e7646d2SAndroid Build Coastguard Worker cupsdSetBusyState(0);
2763*5e7646d2SAndroid Build Coastguard Worker }
2764*5e7646d2SAndroid Build Coastguard Worker
2765*5e7646d2SAndroid Build Coastguard Worker
2766*5e7646d2SAndroid Build Coastguard Worker /*
2767*5e7646d2SAndroid Build Coastguard Worker * 'cupsdStopAllJobs()' - Stop all print jobs.
2768*5e7646d2SAndroid Build Coastguard Worker */
2769*5e7646d2SAndroid Build Coastguard Worker
2770*5e7646d2SAndroid Build Coastguard Worker void
cupsdStopAllJobs(cupsd_jobaction_t action,int kill_delay)2771*5e7646d2SAndroid Build Coastguard Worker cupsdStopAllJobs(
2772*5e7646d2SAndroid Build Coastguard Worker cupsd_jobaction_t action, /* I - Action */
2773*5e7646d2SAndroid Build Coastguard Worker int kill_delay) /* I - Number of seconds before we kill */
2774*5e7646d2SAndroid Build Coastguard Worker {
2775*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
2776*5e7646d2SAndroid Build Coastguard Worker
2777*5e7646d2SAndroid Build Coastguard Worker
2778*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(PrintingJobs);
2779*5e7646d2SAndroid Build Coastguard Worker job;
2780*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(PrintingJobs))
2781*5e7646d2SAndroid Build Coastguard Worker {
2782*5e7646d2SAndroid Build Coastguard Worker if (job->completed)
2783*5e7646d2SAndroid Build Coastguard Worker {
2784*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_COMPLETED, CUPSD_JOB_FORCE, NULL);
2785*5e7646d2SAndroid Build Coastguard Worker }
2786*5e7646d2SAndroid Build Coastguard Worker else
2787*5e7646d2SAndroid Build Coastguard Worker {
2788*5e7646d2SAndroid Build Coastguard Worker if (kill_delay)
2789*5e7646d2SAndroid Build Coastguard Worker job->kill_time = time(NULL) + kill_delay;
2790*5e7646d2SAndroid Build Coastguard Worker
2791*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PENDING, action, NULL);
2792*5e7646d2SAndroid Build Coastguard Worker }
2793*5e7646d2SAndroid Build Coastguard Worker }
2794*5e7646d2SAndroid Build Coastguard Worker }
2795*5e7646d2SAndroid Build Coastguard Worker
2796*5e7646d2SAndroid Build Coastguard Worker
2797*5e7646d2SAndroid Build Coastguard Worker /*
2798*5e7646d2SAndroid Build Coastguard Worker * 'cupsdUnloadCompletedJobs()' - Flush completed job history from memory.
2799*5e7646d2SAndroid Build Coastguard Worker */
2800*5e7646d2SAndroid Build Coastguard Worker
2801*5e7646d2SAndroid Build Coastguard Worker void
cupsdUnloadCompletedJobs(void)2802*5e7646d2SAndroid Build Coastguard Worker cupsdUnloadCompletedJobs(void)
2803*5e7646d2SAndroid Build Coastguard Worker {
2804*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
2805*5e7646d2SAndroid Build Coastguard Worker time_t expire; /* Expiration time */
2806*5e7646d2SAndroid Build Coastguard Worker
2807*5e7646d2SAndroid Build Coastguard Worker
2808*5e7646d2SAndroid Build Coastguard Worker expire = time(NULL) - 60;
2809*5e7646d2SAndroid Build Coastguard Worker
2810*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
2811*5e7646d2SAndroid Build Coastguard Worker job;
2812*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
2813*5e7646d2SAndroid Build Coastguard Worker if (job->attrs && job->state_value >= IPP_JOB_STOPPED && !job->printer &&
2814*5e7646d2SAndroid Build Coastguard Worker job->access_time < expire)
2815*5e7646d2SAndroid Build Coastguard Worker {
2816*5e7646d2SAndroid Build Coastguard Worker if (job->dirty)
2817*5e7646d2SAndroid Build Coastguard Worker cupsdSaveJob(job);
2818*5e7646d2SAndroid Build Coastguard Worker
2819*5e7646d2SAndroid Build Coastguard Worker if (!job->dirty)
2820*5e7646d2SAndroid Build Coastguard Worker unload_job(job);
2821*5e7646d2SAndroid Build Coastguard Worker }
2822*5e7646d2SAndroid Build Coastguard Worker }
2823*5e7646d2SAndroid Build Coastguard Worker
2824*5e7646d2SAndroid Build Coastguard Worker
2825*5e7646d2SAndroid Build Coastguard Worker /*
2826*5e7646d2SAndroid Build Coastguard Worker * 'cupsdUpdateJobs()' - Update the history/file files for all jobs.
2827*5e7646d2SAndroid Build Coastguard Worker */
2828*5e7646d2SAndroid Build Coastguard Worker
2829*5e7646d2SAndroid Build Coastguard Worker void
cupsdUpdateJobs(void)2830*5e7646d2SAndroid Build Coastguard Worker cupsdUpdateJobs(void)
2831*5e7646d2SAndroid Build Coastguard Worker {
2832*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
2833*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time */
2834*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* time-at-completed attribute */
2835*5e7646d2SAndroid Build Coastguard Worker
2836*5e7646d2SAndroid Build Coastguard Worker
2837*5e7646d2SAndroid Build Coastguard Worker curtime = time(NULL);
2838*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = 0;
2839*5e7646d2SAndroid Build Coastguard Worker
2840*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
2841*5e7646d2SAndroid Build Coastguard Worker job;
2842*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
2843*5e7646d2SAndroid Build Coastguard Worker {
2844*5e7646d2SAndroid Build Coastguard Worker if (job->state_value >= IPP_JOB_CANCELED &&
2845*5e7646d2SAndroid Build Coastguard Worker (attr = ippFindAttribute(job->attrs, "time-at-completed",
2846*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_INTEGER)) != NULL)
2847*5e7646d2SAndroid Build Coastguard Worker {
2848*5e7646d2SAndroid Build Coastguard Worker /*
2849*5e7646d2SAndroid Build Coastguard Worker * Update history/file expiration times...
2850*5e7646d2SAndroid Build Coastguard Worker */
2851*5e7646d2SAndroid Build Coastguard Worker
2852*5e7646d2SAndroid Build Coastguard Worker job->completed_time = attr->values[0].integer;
2853*5e7646d2SAndroid Build Coastguard Worker
2854*5e7646d2SAndroid Build Coastguard Worker if (JobHistory < INT_MAX)
2855*5e7646d2SAndroid Build Coastguard Worker job->history_time = job->completed_time + JobHistory;
2856*5e7646d2SAndroid Build Coastguard Worker else
2857*5e7646d2SAndroid Build Coastguard Worker job->history_time = INT_MAX;
2858*5e7646d2SAndroid Build Coastguard Worker
2859*5e7646d2SAndroid Build Coastguard Worker if (job->history_time < curtime)
2860*5e7646d2SAndroid Build Coastguard Worker {
2861*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteJob(job, CUPSD_JOB_PURGE);
2862*5e7646d2SAndroid Build Coastguard Worker continue;
2863*5e7646d2SAndroid Build Coastguard Worker }
2864*5e7646d2SAndroid Build Coastguard Worker
2865*5e7646d2SAndroid Build Coastguard Worker if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
2866*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->history_time;
2867*5e7646d2SAndroid Build Coastguard Worker
2868*5e7646d2SAndroid Build Coastguard Worker if (JobFiles < INT_MAX)
2869*5e7646d2SAndroid Build Coastguard Worker job->file_time = job->completed_time + JobFiles;
2870*5e7646d2SAndroid Build Coastguard Worker else
2871*5e7646d2SAndroid Build Coastguard Worker job->file_time = INT_MAX;
2872*5e7646d2SAndroid Build Coastguard Worker
2873*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "cupsdUpdateJobs: job->file_time=%ld, time-at-completed=%ld, JobFiles=%d", (long)job->file_time, (long)attr->values[0].integer, JobFiles);
2874*5e7646d2SAndroid Build Coastguard Worker
2875*5e7646d2SAndroid Build Coastguard Worker if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
2876*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->file_time;
2877*5e7646d2SAndroid Build Coastguard Worker }
2878*5e7646d2SAndroid Build Coastguard Worker }
2879*5e7646d2SAndroid Build Coastguard Worker
2880*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdUpdateJobs: JobHistoryUpdate=%ld",
2881*5e7646d2SAndroid Build Coastguard Worker (long)JobHistoryUpdate);
2882*5e7646d2SAndroid Build Coastguard Worker }
2883*5e7646d2SAndroid Build Coastguard Worker
2884*5e7646d2SAndroid Build Coastguard Worker
2885*5e7646d2SAndroid Build Coastguard Worker /*
2886*5e7646d2SAndroid Build Coastguard Worker * 'compare_active_jobs()' - Compare the job IDs and priorities of two jobs.
2887*5e7646d2SAndroid Build Coastguard Worker */
2888*5e7646d2SAndroid Build Coastguard Worker
2889*5e7646d2SAndroid Build Coastguard Worker static int /* O - Difference */
compare_active_jobs(void * first,void * second,void * data)2890*5e7646d2SAndroid Build Coastguard Worker compare_active_jobs(void *first, /* I - First job */
2891*5e7646d2SAndroid Build Coastguard Worker void *second, /* I - Second job */
2892*5e7646d2SAndroid Build Coastguard Worker void *data) /* I - App data (not used) */
2893*5e7646d2SAndroid Build Coastguard Worker {
2894*5e7646d2SAndroid Build Coastguard Worker int diff; /* Difference */
2895*5e7646d2SAndroid Build Coastguard Worker
2896*5e7646d2SAndroid Build Coastguard Worker
2897*5e7646d2SAndroid Build Coastguard Worker (void)data;
2898*5e7646d2SAndroid Build Coastguard Worker
2899*5e7646d2SAndroid Build Coastguard Worker if ((diff = ((cupsd_job_t *)second)->priority -
2900*5e7646d2SAndroid Build Coastguard Worker ((cupsd_job_t *)first)->priority) != 0)
2901*5e7646d2SAndroid Build Coastguard Worker return (diff);
2902*5e7646d2SAndroid Build Coastguard Worker else
2903*5e7646d2SAndroid Build Coastguard Worker return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id);
2904*5e7646d2SAndroid Build Coastguard Worker }
2905*5e7646d2SAndroid Build Coastguard Worker
2906*5e7646d2SAndroid Build Coastguard Worker
2907*5e7646d2SAndroid Build Coastguard Worker /*
2908*5e7646d2SAndroid Build Coastguard Worker * 'compare_completed_jobs()' - Compare the job IDs and completion times of two jobs.
2909*5e7646d2SAndroid Build Coastguard Worker */
2910*5e7646d2SAndroid Build Coastguard Worker
2911*5e7646d2SAndroid Build Coastguard Worker static int /* O - Difference */
compare_completed_jobs(void * first,void * second,void * data)2912*5e7646d2SAndroid Build Coastguard Worker compare_completed_jobs(void *first, /* I - First job */
2913*5e7646d2SAndroid Build Coastguard Worker void *second, /* I - Second job */
2914*5e7646d2SAndroid Build Coastguard Worker void *data) /* I - App data (not used) */
2915*5e7646d2SAndroid Build Coastguard Worker {
2916*5e7646d2SAndroid Build Coastguard Worker int diff; /* Difference */
2917*5e7646d2SAndroid Build Coastguard Worker
2918*5e7646d2SAndroid Build Coastguard Worker
2919*5e7646d2SAndroid Build Coastguard Worker (void)data;
2920*5e7646d2SAndroid Build Coastguard Worker
2921*5e7646d2SAndroid Build Coastguard Worker if ((diff = ((cupsd_job_t *)second)->completed_time -
2922*5e7646d2SAndroid Build Coastguard Worker ((cupsd_job_t *)first)->completed_time) != 0)
2923*5e7646d2SAndroid Build Coastguard Worker return (diff);
2924*5e7646d2SAndroid Build Coastguard Worker else
2925*5e7646d2SAndroid Build Coastguard Worker return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id);
2926*5e7646d2SAndroid Build Coastguard Worker }
2927*5e7646d2SAndroid Build Coastguard Worker
2928*5e7646d2SAndroid Build Coastguard Worker
2929*5e7646d2SAndroid Build Coastguard Worker /*
2930*5e7646d2SAndroid Build Coastguard Worker * 'compare_jobs()' - Compare the job IDs of two jobs.
2931*5e7646d2SAndroid Build Coastguard Worker */
2932*5e7646d2SAndroid Build Coastguard Worker
2933*5e7646d2SAndroid Build Coastguard Worker static int /* O - Difference */
compare_jobs(void * first,void * second,void * data)2934*5e7646d2SAndroid Build Coastguard Worker compare_jobs(void *first, /* I - First job */
2935*5e7646d2SAndroid Build Coastguard Worker void *second, /* I - Second job */
2936*5e7646d2SAndroid Build Coastguard Worker void *data) /* I - App data (not used) */
2937*5e7646d2SAndroid Build Coastguard Worker {
2938*5e7646d2SAndroid Build Coastguard Worker (void)data;
2939*5e7646d2SAndroid Build Coastguard Worker
2940*5e7646d2SAndroid Build Coastguard Worker return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id);
2941*5e7646d2SAndroid Build Coastguard Worker }
2942*5e7646d2SAndroid Build Coastguard Worker
2943*5e7646d2SAndroid Build Coastguard Worker
2944*5e7646d2SAndroid Build Coastguard Worker /*
2945*5e7646d2SAndroid Build Coastguard Worker * 'dump_job_history()' - Dump any debug messages for a job.
2946*5e7646d2SAndroid Build Coastguard Worker */
2947*5e7646d2SAndroid Build Coastguard Worker
2948*5e7646d2SAndroid Build Coastguard Worker static void
dump_job_history(cupsd_job_t * job)2949*5e7646d2SAndroid Build Coastguard Worker dump_job_history(cupsd_job_t *job) /* I - Job */
2950*5e7646d2SAndroid Build Coastguard Worker {
2951*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
2952*5e7646d2SAndroid Build Coastguard Worker oldsize; /* Current MaxLogSize */
2953*5e7646d2SAndroid Build Coastguard Worker struct tm date; /* Date/time value */
2954*5e7646d2SAndroid Build Coastguard Worker cupsd_joblog_t *message; /* Current message */
2955*5e7646d2SAndroid Build Coastguard Worker char temp[2048], /* Log message */
2956*5e7646d2SAndroid Build Coastguard Worker *ptr, /* Pointer into log message */
2957*5e7646d2SAndroid Build Coastguard Worker start[256], /* Start time */
2958*5e7646d2SAndroid Build Coastguard Worker end[256]; /* End time */
2959*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *printer; /* Printer for job */
2960*5e7646d2SAndroid Build Coastguard Worker
2961*5e7646d2SAndroid Build Coastguard Worker
2962*5e7646d2SAndroid Build Coastguard Worker /*
2963*5e7646d2SAndroid Build Coastguard Worker * See if we have anything to dump...
2964*5e7646d2SAndroid Build Coastguard Worker */
2965*5e7646d2SAndroid Build Coastguard Worker
2966*5e7646d2SAndroid Build Coastguard Worker if (!job->history)
2967*5e7646d2SAndroid Build Coastguard Worker return;
2968*5e7646d2SAndroid Build Coastguard Worker
2969*5e7646d2SAndroid Build Coastguard Worker /*
2970*5e7646d2SAndroid Build Coastguard Worker * Disable log rotation temporarily...
2971*5e7646d2SAndroid Build Coastguard Worker */
2972*5e7646d2SAndroid Build Coastguard Worker
2973*5e7646d2SAndroid Build Coastguard Worker oldsize = MaxLogSize;
2974*5e7646d2SAndroid Build Coastguard Worker MaxLogSize = 0;
2975*5e7646d2SAndroid Build Coastguard Worker
2976*5e7646d2SAndroid Build Coastguard Worker /*
2977*5e7646d2SAndroid Build Coastguard Worker * Copy the debug messages to the log...
2978*5e7646d2SAndroid Build Coastguard Worker */
2979*5e7646d2SAndroid Build Coastguard Worker
2980*5e7646d2SAndroid Build Coastguard Worker message = (cupsd_joblog_t *)cupsArrayFirst(job->history);
2981*5e7646d2SAndroid Build Coastguard Worker localtime_r(&(message->time), &date);
2982*5e7646d2SAndroid Build Coastguard Worker strftime(start, sizeof(start), "%X", &date);
2983*5e7646d2SAndroid Build Coastguard Worker
2984*5e7646d2SAndroid Build Coastguard Worker message = (cupsd_joblog_t *)cupsArrayLast(job->history);
2985*5e7646d2SAndroid Build Coastguard Worker localtime_r(&(message->time), &date);
2986*5e7646d2SAndroid Build Coastguard Worker strftime(end, sizeof(end), "%X", &date);
2987*5e7646d2SAndroid Build Coastguard Worker
2988*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp),
2989*5e7646d2SAndroid Build Coastguard Worker "[Job %d] The following messages were recorded from %s to %s",
2990*5e7646d2SAndroid Build Coastguard Worker job->id, start, end);
2991*5e7646d2SAndroid Build Coastguard Worker cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp);
2992*5e7646d2SAndroid Build Coastguard Worker
2993*5e7646d2SAndroid Build Coastguard Worker for (message = (cupsd_joblog_t *)cupsArrayFirst(job->history);
2994*5e7646d2SAndroid Build Coastguard Worker message;
2995*5e7646d2SAndroid Build Coastguard Worker message = (cupsd_joblog_t *)cupsArrayNext(job->history))
2996*5e7646d2SAndroid Build Coastguard Worker cupsdWriteErrorLog(CUPSD_LOG_DEBUG, message->message);
2997*5e7646d2SAndroid Build Coastguard Worker
2998*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "[Job %d] End of messages", job->id);
2999*5e7646d2SAndroid Build Coastguard Worker cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp);
3000*5e7646d2SAndroid Build Coastguard Worker
3001*5e7646d2SAndroid Build Coastguard Worker /*
3002*5e7646d2SAndroid Build Coastguard Worker * Log the printer state values...
3003*5e7646d2SAndroid Build Coastguard Worker */
3004*5e7646d2SAndroid Build Coastguard Worker
3005*5e7646d2SAndroid Build Coastguard Worker if ((printer = job->printer) == NULL)
3006*5e7646d2SAndroid Build Coastguard Worker printer = cupsdFindDest(job->dest);
3007*5e7646d2SAndroid Build Coastguard Worker
3008*5e7646d2SAndroid Build Coastguard Worker if (printer)
3009*5e7646d2SAndroid Build Coastguard Worker {
3010*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "[Job %d] printer-state=%d(%s)", job->id,
3011*5e7646d2SAndroid Build Coastguard Worker printer->state,
3012*5e7646d2SAndroid Build Coastguard Worker printer->state == IPP_PRINTER_IDLE ? "idle" :
3013*5e7646d2SAndroid Build Coastguard Worker printer->state == IPP_PRINTER_PROCESSING ? "processing" :
3014*5e7646d2SAndroid Build Coastguard Worker "stopped");
3015*5e7646d2SAndroid Build Coastguard Worker cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp);
3016*5e7646d2SAndroid Build Coastguard Worker
3017*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "[Job %d] printer-state-message=\"%s\"",
3018*5e7646d2SAndroid Build Coastguard Worker job->id, printer->state_message);
3019*5e7646d2SAndroid Build Coastguard Worker cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp);
3020*5e7646d2SAndroid Build Coastguard Worker
3021*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "[Job %d] printer-state-reasons=", job->id);
3022*5e7646d2SAndroid Build Coastguard Worker ptr = temp + strlen(temp);
3023*5e7646d2SAndroid Build Coastguard Worker if (printer->num_reasons == 0)
3024*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, "none", sizeof(temp) - (size_t)(ptr - temp));
3025*5e7646d2SAndroid Build Coastguard Worker else
3026*5e7646d2SAndroid Build Coastguard Worker {
3027*5e7646d2SAndroid Build Coastguard Worker for (i = 0;
3028*5e7646d2SAndroid Build Coastguard Worker i < printer->num_reasons && ptr < (temp + sizeof(temp) - 2);
3029*5e7646d2SAndroid Build Coastguard Worker i ++)
3030*5e7646d2SAndroid Build Coastguard Worker {
3031*5e7646d2SAndroid Build Coastguard Worker if (i)
3032*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ',';
3033*5e7646d2SAndroid Build Coastguard Worker
3034*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, printer->reasons[i], sizeof(temp) - (size_t)(ptr - temp));
3035*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
3036*5e7646d2SAndroid Build Coastguard Worker }
3037*5e7646d2SAndroid Build Coastguard Worker }
3038*5e7646d2SAndroid Build Coastguard Worker cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp);
3039*5e7646d2SAndroid Build Coastguard Worker }
3040*5e7646d2SAndroid Build Coastguard Worker
3041*5e7646d2SAndroid Build Coastguard Worker /*
3042*5e7646d2SAndroid Build Coastguard Worker * Restore log file rotation...
3043*5e7646d2SAndroid Build Coastguard Worker */
3044*5e7646d2SAndroid Build Coastguard Worker
3045*5e7646d2SAndroid Build Coastguard Worker MaxLogSize = oldsize;
3046*5e7646d2SAndroid Build Coastguard Worker
3047*5e7646d2SAndroid Build Coastguard Worker /*
3048*5e7646d2SAndroid Build Coastguard Worker * Free all messages...
3049*5e7646d2SAndroid Build Coastguard Worker */
3050*5e7646d2SAndroid Build Coastguard Worker
3051*5e7646d2SAndroid Build Coastguard Worker free_job_history(job);
3052*5e7646d2SAndroid Build Coastguard Worker }
3053*5e7646d2SAndroid Build Coastguard Worker
3054*5e7646d2SAndroid Build Coastguard Worker
3055*5e7646d2SAndroid Build Coastguard Worker /*
3056*5e7646d2SAndroid Build Coastguard Worker * 'free_job_history()' - Free any log history.
3057*5e7646d2SAndroid Build Coastguard Worker */
3058*5e7646d2SAndroid Build Coastguard Worker
3059*5e7646d2SAndroid Build Coastguard Worker static void
free_job_history(cupsd_job_t * job)3060*5e7646d2SAndroid Build Coastguard Worker free_job_history(cupsd_job_t *job) /* I - Job */
3061*5e7646d2SAndroid Build Coastguard Worker {
3062*5e7646d2SAndroid Build Coastguard Worker char *message; /* Current message */
3063*5e7646d2SAndroid Build Coastguard Worker
3064*5e7646d2SAndroid Build Coastguard Worker
3065*5e7646d2SAndroid Build Coastguard Worker if (!job->history)
3066*5e7646d2SAndroid Build Coastguard Worker return;
3067*5e7646d2SAndroid Build Coastguard Worker
3068*5e7646d2SAndroid Build Coastguard Worker for (message = (char *)cupsArrayFirst(job->history);
3069*5e7646d2SAndroid Build Coastguard Worker message;
3070*5e7646d2SAndroid Build Coastguard Worker message = (char *)cupsArrayNext(job->history))
3071*5e7646d2SAndroid Build Coastguard Worker free(message);
3072*5e7646d2SAndroid Build Coastguard Worker
3073*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(job->history);
3074*5e7646d2SAndroid Build Coastguard Worker job->history = NULL;
3075*5e7646d2SAndroid Build Coastguard Worker }
3076*5e7646d2SAndroid Build Coastguard Worker
3077*5e7646d2SAndroid Build Coastguard Worker
3078*5e7646d2SAndroid Build Coastguard Worker /*
3079*5e7646d2SAndroid Build Coastguard Worker * 'finalize_job()' - Cleanup after job filter processes and support data.
3080*5e7646d2SAndroid Build Coastguard Worker */
3081*5e7646d2SAndroid Build Coastguard Worker
3082*5e7646d2SAndroid Build Coastguard Worker static void
finalize_job(cupsd_job_t * job,int set_job_state)3083*5e7646d2SAndroid Build Coastguard Worker finalize_job(cupsd_job_t *job, /* I - Job */
3084*5e7646d2SAndroid Build Coastguard Worker int set_job_state) /* I - 1 = set the job state */
3085*5e7646d2SAndroid Build Coastguard Worker {
3086*5e7646d2SAndroid Build Coastguard Worker ipp_pstate_t printer_state; /* New printer state value */
3087*5e7646d2SAndroid Build Coastguard Worker ipp_jstate_t job_state; /* New job state value */
3088*5e7646d2SAndroid Build Coastguard Worker const char *message; /* Message for job state */
3089*5e7646d2SAndroid Build Coastguard Worker char buffer[1024]; /* Buffer for formatted messages */
3090*5e7646d2SAndroid Build Coastguard Worker
3091*5e7646d2SAndroid Build Coastguard Worker
3092*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "finalize_job(job=%p(%d))", job, job->id);
3093*5e7646d2SAndroid Build Coastguard Worker
3094*5e7646d2SAndroid Build Coastguard Worker /*
3095*5e7646d2SAndroid Build Coastguard Worker * Clear the "connecting-to-device" and "cups-waiting-for-job-completed"
3096*5e7646d2SAndroid Build Coastguard Worker * reasons, which are only valid when a printer is processing, along with any
3097*5e7646d2SAndroid Build Coastguard Worker * remote printing job state...
3098*5e7646d2SAndroid Build Coastguard Worker */
3099*5e7646d2SAndroid Build Coastguard Worker
3100*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterReasons(job->printer, "-connecting-to-device,"
3101*5e7646d2SAndroid Build Coastguard Worker "cups-waiting-for-job-completed,"
3102*5e7646d2SAndroid Build Coastguard Worker "cups-remote-pending,"
3103*5e7646d2SAndroid Build Coastguard Worker "cups-remote-pending-held,"
3104*5e7646d2SAndroid Build Coastguard Worker "cups-remote-processing,"
3105*5e7646d2SAndroid Build Coastguard Worker "cups-remote-stopped,"
3106*5e7646d2SAndroid Build Coastguard Worker "cups-remote-canceled,"
3107*5e7646d2SAndroid Build Coastguard Worker "cups-remote-aborted,"
3108*5e7646d2SAndroid Build Coastguard Worker "cups-remote-completed");
3109*5e7646d2SAndroid Build Coastguard Worker
3110*5e7646d2SAndroid Build Coastguard Worker /*
3111*5e7646d2SAndroid Build Coastguard Worker * Similarly, clear the "offline-report" reason for non-USB devices since we
3112*5e7646d2SAndroid Build Coastguard Worker * rarely have current information for network devices...
3113*5e7646d2SAndroid Build Coastguard Worker */
3114*5e7646d2SAndroid Build Coastguard Worker
3115*5e7646d2SAndroid Build Coastguard Worker if (!strstr(job->printer->device_uri, "usb:"))
3116*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterReasons(job->printer, "-offline-report");
3117*5e7646d2SAndroid Build Coastguard Worker
3118*5e7646d2SAndroid Build Coastguard Worker /*
3119*5e7646d2SAndroid Build Coastguard Worker * Free the security profile...
3120*5e7646d2SAndroid Build Coastguard Worker */
3121*5e7646d2SAndroid Build Coastguard Worker
3122*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->profile);
3123*5e7646d2SAndroid Build Coastguard Worker job->profile = NULL;
3124*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->bprofile);
3125*5e7646d2SAndroid Build Coastguard Worker job->bprofile = NULL;
3126*5e7646d2SAndroid Build Coastguard Worker
3127*5e7646d2SAndroid Build Coastguard Worker /*
3128*5e7646d2SAndroid Build Coastguard Worker * Clear the unresponsive job watchdog timers...
3129*5e7646d2SAndroid Build Coastguard Worker */
3130*5e7646d2SAndroid Build Coastguard Worker
3131*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = 0;
3132*5e7646d2SAndroid Build Coastguard Worker job->kill_time = 0;
3133*5e7646d2SAndroid Build Coastguard Worker
3134*5e7646d2SAndroid Build Coastguard Worker /*
3135*5e7646d2SAndroid Build Coastguard Worker * Close pipes and status buffer...
3136*5e7646d2SAndroid Build Coastguard Worker */
3137*5e7646d2SAndroid Build Coastguard Worker
3138*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->print_pipes);
3139*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->back_pipes);
3140*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->side_pipes);
3141*5e7646d2SAndroid Build Coastguard Worker
3142*5e7646d2SAndroid Build Coastguard Worker cupsdRemoveSelect(job->status_pipes[0]);
3143*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->status_pipes);
3144*5e7646d2SAndroid Build Coastguard Worker cupsdStatBufDelete(job->status_buffer);
3145*5e7646d2SAndroid Build Coastguard Worker job->status_buffer = NULL;
3146*5e7646d2SAndroid Build Coastguard Worker
3147*5e7646d2SAndroid Build Coastguard Worker /*
3148*5e7646d2SAndroid Build Coastguard Worker * Log the final impression (page) count...
3149*5e7646d2SAndroid Build Coastguard Worker */
3150*5e7646d2SAndroid Build Coastguard Worker
3151*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "total %d", ippGetInteger(job->impressions, 0));
3152*5e7646d2SAndroid Build Coastguard Worker cupsdLogPage(job, buffer);
3153*5e7646d2SAndroid Build Coastguard Worker
3154*5e7646d2SAndroid Build Coastguard Worker /*
3155*5e7646d2SAndroid Build Coastguard Worker * Process the exit status...
3156*5e7646d2SAndroid Build Coastguard Worker */
3157*5e7646d2SAndroid Build Coastguard Worker
3158*5e7646d2SAndroid Build Coastguard Worker if (job->printer->state == IPP_PRINTER_PROCESSING)
3159*5e7646d2SAndroid Build Coastguard Worker printer_state = IPP_PRINTER_IDLE;
3160*5e7646d2SAndroid Build Coastguard Worker else
3161*5e7646d2SAndroid Build Coastguard Worker printer_state = job->printer->state;
3162*5e7646d2SAndroid Build Coastguard Worker
3163*5e7646d2SAndroid Build Coastguard Worker switch (job_state = job->state_value)
3164*5e7646d2SAndroid Build Coastguard Worker {
3165*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PENDING :
3166*5e7646d2SAndroid Build Coastguard Worker message = "Job paused.";
3167*5e7646d2SAndroid Build Coastguard Worker break;
3168*5e7646d2SAndroid Build Coastguard Worker
3169*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_HELD :
3170*5e7646d2SAndroid Build Coastguard Worker message = "Job held.";
3171*5e7646d2SAndroid Build Coastguard Worker break;
3172*5e7646d2SAndroid Build Coastguard Worker
3173*5e7646d2SAndroid Build Coastguard Worker default :
3174*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_PROCESSING :
3175*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_COMPLETED :
3176*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_COMPLETED;
3177*5e7646d2SAndroid Build Coastguard Worker message = "Job completed.";
3178*5e7646d2SAndroid Build Coastguard Worker
3179*5e7646d2SAndroid Build Coastguard Worker if (!job->status)
3180*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0,
3181*5e7646d2SAndroid Build Coastguard Worker "job-completed-successfully");
3182*5e7646d2SAndroid Build Coastguard Worker break;
3183*5e7646d2SAndroid Build Coastguard Worker
3184*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_STOPPED :
3185*5e7646d2SAndroid Build Coastguard Worker message = "Job stopped.";
3186*5e7646d2SAndroid Build Coastguard Worker
3187*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "job-stopped");
3188*5e7646d2SAndroid Build Coastguard Worker break;
3189*5e7646d2SAndroid Build Coastguard Worker
3190*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_CANCELED :
3191*5e7646d2SAndroid Build Coastguard Worker message = "Job canceled.";
3192*5e7646d2SAndroid Build Coastguard Worker
3193*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "job-canceled-by-user");
3194*5e7646d2SAndroid Build Coastguard Worker break;
3195*5e7646d2SAndroid Build Coastguard Worker
3196*5e7646d2SAndroid Build Coastguard Worker case IPP_JOB_ABORTED :
3197*5e7646d2SAndroid Build Coastguard Worker message = "Job aborted.";
3198*5e7646d2SAndroid Build Coastguard Worker break;
3199*5e7646d2SAndroid Build Coastguard Worker }
3200*5e7646d2SAndroid Build Coastguard Worker
3201*5e7646d2SAndroid Build Coastguard Worker if (job->status < 0)
3202*5e7646d2SAndroid Build Coastguard Worker {
3203*5e7646d2SAndroid Build Coastguard Worker /*
3204*5e7646d2SAndroid Build Coastguard Worker * Backend had errors...
3205*5e7646d2SAndroid Build Coastguard Worker */
3206*5e7646d2SAndroid Build Coastguard Worker
3207*5e7646d2SAndroid Build Coastguard Worker int exit_code; /* Exit code from backend */
3208*5e7646d2SAndroid Build Coastguard Worker
3209*5e7646d2SAndroid Build Coastguard Worker /*
3210*5e7646d2SAndroid Build Coastguard Worker * Convert the status to an exit code. Due to the way the W* macros are
3211*5e7646d2SAndroid Build Coastguard Worker * implemented on macOS (bug?), we have to store the exit status in a
3212*5e7646d2SAndroid Build Coastguard Worker * variable first and then convert...
3213*5e7646d2SAndroid Build Coastguard Worker */
3214*5e7646d2SAndroid Build Coastguard Worker
3215*5e7646d2SAndroid Build Coastguard Worker exit_code = -job->status;
3216*5e7646d2SAndroid Build Coastguard Worker if (WIFEXITED(exit_code))
3217*5e7646d2SAndroid Build Coastguard Worker exit_code = WEXITSTATUS(exit_code);
3218*5e7646d2SAndroid Build Coastguard Worker else
3219*5e7646d2SAndroid Build Coastguard Worker {
3220*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "cups-backend-crashed");
3221*5e7646d2SAndroid Build Coastguard Worker exit_code = job->status;
3222*5e7646d2SAndroid Build Coastguard Worker }
3223*5e7646d2SAndroid Build Coastguard Worker
3224*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_WARN, "Backend returned status %d (%s)",
3225*5e7646d2SAndroid Build Coastguard Worker exit_code,
3226*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_FAILED ? "failed" :
3227*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_AUTH_REQUIRED ?
3228*5e7646d2SAndroid Build Coastguard Worker "authentication required" :
3229*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_HOLD ? "hold job" :
3230*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_STOP ? "stop printer" :
3231*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_CANCEL ? "cancel job" :
3232*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_RETRY ? "retry job later" :
3233*5e7646d2SAndroid Build Coastguard Worker exit_code == CUPS_BACKEND_RETRY_CURRENT ? "retry job immediately" :
3234*5e7646d2SAndroid Build Coastguard Worker exit_code < 0 ? "crashed" : "unknown");
3235*5e7646d2SAndroid Build Coastguard Worker
3236*5e7646d2SAndroid Build Coastguard Worker /*
3237*5e7646d2SAndroid Build Coastguard Worker * Do what needs to be done...
3238*5e7646d2SAndroid Build Coastguard Worker */
3239*5e7646d2SAndroid Build Coastguard Worker
3240*5e7646d2SAndroid Build Coastguard Worker switch (exit_code)
3241*5e7646d2SAndroid Build Coastguard Worker {
3242*5e7646d2SAndroid Build Coastguard Worker default :
3243*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_FAILED :
3244*5e7646d2SAndroid Build Coastguard Worker /*
3245*5e7646d2SAndroid Build Coastguard Worker * Backend failure, use the error-policy to determine how to
3246*5e7646d2SAndroid Build Coastguard Worker * act...
3247*5e7646d2SAndroid Build Coastguard Worker */
3248*5e7646d2SAndroid Build Coastguard Worker
3249*5e7646d2SAndroid Build Coastguard Worker if (job->dtype & CUPS_PRINTER_CLASS)
3250*5e7646d2SAndroid Build Coastguard Worker {
3251*5e7646d2SAndroid Build Coastguard Worker /*
3252*5e7646d2SAndroid Build Coastguard Worker * Queued on a class - mark the job as pending and we'll retry on
3253*5e7646d2SAndroid Build Coastguard Worker * another printer...
3254*5e7646d2SAndroid Build Coastguard Worker */
3255*5e7646d2SAndroid Build Coastguard Worker
3256*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3257*5e7646d2SAndroid Build Coastguard Worker {
3258*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_PENDING;
3259*5e7646d2SAndroid Build Coastguard Worker message = "Retrying job on another printer.";
3260*5e7646d2SAndroid Build Coastguard Worker
3261*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0,
3262*5e7646d2SAndroid Build Coastguard Worker "resources-are-not-ready");
3263*5e7646d2SAndroid Build Coastguard Worker }
3264*5e7646d2SAndroid Build Coastguard Worker }
3265*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(job->printer->error_policy, "retry-current-job"))
3266*5e7646d2SAndroid Build Coastguard Worker {
3267*5e7646d2SAndroid Build Coastguard Worker /*
3268*5e7646d2SAndroid Build Coastguard Worker * The error policy is "retry-current-job" - mark the job as pending
3269*5e7646d2SAndroid Build Coastguard Worker * and we'll retry on the same printer...
3270*5e7646d2SAndroid Build Coastguard Worker */
3271*5e7646d2SAndroid Build Coastguard Worker
3272*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3273*5e7646d2SAndroid Build Coastguard Worker {
3274*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_PENDING;
3275*5e7646d2SAndroid Build Coastguard Worker message = "Retrying job on same printer.";
3276*5e7646d2SAndroid Build Coastguard Worker
3277*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "none");
3278*5e7646d2SAndroid Build Coastguard Worker }
3279*5e7646d2SAndroid Build Coastguard Worker }
3280*5e7646d2SAndroid Build Coastguard Worker else if ((job->printer->type & CUPS_PRINTER_FAX) ||
3281*5e7646d2SAndroid Build Coastguard Worker !strcmp(job->printer->error_policy, "retry-job"))
3282*5e7646d2SAndroid Build Coastguard Worker {
3283*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3284*5e7646d2SAndroid Build Coastguard Worker {
3285*5e7646d2SAndroid Build Coastguard Worker /*
3286*5e7646d2SAndroid Build Coastguard Worker * The job was queued on a fax or the error policy is "retry-job" -
3287*5e7646d2SAndroid Build Coastguard Worker * hold the job if the number of retries is less than the
3288*5e7646d2SAndroid Build Coastguard Worker * JobRetryLimit, otherwise abort the job.
3289*5e7646d2SAndroid Build Coastguard Worker */
3290*5e7646d2SAndroid Build Coastguard Worker
3291*5e7646d2SAndroid Build Coastguard Worker job->tries ++;
3292*5e7646d2SAndroid Build Coastguard Worker
3293*5e7646d2SAndroid Build Coastguard Worker if (job->tries > JobRetryLimit && JobRetryLimit > 0)
3294*5e7646d2SAndroid Build Coastguard Worker {
3295*5e7646d2SAndroid Build Coastguard Worker /*
3296*5e7646d2SAndroid Build Coastguard Worker * Too many tries...
3297*5e7646d2SAndroid Build Coastguard Worker */
3298*5e7646d2SAndroid Build Coastguard Worker
3299*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer),
3300*5e7646d2SAndroid Build Coastguard Worker "Job aborted after %d unsuccessful attempts.",
3301*5e7646d2SAndroid Build Coastguard Worker JobRetryLimit);
3302*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_ABORTED;
3303*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3304*5e7646d2SAndroid Build Coastguard Worker
3305*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
3306*5e7646d2SAndroid Build Coastguard Worker }
3307*5e7646d2SAndroid Build Coastguard Worker else
3308*5e7646d2SAndroid Build Coastguard Worker {
3309*5e7646d2SAndroid Build Coastguard Worker /*
3310*5e7646d2SAndroid Build Coastguard Worker * Try again in N seconds...
3311*5e7646d2SAndroid Build Coastguard Worker */
3312*5e7646d2SAndroid Build Coastguard Worker
3313*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer),
3314*5e7646d2SAndroid Build Coastguard Worker "Job held for %d seconds since it could not be sent.",
3315*5e7646d2SAndroid Build Coastguard Worker JobRetryInterval);
3316*5e7646d2SAndroid Build Coastguard Worker
3317*5e7646d2SAndroid Build Coastguard Worker job->hold_until = time(NULL) + JobRetryInterval;
3318*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_HELD;
3319*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3320*5e7646d2SAndroid Build Coastguard Worker
3321*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0,
3322*5e7646d2SAndroid Build Coastguard Worker "resources-are-not-ready");
3323*5e7646d2SAndroid Build Coastguard Worker }
3324*5e7646d2SAndroid Build Coastguard Worker }
3325*5e7646d2SAndroid Build Coastguard Worker }
3326*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(job->printer->error_policy, "abort-job") &&
3327*5e7646d2SAndroid Build Coastguard Worker job_state == IPP_JOB_COMPLETED)
3328*5e7646d2SAndroid Build Coastguard Worker {
3329*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_ABORTED;
3330*5e7646d2SAndroid Build Coastguard Worker
3331*5e7646d2SAndroid Build Coastguard Worker if (ErrorLog)
3332*5e7646d2SAndroid Build Coastguard Worker {
3333*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "Job aborted due to backend errors; please consult the %s file for details.", ErrorLog);
3334*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3335*5e7646d2SAndroid Build Coastguard Worker }
3336*5e7646d2SAndroid Build Coastguard Worker else
3337*5e7646d2SAndroid Build Coastguard Worker message = "Job aborted due to backend errors.";
3338*5e7646d2SAndroid Build Coastguard Worker
3339*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
3340*5e7646d2SAndroid Build Coastguard Worker }
3341*5e7646d2SAndroid Build Coastguard Worker else if (job->state_value == IPP_JOB_PROCESSING)
3342*5e7646d2SAndroid Build Coastguard Worker {
3343*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_PENDING;
3344*5e7646d2SAndroid Build Coastguard Worker printer_state = IPP_PRINTER_STOPPED;
3345*5e7646d2SAndroid Build Coastguard Worker
3346*5e7646d2SAndroid Build Coastguard Worker if (ErrorLog)
3347*5e7646d2SAndroid Build Coastguard Worker {
3348*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "Printer stopped due to backend errors; please consult the %s file for details.", ErrorLog);
3349*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3350*5e7646d2SAndroid Build Coastguard Worker }
3351*5e7646d2SAndroid Build Coastguard Worker else
3352*5e7646d2SAndroid Build Coastguard Worker message = "Printer stopped due to backend errors.";
3353*5e7646d2SAndroid Build Coastguard Worker
3354*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "none");
3355*5e7646d2SAndroid Build Coastguard Worker }
3356*5e7646d2SAndroid Build Coastguard Worker break;
3357*5e7646d2SAndroid Build Coastguard Worker
3358*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_CANCEL :
3359*5e7646d2SAndroid Build Coastguard Worker /*
3360*5e7646d2SAndroid Build Coastguard Worker * Cancel the job...
3361*5e7646d2SAndroid Build Coastguard Worker */
3362*5e7646d2SAndroid Build Coastguard Worker
3363*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3364*5e7646d2SAndroid Build Coastguard Worker {
3365*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_CANCELED;
3366*5e7646d2SAndroid Build Coastguard Worker message = "Job canceled at printer.";
3367*5e7646d2SAndroid Build Coastguard Worker
3368*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "canceled-at-device");
3369*5e7646d2SAndroid Build Coastguard Worker }
3370*5e7646d2SAndroid Build Coastguard Worker break;
3371*5e7646d2SAndroid Build Coastguard Worker
3372*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_HOLD :
3373*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3374*5e7646d2SAndroid Build Coastguard Worker {
3375*5e7646d2SAndroid Build Coastguard Worker /*
3376*5e7646d2SAndroid Build Coastguard Worker * Hold the job...
3377*5e7646d2SAndroid Build Coastguard Worker */
3378*5e7646d2SAndroid Build Coastguard Worker
3379*5e7646d2SAndroid Build Coastguard Worker const char *reason = ippGetString(job->reasons, 0, NULL);
3380*5e7646d2SAndroid Build Coastguard Worker
3381*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-state-reasons=\"%s\"",
3382*5e7646d2SAndroid Build Coastguard Worker reason);
3383*5e7646d2SAndroid Build Coastguard Worker
3384*5e7646d2SAndroid Build Coastguard Worker if (!reason || strncmp(reason, "account-", 8))
3385*5e7646d2SAndroid Build Coastguard Worker {
3386*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, "indefinite", 1);
3387*5e7646d2SAndroid Build Coastguard Worker
3388*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0,
3389*5e7646d2SAndroid Build Coastguard Worker "job-hold-until-specified");
3390*5e7646d2SAndroid Build Coastguard Worker
3391*5e7646d2SAndroid Build Coastguard Worker if (ErrorLog)
3392*5e7646d2SAndroid Build Coastguard Worker {
3393*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "Job held indefinitely due to backend errors; please consult the %s file for details.", ErrorLog);
3394*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3395*5e7646d2SAndroid Build Coastguard Worker }
3396*5e7646d2SAndroid Build Coastguard Worker else
3397*5e7646d2SAndroid Build Coastguard Worker message = "Job held indefinitely due to backend errors.";
3398*5e7646d2SAndroid Build Coastguard Worker }
3399*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(reason, "account-info-needed"))
3400*5e7646d2SAndroid Build Coastguard Worker {
3401*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, "indefinite", 0);
3402*5e7646d2SAndroid Build Coastguard Worker
3403*5e7646d2SAndroid Build Coastguard Worker message = "Job held indefinitely - account information is required.";
3404*5e7646d2SAndroid Build Coastguard Worker }
3405*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(reason, "account-closed"))
3406*5e7646d2SAndroid Build Coastguard Worker {
3407*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, "indefinite", 0);
3408*5e7646d2SAndroid Build Coastguard Worker
3409*5e7646d2SAndroid Build Coastguard Worker message = "Job held indefinitely - account has been closed.";
3410*5e7646d2SAndroid Build Coastguard Worker }
3411*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(reason, "account-limit-reached"))
3412*5e7646d2SAndroid Build Coastguard Worker {
3413*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, "indefinite", 0);
3414*5e7646d2SAndroid Build Coastguard Worker
3415*5e7646d2SAndroid Build Coastguard Worker message = "Job held indefinitely - account limit has been reached.";
3416*5e7646d2SAndroid Build Coastguard Worker }
3417*5e7646d2SAndroid Build Coastguard Worker else
3418*5e7646d2SAndroid Build Coastguard Worker {
3419*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, "indefinite", 0);
3420*5e7646d2SAndroid Build Coastguard Worker
3421*5e7646d2SAndroid Build Coastguard Worker message = "Job held indefinitely - account authorization failed.";
3422*5e7646d2SAndroid Build Coastguard Worker }
3423*5e7646d2SAndroid Build Coastguard Worker
3424*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_HELD;
3425*5e7646d2SAndroid Build Coastguard Worker }
3426*5e7646d2SAndroid Build Coastguard Worker break;
3427*5e7646d2SAndroid Build Coastguard Worker
3428*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_STOP :
3429*5e7646d2SAndroid Build Coastguard Worker /*
3430*5e7646d2SAndroid Build Coastguard Worker * Stop the printer...
3431*5e7646d2SAndroid Build Coastguard Worker */
3432*5e7646d2SAndroid Build Coastguard Worker
3433*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JSTATE_CANCELED || job_state == IPP_JSTATE_ABORTED)
3434*5e7646d2SAndroid Build Coastguard Worker {
3435*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_INFO, "Ignored STOP from backend since the job is %s.", job_state == IPP_JSTATE_CANCELED ? "canceled" : "aborted");
3436*5e7646d2SAndroid Build Coastguard Worker break;
3437*5e7646d2SAndroid Build Coastguard Worker }
3438*5e7646d2SAndroid Build Coastguard Worker
3439*5e7646d2SAndroid Build Coastguard Worker printer_state = IPP_PRINTER_STOPPED;
3440*5e7646d2SAndroid Build Coastguard Worker
3441*5e7646d2SAndroid Build Coastguard Worker if (ErrorLog)
3442*5e7646d2SAndroid Build Coastguard Worker {
3443*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "Printer stopped due to backend errors; please consult the %s file for details.", ErrorLog);
3444*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3445*5e7646d2SAndroid Build Coastguard Worker }
3446*5e7646d2SAndroid Build Coastguard Worker else
3447*5e7646d2SAndroid Build Coastguard Worker message = "Printer stopped due to backend errors.";
3448*5e7646d2SAndroid Build Coastguard Worker
3449*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3450*5e7646d2SAndroid Build Coastguard Worker {
3451*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_PENDING;
3452*5e7646d2SAndroid Build Coastguard Worker
3453*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "resources-are-not-ready");
3454*5e7646d2SAndroid Build Coastguard Worker }
3455*5e7646d2SAndroid Build Coastguard Worker break;
3456*5e7646d2SAndroid Build Coastguard Worker
3457*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_AUTH_REQUIRED :
3458*5e7646d2SAndroid Build Coastguard Worker /*
3459*5e7646d2SAndroid Build Coastguard Worker * Hold the job for authentication...
3460*5e7646d2SAndroid Build Coastguard Worker */
3461*5e7646d2SAndroid Build Coastguard Worker
3462*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3463*5e7646d2SAndroid Build Coastguard Worker {
3464*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobHoldUntil(job, "auth-info-required", 1);
3465*5e7646d2SAndroid Build Coastguard Worker
3466*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_HELD;
3467*5e7646d2SAndroid Build Coastguard Worker message = "Job held for authentication.";
3468*5e7646d2SAndroid Build Coastguard Worker
3469*5e7646d2SAndroid Build Coastguard Worker if (strncmp(job->reasons->values[0].string.text, "account-", 8))
3470*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0,
3471*5e7646d2SAndroid Build Coastguard Worker "cups-held-for-authentication");
3472*5e7646d2SAndroid Build Coastguard Worker }
3473*5e7646d2SAndroid Build Coastguard Worker break;
3474*5e7646d2SAndroid Build Coastguard Worker
3475*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_RETRY :
3476*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3477*5e7646d2SAndroid Build Coastguard Worker {
3478*5e7646d2SAndroid Build Coastguard Worker /*
3479*5e7646d2SAndroid Build Coastguard Worker * Hold the job if the number of retries is less than the
3480*5e7646d2SAndroid Build Coastguard Worker * JobRetryLimit, otherwise abort the job.
3481*5e7646d2SAndroid Build Coastguard Worker */
3482*5e7646d2SAndroid Build Coastguard Worker
3483*5e7646d2SAndroid Build Coastguard Worker job->tries ++;
3484*5e7646d2SAndroid Build Coastguard Worker
3485*5e7646d2SAndroid Build Coastguard Worker if (job->tries > JobRetryLimit && JobRetryLimit > 0)
3486*5e7646d2SAndroid Build Coastguard Worker {
3487*5e7646d2SAndroid Build Coastguard Worker /*
3488*5e7646d2SAndroid Build Coastguard Worker * Too many tries...
3489*5e7646d2SAndroid Build Coastguard Worker */
3490*5e7646d2SAndroid Build Coastguard Worker
3491*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer),
3492*5e7646d2SAndroid Build Coastguard Worker "Job aborted after %d unsuccessful attempts.",
3493*5e7646d2SAndroid Build Coastguard Worker JobRetryLimit);
3494*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_ABORTED;
3495*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3496*5e7646d2SAndroid Build Coastguard Worker
3497*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
3498*5e7646d2SAndroid Build Coastguard Worker }
3499*5e7646d2SAndroid Build Coastguard Worker else
3500*5e7646d2SAndroid Build Coastguard Worker {
3501*5e7646d2SAndroid Build Coastguard Worker /*
3502*5e7646d2SAndroid Build Coastguard Worker * Try again in N seconds...
3503*5e7646d2SAndroid Build Coastguard Worker */
3504*5e7646d2SAndroid Build Coastguard Worker
3505*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer),
3506*5e7646d2SAndroid Build Coastguard Worker "Job held for %d seconds since it could not be sent.",
3507*5e7646d2SAndroid Build Coastguard Worker JobRetryInterval);
3508*5e7646d2SAndroid Build Coastguard Worker
3509*5e7646d2SAndroid Build Coastguard Worker job->hold_until = time(NULL) + JobRetryInterval;
3510*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_HELD;
3511*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3512*5e7646d2SAndroid Build Coastguard Worker
3513*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0,
3514*5e7646d2SAndroid Build Coastguard Worker "resources-are-not-ready");
3515*5e7646d2SAndroid Build Coastguard Worker }
3516*5e7646d2SAndroid Build Coastguard Worker }
3517*5e7646d2SAndroid Build Coastguard Worker break;
3518*5e7646d2SAndroid Build Coastguard Worker
3519*5e7646d2SAndroid Build Coastguard Worker case CUPS_BACKEND_RETRY_CURRENT :
3520*5e7646d2SAndroid Build Coastguard Worker /*
3521*5e7646d2SAndroid Build Coastguard Worker * Mark the job as pending and retry on the same printer...
3522*5e7646d2SAndroid Build Coastguard Worker */
3523*5e7646d2SAndroid Build Coastguard Worker
3524*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3525*5e7646d2SAndroid Build Coastguard Worker {
3526*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_PENDING;
3527*5e7646d2SAndroid Build Coastguard Worker message = "Retrying job on same printer.";
3528*5e7646d2SAndroid Build Coastguard Worker
3529*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "none");
3530*5e7646d2SAndroid Build Coastguard Worker }
3531*5e7646d2SAndroid Build Coastguard Worker break;
3532*5e7646d2SAndroid Build Coastguard Worker }
3533*5e7646d2SAndroid Build Coastguard Worker }
3534*5e7646d2SAndroid Build Coastguard Worker else if (job->status > 0)
3535*5e7646d2SAndroid Build Coastguard Worker {
3536*5e7646d2SAndroid Build Coastguard Worker /*
3537*5e7646d2SAndroid Build Coastguard Worker * Filter had errors; stop job...
3538*5e7646d2SAndroid Build Coastguard Worker */
3539*5e7646d2SAndroid Build Coastguard Worker
3540*5e7646d2SAndroid Build Coastguard Worker if (job_state == IPP_JOB_COMPLETED)
3541*5e7646d2SAndroid Build Coastguard Worker {
3542*5e7646d2SAndroid Build Coastguard Worker job_state = IPP_JOB_STOPPED;
3543*5e7646d2SAndroid Build Coastguard Worker
3544*5e7646d2SAndroid Build Coastguard Worker if (ErrorLog)
3545*5e7646d2SAndroid Build Coastguard Worker {
3546*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "Job stopped due to filter errors; please consult the %s file for details.", ErrorLog);
3547*5e7646d2SAndroid Build Coastguard Worker message = buffer;
3548*5e7646d2SAndroid Build Coastguard Worker }
3549*5e7646d2SAndroid Build Coastguard Worker else
3550*5e7646d2SAndroid Build Coastguard Worker message = "Job stopped due to filter errors.";
3551*5e7646d2SAndroid Build Coastguard Worker
3552*5e7646d2SAndroid Build Coastguard Worker if (WIFSIGNALED(job->status))
3553*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "cups-filter-crashed");
3554*5e7646d2SAndroid Build Coastguard Worker else
3555*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "job-completed-with-errors");
3556*5e7646d2SAndroid Build Coastguard Worker }
3557*5e7646d2SAndroid Build Coastguard Worker }
3558*5e7646d2SAndroid Build Coastguard Worker
3559*5e7646d2SAndroid Build Coastguard Worker /*
3560*5e7646d2SAndroid Build Coastguard Worker * Update the printer and job state.
3561*5e7646d2SAndroid Build Coastguard Worker */
3562*5e7646d2SAndroid Build Coastguard Worker
3563*5e7646d2SAndroid Build Coastguard Worker if (set_job_state && job_state != job->state_value)
3564*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, job_state, CUPSD_JOB_DEFAULT, "%s", message);
3565*5e7646d2SAndroid Build Coastguard Worker
3566*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterState(job->printer, printer_state,
3567*5e7646d2SAndroid Build Coastguard Worker printer_state == IPP_PRINTER_STOPPED);
3568*5e7646d2SAndroid Build Coastguard Worker update_job_attrs(job, 0);
3569*5e7646d2SAndroid Build Coastguard Worker
3570*5e7646d2SAndroid Build Coastguard Worker if (job->history)
3571*5e7646d2SAndroid Build Coastguard Worker {
3572*5e7646d2SAndroid Build Coastguard Worker if (job->status &&
3573*5e7646d2SAndroid Build Coastguard Worker (job->state_value == IPP_JOB_ABORTED ||
3574*5e7646d2SAndroid Build Coastguard Worker job->state_value == IPP_JOB_STOPPED))
3575*5e7646d2SAndroid Build Coastguard Worker dump_job_history(job);
3576*5e7646d2SAndroid Build Coastguard Worker else
3577*5e7646d2SAndroid Build Coastguard Worker free_job_history(job);
3578*5e7646d2SAndroid Build Coastguard Worker }
3579*5e7646d2SAndroid Build Coastguard Worker
3580*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(PrintingJobs, job);
3581*5e7646d2SAndroid Build Coastguard Worker
3582*5e7646d2SAndroid Build Coastguard Worker /*
3583*5e7646d2SAndroid Build Coastguard Worker * Clear informational messages...
3584*5e7646d2SAndroid Build Coastguard Worker */
3585*5e7646d2SAndroid Build Coastguard Worker
3586*5e7646d2SAndroid Build Coastguard Worker if (job->status_level > CUPSD_LOG_ERROR)
3587*5e7646d2SAndroid Build Coastguard Worker job->printer->state_message[0] = '\0';
3588*5e7646d2SAndroid Build Coastguard Worker
3589*5e7646d2SAndroid Build Coastguard Worker /*
3590*5e7646d2SAndroid Build Coastguard Worker * Apply any PPD updates...
3591*5e7646d2SAndroid Build Coastguard Worker */
3592*5e7646d2SAndroid Build Coastguard Worker
3593*5e7646d2SAndroid Build Coastguard Worker if (job->num_keywords)
3594*5e7646d2SAndroid Build Coastguard Worker {
3595*5e7646d2SAndroid Build Coastguard Worker if (cupsdUpdatePrinterPPD(job->printer, job->num_keywords, job->keywords))
3596*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(job->printer);
3597*5e7646d2SAndroid Build Coastguard Worker
3598*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(job->num_keywords, job->keywords);
3599*5e7646d2SAndroid Build Coastguard Worker
3600*5e7646d2SAndroid Build Coastguard Worker job->num_keywords = 0;
3601*5e7646d2SAndroid Build Coastguard Worker job->keywords = NULL;
3602*5e7646d2SAndroid Build Coastguard Worker }
3603*5e7646d2SAndroid Build Coastguard Worker
3604*5e7646d2SAndroid Build Coastguard Worker /*
3605*5e7646d2SAndroid Build Coastguard Worker * Clear the printer <-> job association...
3606*5e7646d2SAndroid Build Coastguard Worker */
3607*5e7646d2SAndroid Build Coastguard Worker
3608*5e7646d2SAndroid Build Coastguard Worker job->printer->job = NULL;
3609*5e7646d2SAndroid Build Coastguard Worker job->printer = NULL;
3610*5e7646d2SAndroid Build Coastguard Worker }
3611*5e7646d2SAndroid Build Coastguard Worker
3612*5e7646d2SAndroid Build Coastguard Worker
3613*5e7646d2SAndroid Build Coastguard Worker /*
3614*5e7646d2SAndroid Build Coastguard Worker * 'get_options()' - Get a string containing the job options.
3615*5e7646d2SAndroid Build Coastguard Worker */
3616*5e7646d2SAndroid Build Coastguard Worker
3617*5e7646d2SAndroid Build Coastguard Worker static char * /* O - Options string */
get_options(cupsd_job_t * job,int banner_page,char * copies,size_t copies_size,char * title,size_t title_size)3618*5e7646d2SAndroid Build Coastguard Worker get_options(cupsd_job_t *job, /* I - Job */
3619*5e7646d2SAndroid Build Coastguard Worker int banner_page, /* I - Printing a banner page? */
3620*5e7646d2SAndroid Build Coastguard Worker char *copies, /* I - Copies buffer */
3621*5e7646d2SAndroid Build Coastguard Worker size_t copies_size, /* I - Size of copies buffer */
3622*5e7646d2SAndroid Build Coastguard Worker char *title, /* I - Title buffer */
3623*5e7646d2SAndroid Build Coastguard Worker size_t title_size) /* I - Size of title buffer */
3624*5e7646d2SAndroid Build Coastguard Worker {
3625*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
3626*5e7646d2SAndroid Build Coastguard Worker size_t newlength; /* New option buffer length */
3627*5e7646d2SAndroid Build Coastguard Worker char *optptr, /* Pointer to options */
3628*5e7646d2SAndroid Build Coastguard Worker *valptr; /* Pointer in value string */
3629*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
3630*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc; /* PPD cache and mapping data */
3631*5e7646d2SAndroid Build Coastguard Worker int num_pwgppds; /* Number of PWG->PPD options */
3632*5e7646d2SAndroid Build Coastguard Worker cups_option_t *pwgppds, /* PWG->PPD options */
3633*5e7646d2SAndroid Build Coastguard Worker *pwgppd, /* Current PWG->PPD option */
3634*5e7646d2SAndroid Build Coastguard Worker *preset; /* Current preset option */
3635*5e7646d2SAndroid Build Coastguard Worker int print_color_mode,
3636*5e7646d2SAndroid Build Coastguard Worker /* Output mode (if any) */
3637*5e7646d2SAndroid Build Coastguard Worker print_quality; /* Print quality (if any) */
3638*5e7646d2SAndroid Build Coastguard Worker const char *ppd; /* PPD option choice */
3639*5e7646d2SAndroid Build Coastguard Worker int exact; /* Did we get an exact match? */
3640*5e7646d2SAndroid Build Coastguard Worker static char *options = NULL;/* Full list of options */
3641*5e7646d2SAndroid Build Coastguard Worker static size_t optlength = 0; /* Length of option buffer */
3642*5e7646d2SAndroid Build Coastguard Worker
3643*5e7646d2SAndroid Build Coastguard Worker
3644*5e7646d2SAndroid Build Coastguard Worker /*
3645*5e7646d2SAndroid Build Coastguard Worker * Building the options string is harder than it needs to be, but for the
3646*5e7646d2SAndroid Build Coastguard Worker * moment we need to pass strings for command-line args and not IPP attribute
3647*5e7646d2SAndroid Build Coastguard Worker * pointers... :)
3648*5e7646d2SAndroid Build Coastguard Worker *
3649*5e7646d2SAndroid Build Coastguard Worker * First build an options array for any PWG->PPD mapped option/choice pairs.
3650*5e7646d2SAndroid Build Coastguard Worker */
3651*5e7646d2SAndroid Build Coastguard Worker
3652*5e7646d2SAndroid Build Coastguard Worker pc = job->printer->pc;
3653*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = 0;
3654*5e7646d2SAndroid Build Coastguard Worker pwgppds = NULL;
3655*5e7646d2SAndroid Build Coastguard Worker
3656*5e7646d2SAndroid Build Coastguard Worker if (pc &&
3657*5e7646d2SAndroid Build Coastguard Worker !ippFindAttribute(job->attrs, "com.apple.print.DocumentTicket.PMSpoolFormat", IPP_TAG_ZERO) &&
3658*5e7646d2SAndroid Build Coastguard Worker !ippFindAttribute(job->attrs, "APPrinterPreset", IPP_TAG_ZERO) &&
3659*5e7646d2SAndroid Build Coastguard Worker (ippFindAttribute(job->attrs, "print-color-mode", IPP_TAG_ZERO) || ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ZERO) || ippFindAttribute(job->attrs, "cupsPrintQuality", IPP_TAG_ZERO)))
3660*5e7646d2SAndroid Build Coastguard Worker {
3661*5e7646d2SAndroid Build Coastguard Worker /*
3662*5e7646d2SAndroid Build Coastguard Worker * Map print-color-mode and print-quality to a preset...
3663*5e7646d2SAndroid Build Coastguard Worker */
3664*5e7646d2SAndroid Build Coastguard Worker
3665*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "print-color-mode",
3666*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) != NULL &&
3667*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->values[0].string.text, "monochrome"))
3668*5e7646d2SAndroid Build Coastguard Worker print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
3669*5e7646d2SAndroid Build Coastguard Worker else
3670*5e7646d2SAndroid Build Coastguard Worker print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
3671*5e7646d2SAndroid Build Coastguard Worker
3672*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ENUM)) != NULL)
3673*5e7646d2SAndroid Build Coastguard Worker {
3674*5e7646d2SAndroid Build Coastguard Worker ipp_quality_t pq = (ipp_quality_t)ippGetInteger(attr, 0);
3675*5e7646d2SAndroid Build Coastguard Worker
3676*5e7646d2SAndroid Build Coastguard Worker if (pq >= IPP_QUALITY_DRAFT && pq <= IPP_QUALITY_HIGH)
3677*5e7646d2SAndroid Build Coastguard Worker print_quality = attr->values[0].integer - IPP_QUALITY_DRAFT;
3678*5e7646d2SAndroid Build Coastguard Worker else
3679*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_NORMAL;
3680*5e7646d2SAndroid Build Coastguard Worker }
3681*5e7646d2SAndroid Build Coastguard Worker else if ((attr = ippFindAttribute(job->attrs, "cupsPrintQuality", IPP_TAG_NAME)) != NULL)
3682*5e7646d2SAndroid Build Coastguard Worker {
3683*5e7646d2SAndroid Build Coastguard Worker const char *pq = ippGetString(attr, 0, NULL);
3684*5e7646d2SAndroid Build Coastguard Worker
3685*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(pq, "draft"))
3686*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_DRAFT;
3687*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(pq, "high"))
3688*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_HIGH;
3689*5e7646d2SAndroid Build Coastguard Worker else
3690*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_NORMAL;
3691*5e7646d2SAndroid Build Coastguard Worker
3692*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ENUM))
3693*5e7646d2SAndroid Build Coastguard Worker {
3694*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping cupsPrintQuality=%s to print-quality=%d", pq, print_quality + IPP_QUALITY_DRAFT);
3695*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddIntegerOption("print-quality", print_quality + IPP_QUALITY_DRAFT, num_pwgppds, &pwgppds);
3696*5e7646d2SAndroid Build Coastguard Worker }
3697*5e7646d2SAndroid Build Coastguard Worker }
3698*5e7646d2SAndroid Build Coastguard Worker else
3699*5e7646d2SAndroid Build Coastguard Worker {
3700*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_NORMAL;
3701*5e7646d2SAndroid Build Coastguard Worker }
3702*5e7646d2SAndroid Build Coastguard Worker
3703*5e7646d2SAndroid Build Coastguard Worker if (pc->num_presets[print_color_mode][print_quality] == 0)
3704*5e7646d2SAndroid Build Coastguard Worker {
3705*5e7646d2SAndroid Build Coastguard Worker /*
3706*5e7646d2SAndroid Build Coastguard Worker * Try to find a preset that works so that we maximize the chances of us
3707*5e7646d2SAndroid Build Coastguard Worker * getting a good print using IPP attributes.
3708*5e7646d2SAndroid Build Coastguard Worker */
3709*5e7646d2SAndroid Build Coastguard Worker
3710*5e7646d2SAndroid Build Coastguard Worker if (pc->num_presets[print_color_mode][_PWG_PRINT_QUALITY_NORMAL] > 0)
3711*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_NORMAL;
3712*5e7646d2SAndroid Build Coastguard Worker else if (pc->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][print_quality] > 0)
3713*5e7646d2SAndroid Build Coastguard Worker print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
3714*5e7646d2SAndroid Build Coastguard Worker else
3715*5e7646d2SAndroid Build Coastguard Worker {
3716*5e7646d2SAndroid Build Coastguard Worker print_quality = _PWG_PRINT_QUALITY_NORMAL;
3717*5e7646d2SAndroid Build Coastguard Worker print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
3718*5e7646d2SAndroid Build Coastguard Worker }
3719*5e7646d2SAndroid Build Coastguard Worker }
3720*5e7646d2SAndroid Build Coastguard Worker
3721*5e7646d2SAndroid Build Coastguard Worker if (pc->num_presets[print_color_mode][print_quality] > 0)
3722*5e7646d2SAndroid Build Coastguard Worker {
3723*5e7646d2SAndroid Build Coastguard Worker /*
3724*5e7646d2SAndroid Build Coastguard Worker * Copy the preset options as long as the corresponding names are not
3725*5e7646d2SAndroid Build Coastguard Worker * already defined in the IPP request...
3726*5e7646d2SAndroid Build Coastguard Worker */
3727*5e7646d2SAndroid Build Coastguard Worker
3728*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_presets[print_color_mode][print_quality],
3729*5e7646d2SAndroid Build Coastguard Worker preset = pc->presets[print_color_mode][print_quality];
3730*5e7646d2SAndroid Build Coastguard Worker i > 0;
3731*5e7646d2SAndroid Build Coastguard Worker i --, preset ++)
3732*5e7646d2SAndroid Build Coastguard Worker {
3733*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, preset->name, IPP_TAG_ZERO))
3734*5e7646d2SAndroid Build Coastguard Worker {
3735*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Adding preset option %s=%s", preset->name, preset->value);
3736*5e7646d2SAndroid Build Coastguard Worker
3737*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption(preset->name, preset->value, num_pwgppds, &pwgppds);
3738*5e7646d2SAndroid Build Coastguard Worker }
3739*5e7646d2SAndroid Build Coastguard Worker }
3740*5e7646d2SAndroid Build Coastguard Worker }
3741*5e7646d2SAndroid Build Coastguard Worker }
3742*5e7646d2SAndroid Build Coastguard Worker
3743*5e7646d2SAndroid Build Coastguard Worker if (pc)
3744*5e7646d2SAndroid Build Coastguard Worker {
3745*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ENUM)) != NULL)
3746*5e7646d2SAndroid Build Coastguard Worker {
3747*5e7646d2SAndroid Build Coastguard Worker int pq = ippGetInteger(attr, 0);
3748*5e7646d2SAndroid Build Coastguard Worker static const char * const pqs[] = { "Draft", "Normal", "High" };
3749*5e7646d2SAndroid Build Coastguard Worker
3750*5e7646d2SAndroid Build Coastguard Worker if (pq >= IPP_QUALITY_DRAFT && pq <= IPP_QUALITY_HIGH)
3751*5e7646d2SAndroid Build Coastguard Worker {
3752*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping print-quality=%d to cupsPrintQuality=%s", pq, pqs[pq - IPP_QUALITY_DRAFT]);
3753*5e7646d2SAndroid Build Coastguard Worker
3754*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("cupsPrintQuality", pqs[pq - IPP_QUALITY_DRAFT], num_pwgppds, &pwgppds);
3755*5e7646d2SAndroid Build Coastguard Worker }
3756*5e7646d2SAndroid Build Coastguard Worker }
3757*5e7646d2SAndroid Build Coastguard Worker
3758*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) &&
3759*5e7646d2SAndroid Build Coastguard Worker !ippFindAttribute(job->attrs, "HPPaperSource", IPP_TAG_ZERO))
3760*5e7646d2SAndroid Build Coastguard Worker {
3761*5e7646d2SAndroid Build Coastguard Worker if ((ppd = _ppdCacheGetInputSlot(pc, job->attrs, NULL)) != NULL)
3762*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption(pc->source_option, ppd, num_pwgppds,
3763*5e7646d2SAndroid Build Coastguard Worker &pwgppds);
3764*5e7646d2SAndroid Build Coastguard Worker }
3765*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) &&
3766*5e7646d2SAndroid Build Coastguard Worker (ppd = _ppdCacheGetMediaType(pc, job->attrs, NULL)) != NULL)
3767*5e7646d2SAndroid Build Coastguard Worker {
3768*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping media to MediaType=%s", ppd);
3769*5e7646d2SAndroid Build Coastguard Worker
3770*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("MediaType", ppd, num_pwgppds, &pwgppds);
3771*5e7646d2SAndroid Build Coastguard Worker }
3772*5e7646d2SAndroid Build Coastguard Worker
3773*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) &&
3774*5e7646d2SAndroid Build Coastguard Worker !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) &&
3775*5e7646d2SAndroid Build Coastguard Worker (ppd = _ppdCacheGetPageSize(pc, job->attrs, NULL, &exact)) != NULL)
3776*5e7646d2SAndroid Build Coastguard Worker {
3777*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping media to Pagesize=%s", ppd);
3778*5e7646d2SAndroid Build Coastguard Worker
3779*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("PageSize", ppd, num_pwgppds, &pwgppds);
3780*5e7646d2SAndroid Build Coastguard Worker
3781*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "media", IPP_TAG_ZERO))
3782*5e7646d2SAndroid Build Coastguard Worker {
3783*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Adding media=%s", ppd);
3784*5e7646d2SAndroid Build Coastguard Worker
3785*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("media", ppd, num_pwgppds, &pwgppds);
3786*5e7646d2SAndroid Build Coastguard Worker }
3787*5e7646d2SAndroid Build Coastguard Worker }
3788*5e7646d2SAndroid Build Coastguard Worker
3789*5e7646d2SAndroid Build Coastguard Worker if (!ippFindAttribute(job->attrs, "OutputBin", IPP_TAG_ZERO) &&
3790*5e7646d2SAndroid Build Coastguard Worker (attr = ippFindAttribute(job->attrs, "output-bin",
3791*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO)) != NULL &&
3792*5e7646d2SAndroid Build Coastguard Worker (attr->value_tag == IPP_TAG_KEYWORD ||
3793*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_NAME) &&
3794*5e7646d2SAndroid Build Coastguard Worker (ppd = _ppdCacheGetOutputBin(pc, attr->values[0].string.text)) != NULL)
3795*5e7646d2SAndroid Build Coastguard Worker {
3796*5e7646d2SAndroid Build Coastguard Worker /*
3797*5e7646d2SAndroid Build Coastguard Worker * Map output-bin to OutputBin option...
3798*5e7646d2SAndroid Build Coastguard Worker */
3799*5e7646d2SAndroid Build Coastguard Worker
3800*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping output-bin to OutputBin=%s", ppd);
3801*5e7646d2SAndroid Build Coastguard Worker
3802*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("OutputBin", ppd, num_pwgppds, &pwgppds);
3803*5e7646d2SAndroid Build Coastguard Worker }
3804*5e7646d2SAndroid Build Coastguard Worker
3805*5e7646d2SAndroid Build Coastguard Worker if (pc->sides_option &&
3806*5e7646d2SAndroid Build Coastguard Worker !ippFindAttribute(job->attrs, pc->sides_option, IPP_TAG_ZERO) &&
3807*5e7646d2SAndroid Build Coastguard Worker (attr = ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD)) != NULL)
3808*5e7646d2SAndroid Build Coastguard Worker {
3809*5e7646d2SAndroid Build Coastguard Worker /*
3810*5e7646d2SAndroid Build Coastguard Worker * Map sides to duplex option...
3811*5e7646d2SAndroid Build Coastguard Worker */
3812*5e7646d2SAndroid Build Coastguard Worker
3813*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(attr->values[0].string.text, "one-sided"))
3814*5e7646d2SAndroid Build Coastguard Worker {
3815*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping sizes to Duplex=%s", pc->sides_1sided);
3816*5e7646d2SAndroid Build Coastguard Worker
3817*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption(pc->sides_option, pc->sides_1sided, num_pwgppds, &pwgppds);
3818*5e7646d2SAndroid Build Coastguard Worker }
3819*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(attr->values[0].string.text, "two-sided-long-edge"))
3820*5e7646d2SAndroid Build Coastguard Worker {
3821*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping sizes to Duplex=%s", pc->sides_2sided_long);
3822*5e7646d2SAndroid Build Coastguard Worker
3823*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption(pc->sides_option, pc->sides_2sided_long, num_pwgppds, &pwgppds);
3824*5e7646d2SAndroid Build Coastguard Worker }
3825*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(attr->values[0].string.text, "two-sided-short-edge"))
3826*5e7646d2SAndroid Build Coastguard Worker {
3827*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping sizes to Duplex=%s", pc->sides_2sided_short);
3828*5e7646d2SAndroid Build Coastguard Worker
3829*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption(pc->sides_option, pc->sides_2sided_short, num_pwgppds, &pwgppds);
3830*5e7646d2SAndroid Build Coastguard Worker }
3831*5e7646d2SAndroid Build Coastguard Worker }
3832*5e7646d2SAndroid Build Coastguard Worker
3833*5e7646d2SAndroid Build Coastguard Worker /*
3834*5e7646d2SAndroid Build Coastguard Worker * Map finishings values...
3835*5e7646d2SAndroid Build Coastguard Worker */
3836*5e7646d2SAndroid Build Coastguard Worker
3837*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = _ppdCacheGetFinishingOptions(pc, job->attrs, IPP_FINISHINGS_NONE, num_pwgppds, &pwgppds);
3838*5e7646d2SAndroid Build Coastguard Worker
3839*5e7646d2SAndroid Build Coastguard Worker for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++)
3840*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG2, "After mapping finishings %s=%s", pwgppd->name, pwgppd->value);
3841*5e7646d2SAndroid Build Coastguard Worker }
3842*5e7646d2SAndroid Build Coastguard Worker
3843*5e7646d2SAndroid Build Coastguard Worker /*
3844*5e7646d2SAndroid Build Coastguard Worker * Map page-delivery values...
3845*5e7646d2SAndroid Build Coastguard Worker */
3846*5e7646d2SAndroid Build Coastguard Worker
3847*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, "page-delivery", IPP_TAG_KEYWORD)) != NULL && !ippFindAttribute(job->attrs, "outputorder", IPP_TAG_ZERO))
3848*5e7646d2SAndroid Build Coastguard Worker {
3849*5e7646d2SAndroid Build Coastguard Worker const char *page_delivery = ippGetString(attr, 0, NULL);
3850*5e7646d2SAndroid Build Coastguard Worker
3851*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(page_delivery, "same-order", 10))
3852*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("OutputOrder", "Normal", num_pwgppds, &pwgppds);
3853*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(page_delivery, "reverse-order", 13))
3854*5e7646d2SAndroid Build Coastguard Worker num_pwgppds = cupsAddOption("OutputOrder", "Reverse", num_pwgppds, &pwgppds);
3855*5e7646d2SAndroid Build Coastguard Worker }
3856*5e7646d2SAndroid Build Coastguard Worker
3857*5e7646d2SAndroid Build Coastguard Worker /*
3858*5e7646d2SAndroid Build Coastguard Worker * Figure out how much room we need...
3859*5e7646d2SAndroid Build Coastguard Worker */
3860*5e7646d2SAndroid Build Coastguard Worker
3861*5e7646d2SAndroid Build Coastguard Worker newlength = ipp_length(job->attrs);
3862*5e7646d2SAndroid Build Coastguard Worker
3863*5e7646d2SAndroid Build Coastguard Worker for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++)
3864*5e7646d2SAndroid Build Coastguard Worker newlength += 1 + strlen(pwgppd->name) + 1 + strlen(pwgppd->value);
3865*5e7646d2SAndroid Build Coastguard Worker
3866*5e7646d2SAndroid Build Coastguard Worker /*
3867*5e7646d2SAndroid Build Coastguard Worker * Then allocate/reallocate the option buffer as needed...
3868*5e7646d2SAndroid Build Coastguard Worker */
3869*5e7646d2SAndroid Build Coastguard Worker
3870*5e7646d2SAndroid Build Coastguard Worker if (newlength == 0) /* This can never happen, but Clang */
3871*5e7646d2SAndroid Build Coastguard Worker newlength = 1; /* thinks it can... */
3872*5e7646d2SAndroid Build Coastguard Worker
3873*5e7646d2SAndroid Build Coastguard Worker if (newlength > optlength || !options)
3874*5e7646d2SAndroid Build Coastguard Worker {
3875*5e7646d2SAndroid Build Coastguard Worker if (!options)
3876*5e7646d2SAndroid Build Coastguard Worker optptr = malloc(newlength);
3877*5e7646d2SAndroid Build Coastguard Worker else
3878*5e7646d2SAndroid Build Coastguard Worker optptr = realloc(options, newlength);
3879*5e7646d2SAndroid Build Coastguard Worker
3880*5e7646d2SAndroid Build Coastguard Worker if (!optptr)
3881*5e7646d2SAndroid Build Coastguard Worker {
3882*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_CRIT,
3883*5e7646d2SAndroid Build Coastguard Worker "Unable to allocate " CUPS_LLFMT " bytes for option buffer.",
3884*5e7646d2SAndroid Build Coastguard Worker CUPS_LLCAST newlength);
3885*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3886*5e7646d2SAndroid Build Coastguard Worker }
3887*5e7646d2SAndroid Build Coastguard Worker
3888*5e7646d2SAndroid Build Coastguard Worker options = optptr;
3889*5e7646d2SAndroid Build Coastguard Worker optlength = newlength;
3890*5e7646d2SAndroid Build Coastguard Worker }
3891*5e7646d2SAndroid Build Coastguard Worker
3892*5e7646d2SAndroid Build Coastguard Worker /*
3893*5e7646d2SAndroid Build Coastguard Worker * Now loop through the attributes and convert them to the textual
3894*5e7646d2SAndroid Build Coastguard Worker * representation used by the filters...
3895*5e7646d2SAndroid Build Coastguard Worker */
3896*5e7646d2SAndroid Build Coastguard Worker
3897*5e7646d2SAndroid Build Coastguard Worker optptr = options;
3898*5e7646d2SAndroid Build Coastguard Worker *optptr = '\0';
3899*5e7646d2SAndroid Build Coastguard Worker
3900*5e7646d2SAndroid Build Coastguard Worker snprintf(title, title_size, "%s-%d", job->printer->name, job->id);
3901*5e7646d2SAndroid Build Coastguard Worker strlcpy(copies, "1", copies_size);
3902*5e7646d2SAndroid Build Coastguard Worker
3903*5e7646d2SAndroid Build Coastguard Worker for (attr = job->attrs->attrs; attr != NULL; attr = attr->next)
3904*5e7646d2SAndroid Build Coastguard Worker {
3905*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(attr->name, "copies") &&
3906*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_INTEGER)
3907*5e7646d2SAndroid Build Coastguard Worker {
3908*5e7646d2SAndroid Build Coastguard Worker /*
3909*5e7646d2SAndroid Build Coastguard Worker * Don't use the # copies attribute if we are printing the job sheets...
3910*5e7646d2SAndroid Build Coastguard Worker */
3911*5e7646d2SAndroid Build Coastguard Worker
3912*5e7646d2SAndroid Build Coastguard Worker if (!banner_page)
3913*5e7646d2SAndroid Build Coastguard Worker snprintf(copies, copies_size, "%d", attr->values[0].integer);
3914*5e7646d2SAndroid Build Coastguard Worker }
3915*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(attr->name, "job-name") &&
3916*5e7646d2SAndroid Build Coastguard Worker (attr->value_tag == IPP_TAG_NAME ||
3917*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_NAMELANG))
3918*5e7646d2SAndroid Build Coastguard Worker strlcpy(title, attr->values[0].string.text, title_size);
3919*5e7646d2SAndroid Build Coastguard Worker else if (attr->group_tag == IPP_TAG_JOB)
3920*5e7646d2SAndroid Build Coastguard Worker {
3921*5e7646d2SAndroid Build Coastguard Worker /*
3922*5e7646d2SAndroid Build Coastguard Worker * Filter out other unwanted attributes...
3923*5e7646d2SAndroid Build Coastguard Worker */
3924*5e7646d2SAndroid Build Coastguard Worker
3925*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag == IPP_TAG_NOVALUE ||
3926*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_MIMETYPE ||
3927*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_NAMELANG ||
3928*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_TEXTLANG ||
3929*5e7646d2SAndroid Build Coastguard Worker (attr->value_tag == IPP_TAG_URI && strcmp(attr->name, "job-uuid") &&
3930*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-authorization-uri")) ||
3931*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_URISCHEME ||
3932*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */
3933*5e7646d2SAndroid Build Coastguard Worker continue;
3934*5e7646d2SAndroid Build Coastguard Worker
3935*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(attr->name, "job-hold-until") ||
3936*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "job-id") ||
3937*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "job-k-octets") ||
3938*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "job-media-sheets") ||
3939*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "job-media-sheets-completed") ||
3940*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "job-state") ||
3941*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "job-state-reasons"))
3942*5e7646d2SAndroid Build Coastguard Worker continue;
3943*5e7646d2SAndroid Build Coastguard Worker
3944*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(attr->name, "job-", 4) &&
3945*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-account-id") &&
3946*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-accounting-user-id") &&
3947*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-authorization-uri") &&
3948*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-billing") &&
3949*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-impressions") &&
3950*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-originating-host-name") &&
3951*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-password") &&
3952*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-password-encryption") &&
3953*5e7646d2SAndroid Build Coastguard Worker strcmp(attr->name, "job-uuid") &&
3954*5e7646d2SAndroid Build Coastguard Worker !(job->printer->type & CUPS_PRINTER_REMOTE))
3955*5e7646d2SAndroid Build Coastguard Worker continue;
3956*5e7646d2SAndroid Build Coastguard Worker
3957*5e7646d2SAndroid Build Coastguard Worker if ((!strcmp(attr->name, "job-impressions") ||
3958*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "page-label") ||
3959*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "page-border") ||
3960*5e7646d2SAndroid Build Coastguard Worker !strncmp(attr->name, "number-up", 9) ||
3961*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "page-ranges") ||
3962*5e7646d2SAndroid Build Coastguard Worker !strcmp(attr->name, "page-set") ||
3963*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(attr->name, "AP_FIRSTPAGE_InputSlot") ||
3964*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(attr->name, "AP_FIRSTPAGE_ManualFeed") ||
3965*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(attr->name, "com.apple.print.PrintSettings."
3966*5e7646d2SAndroid Build Coastguard Worker "PMTotalSidesImaged..n.") ||
3967*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(attr->name, "com.apple.print.PrintSettings."
3968*5e7646d2SAndroid Build Coastguard Worker "PMTotalBeginPages..n.")) &&
3969*5e7646d2SAndroid Build Coastguard Worker banner_page)
3970*5e7646d2SAndroid Build Coastguard Worker continue;
3971*5e7646d2SAndroid Build Coastguard Worker
3972*5e7646d2SAndroid Build Coastguard Worker /*
3973*5e7646d2SAndroid Build Coastguard Worker * Otherwise add them to the list...
3974*5e7646d2SAndroid Build Coastguard Worker */
3975*5e7646d2SAndroid Build Coastguard Worker
3976*5e7646d2SAndroid Build Coastguard Worker if (optptr > options)
3977*5e7646d2SAndroid Build Coastguard Worker strlcat(optptr, " ", optlength - (size_t)(optptr - options));
3978*5e7646d2SAndroid Build Coastguard Worker
3979*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag != IPP_TAG_BOOLEAN)
3980*5e7646d2SAndroid Build Coastguard Worker {
3981*5e7646d2SAndroid Build Coastguard Worker strlcat(optptr, attr->name, optlength - (size_t)(optptr - options));
3982*5e7646d2SAndroid Build Coastguard Worker strlcat(optptr, "=", optlength - (size_t)(optptr - options));
3983*5e7646d2SAndroid Build Coastguard Worker }
3984*5e7646d2SAndroid Build Coastguard Worker
3985*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
3986*5e7646d2SAndroid Build Coastguard Worker {
3987*5e7646d2SAndroid Build Coastguard Worker if (i)
3988*5e7646d2SAndroid Build Coastguard Worker strlcat(optptr, ",", optlength - (size_t)(optptr - options));
3989*5e7646d2SAndroid Build Coastguard Worker
3990*5e7646d2SAndroid Build Coastguard Worker optptr += strlen(optptr);
3991*5e7646d2SAndroid Build Coastguard Worker
3992*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag)
3993*5e7646d2SAndroid Build Coastguard Worker {
3994*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
3995*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
3996*5e7646d2SAndroid Build Coastguard Worker snprintf(optptr, optlength - (size_t)(optptr - options),
3997*5e7646d2SAndroid Build Coastguard Worker "%d", attr->values[i].integer);
3998*5e7646d2SAndroid Build Coastguard Worker break;
3999*5e7646d2SAndroid Build Coastguard Worker
4000*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
4001*5e7646d2SAndroid Build Coastguard Worker if (!attr->values[i].boolean)
4002*5e7646d2SAndroid Build Coastguard Worker strlcat(optptr, "no", optlength - (size_t)(optptr - options));
4003*5e7646d2SAndroid Build Coastguard Worker
4004*5e7646d2SAndroid Build Coastguard Worker strlcat(optptr, attr->name, optlength - (size_t)(optptr - options));
4005*5e7646d2SAndroid Build Coastguard Worker break;
4006*5e7646d2SAndroid Build Coastguard Worker
4007*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
4008*5e7646d2SAndroid Build Coastguard Worker if (attr->values[i].range.lower == attr->values[i].range.upper)
4009*5e7646d2SAndroid Build Coastguard Worker snprintf(optptr, optlength - (size_t)(optptr - options) - 1,
4010*5e7646d2SAndroid Build Coastguard Worker "%d", attr->values[i].range.lower);
4011*5e7646d2SAndroid Build Coastguard Worker else
4012*5e7646d2SAndroid Build Coastguard Worker snprintf(optptr, optlength - (size_t)(optptr - options) - 1,
4013*5e7646d2SAndroid Build Coastguard Worker "%d-%d", attr->values[i].range.lower,
4014*5e7646d2SAndroid Build Coastguard Worker attr->values[i].range.upper);
4015*5e7646d2SAndroid Build Coastguard Worker break;
4016*5e7646d2SAndroid Build Coastguard Worker
4017*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
4018*5e7646d2SAndroid Build Coastguard Worker snprintf(optptr, optlength - (size_t)(optptr - options) - 1,
4019*5e7646d2SAndroid Build Coastguard Worker "%dx%d%s", attr->values[i].resolution.xres,
4020*5e7646d2SAndroid Build Coastguard Worker attr->values[i].resolution.yres,
4021*5e7646d2SAndroid Build Coastguard Worker attr->values[i].resolution.units == IPP_RES_PER_INCH ?
4022*5e7646d2SAndroid Build Coastguard Worker "dpi" : "dpcm");
4023*5e7646d2SAndroid Build Coastguard Worker break;
4024*5e7646d2SAndroid Build Coastguard Worker
4025*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
4026*5e7646d2SAndroid Build Coastguard Worker {
4027*5e7646d2SAndroid Build Coastguard Worker int length = attr->values[i].unknown.length;
4028*5e7646d2SAndroid Build Coastguard Worker
4029*5e7646d2SAndroid Build Coastguard Worker for (valptr = attr->values[i].unknown.data; length > 0; length --)
4030*5e7646d2SAndroid Build Coastguard Worker {
4031*5e7646d2SAndroid Build Coastguard Worker if ((*valptr & 255) < 0x20 || *valptr == 0x7f)
4032*5e7646d2SAndroid Build Coastguard Worker break;
4033*5e7646d2SAndroid Build Coastguard Worker }
4034*5e7646d2SAndroid Build Coastguard Worker
4035*5e7646d2SAndroid Build Coastguard Worker if (length > 0)
4036*5e7646d2SAndroid Build Coastguard Worker {
4037*5e7646d2SAndroid Build Coastguard Worker /*
4038*5e7646d2SAndroid Build Coastguard Worker * Encode this string as hex characters...
4039*5e7646d2SAndroid Build Coastguard Worker */
4040*5e7646d2SAndroid Build Coastguard Worker
4041*5e7646d2SAndroid Build Coastguard Worker *optptr++ = '<';
4042*5e7646d2SAndroid Build Coastguard Worker
4043*5e7646d2SAndroid Build Coastguard Worker for (valptr = attr->values[i].unknown.data, length = attr->values[i].unknown.length; length > 0; length --)
4044*5e7646d2SAndroid Build Coastguard Worker {
4045*5e7646d2SAndroid Build Coastguard Worker snprintf(optptr, optlength - (size_t)(optptr - options) - 1, "%02X", *valptr & 255);
4046*5e7646d2SAndroid Build Coastguard Worker optptr += 2;
4047*5e7646d2SAndroid Build Coastguard Worker }
4048*5e7646d2SAndroid Build Coastguard Worker
4049*5e7646d2SAndroid Build Coastguard Worker *optptr++ = '>';
4050*5e7646d2SAndroid Build Coastguard Worker }
4051*5e7646d2SAndroid Build Coastguard Worker else
4052*5e7646d2SAndroid Build Coastguard Worker {
4053*5e7646d2SAndroid Build Coastguard Worker for (valptr = attr->values[i].unknown.data, length = attr->values[i].unknown.length; length > 0; length --)
4054*5e7646d2SAndroid Build Coastguard Worker {
4055*5e7646d2SAndroid Build Coastguard Worker if (strchr(" \t\n\\\'\"", *valptr))
4056*5e7646d2SAndroid Build Coastguard Worker *optptr++ = '\\';
4057*5e7646d2SAndroid Build Coastguard Worker *optptr++ = *valptr++;
4058*5e7646d2SAndroid Build Coastguard Worker }
4059*5e7646d2SAndroid Build Coastguard Worker }
4060*5e7646d2SAndroid Build Coastguard Worker }
4061*5e7646d2SAndroid Build Coastguard Worker
4062*5e7646d2SAndroid Build Coastguard Worker *optptr = '\0';
4063*5e7646d2SAndroid Build Coastguard Worker break;
4064*5e7646d2SAndroid Build Coastguard Worker
4065*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
4066*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
4067*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
4068*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
4069*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
4070*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
4071*5e7646d2SAndroid Build Coastguard Worker for (valptr = attr->values[i].string.text; *valptr;)
4072*5e7646d2SAndroid Build Coastguard Worker {
4073*5e7646d2SAndroid Build Coastguard Worker if (strchr(" \t\n\\\'\"", *valptr))
4074*5e7646d2SAndroid Build Coastguard Worker *optptr++ = '\\';
4075*5e7646d2SAndroid Build Coastguard Worker *optptr++ = *valptr++;
4076*5e7646d2SAndroid Build Coastguard Worker }
4077*5e7646d2SAndroid Build Coastguard Worker
4078*5e7646d2SAndroid Build Coastguard Worker *optptr = '\0';
4079*5e7646d2SAndroid Build Coastguard Worker break;
4080*5e7646d2SAndroid Build Coastguard Worker
4081*5e7646d2SAndroid Build Coastguard Worker default :
4082*5e7646d2SAndroid Build Coastguard Worker break; /* anti-compiler-warning-code */
4083*5e7646d2SAndroid Build Coastguard Worker }
4084*5e7646d2SAndroid Build Coastguard Worker }
4085*5e7646d2SAndroid Build Coastguard Worker
4086*5e7646d2SAndroid Build Coastguard Worker optptr += strlen(optptr);
4087*5e7646d2SAndroid Build Coastguard Worker }
4088*5e7646d2SAndroid Build Coastguard Worker }
4089*5e7646d2SAndroid Build Coastguard Worker
4090*5e7646d2SAndroid Build Coastguard Worker /*
4091*5e7646d2SAndroid Build Coastguard Worker * Finally loop through the PWG->PPD mapped options and add them...
4092*5e7646d2SAndroid Build Coastguard Worker */
4093*5e7646d2SAndroid Build Coastguard Worker
4094*5e7646d2SAndroid Build Coastguard Worker for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++)
4095*5e7646d2SAndroid Build Coastguard Worker {
4096*5e7646d2SAndroid Build Coastguard Worker *optptr++ = ' ';
4097*5e7646d2SAndroid Build Coastguard Worker strlcpy(optptr, pwgppd->name, optlength - (size_t)(optptr - options));
4098*5e7646d2SAndroid Build Coastguard Worker optptr += strlen(optptr);
4099*5e7646d2SAndroid Build Coastguard Worker *optptr++ = '=';
4100*5e7646d2SAndroid Build Coastguard Worker strlcpy(optptr, pwgppd->value, optlength - (size_t)(optptr - options));
4101*5e7646d2SAndroid Build Coastguard Worker optptr += strlen(optptr);
4102*5e7646d2SAndroid Build Coastguard Worker }
4103*5e7646d2SAndroid Build Coastguard Worker
4104*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_pwgppds, pwgppds);
4105*5e7646d2SAndroid Build Coastguard Worker
4106*5e7646d2SAndroid Build Coastguard Worker /*
4107*5e7646d2SAndroid Build Coastguard Worker * Return the options string...
4108*5e7646d2SAndroid Build Coastguard Worker */
4109*5e7646d2SAndroid Build Coastguard Worker
4110*5e7646d2SAndroid Build Coastguard Worker return (options);
4111*5e7646d2SAndroid Build Coastguard Worker }
4112*5e7646d2SAndroid Build Coastguard Worker
4113*5e7646d2SAndroid Build Coastguard Worker
4114*5e7646d2SAndroid Build Coastguard Worker /*
4115*5e7646d2SAndroid Build Coastguard Worker * 'ipp_length()' - Compute the size of the buffer needed to hold
4116*5e7646d2SAndroid Build Coastguard Worker * the textual IPP attributes.
4117*5e7646d2SAndroid Build Coastguard Worker */
4118*5e7646d2SAndroid Build Coastguard Worker
4119*5e7646d2SAndroid Build Coastguard Worker static size_t /* O - Size of attribute buffer */
ipp_length(ipp_t * ipp)4120*5e7646d2SAndroid Build Coastguard Worker ipp_length(ipp_t *ipp) /* I - IPP request */
4121*5e7646d2SAndroid Build Coastguard Worker {
4122*5e7646d2SAndroid Build Coastguard Worker size_t bytes; /* Number of bytes */
4123*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
4124*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
4125*5e7646d2SAndroid Build Coastguard Worker
4126*5e7646d2SAndroid Build Coastguard Worker
4127*5e7646d2SAndroid Build Coastguard Worker /*
4128*5e7646d2SAndroid Build Coastguard Worker * Loop through all attributes...
4129*5e7646d2SAndroid Build Coastguard Worker */
4130*5e7646d2SAndroid Build Coastguard Worker
4131*5e7646d2SAndroid Build Coastguard Worker bytes = 0;
4132*5e7646d2SAndroid Build Coastguard Worker
4133*5e7646d2SAndroid Build Coastguard Worker for (attr = ipp->attrs; attr != NULL; attr = attr->next)
4134*5e7646d2SAndroid Build Coastguard Worker {
4135*5e7646d2SAndroid Build Coastguard Worker /*
4136*5e7646d2SAndroid Build Coastguard Worker * Skip attributes that won't be sent to filters...
4137*5e7646d2SAndroid Build Coastguard Worker */
4138*5e7646d2SAndroid Build Coastguard Worker
4139*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag == IPP_TAG_NOVALUE ||
4140*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_MIMETYPE ||
4141*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_NAMELANG ||
4142*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_TEXTLANG ||
4143*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_URI ||
4144*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_URISCHEME)
4145*5e7646d2SAndroid Build Coastguard Worker continue;
4146*5e7646d2SAndroid Build Coastguard Worker
4147*5e7646d2SAndroid Build Coastguard Worker /*
4148*5e7646d2SAndroid Build Coastguard Worker * Add space for a leading space and commas between each value.
4149*5e7646d2SAndroid Build Coastguard Worker * For the first attribute, the leading space isn't used, so the
4150*5e7646d2SAndroid Build Coastguard Worker * extra byte can be used as the nul terminator...
4151*5e7646d2SAndroid Build Coastguard Worker */
4152*5e7646d2SAndroid Build Coastguard Worker
4153*5e7646d2SAndroid Build Coastguard Worker bytes ++; /* " " separator */
4154*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values; /* "," separators */
4155*5e7646d2SAndroid Build Coastguard Worker
4156*5e7646d2SAndroid Build Coastguard Worker /*
4157*5e7646d2SAndroid Build Coastguard Worker * Boolean attributes appear as "foo,nofoo,foo,nofoo", while
4158*5e7646d2SAndroid Build Coastguard Worker * other attributes appear as "foo=value1,value2,...,valueN".
4159*5e7646d2SAndroid Build Coastguard Worker */
4160*5e7646d2SAndroid Build Coastguard Worker
4161*5e7646d2SAndroid Build Coastguard Worker if (attr->value_tag != IPP_TAG_BOOLEAN)
4162*5e7646d2SAndroid Build Coastguard Worker bytes += strlen(attr->name);
4163*5e7646d2SAndroid Build Coastguard Worker else
4164*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values * strlen(attr->name);
4165*5e7646d2SAndroid Build Coastguard Worker
4166*5e7646d2SAndroid Build Coastguard Worker /*
4167*5e7646d2SAndroid Build Coastguard Worker * Now add the size required for each value in the attribute...
4168*5e7646d2SAndroid Build Coastguard Worker */
4169*5e7646d2SAndroid Build Coastguard Worker
4170*5e7646d2SAndroid Build Coastguard Worker switch (attr->value_tag)
4171*5e7646d2SAndroid Build Coastguard Worker {
4172*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
4173*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
4174*5e7646d2SAndroid Build Coastguard Worker /*
4175*5e7646d2SAndroid Build Coastguard Worker * Minimum value of a signed integer is -2147483647, or 11 digits.
4176*5e7646d2SAndroid Build Coastguard Worker */
4177*5e7646d2SAndroid Build Coastguard Worker
4178*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values * 11;
4179*5e7646d2SAndroid Build Coastguard Worker break;
4180*5e7646d2SAndroid Build Coastguard Worker
4181*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
4182*5e7646d2SAndroid Build Coastguard Worker /*
4183*5e7646d2SAndroid Build Coastguard Worker * Add two bytes for each false ("no") value...
4184*5e7646d2SAndroid Build Coastguard Worker */
4185*5e7646d2SAndroid Build Coastguard Worker
4186*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4187*5e7646d2SAndroid Build Coastguard Worker if (!attr->values[i].boolean)
4188*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
4189*5e7646d2SAndroid Build Coastguard Worker break;
4190*5e7646d2SAndroid Build Coastguard Worker
4191*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
4192*5e7646d2SAndroid Build Coastguard Worker /*
4193*5e7646d2SAndroid Build Coastguard Worker * A range is two signed integers separated by a hyphen, or
4194*5e7646d2SAndroid Build Coastguard Worker * 23 characters max.
4195*5e7646d2SAndroid Build Coastguard Worker */
4196*5e7646d2SAndroid Build Coastguard Worker
4197*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values * 23;
4198*5e7646d2SAndroid Build Coastguard Worker break;
4199*5e7646d2SAndroid Build Coastguard Worker
4200*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RESOLUTION :
4201*5e7646d2SAndroid Build Coastguard Worker /*
4202*5e7646d2SAndroid Build Coastguard Worker * A resolution is two signed integers separated by an "x" and
4203*5e7646d2SAndroid Build Coastguard Worker * suffixed by the units, or 26 characters max.
4204*5e7646d2SAndroid Build Coastguard Worker */
4205*5e7646d2SAndroid Build Coastguard Worker
4206*5e7646d2SAndroid Build Coastguard Worker bytes += (size_t)attr->num_values * 26;
4207*5e7646d2SAndroid Build Coastguard Worker break;
4208*5e7646d2SAndroid Build Coastguard Worker
4209*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
4210*5e7646d2SAndroid Build Coastguard Worker /*
4211*5e7646d2SAndroid Build Coastguard Worker * Octet strings can contain characters that need quoting. We need
4212*5e7646d2SAndroid Build Coastguard Worker * at least 2 * len + 2 characters to cover the quotes and any
4213*5e7646d2SAndroid Build Coastguard Worker * backslashes in the string.
4214*5e7646d2SAndroid Build Coastguard Worker */
4215*5e7646d2SAndroid Build Coastguard Worker
4216*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4217*5e7646d2SAndroid Build Coastguard Worker bytes += 2 * (size_t)attr->values[i].unknown.length + 2;
4218*5e7646d2SAndroid Build Coastguard Worker break;
4219*5e7646d2SAndroid Build Coastguard Worker
4220*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_TEXT :
4221*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_NAME :
4222*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_KEYWORD :
4223*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_CHARSET :
4224*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_LANGUAGE :
4225*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_URI :
4226*5e7646d2SAndroid Build Coastguard Worker /*
4227*5e7646d2SAndroid Build Coastguard Worker * Strings can contain characters that need quoting. We need
4228*5e7646d2SAndroid Build Coastguard Worker * at least 2 * len + 2 characters to cover the quotes and
4229*5e7646d2SAndroid Build Coastguard Worker * any backslashes in the string.
4230*5e7646d2SAndroid Build Coastguard Worker */
4231*5e7646d2SAndroid Build Coastguard Worker
4232*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
4233*5e7646d2SAndroid Build Coastguard Worker bytes += 2 * strlen(attr->values[i].string.text) + 2;
4234*5e7646d2SAndroid Build Coastguard Worker break;
4235*5e7646d2SAndroid Build Coastguard Worker
4236*5e7646d2SAndroid Build Coastguard Worker default :
4237*5e7646d2SAndroid Build Coastguard Worker break; /* anti-compiler-warning-code */
4238*5e7646d2SAndroid Build Coastguard Worker }
4239*5e7646d2SAndroid Build Coastguard Worker }
4240*5e7646d2SAndroid Build Coastguard Worker
4241*5e7646d2SAndroid Build Coastguard Worker return (bytes);
4242*5e7646d2SAndroid Build Coastguard Worker }
4243*5e7646d2SAndroid Build Coastguard Worker
4244*5e7646d2SAndroid Build Coastguard Worker
4245*5e7646d2SAndroid Build Coastguard Worker /*
4246*5e7646d2SAndroid Build Coastguard Worker * 'load_job_cache()' - Load jobs from the job.cache file.
4247*5e7646d2SAndroid Build Coastguard Worker */
4248*5e7646d2SAndroid Build Coastguard Worker
4249*5e7646d2SAndroid Build Coastguard Worker static void
load_job_cache(const char * filename)4250*5e7646d2SAndroid Build Coastguard Worker load_job_cache(const char *filename) /* I - job.cache filename */
4251*5e7646d2SAndroid Build Coastguard Worker {
4252*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* job.cache file */
4253*5e7646d2SAndroid Build Coastguard Worker char line[1024], /* Line buffer */
4254*5e7646d2SAndroid Build Coastguard Worker *value; /* Value on line */
4255*5e7646d2SAndroid Build Coastguard Worker int linenum; /* Line number in file */
4256*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
4257*5e7646d2SAndroid Build Coastguard Worker int jobid; /* Job ID */
4258*5e7646d2SAndroid Build Coastguard Worker char jobfile[1024]; /* Job filename */
4259*5e7646d2SAndroid Build Coastguard Worker
4260*5e7646d2SAndroid Build Coastguard Worker
4261*5e7646d2SAndroid Build Coastguard Worker /*
4262*5e7646d2SAndroid Build Coastguard Worker * Open the job.cache file...
4263*5e7646d2SAndroid Build Coastguard Worker */
4264*5e7646d2SAndroid Build Coastguard Worker
4265*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsdOpenConfFile(filename)) == NULL)
4266*5e7646d2SAndroid Build Coastguard Worker {
4267*5e7646d2SAndroid Build Coastguard Worker load_request_root();
4268*5e7646d2SAndroid Build Coastguard Worker return;
4269*5e7646d2SAndroid Build Coastguard Worker }
4270*5e7646d2SAndroid Build Coastguard Worker
4271*5e7646d2SAndroid Build Coastguard Worker /*
4272*5e7646d2SAndroid Build Coastguard Worker * Read entries from the job cache file and create jobs as needed.
4273*5e7646d2SAndroid Build Coastguard Worker */
4274*5e7646d2SAndroid Build Coastguard Worker
4275*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_INFO, "Loading job cache file \"%s\"...",
4276*5e7646d2SAndroid Build Coastguard Worker filename);
4277*5e7646d2SAndroid Build Coastguard Worker
4278*5e7646d2SAndroid Build Coastguard Worker linenum = 0;
4279*5e7646d2SAndroid Build Coastguard Worker job = NULL;
4280*5e7646d2SAndroid Build Coastguard Worker
4281*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
4282*5e7646d2SAndroid Build Coastguard Worker {
4283*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(line, "NextJobId"))
4284*5e7646d2SAndroid Build Coastguard Worker {
4285*5e7646d2SAndroid Build Coastguard Worker if (value)
4286*5e7646d2SAndroid Build Coastguard Worker NextJobId = atoi(value);
4287*5e7646d2SAndroid Build Coastguard Worker }
4288*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "<Job"))
4289*5e7646d2SAndroid Build Coastguard Worker {
4290*5e7646d2SAndroid Build Coastguard Worker if (job)
4291*5e7646d2SAndroid Build Coastguard Worker {
4292*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Missing </Job> directive on line %d of %s.", linenum, filename);
4293*5e7646d2SAndroid Build Coastguard Worker continue;
4294*5e7646d2SAndroid Build Coastguard Worker }
4295*5e7646d2SAndroid Build Coastguard Worker
4296*5e7646d2SAndroid Build Coastguard Worker if (!value)
4297*5e7646d2SAndroid Build Coastguard Worker {
4298*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d of %s.", linenum, filename);
4299*5e7646d2SAndroid Build Coastguard Worker continue;
4300*5e7646d2SAndroid Build Coastguard Worker }
4301*5e7646d2SAndroid Build Coastguard Worker
4302*5e7646d2SAndroid Build Coastguard Worker jobid = atoi(value);
4303*5e7646d2SAndroid Build Coastguard Worker
4304*5e7646d2SAndroid Build Coastguard Worker if (jobid < 1)
4305*5e7646d2SAndroid Build Coastguard Worker {
4306*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Bad job ID %d on line %d of %s.", jobid, linenum, filename);
4307*5e7646d2SAndroid Build Coastguard Worker continue;
4308*5e7646d2SAndroid Build Coastguard Worker }
4309*5e7646d2SAndroid Build Coastguard Worker
4310*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, jobid);
4311*5e7646d2SAndroid Build Coastguard Worker if (access(jobfile, 0))
4312*5e7646d2SAndroid Build Coastguard Worker {
4313*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/c%05d.N", RequestRoot, jobid);
4314*5e7646d2SAndroid Build Coastguard Worker if (access(jobfile, 0))
4315*5e7646d2SAndroid Build Coastguard Worker {
4316*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away.",
4317*5e7646d2SAndroid Build Coastguard Worker jobid);
4318*5e7646d2SAndroid Build Coastguard Worker
4319*5e7646d2SAndroid Build Coastguard Worker /*
4320*5e7646d2SAndroid Build Coastguard Worker * job.cache file is out-of-date compared to spool directory; load
4321*5e7646d2SAndroid Build Coastguard Worker * that instead...
4322*5e7646d2SAndroid Build Coastguard Worker */
4323*5e7646d2SAndroid Build Coastguard Worker
4324*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
4325*5e7646d2SAndroid Build Coastguard Worker load_request_root();
4326*5e7646d2SAndroid Build Coastguard Worker return;
4327*5e7646d2SAndroid Build Coastguard Worker }
4328*5e7646d2SAndroid Build Coastguard Worker }
4329*5e7646d2SAndroid Build Coastguard Worker
4330*5e7646d2SAndroid Build Coastguard Worker job = calloc(1, sizeof(cupsd_job_t));
4331*5e7646d2SAndroid Build Coastguard Worker if (!job)
4332*5e7646d2SAndroid Build Coastguard Worker {
4333*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_EMERG,
4334*5e7646d2SAndroid Build Coastguard Worker "[Job %d] Unable to allocate memory for job.", jobid);
4335*5e7646d2SAndroid Build Coastguard Worker break;
4336*5e7646d2SAndroid Build Coastguard Worker }
4337*5e7646d2SAndroid Build Coastguard Worker
4338*5e7646d2SAndroid Build Coastguard Worker job->id = jobid;
4339*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[0] = -1;
4340*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[1] = -1;
4341*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[0] = -1;
4342*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = -1;
4343*5e7646d2SAndroid Build Coastguard Worker job->side_pipes[0] = -1;
4344*5e7646d2SAndroid Build Coastguard Worker job->side_pipes[1] = -1;
4345*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[0] = -1;
4346*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[1] = -1;
4347*5e7646d2SAndroid Build Coastguard Worker
4348*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading from cache...");
4349*5e7646d2SAndroid Build Coastguard Worker }
4350*5e7646d2SAndroid Build Coastguard Worker else if (!job)
4351*5e7646d2SAndroid Build Coastguard Worker {
4352*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
4353*5e7646d2SAndroid Build Coastguard Worker "Missing <Job #> directive on line %d of %s.", linenum, filename);
4354*5e7646d2SAndroid Build Coastguard Worker continue;
4355*5e7646d2SAndroid Build Coastguard Worker }
4356*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "</Job>"))
4357*5e7646d2SAndroid Build Coastguard Worker {
4358*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(Jobs, job);
4359*5e7646d2SAndroid Build Coastguard Worker
4360*5e7646d2SAndroid Build Coastguard Worker if (job->state_value <= IPP_JOB_STOPPED && cupsdLoadJob(job))
4361*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ActiveJobs, job);
4362*5e7646d2SAndroid Build Coastguard Worker else if (job->state_value > IPP_JOB_STOPPED)
4363*5e7646d2SAndroid Build Coastguard Worker {
4364*5e7646d2SAndroid Build Coastguard Worker if (!job->completed_time || !job->creation_time || !job->name || !job->koctets)
4365*5e7646d2SAndroid Build Coastguard Worker {
4366*5e7646d2SAndroid Build Coastguard Worker cupsdLoadJob(job);
4367*5e7646d2SAndroid Build Coastguard Worker unload_job(job);
4368*5e7646d2SAndroid Build Coastguard Worker }
4369*5e7646d2SAndroid Build Coastguard Worker }
4370*5e7646d2SAndroid Build Coastguard Worker
4371*5e7646d2SAndroid Build Coastguard Worker job = NULL;
4372*5e7646d2SAndroid Build Coastguard Worker }
4373*5e7646d2SAndroid Build Coastguard Worker else if (!value)
4374*5e7646d2SAndroid Build Coastguard Worker {
4375*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d of %s.", linenum, filename);
4376*5e7646d2SAndroid Build Coastguard Worker continue;
4377*5e7646d2SAndroid Build Coastguard Worker }
4378*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "State"))
4379*5e7646d2SAndroid Build Coastguard Worker {
4380*5e7646d2SAndroid Build Coastguard Worker job->state_value = (ipp_jstate_t)atoi(value);
4381*5e7646d2SAndroid Build Coastguard Worker
4382*5e7646d2SAndroid Build Coastguard Worker if (job->state_value < IPP_JOB_PENDING)
4383*5e7646d2SAndroid Build Coastguard Worker job->state_value = IPP_JOB_PENDING;
4384*5e7646d2SAndroid Build Coastguard Worker else if (job->state_value > IPP_JOB_COMPLETED)
4385*5e7646d2SAndroid Build Coastguard Worker job->state_value = IPP_JOB_COMPLETED;
4386*5e7646d2SAndroid Build Coastguard Worker }
4387*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Name"))
4388*5e7646d2SAndroid Build Coastguard Worker {
4389*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&(job->name), value);
4390*5e7646d2SAndroid Build Coastguard Worker }
4391*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Created"))
4392*5e7646d2SAndroid Build Coastguard Worker {
4393*5e7646d2SAndroid Build Coastguard Worker job->creation_time = strtol(value, NULL, 10);
4394*5e7646d2SAndroid Build Coastguard Worker }
4395*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Completed"))
4396*5e7646d2SAndroid Build Coastguard Worker {
4397*5e7646d2SAndroid Build Coastguard Worker job->completed_time = strtol(value, NULL, 10);
4398*5e7646d2SAndroid Build Coastguard Worker }
4399*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "HoldUntil"))
4400*5e7646d2SAndroid Build Coastguard Worker {
4401*5e7646d2SAndroid Build Coastguard Worker job->hold_until = strtol(value, NULL, 10);
4402*5e7646d2SAndroid Build Coastguard Worker }
4403*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Priority"))
4404*5e7646d2SAndroid Build Coastguard Worker {
4405*5e7646d2SAndroid Build Coastguard Worker job->priority = atoi(value);
4406*5e7646d2SAndroid Build Coastguard Worker }
4407*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Username"))
4408*5e7646d2SAndroid Build Coastguard Worker {
4409*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->username, value);
4410*5e7646d2SAndroid Build Coastguard Worker }
4411*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Destination"))
4412*5e7646d2SAndroid Build Coastguard Worker {
4413*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->dest, value);
4414*5e7646d2SAndroid Build Coastguard Worker }
4415*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "DestType"))
4416*5e7646d2SAndroid Build Coastguard Worker {
4417*5e7646d2SAndroid Build Coastguard Worker job->dtype = (cups_ptype_t)atoi(value);
4418*5e7646d2SAndroid Build Coastguard Worker }
4419*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "KOctets"))
4420*5e7646d2SAndroid Build Coastguard Worker {
4421*5e7646d2SAndroid Build Coastguard Worker job->koctets = atoi(value);
4422*5e7646d2SAndroid Build Coastguard Worker }
4423*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "NumFiles"))
4424*5e7646d2SAndroid Build Coastguard Worker {
4425*5e7646d2SAndroid Build Coastguard Worker job->num_files = atoi(value);
4426*5e7646d2SAndroid Build Coastguard Worker
4427*5e7646d2SAndroid Build Coastguard Worker if (job->num_files < 0)
4428*5e7646d2SAndroid Build Coastguard Worker {
4429*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d of %s.", job->num_files, linenum, filename);
4430*5e7646d2SAndroid Build Coastguard Worker job->num_files = 0;
4431*5e7646d2SAndroid Build Coastguard Worker continue;
4432*5e7646d2SAndroid Build Coastguard Worker }
4433*5e7646d2SAndroid Build Coastguard Worker
4434*5e7646d2SAndroid Build Coastguard Worker if (job->num_files > 0)
4435*5e7646d2SAndroid Build Coastguard Worker {
4436*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/d%05d-001", RequestRoot,
4437*5e7646d2SAndroid Build Coastguard Worker job->id);
4438*5e7646d2SAndroid Build Coastguard Worker if (access(jobfile, 0))
4439*5e7646d2SAndroid Build Coastguard Worker {
4440*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_INFO, "Data files have gone away.");
4441*5e7646d2SAndroid Build Coastguard Worker job->num_files = 0;
4442*5e7646d2SAndroid Build Coastguard Worker continue;
4443*5e7646d2SAndroid Build Coastguard Worker }
4444*5e7646d2SAndroid Build Coastguard Worker
4445*5e7646d2SAndroid Build Coastguard Worker job->filetypes = calloc((size_t)job->num_files, sizeof(mime_type_t *));
4446*5e7646d2SAndroid Build Coastguard Worker job->compressions = calloc((size_t)job->num_files, sizeof(int));
4447*5e7646d2SAndroid Build Coastguard Worker
4448*5e7646d2SAndroid Build Coastguard Worker if (!job->filetypes || !job->compressions)
4449*5e7646d2SAndroid Build Coastguard Worker {
4450*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_EMERG,
4451*5e7646d2SAndroid Build Coastguard Worker "Unable to allocate memory for %d files.",
4452*5e7646d2SAndroid Build Coastguard Worker job->num_files);
4453*5e7646d2SAndroid Build Coastguard Worker break;
4454*5e7646d2SAndroid Build Coastguard Worker }
4455*5e7646d2SAndroid Build Coastguard Worker }
4456*5e7646d2SAndroid Build Coastguard Worker }
4457*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "File"))
4458*5e7646d2SAndroid Build Coastguard Worker {
4459*5e7646d2SAndroid Build Coastguard Worker int number, /* File number */
4460*5e7646d2SAndroid Build Coastguard Worker compression; /* Compression value */
4461*5e7646d2SAndroid Build Coastguard Worker char super[MIME_MAX_SUPER], /* MIME super type */
4462*5e7646d2SAndroid Build Coastguard Worker type[MIME_MAX_TYPE]; /* MIME type */
4463*5e7646d2SAndroid Build Coastguard Worker
4464*5e7646d2SAndroid Build Coastguard Worker
4465*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%d%*[ \t]%15[^/]/%255s%d", &number, super, type,
4466*5e7646d2SAndroid Build Coastguard Worker &compression) != 4)
4467*5e7646d2SAndroid Build Coastguard Worker {
4468*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File on line %d of %s.", linenum, filename);
4469*5e7646d2SAndroid Build Coastguard Worker continue;
4470*5e7646d2SAndroid Build Coastguard Worker }
4471*5e7646d2SAndroid Build Coastguard Worker
4472*5e7646d2SAndroid Build Coastguard Worker if (number < 1 || number > job->num_files)
4473*5e7646d2SAndroid Build Coastguard Worker {
4474*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File number %d on line %d of %s.", number, linenum, filename);
4475*5e7646d2SAndroid Build Coastguard Worker continue;
4476*5e7646d2SAndroid Build Coastguard Worker }
4477*5e7646d2SAndroid Build Coastguard Worker
4478*5e7646d2SAndroid Build Coastguard Worker number --;
4479*5e7646d2SAndroid Build Coastguard Worker
4480*5e7646d2SAndroid Build Coastguard Worker job->compressions[number] = compression;
4481*5e7646d2SAndroid Build Coastguard Worker job->filetypes[number] = mimeType(MimeDatabase, super, type);
4482*5e7646d2SAndroid Build Coastguard Worker
4483*5e7646d2SAndroid Build Coastguard Worker if (!job->filetypes[number])
4484*5e7646d2SAndroid Build Coastguard Worker {
4485*5e7646d2SAndroid Build Coastguard Worker /*
4486*5e7646d2SAndroid Build Coastguard Worker * If the original MIME type is unknown, auto-type it!
4487*5e7646d2SAndroid Build Coastguard Worker */
4488*5e7646d2SAndroid Build Coastguard Worker
4489*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_ERROR,
4490*5e7646d2SAndroid Build Coastguard Worker "Unknown MIME type %s/%s for file %d.",
4491*5e7646d2SAndroid Build Coastguard Worker super, type, number + 1);
4492*5e7646d2SAndroid Build Coastguard Worker
4493*5e7646d2SAndroid Build Coastguard Worker snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot,
4494*5e7646d2SAndroid Build Coastguard Worker job->id, number + 1);
4495*5e7646d2SAndroid Build Coastguard Worker job->filetypes[number] = mimeFileType(MimeDatabase, jobfile, NULL,
4496*5e7646d2SAndroid Build Coastguard Worker job->compressions + number);
4497*5e7646d2SAndroid Build Coastguard Worker
4498*5e7646d2SAndroid Build Coastguard Worker /*
4499*5e7646d2SAndroid Build Coastguard Worker * If that didn't work, assume it is raw...
4500*5e7646d2SAndroid Build Coastguard Worker */
4501*5e7646d2SAndroid Build Coastguard Worker
4502*5e7646d2SAndroid Build Coastguard Worker if (!job->filetypes[number])
4503*5e7646d2SAndroid Build Coastguard Worker job->filetypes[number] = mimeType(MimeDatabase, "application",
4504*5e7646d2SAndroid Build Coastguard Worker "vnd.cups-raw");
4505*5e7646d2SAndroid Build Coastguard Worker }
4506*5e7646d2SAndroid Build Coastguard Worker }
4507*5e7646d2SAndroid Build Coastguard Worker else
4508*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown %s directive on line %d of %s.", line, linenum, filename);
4509*5e7646d2SAndroid Build Coastguard Worker }
4510*5e7646d2SAndroid Build Coastguard Worker
4511*5e7646d2SAndroid Build Coastguard Worker if (job)
4512*5e7646d2SAndroid Build Coastguard Worker {
4513*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
4514*5e7646d2SAndroid Build Coastguard Worker "Missing </Job> directive on line %d of %s.", linenum, filename);
4515*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteJob(job, CUPSD_JOB_PURGE);
4516*5e7646d2SAndroid Build Coastguard Worker }
4517*5e7646d2SAndroid Build Coastguard Worker
4518*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
4519*5e7646d2SAndroid Build Coastguard Worker }
4520*5e7646d2SAndroid Build Coastguard Worker
4521*5e7646d2SAndroid Build Coastguard Worker
4522*5e7646d2SAndroid Build Coastguard Worker /*
4523*5e7646d2SAndroid Build Coastguard Worker * 'load_next_job_id()' - Load the NextJobId value from the job.cache file.
4524*5e7646d2SAndroid Build Coastguard Worker */
4525*5e7646d2SAndroid Build Coastguard Worker
4526*5e7646d2SAndroid Build Coastguard Worker static void
load_next_job_id(const char * filename)4527*5e7646d2SAndroid Build Coastguard Worker load_next_job_id(const char *filename) /* I - job.cache filename */
4528*5e7646d2SAndroid Build Coastguard Worker {
4529*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* job.cache file */
4530*5e7646d2SAndroid Build Coastguard Worker char line[1024], /* Line buffer */
4531*5e7646d2SAndroid Build Coastguard Worker *value; /* Value on line */
4532*5e7646d2SAndroid Build Coastguard Worker int linenum; /* Line number in file */
4533*5e7646d2SAndroid Build Coastguard Worker int next_job_id; /* NextJobId value from line */
4534*5e7646d2SAndroid Build Coastguard Worker
4535*5e7646d2SAndroid Build Coastguard Worker
4536*5e7646d2SAndroid Build Coastguard Worker /*
4537*5e7646d2SAndroid Build Coastguard Worker * Read the NextJobId directive from the job.cache file and use
4538*5e7646d2SAndroid Build Coastguard Worker * the value (if any).
4539*5e7646d2SAndroid Build Coastguard Worker */
4540*5e7646d2SAndroid Build Coastguard Worker
4541*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpen(filename, "r")) == NULL)
4542*5e7646d2SAndroid Build Coastguard Worker {
4543*5e7646d2SAndroid Build Coastguard Worker if (errno != ENOENT)
4544*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
4545*5e7646d2SAndroid Build Coastguard Worker "Unable to open job cache file \"%s\": %s",
4546*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
4547*5e7646d2SAndroid Build Coastguard Worker
4548*5e7646d2SAndroid Build Coastguard Worker return;
4549*5e7646d2SAndroid Build Coastguard Worker }
4550*5e7646d2SAndroid Build Coastguard Worker
4551*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_INFO,
4552*5e7646d2SAndroid Build Coastguard Worker "Loading NextJobId from job cache file \"%s\"...", filename);
4553*5e7646d2SAndroid Build Coastguard Worker
4554*5e7646d2SAndroid Build Coastguard Worker linenum = 0;
4555*5e7646d2SAndroid Build Coastguard Worker
4556*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
4557*5e7646d2SAndroid Build Coastguard Worker {
4558*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(line, "NextJobId"))
4559*5e7646d2SAndroid Build Coastguard Worker {
4560*5e7646d2SAndroid Build Coastguard Worker if (value)
4561*5e7646d2SAndroid Build Coastguard Worker {
4562*5e7646d2SAndroid Build Coastguard Worker next_job_id = atoi(value);
4563*5e7646d2SAndroid Build Coastguard Worker
4564*5e7646d2SAndroid Build Coastguard Worker if (next_job_id > NextJobId)
4565*5e7646d2SAndroid Build Coastguard Worker NextJobId = next_job_id;
4566*5e7646d2SAndroid Build Coastguard Worker }
4567*5e7646d2SAndroid Build Coastguard Worker break;
4568*5e7646d2SAndroid Build Coastguard Worker }
4569*5e7646d2SAndroid Build Coastguard Worker }
4570*5e7646d2SAndroid Build Coastguard Worker
4571*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
4572*5e7646d2SAndroid Build Coastguard Worker }
4573*5e7646d2SAndroid Build Coastguard Worker
4574*5e7646d2SAndroid Build Coastguard Worker
4575*5e7646d2SAndroid Build Coastguard Worker /*
4576*5e7646d2SAndroid Build Coastguard Worker * 'load_request_root()' - Load jobs from the RequestRoot directory.
4577*5e7646d2SAndroid Build Coastguard Worker */
4578*5e7646d2SAndroid Build Coastguard Worker
4579*5e7646d2SAndroid Build Coastguard Worker static void
load_request_root(void)4580*5e7646d2SAndroid Build Coastguard Worker load_request_root(void)
4581*5e7646d2SAndroid Build Coastguard Worker {
4582*5e7646d2SAndroid Build Coastguard Worker cups_dir_t *dir; /* Directory */
4583*5e7646d2SAndroid Build Coastguard Worker cups_dentry_t *dent; /* Directory entry */
4584*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* New job */
4585*5e7646d2SAndroid Build Coastguard Worker
4586*5e7646d2SAndroid Build Coastguard Worker
4587*5e7646d2SAndroid Build Coastguard Worker /*
4588*5e7646d2SAndroid Build Coastguard Worker * Open the requests directory...
4589*5e7646d2SAndroid Build Coastguard Worker */
4590*5e7646d2SAndroid Build Coastguard Worker
4591*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Scanning %s for jobs...", RequestRoot);
4592*5e7646d2SAndroid Build Coastguard Worker
4593*5e7646d2SAndroid Build Coastguard Worker if ((dir = cupsDirOpen(RequestRoot)) == NULL)
4594*5e7646d2SAndroid Build Coastguard Worker {
4595*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
4596*5e7646d2SAndroid Build Coastguard Worker "Unable to open spool directory \"%s\": %s",
4597*5e7646d2SAndroid Build Coastguard Worker RequestRoot, strerror(errno));
4598*5e7646d2SAndroid Build Coastguard Worker return;
4599*5e7646d2SAndroid Build Coastguard Worker }
4600*5e7646d2SAndroid Build Coastguard Worker
4601*5e7646d2SAndroid Build Coastguard Worker /*
4602*5e7646d2SAndroid Build Coastguard Worker * Read all the c##### files...
4603*5e7646d2SAndroid Build Coastguard Worker */
4604*5e7646d2SAndroid Build Coastguard Worker
4605*5e7646d2SAndroid Build Coastguard Worker while ((dent = cupsDirRead(dir)) != NULL)
4606*5e7646d2SAndroid Build Coastguard Worker if (strlen(dent->filename) >= 6 && dent->filename[0] == 'c')
4607*5e7646d2SAndroid Build Coastguard Worker {
4608*5e7646d2SAndroid Build Coastguard Worker /*
4609*5e7646d2SAndroid Build Coastguard Worker * Allocate memory for the job...
4610*5e7646d2SAndroid Build Coastguard Worker */
4611*5e7646d2SAndroid Build Coastguard Worker
4612*5e7646d2SAndroid Build Coastguard Worker if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL)
4613*5e7646d2SAndroid Build Coastguard Worker {
4614*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Ran out of memory for jobs.");
4615*5e7646d2SAndroid Build Coastguard Worker cupsDirClose(dir);
4616*5e7646d2SAndroid Build Coastguard Worker return;
4617*5e7646d2SAndroid Build Coastguard Worker }
4618*5e7646d2SAndroid Build Coastguard Worker
4619*5e7646d2SAndroid Build Coastguard Worker /*
4620*5e7646d2SAndroid Build Coastguard Worker * Assign the job ID...
4621*5e7646d2SAndroid Build Coastguard Worker */
4622*5e7646d2SAndroid Build Coastguard Worker
4623*5e7646d2SAndroid Build Coastguard Worker job->id = atoi(dent->filename + 1);
4624*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[0] = -1;
4625*5e7646d2SAndroid Build Coastguard Worker job->back_pipes[1] = -1;
4626*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[0] = -1;
4627*5e7646d2SAndroid Build Coastguard Worker job->print_pipes[1] = -1;
4628*5e7646d2SAndroid Build Coastguard Worker job->side_pipes[0] = -1;
4629*5e7646d2SAndroid Build Coastguard Worker job->side_pipes[1] = -1;
4630*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[0] = -1;
4631*5e7646d2SAndroid Build Coastguard Worker job->status_pipes[1] = -1;
4632*5e7646d2SAndroid Build Coastguard Worker
4633*5e7646d2SAndroid Build Coastguard Worker if (job->id >= NextJobId)
4634*5e7646d2SAndroid Build Coastguard Worker NextJobId = job->id + 1;
4635*5e7646d2SAndroid Build Coastguard Worker
4636*5e7646d2SAndroid Build Coastguard Worker /*
4637*5e7646d2SAndroid Build Coastguard Worker * Load the job...
4638*5e7646d2SAndroid Build Coastguard Worker */
4639*5e7646d2SAndroid Build Coastguard Worker
4640*5e7646d2SAndroid Build Coastguard Worker if (cupsdLoadJob(job))
4641*5e7646d2SAndroid Build Coastguard Worker {
4642*5e7646d2SAndroid Build Coastguard Worker /*
4643*5e7646d2SAndroid Build Coastguard Worker * Insert the job into the array, sorting by job priority and ID...
4644*5e7646d2SAndroid Build Coastguard Worker */
4645*5e7646d2SAndroid Build Coastguard Worker
4646*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(Jobs, job);
4647*5e7646d2SAndroid Build Coastguard Worker
4648*5e7646d2SAndroid Build Coastguard Worker if (job->state_value <= IPP_JOB_STOPPED)
4649*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ActiveJobs, job);
4650*5e7646d2SAndroid Build Coastguard Worker else
4651*5e7646d2SAndroid Build Coastguard Worker unload_job(job);
4652*5e7646d2SAndroid Build Coastguard Worker }
4653*5e7646d2SAndroid Build Coastguard Worker else
4654*5e7646d2SAndroid Build Coastguard Worker free(job);
4655*5e7646d2SAndroid Build Coastguard Worker }
4656*5e7646d2SAndroid Build Coastguard Worker
4657*5e7646d2SAndroid Build Coastguard Worker cupsDirClose(dir);
4658*5e7646d2SAndroid Build Coastguard Worker }
4659*5e7646d2SAndroid Build Coastguard Worker
4660*5e7646d2SAndroid Build Coastguard Worker
4661*5e7646d2SAndroid Build Coastguard Worker /*
4662*5e7646d2SAndroid Build Coastguard Worker * 'remove_job_files()' - Remove the document files for a job.
4663*5e7646d2SAndroid Build Coastguard Worker */
4664*5e7646d2SAndroid Build Coastguard Worker
4665*5e7646d2SAndroid Build Coastguard Worker static void
remove_job_files(cupsd_job_t * job)4666*5e7646d2SAndroid Build Coastguard Worker remove_job_files(cupsd_job_t *job) /* I - Job */
4667*5e7646d2SAndroid Build Coastguard Worker {
4668*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
4669*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Document filename */
4670*5e7646d2SAndroid Build Coastguard Worker
4671*5e7646d2SAndroid Build Coastguard Worker
4672*5e7646d2SAndroid Build Coastguard Worker if (job->num_files <= 0)
4673*5e7646d2SAndroid Build Coastguard Worker return;
4674*5e7646d2SAndroid Build Coastguard Worker
4675*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i <= job->num_files; i ++)
4676*5e7646d2SAndroid Build Coastguard Worker {
4677*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
4678*5e7646d2SAndroid Build Coastguard Worker job->id, i);
4679*5e7646d2SAndroid Build Coastguard Worker cupsdUnlinkOrRemoveFile(filename);
4680*5e7646d2SAndroid Build Coastguard Worker }
4681*5e7646d2SAndroid Build Coastguard Worker
4682*5e7646d2SAndroid Build Coastguard Worker free(job->filetypes);
4683*5e7646d2SAndroid Build Coastguard Worker free(job->compressions);
4684*5e7646d2SAndroid Build Coastguard Worker
4685*5e7646d2SAndroid Build Coastguard Worker job->file_time = 0;
4686*5e7646d2SAndroid Build Coastguard Worker job->num_files = 0;
4687*5e7646d2SAndroid Build Coastguard Worker job->filetypes = NULL;
4688*5e7646d2SAndroid Build Coastguard Worker job->compressions = NULL;
4689*5e7646d2SAndroid Build Coastguard Worker
4690*5e7646d2SAndroid Build Coastguard Worker LastEvent |= CUPSD_EVENT_PRINTER_STATE_CHANGED;
4691*5e7646d2SAndroid Build Coastguard Worker }
4692*5e7646d2SAndroid Build Coastguard Worker
4693*5e7646d2SAndroid Build Coastguard Worker
4694*5e7646d2SAndroid Build Coastguard Worker /*
4695*5e7646d2SAndroid Build Coastguard Worker * 'remove_job_history()' - Remove the control file for a job.
4696*5e7646d2SAndroid Build Coastguard Worker */
4697*5e7646d2SAndroid Build Coastguard Worker
4698*5e7646d2SAndroid Build Coastguard Worker static void
remove_job_history(cupsd_job_t * job)4699*5e7646d2SAndroid Build Coastguard Worker remove_job_history(cupsd_job_t *job) /* I - Job */
4700*5e7646d2SAndroid Build Coastguard Worker {
4701*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Control filename */
4702*5e7646d2SAndroid Build Coastguard Worker
4703*5e7646d2SAndroid Build Coastguard Worker
4704*5e7646d2SAndroid Build Coastguard Worker /*
4705*5e7646d2SAndroid Build Coastguard Worker * Remove the job info file...
4706*5e7646d2SAndroid Build Coastguard Worker */
4707*5e7646d2SAndroid Build Coastguard Worker
4708*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot,
4709*5e7646d2SAndroid Build Coastguard Worker job->id);
4710*5e7646d2SAndroid Build Coastguard Worker cupsdUnlinkOrRemoveFile(filename);
4711*5e7646d2SAndroid Build Coastguard Worker
4712*5e7646d2SAndroid Build Coastguard Worker LastEvent |= CUPSD_EVENT_PRINTER_STATE_CHANGED;
4713*5e7646d2SAndroid Build Coastguard Worker }
4714*5e7646d2SAndroid Build Coastguard Worker
4715*5e7646d2SAndroid Build Coastguard Worker
4716*5e7646d2SAndroid Build Coastguard Worker /*
4717*5e7646d2SAndroid Build Coastguard Worker * 'set_time()' - Set one of the "time-at-xyz" attributes.
4718*5e7646d2SAndroid Build Coastguard Worker */
4719*5e7646d2SAndroid Build Coastguard Worker
4720*5e7646d2SAndroid Build Coastguard Worker static void
set_time(cupsd_job_t * job,const char * name)4721*5e7646d2SAndroid Build Coastguard Worker set_time(cupsd_job_t *job, /* I - Job to update */
4722*5e7646d2SAndroid Build Coastguard Worker const char *name) /* I - Name of attribute */
4723*5e7646d2SAndroid Build Coastguard Worker {
4724*5e7646d2SAndroid Build Coastguard Worker char date_name[128]; /* date-time-at-xxx */
4725*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Time attribute */
4726*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time */
4727*5e7646d2SAndroid Build Coastguard Worker
4728*5e7646d2SAndroid Build Coastguard Worker
4729*5e7646d2SAndroid Build Coastguard Worker curtime = time(NULL);
4730*5e7646d2SAndroid Build Coastguard Worker
4731*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s=%ld", name, (long)curtime);
4732*5e7646d2SAndroid Build Coastguard Worker
4733*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, name, IPP_TAG_ZERO)) != NULL)
4734*5e7646d2SAndroid Build Coastguard Worker {
4735*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = IPP_TAG_INTEGER;
4736*5e7646d2SAndroid Build Coastguard Worker attr->values[0].integer = curtime;
4737*5e7646d2SAndroid Build Coastguard Worker }
4738*5e7646d2SAndroid Build Coastguard Worker
4739*5e7646d2SAndroid Build Coastguard Worker snprintf(date_name, sizeof(date_name), "date-%s", name);
4740*5e7646d2SAndroid Build Coastguard Worker
4741*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job->attrs, date_name, IPP_TAG_ZERO)) != NULL)
4742*5e7646d2SAndroid Build Coastguard Worker {
4743*5e7646d2SAndroid Build Coastguard Worker attr->value_tag = IPP_TAG_DATE;
4744*5e7646d2SAndroid Build Coastguard Worker ippSetDate(job->attrs, &attr, 0, ippTimeToDate(curtime));
4745*5e7646d2SAndroid Build Coastguard Worker }
4746*5e7646d2SAndroid Build Coastguard Worker
4747*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(name, "time-at-completed"))
4748*5e7646d2SAndroid Build Coastguard Worker {
4749*5e7646d2SAndroid Build Coastguard Worker job->completed_time = curtime;
4750*5e7646d2SAndroid Build Coastguard Worker
4751*5e7646d2SAndroid Build Coastguard Worker if (JobHistory < INT_MAX && attr)
4752*5e7646d2SAndroid Build Coastguard Worker job->history_time = job->completed_time + JobHistory;
4753*5e7646d2SAndroid Build Coastguard Worker else
4754*5e7646d2SAndroid Build Coastguard Worker job->history_time = INT_MAX;
4755*5e7646d2SAndroid Build Coastguard Worker
4756*5e7646d2SAndroid Build Coastguard Worker if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
4757*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->history_time;
4758*5e7646d2SAndroid Build Coastguard Worker
4759*5e7646d2SAndroid Build Coastguard Worker if (JobFiles < INT_MAX && attr)
4760*5e7646d2SAndroid Build Coastguard Worker job->file_time = job->completed_time + JobFiles;
4761*5e7646d2SAndroid Build Coastguard Worker else
4762*5e7646d2SAndroid Build Coastguard Worker job->file_time = INT_MAX;
4763*5e7646d2SAndroid Build Coastguard Worker
4764*5e7646d2SAndroid Build Coastguard Worker if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
4765*5e7646d2SAndroid Build Coastguard Worker JobHistoryUpdate = job->file_time;
4766*5e7646d2SAndroid Build Coastguard Worker
4767*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_time: JobHistoryUpdate=%ld",
4768*5e7646d2SAndroid Build Coastguard Worker (long)JobHistoryUpdate);
4769*5e7646d2SAndroid Build Coastguard Worker }
4770*5e7646d2SAndroid Build Coastguard Worker }
4771*5e7646d2SAndroid Build Coastguard Worker
4772*5e7646d2SAndroid Build Coastguard Worker
4773*5e7646d2SAndroid Build Coastguard Worker /*
4774*5e7646d2SAndroid Build Coastguard Worker * 'start_job()' - Start a print job.
4775*5e7646d2SAndroid Build Coastguard Worker */
4776*5e7646d2SAndroid Build Coastguard Worker
4777*5e7646d2SAndroid Build Coastguard Worker static void
start_job(cupsd_job_t * job,cupsd_printer_t * printer)4778*5e7646d2SAndroid Build Coastguard Worker start_job(cupsd_job_t *job, /* I - Job ID */
4779*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *printer) /* I - Printer to print job */
4780*5e7646d2SAndroid Build Coastguard Worker {
4781*5e7646d2SAndroid Build Coastguard Worker const char *filename; /* Support filename */
4782*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
4783*5e7646d2SAndroid Build Coastguard Worker "job-cancel-after",
4784*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_INTEGER);
4785*5e7646d2SAndroid Build Coastguard Worker /* job-cancel-after attribute */
4786*5e7646d2SAndroid Build Coastguard Worker
4787*5e7646d2SAndroid Build Coastguard Worker
4788*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))",
4789*5e7646d2SAndroid Build Coastguard Worker job, job->id, printer, printer->name);
4790*5e7646d2SAndroid Build Coastguard Worker
4791*5e7646d2SAndroid Build Coastguard Worker /*
4792*5e7646d2SAndroid Build Coastguard Worker * Make sure we have some files around before we try to print...
4793*5e7646d2SAndroid Build Coastguard Worker */
4794*5e7646d2SAndroid Build Coastguard Worker
4795*5e7646d2SAndroid Build Coastguard Worker if (job->num_files == 0)
4796*5e7646d2SAndroid Build Coastguard Worker {
4797*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
4798*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT,
4799*5e7646d2SAndroid Build Coastguard Worker "Aborting job because it has no files.");
4800*5e7646d2SAndroid Build Coastguard Worker return;
4801*5e7646d2SAndroid Build Coastguard Worker }
4802*5e7646d2SAndroid Build Coastguard Worker
4803*5e7646d2SAndroid Build Coastguard Worker /*
4804*5e7646d2SAndroid Build Coastguard Worker * Update the printer and job state to "processing"...
4805*5e7646d2SAndroid Build Coastguard Worker */
4806*5e7646d2SAndroid Build Coastguard Worker
4807*5e7646d2SAndroid Build Coastguard Worker if (!cupsdLoadJob(job))
4808*5e7646d2SAndroid Build Coastguard Worker return;
4809*5e7646d2SAndroid Build Coastguard Worker
4810*5e7646d2SAndroid Build Coastguard Worker if (!job->printer_message)
4811*5e7646d2SAndroid Build Coastguard Worker job->printer_message = ippFindAttribute(job->attrs,
4812*5e7646d2SAndroid Build Coastguard Worker "job-printer-state-message",
4813*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_TEXT);
4814*5e7646d2SAndroid Build Coastguard Worker if (job->printer_message)
4815*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->printer_message, 0, "");
4816*5e7646d2SAndroid Build Coastguard Worker
4817*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, "job-printing");
4818*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
4819*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterState(printer, IPP_PRINTER_PROCESSING, 0);
4820*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterReasons(printer, "-cups-remote-pending,"
4821*5e7646d2SAndroid Build Coastguard Worker "cups-remote-pending-held,"
4822*5e7646d2SAndroid Build Coastguard Worker "cups-remote-processing,"
4823*5e7646d2SAndroid Build Coastguard Worker "cups-remote-stopped,"
4824*5e7646d2SAndroid Build Coastguard Worker "cups-remote-canceled,"
4825*5e7646d2SAndroid Build Coastguard Worker "cups-remote-aborted,"
4826*5e7646d2SAndroid Build Coastguard Worker "cups-remote-completed");
4827*5e7646d2SAndroid Build Coastguard Worker
4828*5e7646d2SAndroid Build Coastguard Worker job->cost = 0;
4829*5e7646d2SAndroid Build Coastguard Worker job->current_file = 0;
4830*5e7646d2SAndroid Build Coastguard Worker job->file_time = 0;
4831*5e7646d2SAndroid Build Coastguard Worker job->history_time = 0;
4832*5e7646d2SAndroid Build Coastguard Worker job->progress = 0;
4833*5e7646d2SAndroid Build Coastguard Worker job->printer = printer;
4834*5e7646d2SAndroid Build Coastguard Worker printer->job = job;
4835*5e7646d2SAndroid Build Coastguard Worker
4836*5e7646d2SAndroid Build Coastguard Worker if (cancel_after)
4837*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
4838*5e7646d2SAndroid Build Coastguard Worker else if (MaxJobTime > 0)
4839*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + MaxJobTime;
4840*5e7646d2SAndroid Build Coastguard Worker else
4841*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = 0;
4842*5e7646d2SAndroid Build Coastguard Worker
4843*5e7646d2SAndroid Build Coastguard Worker /*
4844*5e7646d2SAndroid Build Coastguard Worker * Check for support files...
4845*5e7646d2SAndroid Build Coastguard Worker */
4846*5e7646d2SAndroid Build Coastguard Worker
4847*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterReasons(job->printer, "-cups-missing-filter-warning,"
4848*5e7646d2SAndroid Build Coastguard Worker "cups-insecure-filter-warning");
4849*5e7646d2SAndroid Build Coastguard Worker
4850*5e7646d2SAndroid Build Coastguard Worker if (printer->pc)
4851*5e7646d2SAndroid Build Coastguard Worker {
4852*5e7646d2SAndroid Build Coastguard Worker for (filename = (const char *)cupsArrayFirst(printer->pc->support_files);
4853*5e7646d2SAndroid Build Coastguard Worker filename;
4854*5e7646d2SAndroid Build Coastguard Worker filename = (const char *)cupsArrayNext(printer->pc->support_files))
4855*5e7646d2SAndroid Build Coastguard Worker {
4856*5e7646d2SAndroid Build Coastguard Worker if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_FILE, !RunUser,
4857*5e7646d2SAndroid Build Coastguard Worker cupsdLogFCMessage, printer))
4858*5e7646d2SAndroid Build Coastguard Worker break;
4859*5e7646d2SAndroid Build Coastguard Worker }
4860*5e7646d2SAndroid Build Coastguard Worker }
4861*5e7646d2SAndroid Build Coastguard Worker
4862*5e7646d2SAndroid Build Coastguard Worker /*
4863*5e7646d2SAndroid Build Coastguard Worker * Setup the last exit status and security profiles...
4864*5e7646d2SAndroid Build Coastguard Worker */
4865*5e7646d2SAndroid Build Coastguard Worker
4866*5e7646d2SAndroid Build Coastguard Worker job->status = 0;
4867*5e7646d2SAndroid Build Coastguard Worker job->profile = cupsdCreateProfile(job->id, 0);
4868*5e7646d2SAndroid Build Coastguard Worker job->bprofile = cupsdCreateProfile(job->id, 1);
4869*5e7646d2SAndroid Build Coastguard Worker
4870*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SANDBOX_H
4871*5e7646d2SAndroid Build Coastguard Worker if ((!job->profile || !job->bprofile) && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF)
4872*5e7646d2SAndroid Build Coastguard Worker {
4873*5e7646d2SAndroid Build Coastguard Worker /*
4874*5e7646d2SAndroid Build Coastguard Worker * Failure to create the sandbox profile means something really bad has
4875*5e7646d2SAndroid Build Coastguard Worker * happened and we need to shutdown immediately.
4876*5e7646d2SAndroid Build Coastguard Worker */
4877*5e7646d2SAndroid Build Coastguard Worker
4878*5e7646d2SAndroid Build Coastguard Worker return;
4879*5e7646d2SAndroid Build Coastguard Worker }
4880*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SANDBOX_H */
4881*5e7646d2SAndroid Build Coastguard Worker
4882*5e7646d2SAndroid Build Coastguard Worker /*
4883*5e7646d2SAndroid Build Coastguard Worker * Create the status pipes and buffer...
4884*5e7646d2SAndroid Build Coastguard Worker */
4885*5e7646d2SAndroid Build Coastguard Worker
4886*5e7646d2SAndroid Build Coastguard Worker if (cupsdOpenPipe(job->status_pipes))
4887*5e7646d2SAndroid Build Coastguard Worker {
4888*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
4889*5e7646d2SAndroid Build Coastguard Worker "Unable to create job status pipes - %s.", strerror(errno));
4890*5e7646d2SAndroid Build Coastguard Worker
4891*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT,
4892*5e7646d2SAndroid Build Coastguard Worker "Job stopped because the scheduler could not create the "
4893*5e7646d2SAndroid Build Coastguard Worker "job status pipes.");
4894*5e7646d2SAndroid Build Coastguard Worker
4895*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->profile);
4896*5e7646d2SAndroid Build Coastguard Worker job->profile = NULL;
4897*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->bprofile);
4898*5e7646d2SAndroid Build Coastguard Worker job->bprofile = NULL;
4899*5e7646d2SAndroid Build Coastguard Worker return;
4900*5e7646d2SAndroid Build Coastguard Worker }
4901*5e7646d2SAndroid Build Coastguard Worker
4902*5e7646d2SAndroid Build Coastguard Worker job->status_buffer = cupsdStatBufNew(job->status_pipes[0], NULL);
4903*5e7646d2SAndroid Build Coastguard Worker job->status_level = CUPSD_LOG_INFO;
4904*5e7646d2SAndroid Build Coastguard Worker
4905*5e7646d2SAndroid Build Coastguard Worker /*
4906*5e7646d2SAndroid Build Coastguard Worker * Create the backchannel pipes and make them non-blocking...
4907*5e7646d2SAndroid Build Coastguard Worker */
4908*5e7646d2SAndroid Build Coastguard Worker
4909*5e7646d2SAndroid Build Coastguard Worker if (cupsdOpenPipe(job->back_pipes))
4910*5e7646d2SAndroid Build Coastguard Worker {
4911*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
4912*5e7646d2SAndroid Build Coastguard Worker "Unable to create back-channel pipes - %s.", strerror(errno));
4913*5e7646d2SAndroid Build Coastguard Worker
4914*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT,
4915*5e7646d2SAndroid Build Coastguard Worker "Job stopped because the scheduler could not create the "
4916*5e7646d2SAndroid Build Coastguard Worker "back-channel pipes.");
4917*5e7646d2SAndroid Build Coastguard Worker
4918*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->status_pipes);
4919*5e7646d2SAndroid Build Coastguard Worker cupsdStatBufDelete(job->status_buffer);
4920*5e7646d2SAndroid Build Coastguard Worker job->status_buffer = NULL;
4921*5e7646d2SAndroid Build Coastguard Worker
4922*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->profile);
4923*5e7646d2SAndroid Build Coastguard Worker job->profile = NULL;
4924*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->bprofile);
4925*5e7646d2SAndroid Build Coastguard Worker job->bprofile = NULL;
4926*5e7646d2SAndroid Build Coastguard Worker return;
4927*5e7646d2SAndroid Build Coastguard Worker }
4928*5e7646d2SAndroid Build Coastguard Worker
4929*5e7646d2SAndroid Build Coastguard Worker fcntl(job->back_pipes[0], F_SETFL,
4930*5e7646d2SAndroid Build Coastguard Worker fcntl(job->back_pipes[0], F_GETFL) | O_NONBLOCK);
4931*5e7646d2SAndroid Build Coastguard Worker fcntl(job->back_pipes[1], F_SETFL,
4932*5e7646d2SAndroid Build Coastguard Worker fcntl(job->back_pipes[1], F_GETFL) | O_NONBLOCK);
4933*5e7646d2SAndroid Build Coastguard Worker
4934*5e7646d2SAndroid Build Coastguard Worker /*
4935*5e7646d2SAndroid Build Coastguard Worker * Create the side-channel pipes and make them non-blocking...
4936*5e7646d2SAndroid Build Coastguard Worker */
4937*5e7646d2SAndroid Build Coastguard Worker
4938*5e7646d2SAndroid Build Coastguard Worker if (socketpair(AF_LOCAL, SOCK_STREAM, 0, job->side_pipes))
4939*5e7646d2SAndroid Build Coastguard Worker {
4940*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
4941*5e7646d2SAndroid Build Coastguard Worker "Unable to create side-channel pipes - %s.", strerror(errno));
4942*5e7646d2SAndroid Build Coastguard Worker
4943*5e7646d2SAndroid Build Coastguard Worker cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT,
4944*5e7646d2SAndroid Build Coastguard Worker "Job stopped because the scheduler could not create the "
4945*5e7646d2SAndroid Build Coastguard Worker "side-channel pipes.");
4946*5e7646d2SAndroid Build Coastguard Worker
4947*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->back_pipes);
4948*5e7646d2SAndroid Build Coastguard Worker
4949*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(job->status_pipes);
4950*5e7646d2SAndroid Build Coastguard Worker cupsdStatBufDelete(job->status_buffer);
4951*5e7646d2SAndroid Build Coastguard Worker job->status_buffer = NULL;
4952*5e7646d2SAndroid Build Coastguard Worker
4953*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->profile);
4954*5e7646d2SAndroid Build Coastguard Worker job->profile = NULL;
4955*5e7646d2SAndroid Build Coastguard Worker cupsdDestroyProfile(job->bprofile);
4956*5e7646d2SAndroid Build Coastguard Worker job->bprofile = NULL;
4957*5e7646d2SAndroid Build Coastguard Worker return;
4958*5e7646d2SAndroid Build Coastguard Worker }
4959*5e7646d2SAndroid Build Coastguard Worker
4960*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[0], F_SETFL,
4961*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[0], F_GETFL) | O_NONBLOCK);
4962*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[1], F_SETFL,
4963*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[1], F_GETFL) | O_NONBLOCK);
4964*5e7646d2SAndroid Build Coastguard Worker
4965*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[0], F_SETFD,
4966*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[0], F_GETFD) | FD_CLOEXEC);
4967*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[1], F_SETFD,
4968*5e7646d2SAndroid Build Coastguard Worker fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC);
4969*5e7646d2SAndroid Build Coastguard Worker
4970*5e7646d2SAndroid Build Coastguard Worker /*
4971*5e7646d2SAndroid Build Coastguard Worker * Now start the first file in the job...
4972*5e7646d2SAndroid Build Coastguard Worker */
4973*5e7646d2SAndroid Build Coastguard Worker
4974*5e7646d2SAndroid Build Coastguard Worker cupsdContinueJob(job);
4975*5e7646d2SAndroid Build Coastguard Worker }
4976*5e7646d2SAndroid Build Coastguard Worker
4977*5e7646d2SAndroid Build Coastguard Worker
4978*5e7646d2SAndroid Build Coastguard Worker /*
4979*5e7646d2SAndroid Build Coastguard Worker * 'stop_job()' - Stop a print job.
4980*5e7646d2SAndroid Build Coastguard Worker */
4981*5e7646d2SAndroid Build Coastguard Worker
4982*5e7646d2SAndroid Build Coastguard Worker static void
stop_job(cupsd_job_t * job,cupsd_jobaction_t action)4983*5e7646d2SAndroid Build Coastguard Worker stop_job(cupsd_job_t *job, /* I - Job */
4984*5e7646d2SAndroid Build Coastguard Worker cupsd_jobaction_t action) /* I - Action */
4985*5e7646d2SAndroid Build Coastguard Worker {
4986*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
4987*5e7646d2SAndroid Build Coastguard Worker
4988*5e7646d2SAndroid Build Coastguard Worker
4989*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_job(job=%p(%d), action=%d)", job,
4990*5e7646d2SAndroid Build Coastguard Worker job->id, action);
4991*5e7646d2SAndroid Build Coastguard Worker
4992*5e7646d2SAndroid Build Coastguard Worker FilterLevel -= job->cost;
4993*5e7646d2SAndroid Build Coastguard Worker job->cost = 0;
4994*5e7646d2SAndroid Build Coastguard Worker
4995*5e7646d2SAndroid Build Coastguard Worker if (action == CUPSD_JOB_DEFAULT && !job->kill_time && job->backend > 0)
4996*5e7646d2SAndroid Build Coastguard Worker job->kill_time = time(NULL) + JobKillDelay;
4997*5e7646d2SAndroid Build Coastguard Worker else if (action >= CUPSD_JOB_FORCE)
4998*5e7646d2SAndroid Build Coastguard Worker job->kill_time = 0;
4999*5e7646d2SAndroid Build Coastguard Worker
5000*5e7646d2SAndroid Build Coastguard Worker for (i = 0; job->filters[i]; i ++)
5001*5e7646d2SAndroid Build Coastguard Worker if (job->filters[i] > 0)
5002*5e7646d2SAndroid Build Coastguard Worker {
5003*5e7646d2SAndroid Build Coastguard Worker cupsdEndProcess(job->filters[i], action >= CUPSD_JOB_FORCE);
5004*5e7646d2SAndroid Build Coastguard Worker
5005*5e7646d2SAndroid Build Coastguard Worker if (action >= CUPSD_JOB_FORCE)
5006*5e7646d2SAndroid Build Coastguard Worker job->filters[i] = -job->filters[i];
5007*5e7646d2SAndroid Build Coastguard Worker }
5008*5e7646d2SAndroid Build Coastguard Worker
5009*5e7646d2SAndroid Build Coastguard Worker if (job->backend > 0)
5010*5e7646d2SAndroid Build Coastguard Worker {
5011*5e7646d2SAndroid Build Coastguard Worker cupsdEndProcess(job->backend, action >= CUPSD_JOB_FORCE);
5012*5e7646d2SAndroid Build Coastguard Worker
5013*5e7646d2SAndroid Build Coastguard Worker if (action >= CUPSD_JOB_FORCE)
5014*5e7646d2SAndroid Build Coastguard Worker job->backend = -job->backend;
5015*5e7646d2SAndroid Build Coastguard Worker }
5016*5e7646d2SAndroid Build Coastguard Worker
5017*5e7646d2SAndroid Build Coastguard Worker if (action >= CUPSD_JOB_FORCE)
5018*5e7646d2SAndroid Build Coastguard Worker {
5019*5e7646d2SAndroid Build Coastguard Worker /*
5020*5e7646d2SAndroid Build Coastguard Worker * Clear job status...
5021*5e7646d2SAndroid Build Coastguard Worker */
5022*5e7646d2SAndroid Build Coastguard Worker
5023*5e7646d2SAndroid Build Coastguard Worker job->status = 0;
5024*5e7646d2SAndroid Build Coastguard Worker }
5025*5e7646d2SAndroid Build Coastguard Worker }
5026*5e7646d2SAndroid Build Coastguard Worker
5027*5e7646d2SAndroid Build Coastguard Worker
5028*5e7646d2SAndroid Build Coastguard Worker /*
5029*5e7646d2SAndroid Build Coastguard Worker * 'unload_job()' - Unload a job from memory.
5030*5e7646d2SAndroid Build Coastguard Worker */
5031*5e7646d2SAndroid Build Coastguard Worker
5032*5e7646d2SAndroid Build Coastguard Worker static void
unload_job(cupsd_job_t * job)5033*5e7646d2SAndroid Build Coastguard Worker unload_job(cupsd_job_t *job) /* I - Job */
5034*5e7646d2SAndroid Build Coastguard Worker {
5035*5e7646d2SAndroid Build Coastguard Worker if (!job->attrs)
5036*5e7646d2SAndroid Build Coastguard Worker return;
5037*5e7646d2SAndroid Build Coastguard Worker
5038*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "Unloading...");
5039*5e7646d2SAndroid Build Coastguard Worker
5040*5e7646d2SAndroid Build Coastguard Worker ippDelete(job->attrs);
5041*5e7646d2SAndroid Build Coastguard Worker
5042*5e7646d2SAndroid Build Coastguard Worker job->attrs = NULL;
5043*5e7646d2SAndroid Build Coastguard Worker job->state = NULL;
5044*5e7646d2SAndroid Build Coastguard Worker job->reasons = NULL;
5045*5e7646d2SAndroid Build Coastguard Worker job->impressions = NULL;
5046*5e7646d2SAndroid Build Coastguard Worker job->sheets = NULL;
5047*5e7646d2SAndroid Build Coastguard Worker job->job_sheets = NULL;
5048*5e7646d2SAndroid Build Coastguard Worker job->printer_message = NULL;
5049*5e7646d2SAndroid Build Coastguard Worker job->printer_reasons = NULL;
5050*5e7646d2SAndroid Build Coastguard Worker }
5051*5e7646d2SAndroid Build Coastguard Worker
5052*5e7646d2SAndroid Build Coastguard Worker
5053*5e7646d2SAndroid Build Coastguard Worker /*
5054*5e7646d2SAndroid Build Coastguard Worker * 'update_job()' - Read a status update from a job's filters.
5055*5e7646d2SAndroid Build Coastguard Worker */
5056*5e7646d2SAndroid Build Coastguard Worker
5057*5e7646d2SAndroid Build Coastguard Worker void
update_job(cupsd_job_t * job)5058*5e7646d2SAndroid Build Coastguard Worker update_job(cupsd_job_t *job) /* I - Job to check */
5059*5e7646d2SAndroid Build Coastguard Worker {
5060*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
5061*5e7646d2SAndroid Build Coastguard Worker char message[CUPSD_SB_BUFFER_SIZE],
5062*5e7646d2SAndroid Build Coastguard Worker /* Message text */
5063*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer update... */
5064*5e7646d2SAndroid Build Coastguard Worker int loglevel, /* Log level for message */
5065*5e7646d2SAndroid Build Coastguard Worker event = 0; /* Events? */
5066*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *printer = job->printer;
5067*5e7646d2SAndroid Build Coastguard Worker /* Printer */
5068*5e7646d2SAndroid Build Coastguard Worker static const char * const levels[] = /* Log levels */
5069*5e7646d2SAndroid Build Coastguard Worker {
5070*5e7646d2SAndroid Build Coastguard Worker "NONE",
5071*5e7646d2SAndroid Build Coastguard Worker "EMERG",
5072*5e7646d2SAndroid Build Coastguard Worker "ALERT",
5073*5e7646d2SAndroid Build Coastguard Worker "CRIT",
5074*5e7646d2SAndroid Build Coastguard Worker "ERROR",
5075*5e7646d2SAndroid Build Coastguard Worker "WARN",
5076*5e7646d2SAndroid Build Coastguard Worker "NOTICE",
5077*5e7646d2SAndroid Build Coastguard Worker "INFO",
5078*5e7646d2SAndroid Build Coastguard Worker "DEBUG",
5079*5e7646d2SAndroid Build Coastguard Worker "DEBUG2"
5080*5e7646d2SAndroid Build Coastguard Worker };
5081*5e7646d2SAndroid Build Coastguard Worker
5082*5e7646d2SAndroid Build Coastguard Worker
5083*5e7646d2SAndroid Build Coastguard Worker /*
5084*5e7646d2SAndroid Build Coastguard Worker * Get the printer associated with this job; if the printer is stopped for
5085*5e7646d2SAndroid Build Coastguard Worker * any reason then job->printer will be reset to NULL, so make sure we have
5086*5e7646d2SAndroid Build Coastguard Worker * a valid pointer...
5087*5e7646d2SAndroid Build Coastguard Worker */
5088*5e7646d2SAndroid Build Coastguard Worker
5089*5e7646d2SAndroid Build Coastguard Worker while ((ptr = cupsdStatBufUpdate(job->status_buffer, &loglevel,
5090*5e7646d2SAndroid Build Coastguard Worker message, sizeof(message))) != NULL)
5091*5e7646d2SAndroid Build Coastguard Worker {
5092*5e7646d2SAndroid Build Coastguard Worker /*
5093*5e7646d2SAndroid Build Coastguard Worker * Process page and printer state messages as needed...
5094*5e7646d2SAndroid Build Coastguard Worker */
5095*5e7646d2SAndroid Build Coastguard Worker
5096*5e7646d2SAndroid Build Coastguard Worker if (loglevel == CUPSD_LOG_PAGE)
5097*5e7646d2SAndroid Build Coastguard Worker {
5098*5e7646d2SAndroid Build Coastguard Worker int impressions = ippGetInteger(job->impressions, 0);
5099*5e7646d2SAndroid Build Coastguard Worker /* Number of impressions printed */
5100*5e7646d2SAndroid Build Coastguard Worker int delta; /* Number of impressions added */
5101*5e7646d2SAndroid Build Coastguard Worker
5102*5e7646d2SAndroid Build Coastguard Worker /*
5103*5e7646d2SAndroid Build Coastguard Worker * Page message; send the message to the page_log file and update the
5104*5e7646d2SAndroid Build Coastguard Worker * job sheet count...
5105*5e7646d2SAndroid Build Coastguard Worker */
5106*5e7646d2SAndroid Build Coastguard Worker
5107*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "PAGE: %s", message);
5108*5e7646d2SAndroid Build Coastguard Worker
5109*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(message, "total ", 6))
5110*5e7646d2SAndroid Build Coastguard Worker {
5111*5e7646d2SAndroid Build Coastguard Worker /*
5112*5e7646d2SAndroid Build Coastguard Worker * Got a total count of pages from a backend or filter...
5113*5e7646d2SAndroid Build Coastguard Worker */
5114*5e7646d2SAndroid Build Coastguard Worker
5115*5e7646d2SAndroid Build Coastguard Worker int total = atoi(message + 6); /* Total impressions */
5116*5e7646d2SAndroid Build Coastguard Worker
5117*5e7646d2SAndroid Build Coastguard Worker if (total > impressions)
5118*5e7646d2SAndroid Build Coastguard Worker {
5119*5e7646d2SAndroid Build Coastguard Worker delta = total - impressions;
5120*5e7646d2SAndroid Build Coastguard Worker impressions = total;
5121*5e7646d2SAndroid Build Coastguard Worker }
5122*5e7646d2SAndroid Build Coastguard Worker else
5123*5e7646d2SAndroid Build Coastguard Worker delta = 0;
5124*5e7646d2SAndroid Build Coastguard Worker }
5125*5e7646d2SAndroid Build Coastguard Worker else
5126*5e7646d2SAndroid Build Coastguard Worker {
5127*5e7646d2SAndroid Build Coastguard Worker /*
5128*5e7646d2SAndroid Build Coastguard Worker * Add the number of copies to the impression count...
5129*5e7646d2SAndroid Build Coastguard Worker */
5130*5e7646d2SAndroid Build Coastguard Worker
5131*5e7646d2SAndroid Build Coastguard Worker int copies; /* Number of copies */
5132*5e7646d2SAndroid Build Coastguard Worker
5133*5e7646d2SAndroid Build Coastguard Worker if (!sscanf(message, "%*d%d", &copies) || copies <= 0)
5134*5e7646d2SAndroid Build Coastguard Worker copies = 1;
5135*5e7646d2SAndroid Build Coastguard Worker
5136*5e7646d2SAndroid Build Coastguard Worker delta = copies;
5137*5e7646d2SAndroid Build Coastguard Worker impressions += copies;
5138*5e7646d2SAndroid Build Coastguard Worker }
5139*5e7646d2SAndroid Build Coastguard Worker
5140*5e7646d2SAndroid Build Coastguard Worker if (job->impressions)
5141*5e7646d2SAndroid Build Coastguard Worker ippSetInteger(job->attrs, &job->impressions, 0, impressions);
5142*5e7646d2SAndroid Build Coastguard Worker
5143*5e7646d2SAndroid Build Coastguard Worker if (job->sheets)
5144*5e7646d2SAndroid Build Coastguard Worker {
5145*5e7646d2SAndroid Build Coastguard Worker const char *sides = ippGetString(ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD), 0, NULL);
5146*5e7646d2SAndroid Build Coastguard Worker
5147*5e7646d2SAndroid Build Coastguard Worker if (sides && strcmp(sides, "one-sided"))
5148*5e7646d2SAndroid Build Coastguard Worker ippSetInteger(job->attrs, &job->sheets, 0, impressions / 2);
5149*5e7646d2SAndroid Build Coastguard Worker else
5150*5e7646d2SAndroid Build Coastguard Worker ippSetInteger(job->attrs, &job->sheets, 0, impressions);
5151*5e7646d2SAndroid Build Coastguard Worker
5152*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, "Printed %d page(s).", ippGetInteger(job->sheets, 0));
5153*5e7646d2SAndroid Build Coastguard Worker }
5154*5e7646d2SAndroid Build Coastguard Worker
5155*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
5156*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
5157*5e7646d2SAndroid Build Coastguard Worker
5158*5e7646d2SAndroid Build Coastguard Worker if (job->printer->page_limit)
5159*5e7646d2SAndroid Build Coastguard Worker cupsdUpdateQuota(job->printer, job->username, delta, 0);
5160*5e7646d2SAndroid Build Coastguard Worker }
5161*5e7646d2SAndroid Build Coastguard Worker else if (loglevel == CUPSD_LOG_JOBSTATE)
5162*5e7646d2SAndroid Build Coastguard Worker {
5163*5e7646d2SAndroid Build Coastguard Worker /*
5164*5e7646d2SAndroid Build Coastguard Worker * Support "keyword" to set job-state-reasons to the specified keyword.
5165*5e7646d2SAndroid Build Coastguard Worker * This is sufficient for the current paid printing stuff.
5166*5e7646d2SAndroid Build Coastguard Worker */
5167*5e7646d2SAndroid Build Coastguard Worker
5168*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "JOBSTATE: %s", message);
5169*5e7646d2SAndroid Build Coastguard Worker
5170*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(message, "cups-retry-as-raster"))
5171*5e7646d2SAndroid Build Coastguard Worker job->retry_as_raster = 1;
5172*5e7646d2SAndroid Build Coastguard Worker else
5173*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->reasons, 0, message);
5174*5e7646d2SAndroid Build Coastguard Worker }
5175*5e7646d2SAndroid Build Coastguard Worker else if (loglevel == CUPSD_LOG_STATE)
5176*5e7646d2SAndroid Build Coastguard Worker {
5177*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "STATE: %s", message);
5178*5e7646d2SAndroid Build Coastguard Worker
5179*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(message, "paused"))
5180*5e7646d2SAndroid Build Coastguard Worker {
5181*5e7646d2SAndroid Build Coastguard Worker cupsdStopPrinter(job->printer, 1);
5182*5e7646d2SAndroid Build Coastguard Worker return;
5183*5e7646d2SAndroid Build Coastguard Worker }
5184*5e7646d2SAndroid Build Coastguard Worker else if (message[0] && cupsdSetPrinterReasons(job->printer, message))
5185*5e7646d2SAndroid Build Coastguard Worker {
5186*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5187*5e7646d2SAndroid Build Coastguard Worker
5188*5e7646d2SAndroid Build Coastguard Worker if (MaxJobTime > 0)
5189*5e7646d2SAndroid Build Coastguard Worker {
5190*5e7646d2SAndroid Build Coastguard Worker /*
5191*5e7646d2SAndroid Build Coastguard Worker * Reset cancel time after connecting to the device...
5192*5e7646d2SAndroid Build Coastguard Worker */
5193*5e7646d2SAndroid Build Coastguard Worker
5194*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < job->printer->num_reasons; i ++)
5195*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(job->printer->reasons[i], "connecting-to-device"))
5196*5e7646d2SAndroid Build Coastguard Worker break;
5197*5e7646d2SAndroid Build Coastguard Worker
5198*5e7646d2SAndroid Build Coastguard Worker if (i >= job->printer->num_reasons)
5199*5e7646d2SAndroid Build Coastguard Worker {
5200*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
5201*5e7646d2SAndroid Build Coastguard Worker "job-cancel-after",
5202*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_INTEGER);
5203*5e7646d2SAndroid Build Coastguard Worker /* job-cancel-after attribute */
5204*5e7646d2SAndroid Build Coastguard Worker
5205*5e7646d2SAndroid Build Coastguard Worker if (cancel_after)
5206*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
5207*5e7646d2SAndroid Build Coastguard Worker else if (MaxJobTime > 0)
5208*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + MaxJobTime;
5209*5e7646d2SAndroid Build Coastguard Worker else
5210*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = 0;
5211*5e7646d2SAndroid Build Coastguard Worker }
5212*5e7646d2SAndroid Build Coastguard Worker }
5213*5e7646d2SAndroid Build Coastguard Worker }
5214*5e7646d2SAndroid Build Coastguard Worker
5215*5e7646d2SAndroid Build Coastguard Worker update_job_attrs(job, 0);
5216*5e7646d2SAndroid Build Coastguard Worker }
5217*5e7646d2SAndroid Build Coastguard Worker else if (loglevel == CUPSD_LOG_ATTR)
5218*5e7646d2SAndroid Build Coastguard Worker {
5219*5e7646d2SAndroid Build Coastguard Worker /*
5220*5e7646d2SAndroid Build Coastguard Worker * Set attribute(s)...
5221*5e7646d2SAndroid Build Coastguard Worker */
5222*5e7646d2SAndroid Build Coastguard Worker
5223*5e7646d2SAndroid Build Coastguard Worker int num_attrs; /* Number of attributes */
5224*5e7646d2SAndroid Build Coastguard Worker cups_option_t *attrs; /* Attributes */
5225*5e7646d2SAndroid Build Coastguard Worker const char *attr; /* Attribute */
5226*5e7646d2SAndroid Build Coastguard Worker
5227*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "ATTR: %s", message);
5228*5e7646d2SAndroid Build Coastguard Worker
5229*5e7646d2SAndroid Build Coastguard Worker num_attrs = cupsParseOptions(message, 0, &attrs);
5230*5e7646d2SAndroid Build Coastguard Worker
5231*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("auth-info-default", num_attrs,
5232*5e7646d2SAndroid Build Coastguard Worker attrs)) != NULL)
5233*5e7646d2SAndroid Build Coastguard Worker {
5234*5e7646d2SAndroid Build Coastguard Worker job->printer->num_options = cupsAddOption("auth-info", attr,
5235*5e7646d2SAndroid Build Coastguard Worker job->printer->num_options,
5236*5e7646d2SAndroid Build Coastguard Worker &(job->printer->options));
5237*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(job->printer);
5238*5e7646d2SAndroid Build Coastguard Worker
5239*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5240*5e7646d2SAndroid Build Coastguard Worker }
5241*5e7646d2SAndroid Build Coastguard Worker
5242*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("auth-info-required", num_attrs,
5243*5e7646d2SAndroid Build Coastguard Worker attrs)) != NULL)
5244*5e7646d2SAndroid Build Coastguard Worker {
5245*5e7646d2SAndroid Build Coastguard Worker cupsdSetAuthInfoRequired(job->printer, attr, NULL);
5246*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(job->printer);
5247*5e7646d2SAndroid Build Coastguard Worker
5248*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5249*5e7646d2SAndroid Build Coastguard Worker }
5250*5e7646d2SAndroid Build Coastguard Worker
5251*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("job-media-progress", num_attrs,
5252*5e7646d2SAndroid Build Coastguard Worker attrs)) != NULL)
5253*5e7646d2SAndroid Build Coastguard Worker {
5254*5e7646d2SAndroid Build Coastguard Worker int progress = atoi(attr);
5255*5e7646d2SAndroid Build Coastguard Worker
5256*5e7646d2SAndroid Build Coastguard Worker
5257*5e7646d2SAndroid Build Coastguard Worker if (progress >= 0 && progress <= 100)
5258*5e7646d2SAndroid Build Coastguard Worker {
5259*5e7646d2SAndroid Build Coastguard Worker job->progress = progress;
5260*5e7646d2SAndroid Build Coastguard Worker
5261*5e7646d2SAndroid Build Coastguard Worker if (job->sheets)
5262*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job,
5263*5e7646d2SAndroid Build Coastguard Worker "Printing page %d, %d%%",
5264*5e7646d2SAndroid Build Coastguard Worker job->sheets->values[0].integer, job->progress);
5265*5e7646d2SAndroid Build Coastguard Worker }
5266*5e7646d2SAndroid Build Coastguard Worker }
5267*5e7646d2SAndroid Build Coastguard Worker
5268*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("printer-alert", num_attrs, attrs)) != NULL)
5269*5e7646d2SAndroid Build Coastguard Worker {
5270*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->printer->alert, attr);
5271*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5272*5e7646d2SAndroid Build Coastguard Worker }
5273*5e7646d2SAndroid Build Coastguard Worker
5274*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("printer-alert-description", num_attrs,
5275*5e7646d2SAndroid Build Coastguard Worker attrs)) != NULL)
5276*5e7646d2SAndroid Build Coastguard Worker {
5277*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&job->printer->alert_description, attr);
5278*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5279*5e7646d2SAndroid Build Coastguard Worker }
5280*5e7646d2SAndroid Build Coastguard Worker
5281*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-colors", num_attrs, attrs)) != NULL)
5282*5e7646d2SAndroid Build Coastguard Worker {
5283*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-colors", (char *)attr);
5284*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5285*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5286*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5287*5e7646d2SAndroid Build Coastguard Worker }
5288*5e7646d2SAndroid Build Coastguard Worker
5289*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-levels", num_attrs, attrs)) != NULL)
5290*5e7646d2SAndroid Build Coastguard Worker {
5291*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-levels", (char *)attr);
5292*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5293*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5294*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5295*5e7646d2SAndroid Build Coastguard Worker }
5296*5e7646d2SAndroid Build Coastguard Worker
5297*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-low-levels", num_attrs, attrs)) != NULL)
5298*5e7646d2SAndroid Build Coastguard Worker {
5299*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-low-levels", (char *)attr);
5300*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5301*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5302*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5303*5e7646d2SAndroid Build Coastguard Worker }
5304*5e7646d2SAndroid Build Coastguard Worker
5305*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-high-levels", num_attrs, attrs)) != NULL)
5306*5e7646d2SAndroid Build Coastguard Worker {
5307*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-high-levels", (char *)attr);
5308*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5309*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5310*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5311*5e7646d2SAndroid Build Coastguard Worker }
5312*5e7646d2SAndroid Build Coastguard Worker
5313*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-message", num_attrs, attrs)) != NULL)
5314*5e7646d2SAndroid Build Coastguard Worker {
5315*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-message", (char *)attr);
5316*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5317*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5318*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5319*5e7646d2SAndroid Build Coastguard Worker }
5320*5e7646d2SAndroid Build Coastguard Worker
5321*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-names", num_attrs, attrs)) != NULL)
5322*5e7646d2SAndroid Build Coastguard Worker {
5323*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-names", (char *)attr);
5324*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5325*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5326*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5327*5e7646d2SAndroid Build Coastguard Worker }
5328*5e7646d2SAndroid Build Coastguard Worker
5329*5e7646d2SAndroid Build Coastguard Worker if ((attr = cupsGetOption("marker-types", num_attrs, attrs)) != NULL)
5330*5e7646d2SAndroid Build Coastguard Worker {
5331*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(job->printer, "marker-types", (char *)attr);
5332*5e7646d2SAndroid Build Coastguard Worker job->printer->marker_time = time(NULL);
5333*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE;
5334*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
5335*5e7646d2SAndroid Build Coastguard Worker }
5336*5e7646d2SAndroid Build Coastguard Worker
5337*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_attrs, attrs);
5338*5e7646d2SAndroid Build Coastguard Worker }
5339*5e7646d2SAndroid Build Coastguard Worker else if (loglevel == CUPSD_LOG_PPD)
5340*5e7646d2SAndroid Build Coastguard Worker {
5341*5e7646d2SAndroid Build Coastguard Worker /*
5342*5e7646d2SAndroid Build Coastguard Worker * Set attribute(s)...
5343*5e7646d2SAndroid Build Coastguard Worker */
5344*5e7646d2SAndroid Build Coastguard Worker
5345*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG, "PPD: %s", message);
5346*5e7646d2SAndroid Build Coastguard Worker
5347*5e7646d2SAndroid Build Coastguard Worker job->num_keywords = cupsParseOptions(message, job->num_keywords,
5348*5e7646d2SAndroid Build Coastguard Worker &job->keywords);
5349*5e7646d2SAndroid Build Coastguard Worker }
5350*5e7646d2SAndroid Build Coastguard Worker else
5351*5e7646d2SAndroid Build Coastguard Worker {
5352*5e7646d2SAndroid Build Coastguard Worker /*
5353*5e7646d2SAndroid Build Coastguard Worker * Strip legacy message prefix...
5354*5e7646d2SAndroid Build Coastguard Worker */
5355*5e7646d2SAndroid Build Coastguard Worker
5356*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(message, "recoverable:", 12))
5357*5e7646d2SAndroid Build Coastguard Worker {
5358*5e7646d2SAndroid Build Coastguard Worker ptr = message + 12;
5359*5e7646d2SAndroid Build Coastguard Worker while (isspace(*ptr & 255))
5360*5e7646d2SAndroid Build Coastguard Worker ptr ++;
5361*5e7646d2SAndroid Build Coastguard Worker }
5362*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(message, "recovered:", 10))
5363*5e7646d2SAndroid Build Coastguard Worker {
5364*5e7646d2SAndroid Build Coastguard Worker ptr = message + 10;
5365*5e7646d2SAndroid Build Coastguard Worker while (isspace(*ptr & 255))
5366*5e7646d2SAndroid Build Coastguard Worker ptr ++;
5367*5e7646d2SAndroid Build Coastguard Worker }
5368*5e7646d2SAndroid Build Coastguard Worker else
5369*5e7646d2SAndroid Build Coastguard Worker ptr = message;
5370*5e7646d2SAndroid Build Coastguard Worker
5371*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
5372*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, loglevel == CUPSD_LOG_INFO ? CUPSD_LOG_DEBUG : loglevel, "%s", ptr);
5373*5e7646d2SAndroid Build Coastguard Worker
5374*5e7646d2SAndroid Build Coastguard Worker if (loglevel < CUPSD_LOG_DEBUG &&
5375*5e7646d2SAndroid Build Coastguard Worker strcmp(job->printer->state_message, ptr))
5376*5e7646d2SAndroid Build Coastguard Worker {
5377*5e7646d2SAndroid Build Coastguard Worker strlcpy(job->printer->state_message, ptr,
5378*5e7646d2SAndroid Build Coastguard Worker sizeof(job->printer->state_message));
5379*5e7646d2SAndroid Build Coastguard Worker
5380*5e7646d2SAndroid Build Coastguard Worker event |= CUPSD_EVENT_PRINTER_STATE | CUPSD_EVENT_JOB_PROGRESS;
5381*5e7646d2SAndroid Build Coastguard Worker
5382*5e7646d2SAndroid Build Coastguard Worker if (loglevel <= job->status_level && job->status_level > CUPSD_LOG_ERROR)
5383*5e7646d2SAndroid Build Coastguard Worker {
5384*5e7646d2SAndroid Build Coastguard Worker /*
5385*5e7646d2SAndroid Build Coastguard Worker * Some messages show in the job-printer-state-message attribute...
5386*5e7646d2SAndroid Build Coastguard Worker */
5387*5e7646d2SAndroid Build Coastguard Worker
5388*5e7646d2SAndroid Build Coastguard Worker if (loglevel != CUPSD_LOG_NOTICE)
5389*5e7646d2SAndroid Build Coastguard Worker job->status_level = loglevel;
5390*5e7646d2SAndroid Build Coastguard Worker
5391*5e7646d2SAndroid Build Coastguard Worker update_job_attrs(job, 1);
5392*5e7646d2SAndroid Build Coastguard Worker
5393*5e7646d2SAndroid Build Coastguard Worker cupsdLogJob(job, CUPSD_LOG_DEBUG,
5394*5e7646d2SAndroid Build Coastguard Worker "Set job-printer-state-message to \"%s\", "
5395*5e7646d2SAndroid Build Coastguard Worker "current level=%s",
5396*5e7646d2SAndroid Build Coastguard Worker job->printer_message->values[0].string.text,
5397*5e7646d2SAndroid Build Coastguard Worker levels[job->status_level]);
5398*5e7646d2SAndroid Build Coastguard Worker }
5399*5e7646d2SAndroid Build Coastguard Worker }
5400*5e7646d2SAndroid Build Coastguard Worker }
5401*5e7646d2SAndroid Build Coastguard Worker
5402*5e7646d2SAndroid Build Coastguard Worker if (!strchr(job->status_buffer->buffer, '\n'))
5403*5e7646d2SAndroid Build Coastguard Worker break;
5404*5e7646d2SAndroid Build Coastguard Worker }
5405*5e7646d2SAndroid Build Coastguard Worker
5406*5e7646d2SAndroid Build Coastguard Worker if (event & CUPSD_EVENT_JOB_PROGRESS)
5407*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job,
5408*5e7646d2SAndroid Build Coastguard Worker "%s", job->printer->state_message);
5409*5e7646d2SAndroid Build Coastguard Worker if (event & CUPSD_EVENT_PRINTER_STATE)
5410*5e7646d2SAndroid Build Coastguard Worker cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL,
5411*5e7646d2SAndroid Build Coastguard Worker (job->printer->type & CUPS_PRINTER_CLASS) ?
5412*5e7646d2SAndroid Build Coastguard Worker "Class \"%s\" state changed." :
5413*5e7646d2SAndroid Build Coastguard Worker "Printer \"%s\" state changed.",
5414*5e7646d2SAndroid Build Coastguard Worker job->printer->name);
5415*5e7646d2SAndroid Build Coastguard Worker
5416*5e7646d2SAndroid Build Coastguard Worker
5417*5e7646d2SAndroid Build Coastguard Worker if (ptr == NULL && !job->status_buffer->bufused)
5418*5e7646d2SAndroid Build Coastguard Worker {
5419*5e7646d2SAndroid Build Coastguard Worker /*
5420*5e7646d2SAndroid Build Coastguard Worker * See if all of the filters and the backend have returned their
5421*5e7646d2SAndroid Build Coastguard Worker * exit statuses.
5422*5e7646d2SAndroid Build Coastguard Worker */
5423*5e7646d2SAndroid Build Coastguard Worker
5424*5e7646d2SAndroid Build Coastguard Worker for (i = 0; job->filters[i] < 0; i ++);
5425*5e7646d2SAndroid Build Coastguard Worker
5426*5e7646d2SAndroid Build Coastguard Worker if (job->filters[i])
5427*5e7646d2SAndroid Build Coastguard Worker {
5428*5e7646d2SAndroid Build Coastguard Worker /*
5429*5e7646d2SAndroid Build Coastguard Worker * EOF but we haven't collected the exit status of all filters...
5430*5e7646d2SAndroid Build Coastguard Worker */
5431*5e7646d2SAndroid Build Coastguard Worker
5432*5e7646d2SAndroid Build Coastguard Worker cupsdCheckProcess();
5433*5e7646d2SAndroid Build Coastguard Worker return;
5434*5e7646d2SAndroid Build Coastguard Worker }
5435*5e7646d2SAndroid Build Coastguard Worker
5436*5e7646d2SAndroid Build Coastguard Worker if (job->current_file >= job->num_files && job->backend > 0)
5437*5e7646d2SAndroid Build Coastguard Worker {
5438*5e7646d2SAndroid Build Coastguard Worker /*
5439*5e7646d2SAndroid Build Coastguard Worker * EOF but we haven't collected the exit status of the backend...
5440*5e7646d2SAndroid Build Coastguard Worker */
5441*5e7646d2SAndroid Build Coastguard Worker
5442*5e7646d2SAndroid Build Coastguard Worker cupsdCheckProcess();
5443*5e7646d2SAndroid Build Coastguard Worker return;
5444*5e7646d2SAndroid Build Coastguard Worker }
5445*5e7646d2SAndroid Build Coastguard Worker
5446*5e7646d2SAndroid Build Coastguard Worker /*
5447*5e7646d2SAndroid Build Coastguard Worker * Handle the end of job stuff...
5448*5e7646d2SAndroid Build Coastguard Worker */
5449*5e7646d2SAndroid Build Coastguard Worker
5450*5e7646d2SAndroid Build Coastguard Worker finalize_job(job, 1);
5451*5e7646d2SAndroid Build Coastguard Worker
5452*5e7646d2SAndroid Build Coastguard Worker /*
5453*5e7646d2SAndroid Build Coastguard Worker * Try printing another job...
5454*5e7646d2SAndroid Build Coastguard Worker */
5455*5e7646d2SAndroid Build Coastguard Worker
5456*5e7646d2SAndroid Build Coastguard Worker if (printer->state != IPP_PRINTER_STOPPED)
5457*5e7646d2SAndroid Build Coastguard Worker cupsdCheckJobs();
5458*5e7646d2SAndroid Build Coastguard Worker }
5459*5e7646d2SAndroid Build Coastguard Worker }
5460*5e7646d2SAndroid Build Coastguard Worker
5461*5e7646d2SAndroid Build Coastguard Worker
5462*5e7646d2SAndroid Build Coastguard Worker /*
5463*5e7646d2SAndroid Build Coastguard Worker * 'update_job_attrs()' - Update the job-printer-* attributes.
5464*5e7646d2SAndroid Build Coastguard Worker */
5465*5e7646d2SAndroid Build Coastguard Worker
5466*5e7646d2SAndroid Build Coastguard Worker void
update_job_attrs(cupsd_job_t * job,int do_message)5467*5e7646d2SAndroid Build Coastguard Worker update_job_attrs(cupsd_job_t *job, /* I - Job to update */
5468*5e7646d2SAndroid Build Coastguard Worker int do_message)/* I - 1 = copy job-printer-state message */
5469*5e7646d2SAndroid Build Coastguard Worker {
5470*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
5471*5e7646d2SAndroid Build Coastguard Worker int num_reasons; /* Actual number of reasons */
5472*5e7646d2SAndroid Build Coastguard Worker const char * const *reasons; /* Reasons */
5473*5e7646d2SAndroid Build Coastguard Worker static const char *none = "none"; /* "none" reason */
5474*5e7646d2SAndroid Build Coastguard Worker
5475*5e7646d2SAndroid Build Coastguard Worker
5476*5e7646d2SAndroid Build Coastguard Worker /*
5477*5e7646d2SAndroid Build Coastguard Worker * Get/create the job-printer-state-* attributes...
5478*5e7646d2SAndroid Build Coastguard Worker */
5479*5e7646d2SAndroid Build Coastguard Worker
5480*5e7646d2SAndroid Build Coastguard Worker if (!job->printer_message)
5481*5e7646d2SAndroid Build Coastguard Worker {
5482*5e7646d2SAndroid Build Coastguard Worker if ((job->printer_message = ippFindAttribute(job->attrs,
5483*5e7646d2SAndroid Build Coastguard Worker "job-printer-state-message",
5484*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_TEXT)) == NULL)
5485*5e7646d2SAndroid Build Coastguard Worker job->printer_message = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_TEXT,
5486*5e7646d2SAndroid Build Coastguard Worker "job-printer-state-message",
5487*5e7646d2SAndroid Build Coastguard Worker NULL, "");
5488*5e7646d2SAndroid Build Coastguard Worker }
5489*5e7646d2SAndroid Build Coastguard Worker
5490*5e7646d2SAndroid Build Coastguard Worker if (!job->printer_reasons)
5491*5e7646d2SAndroid Build Coastguard Worker job->printer_reasons = ippFindAttribute(job->attrs,
5492*5e7646d2SAndroid Build Coastguard Worker "job-printer-state-reasons",
5493*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD);
5494*5e7646d2SAndroid Build Coastguard Worker
5495*5e7646d2SAndroid Build Coastguard Worker /*
5496*5e7646d2SAndroid Build Coastguard Worker * Copy or clear the printer-state-message value as needed...
5497*5e7646d2SAndroid Build Coastguard Worker */
5498*5e7646d2SAndroid Build Coastguard Worker
5499*5e7646d2SAndroid Build Coastguard Worker if (job->state_value != IPP_JOB_PROCESSING &&
5500*5e7646d2SAndroid Build Coastguard Worker job->status_level == CUPSD_LOG_INFO)
5501*5e7646d2SAndroid Build Coastguard Worker {
5502*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->printer_message, 0, "");
5503*5e7646d2SAndroid Build Coastguard Worker
5504*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
5505*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
5506*5e7646d2SAndroid Build Coastguard Worker }
5507*5e7646d2SAndroid Build Coastguard Worker else if (job->printer->state_message[0] && do_message)
5508*5e7646d2SAndroid Build Coastguard Worker {
5509*5e7646d2SAndroid Build Coastguard Worker ippSetString(job->attrs, &job->printer_message, 0, job->printer->state_message);
5510*5e7646d2SAndroid Build Coastguard Worker
5511*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
5512*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
5513*5e7646d2SAndroid Build Coastguard Worker }
5514*5e7646d2SAndroid Build Coastguard Worker
5515*5e7646d2SAndroid Build Coastguard Worker /*
5516*5e7646d2SAndroid Build Coastguard Worker * ... and the printer-state-reasons value...
5517*5e7646d2SAndroid Build Coastguard Worker */
5518*5e7646d2SAndroid Build Coastguard Worker
5519*5e7646d2SAndroid Build Coastguard Worker if (job->printer->num_reasons == 0)
5520*5e7646d2SAndroid Build Coastguard Worker {
5521*5e7646d2SAndroid Build Coastguard Worker num_reasons = 1;
5522*5e7646d2SAndroid Build Coastguard Worker reasons = &none;
5523*5e7646d2SAndroid Build Coastguard Worker }
5524*5e7646d2SAndroid Build Coastguard Worker else
5525*5e7646d2SAndroid Build Coastguard Worker {
5526*5e7646d2SAndroid Build Coastguard Worker num_reasons = job->printer->num_reasons;
5527*5e7646d2SAndroid Build Coastguard Worker reasons = (const char * const *)job->printer->reasons;
5528*5e7646d2SAndroid Build Coastguard Worker }
5529*5e7646d2SAndroid Build Coastguard Worker
5530*5e7646d2SAndroid Build Coastguard Worker if (!job->printer_reasons || job->printer_reasons->num_values != num_reasons)
5531*5e7646d2SAndroid Build Coastguard Worker {
5532*5e7646d2SAndroid Build Coastguard Worker /*
5533*5e7646d2SAndroid Build Coastguard Worker * Replace/create a job-printer-state-reasons attribute...
5534*5e7646d2SAndroid Build Coastguard Worker */
5535*5e7646d2SAndroid Build Coastguard Worker
5536*5e7646d2SAndroid Build Coastguard Worker ippDeleteAttribute(job->attrs, job->printer_reasons);
5537*5e7646d2SAndroid Build Coastguard Worker
5538*5e7646d2SAndroid Build Coastguard Worker job->printer_reasons = ippAddStrings(job->attrs,
5539*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_JOB, IPP_TAG_KEYWORD,
5540*5e7646d2SAndroid Build Coastguard Worker "job-printer-state-reasons",
5541*5e7646d2SAndroid Build Coastguard Worker num_reasons, NULL, NULL);
5542*5e7646d2SAndroid Build Coastguard Worker }
5543*5e7646d2SAndroid Build Coastguard Worker else
5544*5e7646d2SAndroid Build Coastguard Worker {
5545*5e7646d2SAndroid Build Coastguard Worker /*
5546*5e7646d2SAndroid Build Coastguard Worker * Don't bother clearing the reason strings if they are the same...
5547*5e7646d2SAndroid Build Coastguard Worker */
5548*5e7646d2SAndroid Build Coastguard Worker
5549*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_reasons; i ++)
5550*5e7646d2SAndroid Build Coastguard Worker if (strcmp(job->printer_reasons->values[i].string.text, reasons[i]))
5551*5e7646d2SAndroid Build Coastguard Worker break;
5552*5e7646d2SAndroid Build Coastguard Worker
5553*5e7646d2SAndroid Build Coastguard Worker if (i >= num_reasons)
5554*5e7646d2SAndroid Build Coastguard Worker return;
5555*5e7646d2SAndroid Build Coastguard Worker
5556*5e7646d2SAndroid Build Coastguard Worker /*
5557*5e7646d2SAndroid Build Coastguard Worker * Not the same, so free the current strings...
5558*5e7646d2SAndroid Build Coastguard Worker */
5559*5e7646d2SAndroid Build Coastguard Worker
5560*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_reasons; i ++)
5561*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(job->printer_reasons->values[i].string.text);
5562*5e7646d2SAndroid Build Coastguard Worker }
5563*5e7646d2SAndroid Build Coastguard Worker
5564*5e7646d2SAndroid Build Coastguard Worker /*
5565*5e7646d2SAndroid Build Coastguard Worker * Copy the reasons...
5566*5e7646d2SAndroid Build Coastguard Worker */
5567*5e7646d2SAndroid Build Coastguard Worker
5568*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_reasons; i ++)
5569*5e7646d2SAndroid Build Coastguard Worker job->printer_reasons->values[i].string.text = _cupsStrAlloc(reasons[i]);
5570*5e7646d2SAndroid Build Coastguard Worker
5571*5e7646d2SAndroid Build Coastguard Worker job->dirty = 1;
5572*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(CUPSD_DIRTY_JOBS);
5573*5e7646d2SAndroid Build Coastguard Worker }
5574