📄 job.c
字号:
/* * "$Id: job.c,v 1.235 2005/01/03 19:29:59 mike Exp $" * * Job management routines for the Common UNIX Printing System (CUPS). * * Copyright 1997-2005 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal * copyright law. Distribution and use rights are outlined in the file * "LICENSE.txt" which should have been included with this file. If this * file is missing or damaged please contact Easy Software Products * at: * * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 * Hollywood, Maryland 20636 USA * * Voice: (301) 373-9600 * EMail: cups-info@cups.org * WWW: http://www.cups.org * * Contents: * * AddJob() - Add a new job to the job queue... * CancelJob() - Cancel the specified print job. * CancelJobs() - Cancel all jobs for the given destination/user... * CheckJobs() - Check the pending jobs and start any if the * destination is available. * CleanJobs() - Clean out old jobs. * FreeAllJobs() - Free all jobs from memory. * FindJob() - Find the specified job. * GetPrinterJobCount() - Get the number of pending, processing, * or held jobs in a printer or class. * GetUserJobCount() - Get the number of pending, processing, * or held jobs for a user. * HoldJob() - Hold the specified job. * LoadAllJobs() - Load all jobs from disk. * LoadJob() - Load a job from disk. * MoveJob() - Move the specified job to a different * destination. * ReleaseJob() - Release the specified job. * RestartJob() - Restart the specified job. * SaveJob() - Save a job to disk. * SetJobHoldUntil() - Set the hold time for a job... * SetJobPriority() - Set the priority of a job, moving it up/down * in the list as needed. * StartJob() - Start a print job. * StopAllJobs() - Stop all print jobs. * StopJob() - Stop a print job. * UpdateJob() - Read a status update from a job's filters. * ipp_length() - Compute the size of the buffer needed to hold * the textual IPP attributes. * start_process() - Start a background process. * set_hold_until() - Set the hold time and update job-hold-until attribute. *//* * Include necessary headers... */#include "cupsd.h"#include <grp.h>/* * Local globals... */static mime_filter_t gziptoany_filter = { NULL, /* Source type */ NULL, /* Destination type */ 0, /* Cost */ "gziptoany" /* Filter program to run */ };/* * Local functions... */static int ipp_length(ipp_t *ipp);static void set_time(job_t *job, const char *name);static int start_process(const char *command, char *argv[], char *envp[], int in, int out, int err, int root, int *pid);static void set_hold_until(job_t *job, time_t holdtime);/* * 'AddJob()' - Add a new job to the job queue... */job_t * /* O - New job record */AddJob(int priority, /* I - Job priority */ const char *dest) /* I - Job destination */{ job_t *job, /* New job record */ *current, /* Current job in queue */ *prev; /* Previous job in queue */ job = calloc(sizeof(job_t), 1); job->id = NextJobId ++; job->priority = priority; job->pipe = -1; SetString(&job->dest, dest); NumJobs ++; 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; return (job);}/* * 'CancelJob()' - Cancel the specified print job. */voidCancelJob(int id, /* I - Job to cancel */ int purge) /* I - Purge jobs? */{ int i; /* Looping var */ job_t *current, /* Current job */ *prev; /* Previous job in list */ char filename[1024]; /* Job filename */ LogMessage(L_DEBUG, "CancelJob: id = %d", id); for (current = Jobs, prev = NULL; current != NULL; prev = current, current = current->next) if (current->id == id) { /* * Stop any processes that are working on the current... */ DEBUG_puts("CancelJob: found job in list."); if (current->state->values[0].integer == IPP_JOB_PROCESSING) StopJob(current->id, 0); current->state->values[0].integer = IPP_JOB_CANCELLED; set_time(current, "time-at-completed"); /* * Remove the print file for good if we aren't preserving jobs or * files... */ current->current_file = 0; if (!JobHistory || !JobFiles || purge || (current->dtype & CUPS_PRINTER_REMOTE)) for (i = 1; i <= current->num_files; i ++) { snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, current->id, i); unlink(filename); } if (JobHistory && !purge && !(current->dtype & CUPS_PRINTER_REMOTE)) { /* * Save job state info... */ SaveJob(current->id); } else { /* * Remove the job info file... */ snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, current->id); unlink(filename); /* * Update pointers if we aren't preserving jobs... */ if (prev == NULL) Jobs = current->next; else prev->next = current->next; /* * Free all memory used... */ if (current->attrs != NULL) ippDelete(current->attrs); if (current->num_files > 0) { free(current->compressions); free(current->filetypes); } ClearString(¤t->username); ClearString(¤t->dest); free(current); NumJobs --; } return; }}/* * 'CancelJobs()' - Cancel all jobs for the given destination/user... */voidCancelJobs(const char *dest, /* I - Destination to cancel */ const char *username, /* I - Username or NULL */ int purge) /* I - Purge jobs? */{ job_t *current, /* Current job */ *next; /* Next job */ for (current = Jobs; current != NULL;) if ((dest == NULL || !strcmp(current->dest, dest)) && (username == NULL || !strcmp(current->username, username))) { /* * Cancel all jobs matching this destination/user... */ next = current->next; CancelJob(current->id, purge); current = next; } else current = current->next; CheckJobs();}/* * 'CheckJobs()' - Check the pending jobs and start any if the destination * is available. */voidCheckJobs(void){ job_t *current, /* Current job in queue */ *next; /* Next job in queue */ printer_t *printer, /* Printer destination */ *pclass; /* Printer class destination */ DEBUG_puts("CheckJobs()"); for (current = Jobs; current != NULL; current = next) { /* * Save next pointer in case the job is cancelled en-route. */ next = current->next; /* * Start held jobs if they are ready... */ if (current->state->values[0].integer == IPP_JOB_HELD && current->hold_until && current->hold_until < time(NULL)) current->state->values[0].integer = IPP_JOB_PENDING; /* * Start pending jobs if the destination is available... */ if (current->state->values[0].integer == IPP_JOB_PENDING && !NeedReload) { if ((pclass = FindClass(current->dest)) != NULL) { /* * If the class is remote, just pass it to the remote server... */ if (pclass->type & CUPS_PRINTER_REMOTE) printer = pclass; else if (pclass->state != IPP_PRINTER_STOPPED) printer = FindAvailablePrinter(current->dest); else printer = NULL; } else printer = FindPrinter(current->dest); if (printer != NULL && (printer->type & CUPS_PRINTER_IMPLICIT)) { /* * Handle implicit classes... */ pclass = printer; if (pclass->state != IPP_PRINTER_STOPPED) printer = FindAvailablePrinter(current->dest); else printer = NULL; } if (printer == NULL && pclass == NULL) { /* * Whoa, the printer and/or class for this destination went away; * cancel the job... */ LogMessage(L_WARN, "Printer/class %s has gone away; cancelling job %d!", current->dest, current->id); CancelJob(current->id, 1); } else if (printer != NULL) { /* * See if the printer is available or remote and not printing a job; * if so, start the job... */ if (printer->state == IPP_PRINTER_IDLE || /* Printer is idle */ ((printer->type & CUPS_PRINTER_REMOTE) && /* Printer is remote */ !printer->job)) /* and not printing a job */ StartJob(current->id, printer); } } }}/* * 'CleanJobs()' - Clean out old jobs. */voidCleanJobs(void){ job_t *job, /* Current job */ *next; /* Next job */ if (MaxJobs == 0) return; for (job = Jobs; job && NumJobs >= MaxJobs; job = next) { next = job->next; if (job->state->values[0].integer >= IPP_JOB_CANCELLED) CancelJob(job->id, 1); }}/* * 'FreeAllJobs()' - Free all jobs from memory. */voidFreeAllJobs(void){ job_t *job, /* Current job */ *next; /* Next job */ HoldSignals(); StopAllJobs(); for (job = Jobs; job; job = next) { next = job->next; ippDelete(job->attrs); if (job->num_files > 0) { free(job->compressions); free(job->filetypes); } free(job); } Jobs = NULL; ReleaseSignals();}/* * 'FindJob()' - Find the specified job. */job_t * /* O - Job data */FindJob(int id) /* I - Job ID */{ job_t *current; /* Current job */ for (current = Jobs; current != NULL; current = current->next) if (current->id == id) break; return (current);}/* * 'GetPrinterJobCount()' - Get the number of pending, processing, * or held jobs in a printer or class. */int /* O - Job count */GetPrinterJobCount(const char *dest) /* I - Printer or class name */{ int count; /* Job count */ job_t *job; /* Current job */ for (job = Jobs, count = 0; job != NULL; job = job->next) if (job->state->values[0].integer <= IPP_JOB_PROCESSING && strcasecmp(job->dest, dest) == 0) count ++; return (count);}/* * 'GetUserJobCount()' - Get the number of pending, processing, * or held jobs for a user. */int /* O - Job count */GetUserJobCount(const char *username) /* I - Username */{ int count; /* Job count */ job_t *job; /* Current job */ for (job = Jobs, count = 0; job != NULL; job = job->next) if (job->state->values[0].integer <= IPP_JOB_PROCESSING && strcmp(job->username, username) == 0) count ++; return (count);}/* * 'HoldJob()' - Hold the specified job. */voidHoldJob(int id) /* I - Job ID */{ job_t *job; /* Job data */ LogMessage(L_DEBUG, "HoldJob: id = %d", id); if ((job = FindJob(id)) == NULL) return; if (job->state->values[0].integer == IPP_JOB_PROCESSING) StopJob(id, 0); DEBUG_puts("HoldJob: setting state to held..."); job->state->values[0].integer = IPP_JOB_HELD; SaveJob(id); CheckJobs();}/* * 'LoadAllJobs()' - Load all jobs from disk. */voidLoadAllJobs(void){ DIR *dir; /* Directory */ DIRENT *dent; /* Directory entry */ char filename[1024]; /* Full filename of job file */ int fd; /* File descriptor */ job_t *job, /* New job */ *current, /* Current job */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -