• Home
  • Raw
  • Download

Lines Matching full:job

2  * Job management routines for the CUPS scheduler.
28 * Design Notes for Job Management
35 * processing Do nothing/start job
41 * Finalize clears the printer <-> job association, deletes the status
47 * We unload the job attributes when they are not needed to reduce overall
48 * memory consumption. We don't unload jobs where job->state_value <
49 * IPP_JOB_STOPPED, job->printer != NULL, or job->access_time is recent.
53 * When a job is started, a status buffer, several pipes, a security
54 * profile, and a backend process are created for the life of that job.
55 * These are shared for every file in a job. For remote print jobs, the
56 * IPP backend is provided with every file in the job and no filters are
59 * The job->printer member tracks which printer is printing a job, which
60 * can be different than the destination in job->dest for classes. The
61 * printer object also has a job pointer to track which job is being
64 * PRINTING OF JOB FILES (cupsdContinueJob)
66 * Each file in a job is filtered by 0 or more programs. After getting the
67 * list of filters needed and the total cost, the job is either passed or
74 * JOB STATUS UPDATES (update_job)
83 * When all filters and the backend are done, we set the job state to
84 * completed (no errors), aborted (filter errors or abort-job policy),
85 * pending-held (auth required or retry-job policy), or pending
86 * (retry-current-job or stop-printer policies) as appropriate.
90 * JOB FILE COMPLETION (process_children in main.c)
94 * more files in the job, otherwise it waits for the backend to exit and
119 static void dump_job_history(cupsd_job_t *job);
120 static void finalize_job(cupsd_job_t *job, int set_job_state);
121 static void free_job_history(cupsd_job_t *job);
122 static char *get_options(cupsd_job_t *job, int banner_page, char *copies,
129 static void remove_job_files(cupsd_job_t *job);
130 static void remove_job_history(cupsd_job_t *job);
131 static void set_time(cupsd_job_t *job, const char *name);
132 static void start_job(cupsd_job_t *job, cupsd_printer_t *printer);
133 static void stop_job(cupsd_job_t *job, cupsd_jobaction_t action);
134 static void unload_job(cupsd_job_t *job);
135 static void update_job(cupsd_job_t *job);
136 static void update_job_attrs(cupsd_job_t *job, int do_message);
140 * 'cupsdAddJob()' - Add a new job to the job queue.
143 cupsd_job_t * /* O - New job record */
144 cupsdAddJob(int priority, /* I - Job priority */ in cupsdAddJob()
145 const char *dest) /* I - Job destination */ in cupsdAddJob()
147 cupsd_job_t *job; /* New job record */ in cupsdAddJob() local
150 if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL) in cupsdAddJob()
153 job->id = NextJobId ++; in cupsdAddJob()
154 job->priority = priority; in cupsdAddJob()
155 job->back_pipes[0] = -1; in cupsdAddJob()
156 job->back_pipes[1] = -1; in cupsdAddJob()
157 job->print_pipes[0] = -1; in cupsdAddJob()
158 job->print_pipes[1] = -1; in cupsdAddJob()
159 job->side_pipes[0] = -1; in cupsdAddJob()
160 job->side_pipes[1] = -1; in cupsdAddJob()
161 job->status_pipes[0] = -1; in cupsdAddJob()
162 job->status_pipes[1] = -1; in cupsdAddJob()
164 cupsdSetString(&job->dest, dest); in cupsdAddJob()
167 * Add the new job to the "all jobs" and "active jobs" lists... in cupsdAddJob()
170 cupsArrayAdd(Jobs, job); in cupsdAddJob()
171 cupsArrayAdd(ActiveJobs, job); in cupsdAddJob()
173 return (job); in cupsdAddJob()
186 cupsd_job_t *job; /* Current job */ in cupsdCancelJobs() local
189 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdCancelJobs()
190 job; in cupsdCancelJobs()
191 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdCancelJobs()
193 if ((!job->dest || !job->username) && !cupsdLoadJob(job)) in cupsdCancelJobs()
196 if ((!dest || !strcmp(job->dest, dest)) && in cupsdCancelJobs()
197 (!username || !strcmp(job->username, username))) in cupsdCancelJobs()
204 cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_PURGE, in cupsdCancelJobs()
205 "Job purged by user."); in cupsdCancelJobs()
206 else if (job->state_value < IPP_JOB_CANCELED) in cupsdCancelJobs()
207 cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT, in cupsdCancelJobs()
208 "Job canceled by user."); in cupsdCancelJobs()
222 cupsd_job_t *job; /* Current job in queue */ in cupsdCheckJobs() local
225 ipp_attribute_t *attr; /* Job attribute */ in cupsdCheckJobs()
227 const char *reasons; /* job-state-reasons value */ in cupsdCheckJobs()
234 for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); in cupsdCheckJobs()
235 job; in cupsdCheckJobs()
236 job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) in cupsdCheckJobs()
239 "cupsdCheckJobs: Job %d - dest=\"%s\", printer=%p, " in cupsdCheckJobs()
241 "pending_cost=%d, pending_timeout=%ld", job->id, job->dest, in cupsdCheckJobs()
242 job->printer, job->state_value, (long)job->cancel_time, in cupsdCheckJobs()
243 (long)job->hold_until, (long)job->kill_time, in cupsdCheckJobs()
244 job->pending_cost, (long)job->pending_timeout); in cupsdCheckJobs()
250 if (job->kill_time && job->kill_time <= curtime) in cupsdCheckJobs()
252 if (!job->completed) in cupsdCheckJobs()
253 cupsdLogJob(job, CUPSD_LOG_ERROR, "Stopping unresponsive job."); in cupsdCheckJobs()
255 stop_job(job, CUPSD_JOB_FORCE); in cupsdCheckJobs()
263 if (job->cancel_time && job->cancel_time <= curtime) in cupsdCheckJobs()
265 int cancel_after; /* job-cancel-after value */ in cupsdCheckJobs()
267 attr = ippFindAttribute(job->attrs, "job-cancel-after", IPP_TAG_INTEGER); in cupsdCheckJobs()
270 if (job->completed) in cupsdCheckJobs()
271 …cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_FORCE, "Marking stuck job as completed after %d … in cupsdCheckJobs()
273 …cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT, "Canceling stuck job after %d seconds."… in cupsdCheckJobs()
281 if (job->state_value == IPP_JOB_HELD && in cupsdCheckJobs()
282 job->hold_until && in cupsdCheckJobs()
283 job->hold_until < curtime) in cupsdCheckJobs()
285 if (job->pending_timeout) in cupsdCheckJobs()
288 * This job is pending; check that we don't have an active Send-Document in cupsdCheckJobs()
290 * the job so we can start printing... in cupsdCheckJobs()
305 if (cupsdTimeoutJob(job)) in cupsdCheckJobs()
308 cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, "Job submission timed out."); in cupsdCheckJobs()
309 cupsdLogJob(job, CUPSD_LOG_ERROR, "Job submission timed out."); in cupsdCheckJobs()
312 cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, "Job hold expired."); in cupsdCheckJobs()
319 if (job->pending_cost > 0 && in cupsdCheckJobs()
320 ((FilterLevel + job->pending_cost) < FilterLimit || FilterLevel == 0)) in cupsdCheckJobs()
321 cupsdContinueJob(job); in cupsdCheckJobs()
327 reasons = ippGetString(job->reasons, 0, NULL); in cupsdCheckJobs()
328 if (reasons && !strcmp(reasons, "job-held-on-create")) in cupsdCheckJobs()
334 printer = cupsdFindDest(job->dest); in cupsdCheckJobs()
339 ippSetString(job->attrs, &job->reasons, 0, "none"); in cupsdCheckJobs()
346 if (job->state_value == IPP_JOB_PENDING && !NeedReload && in cupsdCheckJobs()
347 (!Sleeping || ACPower) && !DoingShutdown && !job->printer) in cupsdCheckJobs()
349 printer = cupsdFindDest(job->dest); in cupsdCheckJobs()
372 * cancel the job... in cupsdCheckJobs()
375 cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_PURGE, in cupsdCheckJobs()
376 "Job aborted because the destination printer/class " in cupsdCheckJobs()
382 * See if the printer is available or remote and not printing a job; in cupsdCheckJobs()
383 * if so, start the job... in cupsdCheckJobs()
389 * Add/update a job-printer-uri-actual attribute for this job in cupsdCheckJobs()
390 * so that we know which printer actually printed the job... in cupsdCheckJobs()
393 if ((attr = ippFindAttribute(job->attrs, "job-printer-uri-actual", IPP_TAG_URI)) != NULL) in cupsdCheckJobs()
394 ippSetString(job->attrs, &attr, 0, printer->uri); in cupsdCheckJobs()
396 … ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri-actual", NULL, printer->uri); in cupsdCheckJobs()
398 job->dirty = 1; in cupsdCheckJobs()
402 if (!printer->job && printer->state == IPP_PRINTER_IDLE) in cupsdCheckJobs()
405 * Start the job... in cupsdCheckJobs()
409 start_job(job, printer); in cupsdCheckJobs()
425 cupsd_job_t *job; /* Current job */ in cupsdCleanJobs() local
441 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdCleanJobs()
442 job; in cupsdCleanJobs()
443 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdCleanJobs()
445 …: Job %d, state=%d, printer=%p, history_time=%d, file_time=%d", job->id, (int)job->state_value, (v… in cupsdCleanJobs()
447 if ((job->history_time && job->history_time < JobHistoryUpdate) || !JobHistoryUpdate) in cupsdCleanJobs()
448 JobHistoryUpdate = job->history_time; in cupsdCleanJobs()
450 if ((job->file_time && job->file_time < JobHistoryUpdate) || !JobHistoryUpdate) in cupsdCleanJobs()
451 JobHistoryUpdate = job->file_time; in cupsdCleanJobs()
453 if (job->state_value >= IPP_JOB_CANCELED && !job->printer) in cupsdCleanJobs()
456 * Expire old jobs (or job files)... in cupsdCleanJobs()
460 (job->history_time && job->history_time <= curtime)) in cupsdCleanJobs()
462 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing from history."); in cupsdCleanJobs()
463 cupsdDeleteJob(job, CUPSD_JOB_PURGE); in cupsdCleanJobs()
465 else if (job->file_time && job->file_time <= curtime && job->num_files > 0) in cupsdCleanJobs()
467 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing document files."); in cupsdCleanJobs()
468 remove_job_files(job); in cupsdCleanJobs()
481 * 'cupsdContinueJob()' - Continue printing with the next file in a job.
485 cupsdContinueJob(cupsd_job_t *job) /* I - Job */ in cupsdContinueJob() argument
489 cups_array_t *filters = NULL,/* Filters for job */ in cupsdContinueJob()
499 /* New job state on abort */ in cupsdContinueJob()
507 struct stat fileinfo; /* Job file information */ in cupsdContinueJob()
510 filename[1024], /* Job filename */ in cupsdContinueJob()
512 jobid[255], /* Job ID string */ in cupsdContinueJob()
514 /* Job title string */ in cupsdContinueJob()
550 "cupsdContinueJob(job=%p(%d)): current_file=%d, num_files=%d", in cupsdContinueJob()
551 job, job->id, job->current_file, job->num_files); in cupsdContinueJob()
558 FilterLevel -= job->cost; in cupsdContinueJob()
560 job->cost = 0; in cupsdContinueJob()
561 job->pending_cost = 0; in cupsdContinueJob()
563 memset(job->filters, 0, sizeof(job->filters)); in cupsdContinueJob()
565 if (job->printer->raw) in cupsdContinueJob()
572 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Sending job to queue tagged as raw..."); in cupsdContinueJob()
580 mime_type_t *dst = job->printer->filetype; in cupsdContinueJob()
584 job->id, job->current_file + 1); in cupsdContinueJob()
588 if (job->retry_as_raster) in cupsdContinueJob()
597 snprintf(type, sizeof(type), "%s/image/urf", job->printer->name); in cupsdContinueJob()
600 snprintf(type, sizeof(type), "%s/image/pwg-raster", job->printer->name); in cupsdContinueJob()
605 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Retrying job as \"%s\".", strchr(dst->type, '/') + 1); in cupsdContinueJob()
607 cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to retry job using a supported raster format."); in cupsdContinueJob()
610 …filters = mimeFilter2(MimeDatabase, job->filetypes[job->current_file], (size_t)fileinfo.st_size, d… in cupsdContinueJob()
614 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdContinueJob()
616 job->current_file); in cupsdContinueJob()
618 abort_message = "Aborting job because it cannot be printed."; in cupsdContinueJob()
621 ippSetString(job->attrs, &job->reasons, 0, "document-unprintable-error"); in cupsdContinueJob()
629 cupsdLogJob(job, CUPSD_LOG_DEBUG, "%d filters for job:", in cupsdContinueJob()
634 cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s (%s/%s to %s/%s, cost %d)", in cupsdContinueJob()
642 if (!job->printer->remote) in cupsdContinueJob()
648 strcmp(filter->dst->type, job->printer->name)) in cupsdContinueJob()
663 "FINAL_CONTENT_TYPE=printer/%s", job->printer->name); in cupsdContinueJob()
687 if (job->printer->prefiltertype && filters) in cupsdContinueJob()
696 job->printer->prefiltertype))) in cupsdContinueJob()
699 job->cost += prefilter->cost; in cupsdContinueJob()
715 if (job->cost < 100) in cupsdContinueJob()
716 job->cost = 100; in cupsdContinueJob()
722 if ((FilterLevel + job->cost) > FilterLimit && FilterLevel > 0 && in cupsdContinueJob()
726 * Don't print this job quite yet... in cupsdContinueJob()
731 cupsdLogJob(job, CUPSD_LOG_INFO, in cupsdContinueJob()
733 cupsdLogJob(job, CUPSD_LOG_DEBUG2, in cupsdContinueJob()
735 job->current_file, job->cost, FilterLevel, in cupsdContinueJob()
738 job->pending_cost = job->cost; in cupsdContinueJob()
739 job->cost = 0; in cupsdContinueJob()
743 FilterLevel += job->cost; in cupsdContinueJob()
749 if ((job->compressions[job->current_file] && (!job->printer->remote || job->num_files == 1)) || in cupsdContinueJob()
750 (!job->printer->remote && job->printer->raw && job->num_files > 1)) in cupsdContinueJob()
761 cupsdLogJob(job, CUPSD_LOG_DEBUG, in cupsdContinueJob()
766 abort_message = "Stopping job because the scheduler ran out of memory."; in cupsdContinueJob()
776 if (job->printer->port_monitor) in cupsdContinueJob()
790 "%s/monitor/%s", ServerBin, job->printer->port_monitor); in cupsdContinueJob()
794 cupsdLogJob(job, CUPSD_LOG_DEBUG, in cupsdContinueJob()
797 abort_message = "Stopping job because the scheduler ran out of memory."; in cupsdContinueJob()
809 cupsdLogJob(job, CUPSD_LOG_DEBUG, in cupsdContinueJob()
813 abort_message = "Aborting job because it needs too many filters to print."; in cupsdContinueJob()
816 ippSetString(job->attrs, &job->reasons, 0, "document-unprintable-error"); in cupsdContinueJob()
825 if (job->job_sheets == NULL) in cupsdContinueJob()
827 cupsdLogJob(job, CUPSD_LOG_DEBUG, "No job-sheets attribute."); in cupsdContinueJob()
828 if ((job->job_sheets = in cupsdContinueJob()
829 ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) in cupsdContinueJob()
830 cupsdLogJob(job, CUPSD_LOG_DEBUG, in cupsdContinueJob()
833 else if (job->job_sheets->num_values == 1) in cupsdContinueJob()
834 cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s", in cupsdContinueJob()
835 job->job_sheets->values[0].string.text); in cupsdContinueJob()
837 cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s,%s", in cupsdContinueJob()
838 job->job_sheets->values[0].string.text, in cupsdContinueJob()
839 job->job_sheets->values[1].string.text); in cupsdContinueJob()
841 if (job->printer->type & CUPS_PRINTER_REMOTE) in cupsdContinueJob()
843 else if (job->job_sheets == NULL) in cupsdContinueJob()
845 else if (_cups_strcasecmp(job->job_sheets->values[0].string.text, "none") != 0 && in cupsdContinueJob()
846 job->current_file == 0) in cupsdContinueJob()
848 else if (job->job_sheets->num_values > 1 && in cupsdContinueJob()
849 _cups_strcasecmp(job->job_sheets->values[1].string.text, "none") != 0 && in cupsdContinueJob()
850 job->current_file == (job->num_files - 1)) in cupsdContinueJob()
855 if ((options = get_options(job, banner_page, copies, sizeof(copies), title, in cupsdContinueJob()
858 abort_message = "Stopping job because the scheduler ran out of memory."; in cupsdContinueJob()
868 * argv[1] = job ID in cupsdContinueJob()
881 if (job->printer->remote) in cupsdContinueJob()
882 argc = 6 + job->num_files; in cupsdContinueJob()
891 abort_message = "Stopping job because the scheduler ran out of memory."; in cupsdContinueJob()
896 sprintf(jobid, "%d", job->id); in cupsdContinueJob()
898 argv[0] = job->printer->name; in cupsdContinueJob()
900 argv[2] = job->username; in cupsdContinueJob()
905 if (job->printer->remote && job->num_files > 1) in cupsdContinueJob()
907 for (i = 0; i < job->num_files; i ++) in cupsdContinueJob()
910 job->id, i + 1); in cupsdContinueJob()
917 job->id, job->current_file + 1); in cupsdContinueJob()
922 cupsdLogJob(job, CUPSD_LOG_DEBUG, "argv[%d]=\"%s\"", i, argv[i]); in cupsdContinueJob()
928 attr = ippFindAttribute(job->attrs, "attributes-natural-language", in cupsdContinueJob()
970 if ((attr = ippFindAttribute(job->attrs, "document-format", in cupsdContinueJob()
978 job->filetypes[job->current_file]->super, in cupsdContinueJob()
979 job->filetypes[job->current_file]->type); in cupsdContinueJob()
981 job->printer->device_uri); in cupsdContinueJob()
983 job->printer->name); in cupsdContinueJob()
985 job->printer->info ? job->printer->info : ""); in cupsdContinueJob()
987 job->printer->location ? job->printer->location : ""); in cupsdContinueJob()
988 snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", job->printer->name); in cupsdContinueJob()
989 if (job->printer->num_reasons > 0) in cupsdContinueJob()
994 for (psrlen = 22, i = 0; i < job->printer->num_reasons; i ++) in cupsdContinueJob()
995 psrlen += strlen(job->printer->reasons[i]) + 1; in cupsdContinueJob()
1005 i < job->printer->num_reasons; in cupsdContinueJob()
1010 strlcpy(psrptr, job->printer->reasons[i], psrlen - (size_t)(psrptr - printer_state_reasons)); in cupsdContinueJob()
1017 if (job->printer->num_auth_info_required == 1) in cupsdContinueJob()
1020 job->printer->auth_info_required[0]); in cupsdContinueJob()
1021 else if (job->printer->num_auth_info_required == 2) in cupsdContinueJob()
1024 job->printer->auth_info_required[0], in cupsdContinueJob()
1025 job->printer->auth_info_required[1]); in cupsdContinueJob()
1026 else if (job->printer->num_auth_info_required == 3) in cupsdContinueJob()
1029 job->printer->auth_info_required[0], in cupsdContinueJob()
1030 job->printer->auth_info_required[1], in cupsdContinueJob()
1031 job->printer->auth_info_required[2]); in cupsdContinueJob()
1032 else if (job->printer->num_auth_info_required == 4) in cupsdContinueJob()
1035 job->printer->auth_info_required[0], in cupsdContinueJob()
1036 job->printer->auth_info_required[1], in cupsdContinueJob()
1037 job->printer->auth_info_required[2], in cupsdContinueJob()
1038 job->printer->auth_info_required[3]); in cupsdContinueJob()
1059 envp[envc ++] = banner_page ? "CUPS_FILETYPE=job-sheet" : in cupsdContinueJob()
1067 if ((attr = ippFindAttribute(job->attrs, "job-sheets", in cupsdContinueJob()
1082 if (job->dtype & CUPS_PRINTER_CLASS) in cupsdContinueJob()
1084 snprintf(class_name, sizeof(class_name), "CLASS=%s", job->dest); in cupsdContinueJob()
1091 i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])); in cupsdContinueJob()
1093 if (job->auth_env[i]) in cupsdContinueJob()
1094 envp[envc ++] = job->auth_env[i]; in cupsdContinueJob()
1098 if (job->auth_uid) in cupsdContinueJob()
1099 envp[envc ++] = job->auth_uid; in cupsdContinueJob()
1105 cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"AUTH_%c****\"", i, in cupsdContinueJob()
1108 cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"%s\"", i, envp[i]); in cupsdContinueJob()
1110 cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"DEVICE_URI=%s\"", i, in cupsdContinueJob()
1111 job->printer->sanitized_device_uri); in cupsdContinueJob()
1113 if (job->printer->remote) in cupsdContinueJob()
1114 job->current_file = job->num_files; in cupsdContinueJob()
1116 job->current_file ++; in cupsdContinueJob()
1136 abort_message = "Stopping job because the scheduler could not create " in cupsdContinueJob()
1144 if (job->current_file == 1 || in cupsdContinueJob()
1145 (job->printer->pc && job->printer->pc->single_file)) in cupsdContinueJob()
1147 if (strncmp(job->printer->device_uri, "file:", 5) != 0) in cupsdContinueJob()
1149 if (cupsdOpenPipe(job->print_pipes)) in cupsdContinueJob()
1151 abort_message = "Stopping job because the scheduler could not " in cupsdContinueJob()
1159 job->print_pipes[0] = -1; in cupsdContinueJob()
1160 if (!strcmp(job->printer->device_uri, "file:/dev/null") || in cupsdContinueJob()
1161 !strcmp(job->printer->device_uri, "file:///dev/null")) in cupsdContinueJob()
1162 job->print_pipes[1] = -1; in cupsdContinueJob()
1165 if (!strncmp(job->printer->device_uri, "file:/dev/", 10)) in cupsdContinueJob()
1166 job->print_pipes[1] = open(job->printer->device_uri + 5, in cupsdContinueJob()
1168 else if (!strncmp(job->printer->device_uri, "file:///dev/", 12)) in cupsdContinueJob()
1169 job->print_pipes[1] = open(job->printer->device_uri + 7, in cupsdContinueJob()
1171 else if (!strncmp(job->printer->device_uri, "file:///", 8)) in cupsdContinueJob()
1172 job->print_pipes[1] = open(job->printer->device_uri + 7, in cupsdContinueJob()
1175 job->print_pipes[1] = open(job->printer->device_uri + 5, in cupsdContinueJob()
1178 if (job->print_pipes[1] < 0) in cupsdContinueJob()
1180 abort_message = "Stopping job because the scheduler could not " in cupsdContinueJob()
1186 fcntl(job->print_pipes[1], F_SETFD, in cupsdContinueJob()
1187 fcntl(job->print_pipes[1], F_GETFD) | FD_CLOEXEC); in cupsdContinueJob()
1192 filterfds[slot][0] = job->print_pipes[0]; in cupsdContinueJob()
1193 filterfds[slot][1] = job->print_pipes[1]; in cupsdContinueJob()
1197 filterfds[slot][1], job->status_pipes[1], in cupsdContinueJob()
1198 job->back_pipes[0], job->side_pipes[0], 0, in cupsdContinueJob()
1199 job->profile, job, job->filters + i); in cupsdContinueJob()
1205 cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to start filter \"%s\" - %s.", in cupsdContinueJob()
1208 abort_message = "Stopping job because the scheduler could not execute a " in cupsdContinueJob()
1214 cupsdLogJob(job, CUPSD_LOG_INFO, "Started filter %s (PID %d)", command, in cupsdContinueJob()
1233 if (strncmp(job->printer->device_uri, "file:", 5) != 0) in cupsdContinueJob()
1235 if (job->current_file == 1 || job->printer->remote || in cupsdContinueJob()
1236 (job->printer->pc && job->printer->pc->single_file)) in cupsdContinueJob()
1238 sscanf(job->printer->device_uri, "%254[^:]", scheme); in cupsdContinueJob()
1252 argv[0] = job->printer->sanitized_device_uri; in cupsdContinueJob()
1258 filterfds[slot][1], job->status_pipes[1], in cupsdContinueJob()
1259 job->back_pipes[1], job->side_pipes[1], in cupsdContinueJob()
1260 backroot, job->bprofile, job, &(job->backend)); in cupsdContinueJob()
1264 abort_message = "Stopping job because the sheduler could not execute " in cupsdContinueJob()
1271 cupsdLogJob(job, CUPSD_LOG_INFO, "Started backend %s (PID %d)", in cupsdContinueJob()
1276 if (job->current_file == job->num_files || in cupsdContinueJob()
1277 (job->printer->pc && job->printer->pc->single_file)) in cupsdContinueJob()
1278 cupsdClosePipe(job->print_pipes); in cupsdContinueJob()
1280 if (job->current_file == job->num_files) in cupsdContinueJob()
1282 cupsdClosePipe(job->back_pipes); in cupsdContinueJob()
1283 cupsdClosePipe(job->side_pipes); in cupsdContinueJob()
1285 close(job->status_pipes[1]); in cupsdContinueJob()
1286 job->status_pipes[1] = -1; in cupsdContinueJob()
1294 if (job->current_file == job->num_files || in cupsdContinueJob()
1295 (job->printer->pc && job->printer->pc->single_file)) in cupsdContinueJob()
1296 cupsdClosePipe(job->print_pipes); in cupsdContinueJob()
1298 if (job->current_file == job->num_files) in cupsdContinueJob()
1300 close(job->status_pipes[1]); in cupsdContinueJob()
1301 job->status_pipes[1] = -1; in cupsdContinueJob()
1314 cupsdAddSelect(job->status_buffer->fd, (cupsd_selfunc_t)update_job, NULL, in cupsdContinueJob()
1315 job); in cupsdContinueJob()
1317 cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "Job #%d started.", in cupsdContinueJob()
1318 job->id); in cupsdContinueJob()
1324 * If we get here, we need to abort the current job and close out all in cupsdContinueJob()
1330 FilterLevel -= job->cost; in cupsdContinueJob()
1331 job->cost = 0; in cupsdContinueJob()
1349 cupsdClosePipe(job->print_pipes); in cupsdContinueJob()
1350 cupsdClosePipe(job->back_pipes); in cupsdContinueJob()
1351 cupsdClosePipe(job->side_pipes); in cupsdContinueJob()
1353 cupsdRemoveSelect(job->status_pipes[0]); in cupsdContinueJob()
1354 cupsdClosePipe(job->status_pipes); in cupsdContinueJob()
1355 cupsdStatBufDelete(job->status_buffer); in cupsdContinueJob()
1356 job->status_buffer = NULL; in cupsdContinueJob()
1359 * Update the printer and job state. in cupsdContinueJob()
1362 cupsdSetJobState(job, abort_state, CUPSD_JOB_DEFAULT, "%s", abort_message); in cupsdContinueJob()
1363 cupsdSetPrinterState(job->printer, IPP_PRINTER_IDLE, 0); in cupsdContinueJob()
1364 update_job_attrs(job, 0); in cupsdContinueJob()
1366 if (job->history) in cupsdContinueJob()
1367 free_job_history(job); in cupsdContinueJob()
1369 cupsArrayRemove(PrintingJobs, job); in cupsdContinueJob()
1372 * Clear the printer <-> job association... in cupsdContinueJob()
1375 job->printer->job = NULL; in cupsdContinueJob()
1376 job->printer = NULL; in cupsdContinueJob()
1381 * 'cupsdDeleteJob()' - Free all memory used by a job.
1385 cupsdDeleteJob(cupsd_job_t *job, /* I - Job */ in cupsdDeleteJob() argument
1391 if (job->printer) in cupsdDeleteJob()
1392 finalize_job(job, 1); in cupsdDeleteJob()
1395 remove_job_history(job); in cupsdDeleteJob()
1397 cupsdClearString(&job->username); in cupsdDeleteJob()
1398 cupsdClearString(&job->dest); in cupsdDeleteJob()
1400 i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])); in cupsdDeleteJob()
1402 cupsdClearString(job->auth_env + i); in cupsdDeleteJob()
1403 cupsdClearString(&job->auth_uid); in cupsdDeleteJob()
1406 remove_job_files(job); in cupsdDeleteJob()
1407 else if (job->num_files > 0) in cupsdDeleteJob()
1409 free(job->compressions); in cupsdDeleteJob()
1410 free(job->filetypes); in cupsdDeleteJob()
1412 job->num_files = 0; in cupsdDeleteJob()
1415 if (job->history) in cupsdDeleteJob()
1416 free_job_history(job); in cupsdDeleteJob()
1418 unload_job(job); in cupsdDeleteJob()
1420 cupsArrayRemove(Jobs, job); in cupsdDeleteJob()
1421 cupsArrayRemove(ActiveJobs, job); in cupsdDeleteJob()
1422 cupsArrayRemove(PrintingJobs, job); in cupsdDeleteJob()
1424 free(job); in cupsdDeleteJob()
1435 cupsd_job_t *job; /* Current job */ in cupsdFreeAllJobs() local
1446 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdFreeAllJobs()
1447 job; in cupsdFreeAllJobs()
1448 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdFreeAllJobs()
1449 cupsdDeleteJob(job, CUPSD_JOB_DEFAULT); in cupsdFreeAllJobs()
1456 * 'cupsdFindJob()' - Find the specified job.
1459 cupsd_job_t * /* O - Job data */
1460 cupsdFindJob(int id) /* I - Job ID */ in cupsdFindJob()
1480 cupsd_job_t *job; /* Current job */ in cupsdGetCompletedJobs() local
1485 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdGetCompletedJobs()
1486 job; in cupsdGetCompletedJobs()
1487 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdGetCompletedJobs()
1488 …if ((!p || !_cups_strcasecmp(p->name, job->dest)) && job->state_value >= IPP_JOB_STOPPED && job->c… in cupsdGetCompletedJobs()
1489 cupsArrayAdd(list, job); in cupsdGetCompletedJobs()
1500 int /* O - Job count */
1504 int count; /* Job count */ in cupsdGetPrinterJobCount()
1505 cupsd_job_t *job; /* Current job */ in cupsdGetPrinterJobCount() local
1508 for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0; in cupsdGetPrinterJobCount()
1509 job; in cupsdGetPrinterJobCount()
1510 job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) in cupsdGetPrinterJobCount()
1511 if (job->dest && !_cups_strcasecmp(job->dest, dest)) in cupsdGetPrinterJobCount()
1523 int /* O - Job count */
1527 int count; /* Job count */ in cupsdGetUserJobCount()
1528 cupsd_job_t *job; /* Current job */ in cupsdGetUserJobCount() local
1531 for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0; in cupsdGetUserJobCount()
1532 job; in cupsdGetUserJobCount()
1533 job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) in cupsdGetUserJobCount()
1534 if (!_cups_strcasecmp(job->username, username)) in cupsdGetUserJobCount()
1548 char filename[1024]; /* Full filename of job.cache file */ in cupsdLoadAllJobs()
1549 struct stat fileinfo; /* Information on job.cache file */ in cupsdLoadAllJobs()
1552 int load_cache = 1; /* Load the job.cache file? */ in cupsdLoadAllJobs()
1556 * Create the job arrays as needed... in cupsdLoadAllJobs()
1569 * See whether the job.cache file is older than the RequestRoot directory... in cupsdLoadAllJobs()
1572 snprintf(filename, sizeof(filename), "%s/job.cache", CacheDir); in cupsdLoadAllJobs()
1577 * No job.cache file... in cupsdLoadAllJobs()
1602 * Job history file is newer than job.cache file... in cupsdLoadAllJobs()
1614 * Load the most recent source for job data... in cupsdLoadAllJobs()
1620 * Load the job.cache file... in cupsdLoadAllJobs()
1628 * Load the job history files... in cupsdLoadAllJobs()
1646 * 'cupsdLoadJob()' - Load a single job.
1650 cupsdLoadJob(cupsd_job_t *job) /* I - Job */ in cupsdLoadJob() argument
1653 char jobfile[1024]; /* Job filename */ in cupsdLoadJob()
1654 cups_file_t *fp; /* Job file */ in cupsdLoadJob()
1656 ipp_attribute_t *attr; /* Job attribute */ in cupsdLoadJob()
1663 if (job->attrs) in cupsdLoadJob()
1665 if (job->state_value > IPP_JOB_STOPPED) in cupsdLoadJob()
1666 job->access_time = time(NULL); in cupsdLoadJob()
1671 if ((job->attrs = ippNew()) == NULL) in cupsdLoadJob()
1673 cupsdLogJob(job, CUPSD_LOG_ERROR, "Ran out of memory for job attributes."); in cupsdLoadJob()
1678 * Load job attributes... in cupsdLoadJob()
1681 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading attributes..."); in cupsdLoadJob()
1683 snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id); in cupsdLoadJob()
1687 if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA) in cupsdLoadJob()
1689 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1690 "Unable to read job control file \"%s\".", jobfile); in cupsdLoadJob()
1698 * Copy attribute data to the job object... in cupsdLoadJob()
1701 if (!ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) in cupsdLoadJob()
1703 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1708 if ((job->state = ippFindAttribute(job->attrs, "job-state", in cupsdLoadJob()
1711 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1712 "Missing or bad job-state attribute in control file."); in cupsdLoadJob()
1716 job->state_value = (ipp_jstate_t)job->state->values[0].integer; in cupsdLoadJob()
1717 job->file_time = 0; in cupsdLoadJob()
1718 job->history_time = 0; in cupsdLoadJob()
1720 if ((attr = ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) != NULL) in cupsdLoadJob()
1721 job->creation_time = attr->values[0].integer; in cupsdLoadJob()
1723 …if (job->state_value >= IPP_JOB_CANCELED && (attr = ippFindAttribute(job->attrs, "time-at-complete… in cupsdLoadJob()
1725 job->completed_time = attr->values[0].integer; in cupsdLoadJob()
1728 job->history_time = job->completed_time + JobHistory; in cupsdLoadJob()
1730 job->history_time = INT_MAX; in cupsdLoadJob()
1732 if (job->history_time < time(NULL)) in cupsdLoadJob()
1735 if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate) in cupsdLoadJob()
1736 JobHistoryUpdate = job->history_time; in cupsdLoadJob()
1739 job->file_time = job->completed_time + JobFiles; in cupsdLoadJob()
1741 job->file_time = INT_MAX; in cupsdLoadJob()
1743 …cupsdLogJob(job, CUPSD_LOG_DEBUG2, "cupsdLoadJob: job->file_time=%ld, time-at-completed=%ld, JobFi… in cupsdLoadJob()
1745 if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate) in cupsdLoadJob()
1746 JobHistoryUpdate = job->file_time; in cupsdLoadJob()
1752 if (!job->dest) in cupsdLoadJob()
1754 if ((attr = ippFindAttribute(job->attrs, "job-printer-uri", in cupsdLoadJob()
1757 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1758 "No job-printer-uri attribute in control file."); in cupsdLoadJob()
1762 if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype), in cupsdLoadJob()
1765 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1766 "Unable to queue job for destination \"%s\".", in cupsdLoadJob()
1771 cupsdSetString(&job->dest, dest); in cupsdLoadJob()
1773 else if ((destptr = cupsdFindDest(job->dest)) == NULL) in cupsdLoadJob()
1775 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1776 "Unable to queue job for destination \"%s\".", in cupsdLoadJob()
1777 job->dest); in cupsdLoadJob()
1781 if ((job->reasons = ippFindAttribute(job->attrs, "job-state-reasons", in cupsdLoadJob()
1784 const char *reason; /* job-state-reason keyword */ in cupsdLoadJob()
1786 cupsdLogJob(job, CUPSD_LOG_DEBUG, in cupsdLoadJob()
1787 "Adding missing job-state-reasons attribute to control file."); in cupsdLoadJob()
1789 switch (job->state_value) in cupsdLoadJob()
1800 if ((attr = ippFindAttribute(job->attrs, "job-hold-until", in cupsdLoadJob()
1806 reason = "job-hold-until-specified"; in cupsdLoadJob()
1808 reason = "job-incoming"; in cupsdLoadJob()
1812 reason = "job-printing"; in cupsdLoadJob()
1816 reason = "job-stopped"; in cupsdLoadJob()
1820 reason = "job-canceled-by-user"; in cupsdLoadJob()
1828 reason = "job-completed-successfully"; in cupsdLoadJob()
1832 job->reasons = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, in cupsdLoadJob()
1833 "job-state-reasons", NULL, reason); in cupsdLoadJob()
1835 else if (job->state_value == IPP_JOB_PENDING) in cupsdLoadJob()
1838 ippSetString(job->attrs, &job->reasons, 0, "printer-stopped"); in cupsdLoadJob()
1840 ippSetString(job->attrs, &job->reasons, 0, "none"); in cupsdLoadJob()
1843 job->impressions = ippFindAttribute(job->attrs, "job-impressions-completed", IPP_TAG_INTEGER); in cupsdLoadJob()
1844 job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed", IPP_TAG_INTEGER); in cupsdLoadJob()
1845 job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME); in cupsdLoadJob()
1847 if (!job->impressions) in cupsdLoadJob()
1848job->impressions = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-impressions-comple… in cupsdLoadJob()
1849 if (!job->sheets) in cupsdLoadJob()
1850job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-media-sheets-completed"… in cupsdLoadJob()
1852 if (!job->priority) in cupsdLoadJob()
1854 if ((attr = ippFindAttribute(job->attrs, "job-priority", in cupsdLoadJob()
1857 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1858 "Missing or bad job-priority attribute in control file."); in cupsdLoadJob()
1862 job->priority = attr->values[0].integer; in cupsdLoadJob()
1865 if (!job->username) in cupsdLoadJob()
1867 if ((attr = ippFindAttribute(job->attrs, "job-originating-user-name", in cupsdLoadJob()
1870 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1871 "Missing or bad job-originating-user-name " in cupsdLoadJob()
1876 cupsdSetString(&job->username, attr->values[0].string.text); in cupsdLoadJob()
1879 if (!job->name) in cupsdLoadJob()
1881 if ((attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL) in cupsdLoadJob()
1882 cupsdSetString(&job->name, attr->values[0].string.text); in cupsdLoadJob()
1886 * Set the job hold-until time and state... in cupsdLoadJob()
1889 if (job->state_value == IPP_JOB_HELD) in cupsdLoadJob()
1891 if ((attr = ippFindAttribute(job->attrs, "job-hold-until", in cupsdLoadJob()
1893 attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); in cupsdLoadJob()
1896 cupsdSetJobHoldUntil(job, attr->values[0].string.text, CUPSD_JOB_DEFAULT); in cupsdLoadJob()
1899 job->state->values[0].integer = IPP_JOB_PENDING; in cupsdLoadJob()
1900 job->state_value = IPP_JOB_PENDING; in cupsdLoadJob()
1903 else if (job->state_value == IPP_JOB_PROCESSING) in cupsdLoadJob()
1905 job->state->values[0].integer = IPP_JOB_PENDING; in cupsdLoadJob()
1906 job->state_value = IPP_JOB_PENDING; in cupsdLoadJob()
1909 if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL) in cupsdLoadJob()
1910 job->koctets = attr->values[0].integer; in cupsdLoadJob()
1912 if (!job->num_files) in cupsdLoadJob()
1921 job->id, fileid); in cupsdLoadJob()
1926 cupsdLogJob(job, CUPSD_LOG_DEBUG, in cupsdLoadJob()
1929 if (fileid > job->num_files) in cupsdLoadJob()
1931 if (job->num_files == 0) in cupsdLoadJob()
1938 compressions = (int *)realloc(job->compressions, sizeof(int) * (size_t)fileid); in cupsdLoadJob()
1939 filetypes = (mime_type_t **)realloc(job->filetypes, sizeof(mime_type_t *) * (size_t)fileid); in cupsdLoadJob()
1943 job->compressions = compressions; in cupsdLoadJob()
1946 job->filetypes = filetypes; in cupsdLoadJob()
1950 cupsdLogJob(job, CUPSD_LOG_ERROR, in cupsdLoadJob()
1951 "Ran out of memory for job file types."); in cupsdLoadJob()
1953 ippDelete(job->attrs); in cupsdLoadJob()
1954 job->attrs = NULL; in cupsdLoadJob()
1956 if (job->compressions) in cupsdLoadJob()
1958 free(job->compressions); in cupsdLoadJob()
1959 job->compressions = NULL; in cupsdLoadJob()
1962 if (job->filetypes) in cupsdLoadJob()
1964 free(job->filetypes); in cupsdLoadJob()
1965 job->filetypes = NULL; in cupsdLoadJob()
1968 job->num_files = 0; in cupsdLoadJob()
1972 job->num_files = fileid; in cupsdLoadJob()
1975 job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, jobfile, NULL, in cupsdLoadJob()
1976 job->compressions + fileid - 1); in cupsdLoadJob()
1978 if (!job->filetypes[fileid - 1]) in cupsdLoadJob()
1979 job->filetypes[fileid - 1] = mimeType(MimeDatabase, "application", in cupsdLoadJob()
1988 if (job->state_value < IPP_JOB_STOPPED) in cupsdLoadJob()
1990 snprintf(jobfile, sizeof(jobfile), "%s/a%05d", RequestRoot, job->id); in cupsdLoadJob()
1993 i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])); in cupsdLoadJob()
1995 cupsdClearString(job->auth_env + i); in cupsdLoadJob()
1996 cupsdClearString(&job->auth_uid); in cupsdLoadJob()
2029 cupsdSetStringf(&job->auth_uid, "AUTH_UID=%s", value); in cupsdLoadJob()
2032 else if (i >= (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]))) in cupsdLoadJob()
2036 cupsdSetStringf(job->auth_env + i, "AUTH_USERNAME=%s", data); in cupsdLoadJob()
2038 cupsdSetStringf(job->auth_env + i, "AUTH_DOMAIN=%s", data); in cupsdLoadJob()
2040 cupsdSetStringf(job->auth_env + i, "AUTH_PASSWORD=%s", data); in cupsdLoadJob()
2042 cupsdSetStringf(job->auth_env + i, "AUTH_NEGOTIATE=%s", value); in cupsdLoadJob()
2054 job->access_time = time(NULL); in cupsdLoadJob()
2063 ippDelete(job->attrs); in cupsdLoadJob()
2064 job->attrs = NULL; in cupsdLoadJob()
2066 remove_job_history(job); in cupsdLoadJob()
2067 remove_job_files(job); in cupsdLoadJob()
2074 * 'cupsdMoveJob()' - Move the specified job to a different destination.
2078 cupsdMoveJob(cupsd_job_t *job, /* I - Job */ in cupsdMoveJob() argument
2081 ipp_attribute_t *attr; /* job-printer-uri attribute */ in cupsdMoveJob()
2090 if (job->state_value > IPP_JOB_STOPPED) in cupsdMoveJob()
2097 olddest = job->dest; in cupsdMoveJob()
2099 if (job->printer) in cupsdMoveJob()
2100 oldp = job->printer; in cupsdMoveJob()
2108 if (job->state_value > IPP_JOB_HELD) in cupsdMoveJob()
2109 cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, in cupsdMoveJob()
2110 "Stopping job prior to move."); in cupsdMoveJob()
2112 cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, oldp, job, in cupsdMoveJob()
2113 "Job #%d moved from %s to %s.", job->id, olddest, in cupsdMoveJob()
2116 cupsdSetString(&job->dest, p->name); in cupsdMoveJob()
2117 job->dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE); in cupsdMoveJob()
2119 if ((attr = ippFindAttribute(job->attrs, "job-printer-uri", in cupsdMoveJob()
2121 ippSetString(job->attrs, &attr, 0, p->uri); in cupsdMoveJob()
2123 cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job, in cupsdMoveJob()
2124 "Job #%d moved from %s to %s.", job->id, olddest, in cupsdMoveJob()
2127 job->dirty = 1; in cupsdMoveJob()
2133 * 'cupsdReleaseJob()' - Release the specified job.
2137 cupsdReleaseJob(cupsd_job_t *job) /* I - Job */ in cupsdReleaseJob() argument
2139 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReleaseJob(job=%p(%d))", job, in cupsdReleaseJob()
2140 job->id); in cupsdReleaseJob()
2142 if (job->state_value == IPP_JOB_HELD) in cupsdReleaseJob()
2148 if (job->pending_timeout) in cupsdReleaseJob()
2149 cupsdTimeoutJob(job); in cupsdReleaseJob()
2151 cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, in cupsdReleaseJob()
2152 "Job released by user."); in cupsdReleaseJob()
2158 * 'cupsdRestartJob()' - Restart the specified job.
2162 cupsdRestartJob(cupsd_job_t *job) /* I - Job */ in cupsdRestartJob() argument
2164 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdRestartJob(job=%p(%d))", job, in cupsdRestartJob()
2165 job->id); in cupsdRestartJob()
2167 if (job->state_value == IPP_JOB_STOPPED || job->num_files) in cupsdRestartJob()
2168 cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, in cupsdRestartJob()
2169 "Job restarted by user."); in cupsdRestartJob()
2181 cups_file_t *fp; /* job.cache file */ in cupsdSaveAllJobs()
2182 char filename[1024], /* job.cache filename */ in cupsdSaveAllJobs()
2184 cupsd_job_t *job; /* Current job */ in cupsdSaveAllJobs() local
2189 snprintf(filename, sizeof(filename), "%s/job.cache", CacheDir); in cupsdSaveAllJobs()
2193 cupsdLogMessage(CUPSD_LOG_INFO, "Saving job.cache..."); in cupsdSaveAllJobs()
2203 cupsFilePuts(fp, "# Job cache file for " CUPS_SVERSION "\n"); in cupsdSaveAllJobs()
2208 * Write each job known to the system... in cupsdSaveAllJobs()
2211 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdSaveAllJobs()
2212 job; in cupsdSaveAllJobs()
2213 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdSaveAllJobs()
2215 if (job->printer && job->printer->temporary) in cupsdSaveAllJobs()
2224 cupsFilePrintf(fp, "<Job %d>\n", job->id); in cupsdSaveAllJobs()
2225 cupsFilePrintf(fp, "State %d\n", job->state_value); in cupsdSaveAllJobs()
2226 cupsFilePrintf(fp, "Created %ld\n", (long)job->creation_time); in cupsdSaveAllJobs()
2227 if (job->completed_time) in cupsdSaveAllJobs()
2228 cupsFilePrintf(fp, "Completed %ld\n", (long)job->completed_time); in cupsdSaveAllJobs()
2229 cupsFilePrintf(fp, "Priority %d\n", job->priority); in cupsdSaveAllJobs()
2230 if (job->hold_until) in cupsdSaveAllJobs()
2231 cupsFilePrintf(fp, "HoldUntil %ld\n", (long)job->hold_until); in cupsdSaveAllJobs()
2232 cupsFilePrintf(fp, "Username %s\n", job->username); in cupsdSaveAllJobs()
2233 if (job->name) in cupsdSaveAllJobs()
2234 cupsFilePutConf(fp, "Name", job->name); in cupsdSaveAllJobs()
2235 cupsFilePrintf(fp, "Destination %s\n", job->dest); in cupsdSaveAllJobs()
2236 cupsFilePrintf(fp, "DestType %d\n", job->dtype); in cupsdSaveAllJobs()
2237 cupsFilePrintf(fp, "KOctets %d\n", job->koctets); in cupsdSaveAllJobs()
2238 cupsFilePrintf(fp, "NumFiles %d\n", job->num_files); in cupsdSaveAllJobs()
2239 for (i = 0; i < job->num_files; i ++) in cupsdSaveAllJobs()
2240 cupsFilePrintf(fp, "File %d %s/%s %d\n", i + 1, job->filetypes[i]->super, in cupsdSaveAllJobs()
2241 job->filetypes[i]->type, job->compressions[i]); in cupsdSaveAllJobs()
2242 cupsFilePuts(fp, "</Job>\n"); in cupsdSaveAllJobs()
2250 * 'cupsdSaveJob()' - Save a job to disk.
2254 cupsdSaveJob(cupsd_job_t *job) /* I - Job */ in cupsdSaveJob() argument
2256 char filename[1024]; /* Job control filename */ in cupsdSaveJob()
2257 cups_file_t *fp; /* Job file */ in cupsdSaveJob()
2260 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p", in cupsdSaveJob()
2261 job, job->id, job->attrs); in cupsdSaveJob()
2263 if (job->printer && job->printer->temporary) in cupsdSaveJob()
2269 job->dirty = 0; in cupsdSaveJob()
2273 snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id); in cupsdSaveJob()
2280 job->attrs->state = IPP_IDLE; in cupsdSaveJob()
2283 job->attrs) != IPP_DATA) in cupsdSaveJob()
2285 cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to write job control file."); in cupsdSaveJob()
2293 * Remove backup file and mark this job as clean... in cupsdSaveJob()
2299 job->dirty = 0; in cupsdSaveJob()
2305 * 'cupsdSetJobHoldUntil()' - Set the hold time for a job.
2309 cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ in cupsdSetJobHoldUntil() argument
2311 int update)/* I - Update job-hold-until attr? */ in cupsdSetJobHoldUntil()
2321 "cupsdSetJobHoldUntil(job=%p(%d), when=\"%s\", update=%d)", in cupsdSetJobHoldUntil()
2322 job, job->id, when, update); in cupsdSetJobHoldUntil()
2327 * Update the job-hold-until attribute... in cupsdSetJobHoldUntil()
2330 ipp_attribute_t *attr; /* job-hold-until attribute */ in cupsdSetJobHoldUntil()
2332 if ((attr = ippFindAttribute(job->attrs, "job-hold-until", in cupsdSetJobHoldUntil()
2334 attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); in cupsdSetJobHoldUntil()
2337 ippSetString(job->attrs, &attr, 0, when); in cupsdSetJobHoldUntil()
2339 attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, in cupsdSetJobHoldUntil()
2340 "job-hold-until", NULL, when); in cupsdSetJobHoldUntil()
2349 job->dirty = 1; in cupsdSetJobHoldUntil()
2356 ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified"); in cupsdSetJobHoldUntil()
2358 ippSetString(job->attrs, &job->reasons, 0, "none"); in cupsdSetJobHoldUntil()
2364 job->cancel_time = 0; in cupsdSetJobHoldUntil()
2372 job->hold_until = 0; in cupsdSetJobHoldUntil()
2375 job->cancel_time = time(NULL) + MaxHoldTime; in cupsdSetJobHoldUntil()
2387 job->hold_until = curtime; in cupsdSetJobHoldUntil()
2389 job->hold_until = curtime + in cupsdSetJobHoldUntil()
2403 job->hold_until = curtime; in cupsdSetJobHoldUntil()
2405 job->hold_until = curtime + in cupsdSetJobHoldUntil()
2419 job->hold_until = curtime; in cupsdSetJobHoldUntil()
2421 job->hold_until = curtime + in cupsdSetJobHoldUntil()
2435 job->hold_until = curtime; in cupsdSetJobHoldUntil()
2437 job->hold_until = curtime + in cupsdSetJobHoldUntil()
2451 job->hold_until = curtime; in cupsdSetJobHoldUntil()
2453 job->hold_until = curtime + in cupsdSetJobHoldUntil()
2467 job->hold_until = curtime + in cupsdSetJobHoldUntil()
2475 if (job->hold_until < curtime) in cupsdSetJobHoldUntil()
2476 job->hold_until += 24 * 60 * 60; in cupsdSetJobHoldUntil()
2480 (int)job->hold_until); in cupsdSetJobHoldUntil()
2485 * 'cupsdSetJobPriority()' - Set the priority of a job, moving it up/down in
2491 cupsd_job_t *job, /* I - Job ID */ in cupsdSetJobPriority() argument
2494 ipp_attribute_t *attr; /* Job attribute */ in cupsdSetJobPriority()
2501 if (job->state_value >= IPP_JOB_PROCESSING) in cupsdSetJobPriority()
2505 * Set the new priority and re-add the job into the active list... in cupsdSetJobPriority()
2508 cupsArrayRemove(ActiveJobs, job); in cupsdSetJobPriority()
2510 job->priority = priority; in cupsdSetJobPriority()
2512 if ((attr = ippFindAttribute(job->attrs, "job-priority", in cupsdSetJobPriority()
2516 ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority", in cupsdSetJobPriority()
2519 cupsArrayAdd(ActiveJobs, job); in cupsdSetJobPriority()
2521 job->dirty = 1; in cupsdSetJobPriority()
2527 * 'cupsdSetJobState()' - Set the state of the specified print job.
2532 cupsd_job_t *job, /* I - Job to cancel */ in cupsdSetJobState() argument
2533 ipp_jstate_t newstate, /* I - New job state */ in cupsdSetJobState()
2540 char filename[1024]; /* Job filename */ in cupsdSetJobState()
2541 ipp_attribute_t *attr; /* Job attribute */ in cupsdSetJobState()
2545 "cupsdSetJobState(job=%p(%d), state=%d, newstate=%d, " in cupsdSetJobState()
2546 "action=%d, message=\"%s\")", job, job->id, job->state_value, in cupsdSetJobState()
2551 * Make sure we have the job attributes... in cupsdSetJobState()
2554 if (!cupsdLoadJob(job)) in cupsdSetJobState()
2559 * job... in cupsdSetJobState()
2562 oldstate = job->state_value; in cupsdSetJobState()
2567 * Stop any processes that are working on the current job... in cupsdSetJobState()
2571 stop_job(job, action); in cupsdSetJobState()
2574 * Set the new job state... in cupsdSetJobState()
2577 job->state_value = newstate; in cupsdSetJobState()
2579 if (job->state) in cupsdSetJobState()
2580 job->state->values[0].integer = (int)newstate; in cupsdSetJobState()
2586 * Update job-hold-until as needed... in cupsdSetJobState()
2589 if ((attr = ippFindAttribute(job->attrs, "job-hold-until", in cupsdSetJobState()
2591 attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); in cupsdSetJobState()
2595 ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD); in cupsdSetJobState()
2596 ippSetString(job->attrs, &attr, 0, "no-hold"); in cupsdSetJobState()
2605 set_time(job, "time-at-completed"); in cupsdSetJobState()
2606 ippSetString(job->attrs, &job->reasons, 0, "processing-to-stop-point"); in cupsdSetJobState()
2624 cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, "%s", buffer); in cupsdSetJobState()
2626 cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "%s", buffer); in cupsdSetJobState()
2629 cupsdLogJob(job, CUPSD_LOG_ERROR, "%s", buffer); in cupsdSetJobState()
2631 cupsdLogJob(job, CUPSD_LOG_INFO, "%s", buffer); in cupsdSetJobState()
2642 * Add the job to the "printing" list... in cupsdSetJobState()
2645 if (!cupsArrayFind(PrintingJobs, job)) in cupsdSetJobState()
2646 cupsArrayAdd(PrintingJobs, job); in cupsdSetJobState()
2652 set_time(job, "time-at-processing"); in cupsdSetJobState()
2658 * Make sure the job is in the active list... in cupsdSetJobState()
2661 if (!cupsArrayFind(ActiveJobs, job)) in cupsdSetJobState()
2662 cupsArrayAdd(ActiveJobs, job); in cupsdSetJobState()
2665 * Save the job state to disk... in cupsdSetJobState()
2668 job->dirty = 1; in cupsdSetJobState()
2678 * Remove the job from the active list if there are no processes still in cupsdSetJobState()
2682 for (i = 0; job->filters[i] < 0; i++); in cupsdSetJobState()
2684 if (!job->filters[i] && job->backend <= 0) in cupsdSetJobState()
2685 cupsArrayRemove(ActiveJobs, job); in cupsdSetJobState()
2690 * Otherwise just remove the job from the active list immediately... in cupsdSetJobState()
2693 cupsArrayRemove(ActiveJobs, job); in cupsdSetJobState()
2697 * Expire job subscriptions since the job is now "completed"... in cupsdSetJobState()
2700 cupsdExpireSubscriptions(NULL, job); in cupsdSetJobState()
2716 snprintf(filename, sizeof(filename), "%s/a%05d", RequestRoot, job->id); in cupsdSetJobState()
2723 i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])); in cupsdSetJobState()
2725 cupsdClearString(job->auth_env + i); in cupsdSetJobState()
2727 cupsdClearString(&job->auth_uid); in cupsdSetJobState()
2735 remove_job_files(job); in cupsdSetJobState()
2740 * Save job state info... in cupsdSetJobState()
2743 job->dirty = 1; in cupsdSetJobState()
2746 else if (!job->printer) in cupsdSetJobState()
2749 * Delete the job immediately if not actively printing... in cupsdSetJobState()
2752 cupsdDeleteJob(job, CUPSD_JOB_PURGE); in cupsdSetJobState()
2753 job = NULL; in cupsdSetJobState()
2759 * Finalize the job immediately if we forced things... in cupsdSetJobState()
2762 if (action >= CUPSD_JOB_FORCE && job && job->printer) in cupsdSetJobState()
2763 finalize_job(job, 0); in cupsdSetJobState()
2782 cupsd_job_t *job; /* Current job */ in cupsdStopAllJobs() local
2785 for (job = (cupsd_job_t *)cupsArrayFirst(PrintingJobs); in cupsdStopAllJobs()
2786 job; in cupsdStopAllJobs()
2787 job = (cupsd_job_t *)cupsArrayNext(PrintingJobs)) in cupsdStopAllJobs()
2789 if (job->completed) in cupsdStopAllJobs()
2791 cupsdSetJobState(job, IPP_JOB_COMPLETED, CUPSD_JOB_FORCE, NULL); in cupsdStopAllJobs()
2796 job->kill_time = time(NULL) + kill_delay; in cupsdStopAllJobs()
2798 cupsdSetJobState(job, IPP_JOB_PENDING, action, NULL); in cupsdStopAllJobs()
2805 * 'cupsdUnloadCompletedJobs()' - Flush completed job history from memory.
2811 cupsd_job_t *job; /* Current job */ in cupsdUnloadCompletedJobs() local
2817 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdUnloadCompletedJobs()
2818 job; in cupsdUnloadCompletedJobs()
2819 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdUnloadCompletedJobs()
2820 if (job->attrs && job->state_value >= IPP_JOB_STOPPED && !job->printer && in cupsdUnloadCompletedJobs()
2821 job->access_time < expire) in cupsdUnloadCompletedJobs()
2823 if (job->dirty) in cupsdUnloadCompletedJobs()
2824 cupsdSaveJob(job); in cupsdUnloadCompletedJobs()
2826 if (!job->dirty) in cupsdUnloadCompletedJobs()
2827 unload_job(job); in cupsdUnloadCompletedJobs()
2839 cupsd_job_t *job; /* Current job */ in cupsdUpdateJobs() local
2847 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); in cupsdUpdateJobs()
2848 job; in cupsdUpdateJobs()
2849 job = (cupsd_job_t *)cupsArrayNext(Jobs)) in cupsdUpdateJobs()
2851 if (job->state_value >= IPP_JOB_CANCELED && in cupsdUpdateJobs()
2852 (attr = ippFindAttribute(job->attrs, "time-at-completed", in cupsdUpdateJobs()
2859 job->completed_time = attr->values[0].integer; in cupsdUpdateJobs()
2862 job->history_time = job->completed_time + JobHistory; in cupsdUpdateJobs()
2864 job->history_time = INT_MAX; in cupsdUpdateJobs()
2866 if (job->history_time < curtime) in cupsdUpdateJobs()
2868 cupsdDeleteJob(job, CUPSD_JOB_PURGE); in cupsdUpdateJobs()
2872 if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate) in cupsdUpdateJobs()
2873 JobHistoryUpdate = job->history_time; in cupsdUpdateJobs()
2876 job->file_time = job->completed_time + JobFiles; in cupsdUpdateJobs()
2878 job->file_time = INT_MAX; in cupsdUpdateJobs()
2880 …cupsdLogJob(job, CUPSD_LOG_DEBUG2, "cupsdUpdateJobs: job->file_time=%ld, time-at-completed=%ld, Jo… in cupsdUpdateJobs()
2882 if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate) in cupsdUpdateJobs()
2883 JobHistoryUpdate = job->file_time; in cupsdUpdateJobs()
2893 * 'compare_active_jobs()' - Compare the job IDs and priorities of two jobs.
2897 compare_active_jobs(void *first, /* I - First job */ in compare_active_jobs()
2898 void *second, /* I - Second job */ in compare_active_jobs()
2915 * 'compare_completed_jobs()' - Compare the job IDs and completion times of two jobs.
2919 compare_completed_jobs(void *first, /* I - First job */ in compare_completed_jobs()
2920 void *second, /* I - Second job */ in compare_completed_jobs()
2937 * 'compare_jobs()' - Compare the job IDs of two jobs.
2941 compare_jobs(void *first, /* I - First job */ in compare_jobs()
2942 void *second, /* I - Second job */ in compare_jobs()
2952 * 'dump_job_history()' - Dump any debug messages for a job.
2956 dump_job_history(cupsd_job_t *job) /* I - Job */ in dump_job_history() argument
2966 cupsd_printer_t *printer; /* Printer for job */ in dump_job_history()
2973 if (!job->history) in dump_job_history()
2987 message = (cupsd_joblog_t *)cupsArrayFirst(job->history); in dump_job_history()
2991 message = (cupsd_joblog_t *)cupsArrayLast(job->history); in dump_job_history()
2996 "[Job %d] The following messages were recorded from %s to %s", in dump_job_history()
2997 job->id, start, end); in dump_job_history()
3000 for (message = (cupsd_joblog_t *)cupsArrayFirst(job->history); in dump_job_history()
3002 message = (cupsd_joblog_t *)cupsArrayNext(job->history)) in dump_job_history()
3005 snprintf(temp, sizeof(temp), "[Job %d] End of messages", job->id); in dump_job_history()
3012 if ((printer = job->printer) == NULL) in dump_job_history()
3013 printer = cupsdFindDest(job->dest); in dump_job_history()
3017 snprintf(temp, sizeof(temp), "[Job %d] printer-state=%d(%s)", job->id, in dump_job_history()
3024 snprintf(temp, sizeof(temp), "[Job %d] printer-state-message=\"%s\"", in dump_job_history()
3025 job->id, printer->state_message); in dump_job_history()
3028 snprintf(temp, sizeof(temp), "[Job %d] printer-state-reasons=", job->id); in dump_job_history()
3058 free_job_history(job); in dump_job_history()
3067 free_job_history(cupsd_job_t *job) /* I - Job */ in free_job_history() argument
3072 if (!job->history) in free_job_history()
3075 for (message = (char *)cupsArrayFirst(job->history); in free_job_history()
3077 message = (char *)cupsArrayNext(job->history)) in free_job_history()
3080 cupsArrayDelete(job->history); in free_job_history()
3081 job->history = NULL; in free_job_history()
3086 * 'finalize_job()' - Cleanup after job filter processes and support data.
3090 finalize_job(cupsd_job_t *job, /* I - Job */ in finalize_job() argument
3091 int set_job_state) /* I - 1 = set the job state */ in finalize_job()
3094 ipp_jstate_t job_state; /* New job state value */ in finalize_job()
3095 const char *message; /* Message for job state */ in finalize_job()
3099 cupsdLogMessage(CUPSD_LOG_DEBUG2, "finalize_job(job=%p(%d))", job, job->id); in finalize_job()
3102 * Clear the "connecting-to-device" and "cups-waiting-for-job-completed" in finalize_job()
3104 * remote printing job state... in finalize_job()
3107 cupsdSetPrinterReasons(job->printer, "-connecting-to-device," in finalize_job()
3108 "cups-waiting-for-job-completed," in finalize_job()
3122 if (strncmp(job->printer->device_uri, "usb:", 4) && in finalize_job()
3123 strncmp(job->printer->device_uri, "ippusb:", 7)) in finalize_job()
3124 cupsdSetPrinterReasons(job->printer, "-offline-report"); in finalize_job()
3130 cupsdDestroyProfile(job->profile); in finalize_job()
3131 job->profile = NULL; in finalize_job()
3132 cupsdDestroyProfile(job->bprofile); in finalize_job()
3133 job->bprofile = NULL; in finalize_job()
3136 * Clear the unresponsive job watchdog timers... in finalize_job()
3139 job->cancel_time = 0; in finalize_job()
3140 job->kill_time = 0; in finalize_job()
3146 cupsdClosePipe(job->print_pipes); in finalize_job()
3147 cupsdClosePipe(job->back_pipes); in finalize_job()
3148 cupsdClosePipe(job->side_pipes); in finalize_job()
3150 cupsdRemoveSelect(job->status_pipes[0]); in finalize_job()
3151 cupsdClosePipe(job->status_pipes); in finalize_job()
3152 cupsdStatBufDelete(job->status_buffer); in finalize_job()
3153 job->status_buffer = NULL; in finalize_job()
3159 snprintf(buffer, sizeof(buffer), "total %d", ippGetInteger(job->impressions, 0)); in finalize_job()
3160 cupsdLogPage(job, buffer); in finalize_job()
3166 if (job->printer->state == IPP_PRINTER_PROCESSING) in finalize_job()
3169 printer_state = job->printer->state; in finalize_job()
3171 switch (job_state = job->state_value) in finalize_job()
3174 message = "Job paused."; in finalize_job()
3178 message = "Job held."; in finalize_job()
3185 message = "Job completed."; in finalize_job()
3187 if (!job->status) in finalize_job()
3188 ippSetString(job->attrs, &job->reasons, 0, in finalize_job()
3189 "job-completed-successfully"); in finalize_job()
3193 message = "Job stopped."; in finalize_job()
3195 ippSetString(job->attrs, &job->reasons, 0, "job-stopped"); in finalize_job()
3199 message = "Job canceled."; in finalize_job()
3201 ippSetString(job->attrs, &job->reasons, 0, "job-canceled-by-user"); in finalize_job()
3205 message = "Job aborted."; in finalize_job()
3209 if (job->status < 0) in finalize_job()
3223 exit_code = -job->status; in finalize_job()
3228 ippSetString(job->attrs, &job->reasons, 0, "cups-backend-crashed"); in finalize_job()
3229 exit_code = job->status; in finalize_job()
3232 cupsdLogJob(job, CUPSD_LOG_INFO, "Backend returned status %d (%s)", in finalize_job()
3237 exit_code == CUPS_BACKEND_HOLD ? "hold job" : in finalize_job()
3239 exit_code == CUPS_BACKEND_CANCEL ? "cancel job" : in finalize_job()
3240 exit_code == CUPS_BACKEND_RETRY ? "retry job later" : in finalize_job()
3241 exit_code == CUPS_BACKEND_RETRY_CURRENT ? "retry job immediately" : in finalize_job()
3257 if (job->dtype & CUPS_PRINTER_CLASS) in finalize_job()
3260 * Queued on a class - mark the job as pending and we'll retry on in finalize_job()
3267 message = "Retrying job on another printer."; in finalize_job()
3269 ippSetString(job->attrs, &job->reasons, 0, in finalize_job()
3273 else if (!strcmp(job->printer->error_policy, "retry-current-job")) in finalize_job()
3276 * The error policy is "retry-current-job" - mark the job as pending in finalize_job()
3283 message = "Retrying job on same printer."; in finalize_job()
3285 ippSetString(job->attrs, &job->reasons, 0, "none"); in finalize_job()
3288 else if ((job->printer->type & CUPS_PRINTER_FAX) || in finalize_job()
3289 !strcmp(job->printer->error_policy, "retry-job")) in finalize_job()
3294 * The job was queued on a fax or the error policy is "retry-job" - in finalize_job()
3295 * hold the job if the number of retries is less than the in finalize_job()
3296 * JobRetryLimit, otherwise abort the job. in finalize_job()
3299 job->tries ++; in finalize_job()
3301 if (job->tries > JobRetryLimit && JobRetryLimit > 0) in finalize_job()
3308 "Job aborted after %d unsuccessful attempts.", in finalize_job()
3313 ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system"); in finalize_job()
3322 "Job held for %d seconds since it could not be sent.", in finalize_job()
3325 job->hold_until = time(NULL) + JobRetryInterval; in finalize_job()
3329 ippSetString(job->attrs, &job->reasons, 0, in finalize_job()
3334 else if (!strcmp(job->printer->error_policy, "abort-job") && in finalize_job()
3341 …snprintf(buffer, sizeof(buffer), "Job aborted due to backend errors; please consult the %s file fo… in finalize_job()
3345 message = "Job aborted due to backend errors."; in finalize_job()
3347 ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system"); in finalize_job()
3349 else if (job->state_value == IPP_JOB_PROCESSING) in finalize_job()
3362 ippSetString(job->attrs, &job->reasons, 0, "none"); in finalize_job()
3368 * Cancel the job... in finalize_job()
3374 message = "Job canceled at printer."; in finalize_job()
3376 ippSetString(job->attrs, &job->reasons, 0, "canceled-at-device"); in finalize_job()
3384 * Hold the job... in finalize_job()
3387 const char *reason = ippGetString(job->reasons, 0, NULL); in finalize_job()
3389 cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-state-reasons=\"%s\"", in finalize_job()
3394 cupsdSetJobHoldUntil(job, "indefinite", 1); in finalize_job()
3396 ippSetString(job->attrs, &job->reasons, 0, in finalize_job()
3397 "job-hold-until-specified"); in finalize_job()
3401 …snprintf(buffer, sizeof(buffer), "Job held indefinitely due to backend errors; please consult the … in finalize_job()
3405 message = "Job held indefinitely due to backend errors."; in finalize_job()
3409 cupsdSetJobHoldUntil(job, "indefinite", 0); in finalize_job()
3411 message = "Job held indefinitely - account information is required."; in finalize_job()
3415 cupsdSetJobHoldUntil(job, "indefinite", 0); in finalize_job()
3417 message = "Job held indefinitely - account has been closed."; in finalize_job()
3421 cupsdSetJobHoldUntil(job, "indefinite", 0); in finalize_job()
3423 message = "Job held indefinitely - account limit has been reached."; in finalize_job()
3427 cupsdSetJobHoldUntil(job, "indefinite", 0); in finalize_job()
3429 message = "Job held indefinitely - account authorization failed."; in finalize_job()
3443 …cupsdLogJob(job, CUPSD_LOG_INFO, "Ignored STOP from backend since the job is %s.", job_state == IP… in finalize_job()
3461 ippSetString(job->attrs, &job->reasons, 0, "resources-are-not-ready"); in finalize_job()
3467 * Hold the job for authentication... in finalize_job()
3472 cupsdSetJobHoldUntil(job, "auth-info-required", 1); in finalize_job()
3475 message = "Job held for authentication."; in finalize_job()
3477 if (strncmp(job->reasons->values[0].string.text, "account-", 8)) in finalize_job()
3478 ippSetString(job->attrs, &job->reasons, 0, in finalize_job()
3487 * Hold the job if the number of retries is less than the in finalize_job()
3488 * JobRetryLimit, otherwise abort the job. in finalize_job()
3491 job->tries ++; in finalize_job()
3493 if (job->tries > JobRetryLimit && JobRetryLimit > 0) in finalize_job()
3500 "Job aborted after %d unsuccessful attempts.", in finalize_job()
3505 ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system"); in finalize_job()
3514 "Job held for %d seconds since it could not be sent.", in finalize_job()
3517 job->hold_until = time(NULL) + JobRetryInterval; in finalize_job()
3521 ippSetString(job->attrs, &job->reasons, 0, in finalize_job()
3529 * Mark the job as pending and retry on the same printer... in finalize_job()
3535 message = "Retrying job on same printer."; in finalize_job()
3537 ippSetString(job->attrs, &job->reasons, 0, "none"); in finalize_job()
3542 else if (job->status > 0) in finalize_job()
3545 * Filter had errors; stop job... in finalize_job()
3554 …snprintf(buffer, sizeof(buffer), "Job stopped due to filter errors; please consult the %s file for… in finalize_job()
3558 message = "Job stopped due to filter errors."; in finalize_job()
3560 if (WIFSIGNALED(job->status)) in finalize_job()
3561 ippSetString(job->attrs, &job->reasons, 0, "cups-filter-crashed"); in finalize_job()
3563 ippSetString(job->attrs, &job->reasons, 0, "job-completed-with-errors"); in finalize_job()
3568 * Update the printer and job state. in finalize_job()
3571 if (set_job_state && job_state != job->state_value) in finalize_job()
3572 cupsdSetJobState(job, job_state, CUPSD_JOB_DEFAULT, "%s", message); in finalize_job()
3574 cupsdSetPrinterState(job->printer, printer_state, in finalize_job()
3576 update_job_attrs(job, 0); in finalize_job()
3578 if (job->history) in finalize_job()
3580 if (job->status && in finalize_job()
3581 (job->state_value == IPP_JOB_ABORTED || in finalize_job()
3582 job->state_value == IPP_JOB_STOPPED)) in finalize_job()
3583 dump_job_history(job); in finalize_job()
3585 free_job_history(job); in finalize_job()
3588 cupsArrayRemove(PrintingJobs, job); in finalize_job()
3594 if (job->status_level > CUPSD_LOG_ERROR) in finalize_job()
3595 job->printer->state_message[0] = '\0'; in finalize_job()
3601 if (job->num_keywords) in finalize_job()
3603 if (cupsdUpdatePrinterPPD(job->printer, job->num_keywords, job->keywords)) in finalize_job()
3604 cupsdSetPrinterAttrs(job->printer); in finalize_job()
3606 cupsFreeOptions(job->num_keywords, job->keywords); in finalize_job()
3608 job->num_keywords = 0; in finalize_job()
3609 job->keywords = NULL; in finalize_job()
3613 * Clear the printer <-> job association... in finalize_job()
3616 job->printer->job = NULL; in finalize_job()
3617 job->printer = NULL; in finalize_job()
3622 * 'get_options()' - Get a string containing the job options.
3626 get_options(cupsd_job_t *job, /* I - Job */ in get_options() argument
3660 pc = job->printer->pc; in get_options()
3665 !ippFindAttribute(job->attrs, "com.apple.print.DocumentTicket.PMSpoolFormat", IPP_TAG_ZERO) && in get_options()
3666 !ippFindAttribute(job->attrs, "APPrinterPreset", IPP_TAG_ZERO) && in get_options()
3667 …Attribute(job->attrs, "print-color-mode", IPP_TAG_ZERO) || ippFindAttribute(job->attrs, "print-qua… in get_options()
3673 if ((attr = ippFindAttribute(job->attrs, "print-color-mode", in get_options()
3680 if ((attr = ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ENUM)) != NULL) in get_options()
3689 else if ((attr = ippFindAttribute(job->attrs, "cupsPrintQuality", IPP_TAG_NAME)) != NULL) in get_options()
3700 if (!ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ENUM)) in get_options()
3702 …cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping cupsPrintQuality=%s to print-quality=%d", pq, print_qu… in get_options()
3741 if (!ippFindAttribute(job->attrs, preset->name, IPP_TAG_ZERO)) in get_options()
3743 … cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Adding preset option %s=%s", preset->name, preset->value); in get_options()
3753 if ((attr = ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ENUM)) != NULL) in get_options()
3760 …cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping print-quality=%d to cupsPrintQuality=%s", pq, pqs[pq -… in get_options()
3766 if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) && in get_options()
3767 !ippFindAttribute(job->attrs, "HPPaperSource", IPP_TAG_ZERO)) in get_options()
3769 if ((ppd = _ppdCacheGetInputSlot(pc, job->attrs, NULL)) != NULL) in get_options()
3773 if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) && in get_options()
3774 (ppd = _ppdCacheGetMediaType(pc, job->attrs, NULL)) != NULL) in get_options()
3776 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping media to MediaType=%s", ppd); in get_options()
3781 if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) && in get_options()
3782 !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) && in get_options()
3783 (ppd = _ppdCacheGetPageSize(pc, job->attrs, NULL, &exact)) != NULL) in get_options()
3785 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping media to Pagesize=%s", ppd); in get_options()
3789 if (!ippFindAttribute(job->attrs, "media", IPP_TAG_ZERO)) in get_options()
3791 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Adding media=%s", ppd); in get_options()
3797 if (!ippFindAttribute(job->attrs, "OutputBin", IPP_TAG_ZERO) && in get_options()
3798 (attr = ippFindAttribute(job->attrs, "output-bin", in get_options()
3808 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping output-bin to OutputBin=%s", ppd); in get_options()
3814 !ippFindAttribute(job->attrs, pc->sides_option, IPP_TAG_ZERO) && in get_options()
3815 (attr = ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD)) != NULL) in get_options()
3823 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping sizes to Duplex=%s", pc->sides_1sided); in get_options()
3829 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping sizes to Duplex=%s", pc->sides_2sided_long); in get_options()
3835 cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Mapping sizes to Duplex=%s", pc->sides_2sided_short); in get_options()
3845 …num_pwgppds = _ppdCacheGetFinishingOptions(pc, job->attrs, IPP_FINISHINGS_NONE, num_pwgppds, &pwgp… in get_options()
3848 … cupsdLogJob(job, CUPSD_LOG_DEBUG2, "After mapping finishings %s=%s", pwgppd->name, pwgppd->value); in get_options()
3855 …if ((attr = ippFindAttribute(job->attrs, "page-delivery", IPP_TAG_KEYWORD)) != NULL && !ippFindAtt… in get_options()
3869 newlength = ipp_length(job->attrs); in get_options()
3890 cupsdLogJob(job, CUPSD_LOG_CRIT, in get_options()
3908 snprintf(title, title_size, "%s-%d", job->printer->name, job->id); in get_options()
3911 for (attr = job->attrs->attrs; attr != NULL; attr = attr->next) in get_options()
3917 * Don't use the # copies attribute if we are printing the job sheets... in get_options()
3923 else if (!strcmp(attr->name, "job-name") && in get_options()
3937 (attr->value_tag == IPP_TAG_URI && strcmp(attr->name, "job-uuid") && in get_options()
3938 strcmp(attr->name, "job-authorization-uri")) || in get_options()
3943 if (!strcmp(attr->name, "job-hold-until") || in get_options()
3944 !strcmp(attr->name, "job-id") || in get_options()
3945 !strcmp(attr->name, "job-k-octets") || in get_options()
3946 !strcmp(attr->name, "job-media-sheets") || in get_options()
3947 !strcmp(attr->name, "job-media-sheets-completed") || in get_options()
3948 !strcmp(attr->name, "job-state") || in get_options()
3949 !strcmp(attr->name, "job-state-reasons")) in get_options()
3952 if (!strncmp(attr->name, "job-", 4) && in get_options()
3953 strcmp(attr->name, "job-account-id") && in get_options()
3954 strcmp(attr->name, "job-accounting-user-id") && in get_options()
3955 strcmp(attr->name, "job-authorization-uri") && in get_options()
3956 strcmp(attr->name, "job-billing") && in get_options()
3957 strcmp(attr->name, "job-impressions") && in get_options()
3958 strcmp(attr->name, "job-originating-host-name") && in get_options()
3959 strcmp(attr->name, "job-password") && in get_options()
3960 strcmp(attr->name, "job-password-encryption") && in get_options()
3961 strcmp(attr->name, "job-uuid") && in get_options()
3962 !(job->printer->type & CUPS_PRINTER_REMOTE)) in get_options()
3965 if ((!strcmp(attr->name, "job-impressions") || in get_options()
4254 * 'load_job_cache()' - Load jobs from the job.cache file.
4258 load_job_cache(const char *filename) /* I - job.cache filename */ in load_job_cache()
4260 cups_file_t *fp; /* job.cache file */ in load_job_cache()
4264 cupsd_job_t *job; /* Current job */ in load_job_cache() local
4265 int jobid; /* Job ID */ in load_job_cache()
4266 char jobfile[1024]; /* Job filename */ in load_job_cache()
4270 * Open the job.cache file... in load_job_cache()
4280 * Read entries from the job cache file and create jobs as needed. in load_job_cache()
4283 cupsdLogMessage(CUPSD_LOG_INFO, "Loading job cache file \"%s\"...", in load_job_cache()
4287 job = NULL; in load_job_cache()
4296 else if (!_cups_strcasecmp(line, "<Job")) in load_job_cache()
4298 if (job) in load_job_cache()
4300 … cupsdLogMessage(CUPSD_LOG_ERROR, "Missing </Job> directive on line %d of %s.", linenum, filename); in load_job_cache()
4306 cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d of %s.", linenum, filename); in load_job_cache()
4314 … cupsdLogMessage(CUPSD_LOG_ERROR, "Bad job ID %d on line %d of %s.", jobid, linenum, filename); in load_job_cache()
4324 cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away.", in load_job_cache()
4328 * job.cache file is out-of-date compared to spool directory; load in load_job_cache()
4338 job = calloc(1, sizeof(cupsd_job_t)); in load_job_cache()
4339 if (!job) in load_job_cache()
4342 "[Job %d] Unable to allocate memory for job.", jobid); in load_job_cache()
4346 job->id = jobid; in load_job_cache()
4347 job->back_pipes[0] = -1; in load_job_cache()
4348 job->back_pipes[1] = -1; in load_job_cache()
4349 job->print_pipes[0] = -1; in load_job_cache()
4350 job->print_pipes[1] = -1; in load_job_cache()
4351 job->side_pipes[0] = -1; in load_job_cache()
4352 job->side_pipes[1] = -1; in load_job_cache()
4353 job->status_pipes[0] = -1; in load_job_cache()
4354 job->status_pipes[1] = -1; in load_job_cache()
4356 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading from cache..."); in load_job_cache()
4358 else if (!job) in load_job_cache()
4361 "Missing <Job #> directive on line %d of %s.", linenum, filename); in load_job_cache()
4364 else if (!_cups_strcasecmp(line, "</Job>")) in load_job_cache()
4366 cupsArrayAdd(Jobs, job); in load_job_cache()
4368 if (job->state_value <= IPP_JOB_STOPPED && cupsdLoadJob(job)) in load_job_cache()
4369 cupsArrayAdd(ActiveJobs, job); in load_job_cache()
4370 else if (job->state_value > IPP_JOB_STOPPED) in load_job_cache()
4372 if (!job->completed_time || !job->creation_time || !job->name || !job->koctets) in load_job_cache()
4374 cupsdLoadJob(job); in load_job_cache()
4375 unload_job(job); in load_job_cache()
4379 job = NULL; in load_job_cache()
4388 job->state_value = (ipp_jstate_t)atoi(value); in load_job_cache()
4390 if (job->state_value < IPP_JOB_PENDING) in load_job_cache()
4391 job->state_value = IPP_JOB_PENDING; in load_job_cache()
4392 else if (job->state_value > IPP_JOB_COMPLETED) in load_job_cache()
4393 job->state_value = IPP_JOB_COMPLETED; in load_job_cache()
4397 cupsdSetString(&(job->name), value); in load_job_cache()
4401 job->creation_time = strtol(value, NULL, 10); in load_job_cache()
4405 job->completed_time = strtol(value, NULL, 10); in load_job_cache()
4409 job->hold_until = strtol(value, NULL, 10); in load_job_cache()
4413 job->priority = atoi(value); in load_job_cache()
4417 cupsdSetString(&job->username, value); in load_job_cache()
4421 cupsdSetString(&job->dest, value); in load_job_cache()
4425 job->dtype = (cups_ptype_t)atoi(value); in load_job_cache()
4429 job->koctets = atoi(value); in load_job_cache()
4433 job->num_files = atoi(value); in load_job_cache()
4435 if (job->num_files < 0) in load_job_cache()
4437 …cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d of %s.", job->num_files, linenu… in load_job_cache()
4438 job->num_files = 0; in load_job_cache()
4442 if (job->num_files > 0) in load_job_cache()
4445 job->id); in load_job_cache()
4448 cupsdLogJob(job, CUPSD_LOG_INFO, "Data files have gone away."); in load_job_cache()
4449 job->num_files = 0; in load_job_cache()
4453 job->filetypes = calloc((size_t)job->num_files, sizeof(mime_type_t *)); in load_job_cache()
4454 job->compressions = calloc((size_t)job->num_files, sizeof(int)); in load_job_cache()
4456 if (!job->filetypes || !job->compressions) in load_job_cache()
4458 cupsdLogJob(job, CUPSD_LOG_EMERG, in load_job_cache()
4460 job->num_files); in load_job_cache()
4480 if (number < 1 || number > job->num_files) in load_job_cache()
4488 job->compressions[number] = compression; in load_job_cache()
4489 job->filetypes[number] = mimeType(MimeDatabase, super, type); in load_job_cache()
4491 if (!job->filetypes[number]) in load_job_cache()
4497 cupsdLogJob(job, CUPSD_LOG_ERROR, in load_job_cache()
4502 job->id, number + 1); in load_job_cache()
4503 job->filetypes[number] = mimeFileType(MimeDatabase, jobfile, NULL, in load_job_cache()
4504 job->compressions + number); in load_job_cache()
4510 if (!job->filetypes[number]) in load_job_cache()
4511 job->filetypes[number] = mimeType(MimeDatabase, "application", in load_job_cache()
4519 if (job) in load_job_cache()
4522 "Missing </Job> directive on line %d of %s.", linenum, filename); in load_job_cache()
4523 cupsdDeleteJob(job, CUPSD_JOB_PURGE); in load_job_cache()
4531 * 'load_next_job_id()' - Load the NextJobId value from the job.cache file.
4535 load_next_job_id(const char *filename) /* I - job.cache filename */ in load_next_job_id()
4537 cups_file_t *fp; /* job.cache file */ in load_next_job_id()
4545 * Read the NextJobId directive from the job.cache file and use in load_next_job_id()
4553 "Unable to open job cache file \"%s\": %s", in load_next_job_id()
4560 "Loading NextJobId from job cache file \"%s\"...", filename); in load_next_job_id()
4592 cupsd_job_t *job; /* New job */ in load_request_root() local
4617 * Allocate memory for the job... in load_request_root()
4620 if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL) in load_request_root()
4628 * Assign the job ID... in load_request_root()
4631 job->id = atoi(dent->filename + 1); in load_request_root()
4632 job->back_pipes[0] = -1; in load_request_root()
4633 job->back_pipes[1] = -1; in load_request_root()
4634 job->print_pipes[0] = -1; in load_request_root()
4635 job->print_pipes[1] = -1; in load_request_root()
4636 job->side_pipes[0] = -1; in load_request_root()
4637 job->side_pipes[1] = -1; in load_request_root()
4638 job->status_pipes[0] = -1; in load_request_root()
4639 job->status_pipes[1] = -1; in load_request_root()
4641 if (job->id >= NextJobId) in load_request_root()
4642 NextJobId = job->id + 1; in load_request_root()
4645 * Load the job... in load_request_root()
4648 if (cupsdLoadJob(job)) in load_request_root()
4651 * Insert the job into the array, sorting by job priority and ID... in load_request_root()
4654 cupsArrayAdd(Jobs, job); in load_request_root()
4656 if (job->state_value <= IPP_JOB_STOPPED) in load_request_root()
4657 cupsArrayAdd(ActiveJobs, job); in load_request_root()
4659 unload_job(job); in load_request_root()
4662 free(job); in load_request_root()
4670 * 'remove_job_files()' - Remove the document files for a job.
4674 remove_job_files(cupsd_job_t *job) /* I - Job */ in remove_job_files() argument
4680 if (job->num_files <= 0) in remove_job_files()
4683 for (i = 1; i <= job->num_files; i ++) in remove_job_files()
4686 job->id, i); in remove_job_files()
4690 free(job->filetypes); in remove_job_files()
4691 free(job->compressions); in remove_job_files()
4693 job->file_time = 0; in remove_job_files()
4694 job->num_files = 0; in remove_job_files()
4695 job->filetypes = NULL; in remove_job_files()
4696 job->compressions = NULL; in remove_job_files()
4703 * 'remove_job_history()' - Remove the control file for a job.
4707 remove_job_history(cupsd_job_t *job) /* I - Job */ in remove_job_history() argument
4713 * Remove the job info file... in remove_job_history()
4717 job->id); in remove_job_history()
4729 set_time(cupsd_job_t *job, /* I - Job to update */ in set_time() argument
4739 cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s=%ld", name, (long)curtime); in set_time()
4741 if ((attr = ippFindAttribute(job->attrs, name, IPP_TAG_ZERO)) != NULL) in set_time()
4749 if ((attr = ippFindAttribute(job->attrs, date_name, IPP_TAG_ZERO)) != NULL) in set_time()
4752 ippSetDate(job->attrs, &attr, 0, ippTimeToDate(curtime)); in set_time()
4757 job->completed_time = curtime; in set_time()
4760 job->history_time = job->completed_time + JobHistory; in set_time()
4762 job->history_time = INT_MAX; in set_time()
4764 if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate) in set_time()
4765 JobHistoryUpdate = job->history_time; in set_time()
4768 job->file_time = job->completed_time + JobFiles; in set_time()
4770 job->file_time = INT_MAX; in set_time()
4772 if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate) in set_time()
4773 JobHistoryUpdate = job->file_time; in set_time()
4782 * 'start_job()' - Start a print job.
4786 start_job(cupsd_job_t *job, /* I - Job ID */ in start_job() argument
4787 cupsd_printer_t *printer) /* I - Printer to print job */ in start_job()
4790 ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs, in start_job()
4791 "job-cancel-after", in start_job()
4793 /* job-cancel-after attribute */ in start_job()
4796 cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))", in start_job()
4797 job, job->id, printer, printer->name); in start_job()
4803 if (job->num_files == 0) in start_job()
4805 ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system"); in start_job()
4806 cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, in start_job()
4807 "Aborting job because it has no files."); in start_job()
4812 * Update the printer and job state to "processing"... in start_job()
4815 if (!cupsdLoadJob(job)) in start_job()
4818 if (!job->printer_message) in start_job()
4819 job->printer_message = ippFindAttribute(job->attrs, in start_job()
4820 "job-printer-state-message", in start_job()
4822 if (job->printer_message) in start_job()
4823 ippSetString(job->attrs, &job->printer_message, 0, ""); in start_job()
4825 ippSetString(job->attrs, &job->reasons, 0, "job-printing"); in start_job()
4826 cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL); in start_job()
4836 job->cost = 0; in start_job()
4837 job->current_file = 0; in start_job()
4838 job->file_time = 0; in start_job()
4839 job->history_time = 0; in start_job()
4840 job->progress = 0; in start_job()
4841 job->printer = printer; in start_job()
4842 printer->job = job; in start_job()
4845 job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0); in start_job()
4847 job->cancel_time = time(NULL) + MaxJobTime; in start_job()
4849 job->cancel_time = 0; in start_job()
4855 cupsdSetPrinterReasons(job->printer, "-cups-missing-filter-warning," in start_job()
4874 job->status = 0; in start_job()
4875 job->profile = cupsdCreateProfile(job->id, 0); in start_job()
4876 job->bprofile = cupsdCreateProfile(job->id, 1); in start_job()
4879 if ((!job->profile || !job->bprofile) && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF) in start_job()
4894 if (cupsdOpenPipe(job->status_pipes)) in start_job()
4896 cupsdLogJob(job, CUPSD_LOG_DEBUG, in start_job()
4897 "Unable to create job status pipes - %s.", strerror(errno)); in start_job()
4899 cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT, in start_job()
4900 "Job stopped because the scheduler could not create the " in start_job()
4901 "job status pipes."); in start_job()
4903 cupsdDestroyProfile(job->profile); in start_job()
4904 job->profile = NULL; in start_job()
4905 cupsdDestroyProfile(job->bprofile); in start_job()
4906 job->bprofile = NULL; in start_job()
4910 job->status_buffer = cupsdStatBufNew(job->status_pipes[0], NULL); in start_job()
4911 job->status_level = CUPSD_LOG_INFO; in start_job()
4917 if (cupsdOpenPipe(job->back_pipes)) in start_job()
4919 cupsdLogJob(job, CUPSD_LOG_DEBUG, in start_job()
4922 cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT, in start_job()
4923 "Job stopped because the scheduler could not create the " in start_job()
4926 cupsdClosePipe(job->status_pipes); in start_job()
4927 cupsdStatBufDelete(job->status_buffer); in start_job()
4928 job->status_buffer = NULL; in start_job()
4930 cupsdDestroyProfile(job->profile); in start_job()
4931 job->profile = NULL; in start_job()
4932 cupsdDestroyProfile(job->bprofile); in start_job()
4933 job->bprofile = NULL; in start_job()
4937 fcntl(job->back_pipes[0], F_SETFL, in start_job()
4938 fcntl(job->back_pipes[0], F_GETFL) | O_NONBLOCK); in start_job()
4939 fcntl(job->back_pipes[1], F_SETFL, in start_job()
4940 fcntl(job->back_pipes[1], F_GETFL) | O_NONBLOCK); in start_job()
4946 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, job->side_pipes)) in start_job()
4948 cupsdLogJob(job, CUPSD_LOG_DEBUG, in start_job()
4951 cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT, in start_job()
4952 "Job stopped because the scheduler could not create the " in start_job()
4955 cupsdClosePipe(job->back_pipes); in start_job()
4957 cupsdClosePipe(job->status_pipes); in start_job()
4958 cupsdStatBufDelete(job->status_buffer); in start_job()
4959 job->status_buffer = NULL; in start_job()
4961 cupsdDestroyProfile(job->profile); in start_job()
4962 job->profile = NULL; in start_job()
4963 cupsdDestroyProfile(job->bprofile); in start_job()
4964 job->bprofile = NULL; in start_job()
4968 fcntl(job->side_pipes[0], F_SETFL, in start_job()
4969 fcntl(job->side_pipes[0], F_GETFL) | O_NONBLOCK); in start_job()
4970 fcntl(job->side_pipes[1], F_SETFL, in start_job()
4971 fcntl(job->side_pipes[1], F_GETFL) | O_NONBLOCK); in start_job()
4973 fcntl(job->side_pipes[0], F_SETFD, in start_job()
4974 fcntl(job->side_pipes[0], F_GETFD) | FD_CLOEXEC); in start_job()
4975 fcntl(job->side_pipes[1], F_SETFD, in start_job()
4976 fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC); in start_job()
4979 * Now start the first file in the job... in start_job()
4982 cupsdContinueJob(job); in start_job()
4987 * 'stop_job()' - Stop a print job.
4991 stop_job(cupsd_job_t *job, /* I - Job */ in stop_job() argument
4997 cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_job(job=%p(%d), action=%d)", job, in stop_job()
4998 job->id, action); in stop_job()
5000 FilterLevel -= job->cost; in stop_job()
5001 job->cost = 0; in stop_job()
5003 if (action == CUPSD_JOB_DEFAULT && !job->kill_time && job->backend > 0) in stop_job()
5004 job->kill_time = time(NULL) + JobKillDelay; in stop_job()
5006 job->kill_time = 0; in stop_job()
5008 for (i = 0; job->filters[i]; i ++) in stop_job()
5009 if (job->filters[i] > 0) in stop_job()
5011 cupsdEndProcess(job->filters[i], action >= CUPSD_JOB_FORCE); in stop_job()
5014 job->filters[i] = -job->filters[i]; in stop_job()
5017 if (job->backend > 0) in stop_job()
5019 cupsdEndProcess(job->backend, action >= CUPSD_JOB_FORCE); in stop_job()
5022 job->backend = -job->backend; in stop_job()
5028 * Clear job status... in stop_job()
5031 job->status = 0; in stop_job()
5037 * 'unload_job()' - Unload a job from memory.
5041 unload_job(cupsd_job_t *job) /* I - Job */ in unload_job() argument
5043 if (!job->attrs) in unload_job()
5046 cupsdLogJob(job, CUPSD_LOG_DEBUG, "Unloading..."); in unload_job()
5048 ippDelete(job->attrs); in unload_job()
5050 job->attrs = NULL; in unload_job()
5051 job->state = NULL; in unload_job()
5052 job->reasons = NULL; in unload_job()
5053 job->impressions = NULL; in unload_job()
5054 job->sheets = NULL; in unload_job()
5055 job->job_sheets = NULL; in unload_job()
5056 job->printer_message = NULL; in unload_job()
5057 job->printer_reasons = NULL; in unload_job()
5062 * 'update_job()' - Read a status update from a job's filters.
5066 update_job(cupsd_job_t *job) /* I - Job to check */ in update_job() argument
5074 cupsd_printer_t *printer = job->printer; in update_job()
5092 * Get the printer associated with this job; if the printer is stopped for in update_job()
5093 * any reason then job->printer will be reset to NULL, so make sure we have in update_job()
5097 while ((ptr = cupsdStatBufUpdate(job->status_buffer, &loglevel, in update_job()
5106 int impressions = ippGetInteger(job->impressions, 0); in update_job()
5112 * job sheet count... in update_job()
5115 cupsdLogJob(job, CUPSD_LOG_DEBUG, "PAGE: %s", message); in update_job()
5148 if (job->impressions) in update_job()
5149 ippSetInteger(job->attrs, &job->impressions, 0, impressions); in update_job()
5151 if (job->sheets) in update_job()
5153 const char *sides = ippGetString(ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD), 0, NULL); in update_job()
5156 ippSetInteger(job->attrs, &job->sheets, 0, impressions / 2); in update_job()
5158 ippSetInteger(job->attrs, &job->sheets, 0, impressions); in update_job()
5160 …cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, "Printed %d page(s).", ippGetInteger(jo… in update_job()
5163 job->dirty = 1; in update_job()
5166 if (job->printer->page_limit) in update_job()
5167 cupsdUpdateQuota(job->printer, job->username, delta, 0); in update_job()
5172 * Support "keyword" to set job-state-reasons to the specified keyword. in update_job()
5176 cupsdLogJob(job, CUPSD_LOG_DEBUG, "JOBSTATE: %s", message); in update_job()
5179 job->retry_as_raster = 1; in update_job()
5181 ippSetString(job->attrs, &job->reasons, 0, message); in update_job()
5185 cupsdLogJob(job, CUPSD_LOG_DEBUG, "STATE: %s", message); in update_job()
5189 cupsdStopPrinter(job->printer, 1); in update_job()
5192 else if (message[0] && cupsdSetPrinterReasons(job->printer, message)) in update_job()
5202 for (i = 0; i < job->printer->num_reasons; i ++) in update_job()
5203 if (!strcmp(job->printer->reasons[i], "connecting-to-device")) in update_job()
5206 if (i >= job->printer->num_reasons) in update_job()
5208 ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs, in update_job()
5209 "job-cancel-after", in update_job()
5211 /* job-cancel-after attribute */ in update_job()
5214 job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0); in update_job()
5216 job->cancel_time = time(NULL) + MaxJobTime; in update_job()
5218 job->cancel_time = 0; in update_job()
5223 update_job_attrs(job, 0); in update_job()
5235 cupsdLogJob(job, CUPSD_LOG_DEBUG, "ATTR: %s", message); in update_job()
5242 job->printer->num_options = cupsAddOption("auth-info", attr, in update_job()
5243 job->printer->num_options, in update_job()
5244 &(job->printer->options)); in update_job()
5245 cupsdSetPrinterAttrs(job->printer); in update_job()
5253 cupsdSetAuthInfoRequired(job->printer, attr, NULL); in update_job()
5254 cupsdSetPrinterAttrs(job->printer); in update_job()
5259 if ((attr = cupsGetOption("job-media-progress", num_attrs, in update_job()
5267 job->progress = progress; in update_job()
5269 if (job->sheets) in update_job()
5270 cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, in update_job()
5272 job->sheets->values[0].integer, job->progress); in update_job()
5278 cupsdSetString(&job->printer->alert, attr); in update_job()
5285 cupsdSetString(&job->printer->alert_description, attr); in update_job()
5291 cupsdSetPrinterAttr(job->printer, "marker-colors", (char *)attr); in update_job()
5292 job->printer->marker_time = time(NULL); in update_job()
5299 cupsdSetPrinterAttr(job->printer, "marker-levels", (char *)attr); in update_job()
5300 job->printer->marker_time = time(NULL); in update_job()
5307 cupsdSetPrinterAttr(job->printer, "marker-low-levels", (char *)attr); in update_job()
5308 job->printer->marker_time = time(NULL); in update_job()
5315 cupsdSetPrinterAttr(job->printer, "marker-high-levels", (char *)attr); in update_job()
5316 job->printer->marker_time = time(NULL); in update_job()
5323 cupsdSetPrinterAttr(job->printer, "marker-message", (char *)attr); in update_job()
5324 job->printer->marker_time = time(NULL); in update_job()
5331 cupsdSetPrinterAttr(job->printer, "marker-names", (char *)attr); in update_job()
5332 job->printer->marker_time = time(NULL); in update_job()
5339 cupsdSetPrinterAttr(job->printer, "marker-types", (char *)attr); in update_job()
5340 job->printer->marker_time = time(NULL); in update_job()
5353 cupsdLogJob(job, CUPSD_LOG_DEBUG, "PPD: %s", message); in update_job()
5355 job->num_keywords = cupsParseOptions(message, job->num_keywords, in update_job()
5356 &job->keywords); in update_job()
5380 cupsdLogJob(job, loglevel == CUPSD_LOG_INFO ? CUPSD_LOG_DEBUG : loglevel, "%s", ptr); in update_job()
5383 strcmp(job->printer->state_message, ptr)) in update_job()
5385 strlcpy(job->printer->state_message, ptr, in update_job()
5386 sizeof(job->printer->state_message)); in update_job()
5390 if (loglevel <= job->status_level && job->status_level > CUPSD_LOG_ERROR) in update_job()
5393 * Some messages show in the job-printer-state-message attribute... in update_job()
5397 job->status_level = loglevel; in update_job()
5399 update_job_attrs(job, 1); in update_job()
5401 cupsdLogJob(job, CUPSD_LOG_DEBUG, in update_job()
5402 "Set job-printer-state-message to \"%s\", " in update_job()
5404 job->printer_message->values[0].string.text, in update_job()
5405 levels[job->status_level]); in update_job()
5410 if (!strchr(job->status_buffer->buffer, '\n')) in update_job()
5415 cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, in update_job()
5416 "%s", job->printer->state_message); in update_job()
5418 cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, in update_job()
5419 (job->printer->type & CUPS_PRINTER_CLASS) ? in update_job()
5422 job->printer->name); in update_job()
5425 if (ptr == NULL && !job->status_buffer->bufused) in update_job()
5432 for (i = 0; job->filters[i] < 0; i ++); in update_job()
5434 if (job->filters[i]) in update_job()
5444 if (job->current_file >= job->num_files && job->backend > 0) in update_job()
5455 * Handle the end of job stuff... in update_job()
5458 finalize_job(job, 1); in update_job()
5461 * Try printing another job... in update_job()
5471 * 'update_job_attrs()' - Update the job-printer-* attributes.
5475 update_job_attrs(cupsd_job_t *job, /* I - Job to update */ in update_job_attrs() argument
5476 int do_message)/* I - 1 = copy job-printer-state message */ in update_job_attrs()
5485 * Get/create the job-printer-state-* attributes... in update_job_attrs()
5488 if (!job->printer_message) in update_job_attrs()
5490 if ((job->printer_message = ippFindAttribute(job->attrs, in update_job_attrs()
5491 "job-printer-state-message", in update_job_attrs()
5493 job->printer_message = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_TEXT, in update_job_attrs()
5494 "job-printer-state-message", in update_job_attrs()
5498 if (!job->printer_reasons) in update_job_attrs()
5499 job->printer_reasons = ippFindAttribute(job->attrs, in update_job_attrs()
5500 "job-printer-state-reasons", in update_job_attrs()
5507 if (job->state_value != IPP_JOB_PROCESSING && in update_job_attrs()
5508 job->status_level == CUPSD_LOG_INFO) in update_job_attrs()
5510 ippSetString(job->attrs, &job->printer_message, 0, ""); in update_job_attrs()
5512 job->dirty = 1; in update_job_attrs()
5515 else if (job->printer->state_message[0] && do_message) in update_job_attrs()
5517 ippSetString(job->attrs, &job->printer_message, 0, job->printer->state_message); in update_job_attrs()
5519 job->dirty = 1; in update_job_attrs()
5527 if (job->printer->num_reasons == 0) in update_job_attrs()
5534 num_reasons = job->printer->num_reasons; in update_job_attrs()
5535 reasons = (const char * const *)job->printer->reasons; in update_job_attrs()
5538 if (!job->printer_reasons || job->printer_reasons->num_values != num_reasons) in update_job_attrs()
5541 * Replace/create a job-printer-state-reasons attribute... in update_job_attrs()
5544 ippDeleteAttribute(job->attrs, job->printer_reasons); in update_job_attrs()
5546 job->printer_reasons = ippAddStrings(job->attrs, in update_job_attrs()
5548 "job-printer-state-reasons", in update_job_attrs()
5558 if (strcmp(job->printer_reasons->values[i].string.text, reasons[i])) in update_job_attrs()
5569 _cupsStrFree(job->printer_reasons->values[i].string.text); in update_job_attrs()
5577 job->printer_reasons->values[i].string.text = _cupsStrAlloc(reasons[i]); in update_job_attrs()
5579 job->dirty = 1; in update_job_attrs()