📄 job.c
字号:
else job->hold_until = curtime + ((23 - curdate->tm_hour) * 60 + 59 - curdate->tm_min) * 60 + 60 - curdate->tm_sec; } else if (strcmp(when, "weekend") == 0) { /* * Hold to weekend unless we are in the weekend. */ curtime = time(NULL); curdate = localtime(&curtime); if (curdate->tm_wday == 0 || curdate->tm_wday == 6) job->hold_until = curtime; else job->hold_until = curtime + (((5 - curdate->tm_wday) * 24 + (17 - curdate->tm_hour)) * 60 + 59 - curdate->tm_min) * 60 + 60 - curdate->tm_sec; } else if (sscanf(when, "%d:%d:%d", &hour, &minute, &second) >= 2) { /* * Hold to specified GMT time (HH:MM or HH:MM:SS)... */ curtime = time(NULL); curdate = gmtime(&curtime); job->hold_until = curtime + ((hour - curdate->tm_hour) * 60 + minute - curdate->tm_min) * 60 + second - curdate->tm_sec; /* * Hold until next day as needed... */ if (job->hold_until < curtime) job->hold_until += 24 * 60 * 60 * 60; } LogMessage(L_DEBUG, "SetJobHoldUntil: hold_until = %d", (int)job->hold_until);}/* * 'SetJobPriority()' - Set the priority of a job, moving it up/down in the * list as needed. */voidSetJobPriority(int id, /* I - Job ID */ int priority) /* I - New priority (0 to 100) */{ job_t *job, /* Job to change */ *current, /* Current job */ *prev; /* Previous job */ ipp_attribute_t *attr; /* Job attribute */ /* * Find the job... */ for (current = Jobs, prev = NULL; current != NULL; prev = current, current = current->next) if (current->id == id) break; if (current == NULL) return; /* * Set the new priority... */ job = current; job->priority = priority; if ((attr = ippFindAttribute(job->attrs, "job-priority", IPP_TAG_INTEGER)) != NULL) attr->values[0].integer = priority; else ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority", priority); SaveJob(job->id); /* * See if we need to do any sorting... */ if ((prev == NULL || job->priority < prev->priority) && (job->next == NULL || job->next->priority < job->priority)) return; /* * Remove the job from the list, and then insert it where it belongs... */ if (prev == NULL) Jobs = job->next; else prev->next = job->next; for (current = Jobs, prev = NULL; current != NULL; prev = current, current = current->next) if (job->priority > current->priority) break; job->next = current; if (prev != NULL) prev->next = job; else Jobs = job;}/* * 'StartJob()' - Start a print job. */voidStartJob(int id, /* I - Job ID */ printer_t *printer) /* I - Printer to print job */{ job_t *current; /* Current job */ int i; /* Looping var */ int slot; /* Pipe slot */ int num_filters; /* Number of filters for job */ mime_filter_t *filters; /* Filters for job */ char method[255], /* Method for output */ *optptr, /* Pointer to options */ *valptr; /* Pointer in value string */ ipp_attribute_t *attr; /* Current attribute */ int pid; /* Process ID of new filter process */ int banner_page; /* 1 if banner page, 0 otherwise */ int statusfds[2], /* Pipes used between the filters and scheduler */ filterfds[2][2]; /* Pipes used between the filters */ int envc; /* Number of environment variables */ char *argv[8], /* Filter command-line arguments */ filename[1024], /* Job filename */ command[1024], /* Full path to filter/backend command */ jobid[255], /* Job ID string */ title[IPP_MAX_NAME], /* Job title string */ copies[255], /* # copies string */ *envp[100], /* Environment variables */#ifdef __APPLE__ processPath[1050], /* CFProcessPath environment variable */#endif /* __APPLE__ */ path[1024], /* PATH environment variable */ ipp_port[1024], /* IPP_PORT environment variable */ language[255], /* LANG environment variable */ charset[255], /* CHARSET environment variable */ classification[1024], /* CLASSIFICATION environment variable */ content_type[1024], /* CONTENT_TYPE environment variable */ device_uri[1024], /* DEVICE_URI environment variable */ sani_uri[1024], /* Sanitized DEVICE_URI env var */ ppd[1024], /* PPD environment variable */ class_name[255], /* CLASS environment variable */ printer_name[255], /* PRINTER environment variable */ root[1024], /* CUPS_SERVERROOT environment variable */ cache[255], /* RIP_MAX_CACHE environment variable */ tmpdir[1024], /* TMPDIR environment variable */ ld_library_path[1024], /* LD_LIBRARY_PATH environment variable */ ld_preload[1024], /* LD_PRELOAD environment variable */ dyld_library_path[1024],/* DYLD_LIBRARY_PATH environment variable */ shlib_path[1024], /* SHLIB_PATH environment variable */ nlspath[1024], /* NLSPATH environment variable */ datadir[1024], /* CUPS_DATADIR environment variable */ fontpath[1050], /* CUPS_FONTPATH environment variable */ vg_args[1024], /* VG_ARGS environment variable */ ld_assume_kernel[1024]; /* LD_ASSUME_KERNEL environment variable */ static char *options = NULL; /* Full list of options */ static int optlength = 0; /* Length of option buffer */ LogMessage(L_DEBUG, "StartJob(%d, %p)", id, printer); for (current = Jobs; current != NULL; current = current->next) if (current->id == id) break; if (current == NULL) return; LogMessage(L_DEBUG, "StartJob() id = %d, file = %d/%d", id, current->current_file, current->num_files); if (current->num_files == 0) { LogMessage(L_ERROR, "Job ID %d has no files! Cancelling it!", id); CancelJob(id, 0); return; } /* * Figure out what filters are required to convert from * the source to the destination type... */ num_filters = 0; current->cost = 0; if (printer->raw) { /* * Remote jobs and raw queues go directly to the printer without * filtering... */ LogMessage(L_DEBUG, "StartJob: Sending job to queue tagged as raw..."); filters = NULL; } else { /* * Local jobs get filtered... */ filters = mimeFilter(MimeDatabase, current->filetypes[current->current_file], printer->filetype, &num_filters, MAX_FILTERS - 1); if (num_filters == 0) { LogMessage(L_ERROR, "Unable to convert file %d to printable format for job %d!", current->current_file, current->id); LogMessage(L_INFO, "Hint: Do you have ESP Ghostscript installed?"); if (LogLevel < L_DEBUG) LogMessage(L_INFO, "Hint: Try setting the LogLevel to \"debug\"."); current->current_file ++; if (current->current_file == current->num_files) CancelJob(current->id, 0); return; } /* * Remove NULL ("-") filters... */ for (i = 0; i < num_filters;) if (strcmp(filters[i].filter, "-") == 0) { num_filters --; if (i < num_filters) memcpy(filters + i, filters + i + 1, (num_filters - i) * sizeof(mime_filter_t)); } else i ++; if (num_filters == 0) { free(filters); filters = NULL; } else { /* * Compute filter cost... */ for (i = 0; i < num_filters; i ++) current->cost += filters[i].cost; } } /* * See if the filter cost is too high... */ if ((FilterLevel + current->cost) > FilterLimit && FilterLevel > 0 && FilterLimit > 0) { /* * Don't print this job quite yet... */ if (filters != NULL) free(filters); LogMessage(L_INFO, "Holding job %d because filter limit has been reached.", id); LogMessage(L_DEBUG, "StartJob: id = %d, file = %d, " "cost = %d, level = %d, limit = %d", id, current->current_file, current->cost, FilterLevel, FilterLimit); return; } FilterLevel += current->cost; /* * Add decompression filters, if any... */ if (current->compressions[current->current_file]) { /* * Add gziptoany filter to the front of the list... */ mime_filter_t *temp_filters; if (num_filters == 0) temp_filters = malloc(sizeof(mime_filter_t)); else temp_filters = realloc(filters, sizeof(mime_filter_t) * (num_filters + 1)); if (temp_filters == NULL) { LogMessage(L_ERROR, "Unable to add decompression filter - %s", strerror(errno)); if (filters != NULL) free(filters); current->current_file ++; if (current->current_file == current->num_files) CancelJob(current->id, 0); return; } filters = temp_filters; memmove(filters + 1, filters, num_filters * sizeof(mime_filter_t)); *filters = gziptoany_filter; num_filters ++; } /* * Update the printer and job state to "processing"... */ current->state->values[0].integer = IPP_JOB_PROCESSING; current->status = 0; current->printer = printer; printer->job = current; SetPrinterState(printer, IPP_PRINTER_PROCESSING, 0); if (current->current_file == 0) set_time(current, "time-at-processing"); /* * Determine if we are printing a banner page or not... */ if (current->job_sheets == NULL) { LogMessage(L_DEBUG, "No job-sheets attribute."); if ((current->job_sheets = ippFindAttribute(current->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) LogMessage(L_DEBUG, "... but someone added one without setting job_sheets!"); } else if (current->job_sheets->num_values == 1) LogMessage(L_DEBUG, "job-sheets=%s", current->job_sheets->values[0].string.text); else LogMessage(L_DEBUG, "job-sheets=%s,%s", current->job_sheets->values[0].string.text, current->job_sheets->values[1].string.text); if (printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) banner_page = 0; else if (current->job_sheets == NULL) banner_page = 0; else if (strcasecmp(current->job_sheets->values[0].string.text, "none") != 0 && current->current_file == 0) banner_page = 1; else if (current->job_sheets->num_values > 1 && strcasecmp(current->job_sheets->values[1].string.text, "none") != 0 && current->current_file == (current->num_files - 1)) banner_page = 1; else banner_page = 0; LogMessage(L_DEBUG, "banner_page = %d", banner_page); /* * Building the options string is harder than it needs to be, but * for the moment we need to pass strings for command-line args and * not IPP attribute pointers... :) * * First allocate/reallocate the option buffer as needed... */ i = ipp_length(current->attrs); if (i > optlength) { if (optlength == 0) optptr = malloc(i); else optptr = realloc(options, i); if (optptr == NULL) { LogMessage(L_CRIT, "StartJob: Unable to allocate %d bytes for option buffer for job %d!", i, id); if (filters != NULL) free(filters); FilterLevel -= current->cost; CancelJob(id, 0); return; } options = optptr; optlength = i; } /* * Now loop through the attributes and convert them to the textual * representation used by the filters... */ optptr = options; *optptr = '\0'; snprintf(title, sizeof(title), "%s-%d", printer->name, current->id); strcpy(copies, "1"); for (attr = current->attrs->attrs; attr != NULL; attr = attr->next) { if (strcmp(attr->name, "copies") == 0 && attr->value_tag == IPP_TAG_INTEGER) { /* * Don't use the # copies attribute if we are printing the job sheets... */ if (!banner_page) sprintf(copies, "%d", attr->values[0].integer); } else if (strcmp(attr->name, "job-name") == 0 && (attr->value_tag == IPP_TAG_NAME || attr->value_tag == IPP_TAG_NAMELANG)) strlcpy(title, attr->values[0].string.text, sizeof(title)); else if (attr->group_tag == IPP_TAG_JOB) { /* * Filter out other unwanted attributes... */ if (attr->value_tag == IPP_TAG_MIMETYPE || attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_TEXTLANG || attr->value_tag == IPP_TAG_URI || attr->value_tag == IPP_TAG_URISCHEME || attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */ continue; if (strncmp(attr->name, "time-", 5) == 0) continue; if (strncmp(attr->name, "job-", 4) == 0 && !(printer->type & CUPS_PRINTER_REMOTE)) continue; if (strncmp(attr->name, "job-", 4) == 0 && strcmp(attr->name, "job-billing") != 0 && strcmp(attr->name, "job-sheets") != 0 && strcmp(attr->name, "job-hold-until") != 0 && strcmp(attr->name, "job-priority") != 0) continue; if ((strcmp(attr->name, "page-label") == 0 || strcmp(attr->name, "page-border") == 0 || strncmp(attr->name, "number-up", 9) == 0 || strcmp(attr->name, "page-set") == 0) && banner_page) continue; /* * Otherwise add them to the list... */ if (optptr > options) strlcat(optptr, " ", optlength - (optptr - options)); if (attr->value_tag != IPP_TAG_BOOLEAN) { strlcat(optptr, attr->name, optlength - (optptr - options)); strlcat(optptr, "=", optlength - (optptr - options)); } for (i = 0; i < attr->num_values; i ++) { if (i) strlcat(optptr, ",", optlength - (optptr - options)); optptr += strlen(optptr); switch (attr->value_tag) { case IPP_TAG_INTEGER : case IPP_TAG_ENUM : snprintf(optptr, optlength - (optptr - options), "%d", attr->values[i].integer); break; case IPP_TAG_BOOLEAN : if (!attr->values[i].boolean) strlcat(optptr, "no", optlength - (optptr - options)); case IPP_TAG_NOVALUE : strlcat(optptr, attr->name, optlength - (optptr - options)); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -