📄 job.c
字号:
LogMessage(L_DEBUG2, "StartJob: Adding fd %d to InputSet...", current->pipe); FD_SET(current->pipe, InputSet);}/* * 'StopAllJobs()' - Stop all print jobs. */voidStopAllJobs(void){ job_t *current; /* Current job */ DEBUG_puts("StopAllJobs()"); for (current = Jobs; current != NULL; current = current->next) if (current->state->values[0].integer == IPP_JOB_PROCESSING) { StopJob(current->id, 1); current->state->values[0].integer = IPP_JOB_PENDING; }}/* * 'StopJob()' - Stop a print job. */voidStopJob(int id, /* I - Job ID */ int force) /* I - 1 = Force all filters to stop */{ int i; /* Looping var */ job_t *current; /* Current job */ LogMessage(L_DEBUG, "StopJob: id = %d, force = %d", id, force); for (current = Jobs; current != NULL; current = current->next) if (current->id == id) { DEBUG_puts("StopJob: found job in list."); if (current->state->values[0].integer == IPP_JOB_PROCESSING) { DEBUG_puts("StopJob: job state is \'processing\'."); FilterLevel -= current->cost; if (current->status < 0 && !(current->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) && !(current->printer->type & CUPS_PRINTER_FAX)) SetPrinterState(current->printer, IPP_PRINTER_STOPPED, 1); else if (current->printer->state != IPP_PRINTER_STOPPED) SetPrinterState(current->printer, IPP_PRINTER_IDLE, 0); LogMessage(L_DEBUG, "StopJob: printer state is %d", current->printer->state); current->state->values[0].integer = IPP_JOB_STOPPED; current->printer->job = NULL; current->printer = NULL; current->current_file --; for (i = 0; current->procs[i]; i ++) if (current->procs[i] > 0) { kill(current->procs[i], force ? SIGKILL : SIGTERM); current->procs[i] = 0; } if (current->pipe >= 0) { /* * Close the pipe and clear the input bit. */ LogMessage(L_DEBUG2, "StopJob: Removing fd %d from InputSet...", current->pipe); close(current->pipe); FD_CLR(current->pipe, InputSet); current->pipe = -1; } if (current->buffer) { /* * Free the status buffer... */ LogMessage(L_DEBUG2, "StopJob: Freeing status buffer..."); free(current->buffer); current->buffer = NULL; current->bufused = 0; } } return; }}/* * 'UpdateJob()' - Read a status update from a job's filters. */voidUpdateJob(job_t *job) /* I - Job to check */{ int i; /* Looping var */ int bytes; /* Number of bytes read */ int copies; /* Number of copies printed */ char *lineptr, /* Pointer to end of line in buffer */ *message; /* Pointer to message text */ int loglevel; /* Log level for message */ int job_history; /* Did CancelJob() keep the job? */ cups_ptype_t ptype; /* Printer type (color, small, etc.) */ if ((bytes = read(job->pipe, job->buffer + job->bufused, JOB_BUFFER_SIZE - job->bufused - 1)) > 0) { job->bufused += bytes; job->buffer[job->bufused] = '\0'; if ((lineptr = strchr(job->buffer, '\n')) == NULL && job->bufused == (JOB_BUFFER_SIZE - 1)) lineptr = job->buffer + job->bufused; } else if (bytes < 0 && errno == EINTR) return; else { lineptr = job->buffer + job->bufused; *lineptr = '\0'; } if (job->bufused == 0 && bytes == 0) lineptr = NULL; while (lineptr != NULL) { /* * Terminate each line and process it... */ *lineptr++ = '\0'; /* * Figure out the logging level... */ if (strncmp(job->buffer, "EMERG:", 6) == 0) { loglevel = L_EMERG; message = job->buffer + 6; } else if (strncmp(job->buffer, "ALERT:", 6) == 0) { loglevel = L_ALERT; message = job->buffer + 6; } else if (strncmp(job->buffer, "CRIT:", 5) == 0) { loglevel = L_CRIT; message = job->buffer + 5; } else if (strncmp(job->buffer, "ERROR:", 6) == 0) { loglevel = L_ERROR; message = job->buffer + 6; } else if (strncmp(job->buffer, "WARNING:", 8) == 0) { loglevel = L_WARN; message = job->buffer + 8; } else if (strncmp(job->buffer, "NOTICE:", 6) == 0) { loglevel = L_NOTICE; message = job->buffer + 6; } else if (strncmp(job->buffer, "INFO:", 5) == 0) { loglevel = L_INFO; message = job->buffer + 5; } else if (strncmp(job->buffer, "DEBUG:", 6) == 0) { loglevel = L_DEBUG; message = job->buffer + 6; } else if (strncmp(job->buffer, "DEBUG2:", 7) == 0) { loglevel = L_DEBUG2; message = job->buffer + 7; } else if (strncmp(job->buffer, "PAGE:", 5) == 0) { loglevel = L_PAGE; message = job->buffer + 5; } else if (strncmp(job->buffer, "STATE:", 6) == 0) { loglevel = L_STATE; message = job->buffer + 6; } else { loglevel = L_DEBUG; message = job->buffer; } /* * Skip leading whitespace in the message... */ while (isspace(*message & 255)) message ++; /* * Send it to the log file and printer state message as needed... */ if (loglevel == L_PAGE) { /* * Page message; send the message to the page_log file and update the * job sheet count... */ if (job->sheets != NULL) { if (!strncasecmp(message, "total ", 6)) { /* * Got a total count of pages from a backend or filter... */ copies = atoi(message + 6); copies -= job->sheets->values[0].integer; /* Just track the delta */ } else if (!sscanf(message, "%*d%d", &copies)) copies = 1; job->sheets->values[0].integer += copies; if (job->printer->page_limit) UpdateQuota(job->printer, job->username, copies, 0); } LogPage(job, message); } else if (loglevel == L_STATE) SetPrinterReasons(job->printer, message); else { /* * Other status message; send it to the error_log file... */ if (loglevel != L_INFO || LogLevel == L_DEBUG2) LogMessage(loglevel, "[Job %d] %s", job->id, message); if ((loglevel == L_INFO && !job->status) || loglevel < L_INFO) { strlcpy(job->printer->state_message, message, sizeof(job->printer->state_message)); AddPrinterHistory(job->printer); } } /* * Copy over the buffer data we've used up... */ cups_strcpy(job->buffer, lineptr); job->bufused -= lineptr - job->buffer; if (job->bufused < 0) job->bufused = 0; lineptr = strchr(job->buffer, '\n'); } if (bytes <= 0) { /* * See if all of the filters and the backend have returned their * exit statuses. */ for (i = 0; job->procs[i]; i ++) if (job->procs[i] > 0) return; /* * Handle the end of job stuff... */ LogMessage(L_DEBUG, "UpdateJob: job %d, file %d is complete.", job->id, job->current_file - 1); if (job->pipe >= 0) { /* * Close the pipe and clear the input bit. */ LogMessage(L_DEBUG2, "UpdateJob: Removing fd %d from InputSet...", job->pipe); close(job->pipe); FD_CLR(job->pipe, InputSet); job->pipe = -1; } if (job->status < 0) { /* * Backend had errors; stop it... */ ptype = job->printer->type; StopJob(job->id, 0); job->state->values[0].integer = IPP_JOB_PENDING; SaveJob(job->id); /* * If the job was queued to a class, try requeuing it... For * faxes, hold the current job for 5 minutes. */ if (job->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) CheckJobs(); else if (ptype & CUPS_PRINTER_FAX) { /* * See how many times we've tried to send the job; if more than * the limit, cancel the job. */ job->tries ++; if (job->tries >= FaxRetryLimit) { /* * Too many tries... */ LogMessage(L_ERROR, "Canceling fax job %d since it could not be sent after %d tries.", job->id, FaxRetryLimit); CancelJob(job->id, 0); } else { /* * Try again in N seconds... */ set_hold_until(job, time(NULL) + FaxRetryInterval); } CheckJobs(); } } else if (job->status > 0) { /* * Filter had errors; cancel it... */ if (job->current_file < job->num_files) StartJob(job->id, job->printer); else { job_history = JobHistory && !(job->dtype & CUPS_PRINTER_REMOTE); CancelJob(job->id, 0); if (job_history) { job->state->values[0].integer = IPP_JOB_ABORTED; SaveJob(job->id); } CheckJobs(); } } else { /* * Job printed successfully; cancel it... */ if (job->current_file < job->num_files) { FilterLevel -= job->cost; StartJob(job->id, job->printer); } else { job_history = JobHistory && !(job->dtype & CUPS_PRINTER_REMOTE); CancelJob(job->id, 0); if (job_history) { job->state->values[0].integer = IPP_JOB_COMPLETED; SaveJob(job->id); } CheckJobs(); } } }}/* * 'ipp_length()' - Compute the size of the buffer needed to hold * the textual IPP attributes. */int /* O - Size of buffer to hold IPP attributes */ipp_length(ipp_t *ipp) /* I - IPP request */{ int bytes; /* Number of bytes */ int i; /* Looping var */ ipp_attribute_t *attr; /* Current attribute */ /* * Loop through all attributes... */ bytes = 0; for (attr = ipp->attrs; attr != NULL; attr = attr->next) { /* * Skip attributes that won't be sent to filters... */ 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) continue; if (strncmp(attr->name, "time-", 5) == 0) continue; /* * Add space for a leading space and commas between each value. * For the first attribute, the leading space isn't used, so the * extra byte can be used as the nul terminator... */ bytes ++; /* " " separator */ bytes += attr->num_values; /* "," separators */ /* * Boolean attributes appear as "foo,nofoo,foo,nofoo", while * other attributes appear as "foo=value1,value2,...,valueN". */ if (attr->value_tag != IPP_TAG_BOOLEAN) bytes += strlen(attr->name); else bytes += attr->num_values * strlen(attr->name); /* * Now add the size required for each value in the attribute... */ switch (attr->value_tag) { case IPP_TAG_INTEGER : case IPP_TAG_ENUM : /* * Minimum value of a signed integer is -2147483647, or 11 digits. */ bytes += attr->num_values * 11; break; case IPP_TAG_BOOLEAN : /* * Add two bytes for each false ("no") value... */ for (i = 0; i < attr->num_values; i ++) if (!attr->values[i].boolean) bytes += 2; break; case IPP_TAG_RANGE : /* * A range is two signed integers separated by a hyphen, or * 23 characters max. */ bytes += attr->num_values * 23; break; case IPP_TAG_RESOLUTION : /* * A resolution is two signed integers se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -