#include <grp.h>
#include <cups/backend.h>
#include <cups/dir.h>
+#ifdef __APPLE__
+# include <IOKit/pwr_mgt/IOPMLib.h>
+# ifdef HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H
+# include <IOKit/pwr_mgt/IOPMLibPrivate.h>
+# endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
+#endif /* __APPLE__ */
/*
* Start pending jobs if the destination is available...
*/
- if (job->state_value == IPP_JOB_PENDING && !NeedReload && !Sleeping &&
+ if (job->state_value == IPP_JOB_PENDING && !NeedReload &&
+#ifndef kIOPMAssertionTypeDenySystemSleep
+ !Sleeping &&
+#endif /* !kIOPMAssertionTypeDenySystemSleep */
!DoingShutdown && !job->printer)
{
printer = cupsdFindDest(job->dest);
int filterfds[2][2] = { { -1, -1 }, { -1, -1 } };
/* Pipes used between filters */
int envc; /* Number of environment variables */
+ struct stat fileinfo; /* Job file information */
char **argv = NULL, /* Filter command-line arguments */
filename[1024], /* Job filename */
command[1024], /* Full path to command */
* Local jobs get filtered...
*/
- filters = mimeFilter(MimeDatabase, job->filetypes[job->current_file],
- job->printer->filetype, &(job->cost));
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
+ job->id, job->current_file + 1);
+ if (stat(filename, &fileinfo))
+ fileinfo.st_size = 0;
+
+ filters = mimeFilter2(MimeDatabase, job->filetypes[job->current_file],
+ fileinfo.st_size, job->printer->filetype,
+ &(job->cost));
if (!filters)
{
banner_page = 0;
else if (job->job_sheets == NULL)
banner_page = 0;
- else if (strcasecmp(job->job_sheets->values[0].string.text, "none") != 0 &&
+ else if (_cups_strcasecmp(job->job_sheets->values[0].string.text, "none") != 0 &&
job->current_file == 0)
banner_page = 1;
else if (job->job_sheets->num_values > 1 &&
- strcasecmp(job->job_sheets->values[1].string.text, "none") != 0 &&
+ _cups_strcasecmp(job->job_sheets->values[1].string.text, "none") != 0 &&
job->current_file == (job->num_files - 1))
banner_page = 1;
else
}
envp[envc ++] = auth_info_required;
- if (job->auth_username)
- envp[envc ++] = job->auth_username;
- if (job->auth_domain)
- envp[envc ++] = job->auth_domain;
- if (job->auth_password)
- envp[envc ++] = job->auth_password;
+
+ for (i = 0;
+ i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
+ i ++)
+ if (job->auth_env[i])
+ envp[envc ++] = job->auth_env[i];
+ else
+ break;
+
if (job->auth_uid)
envp[envc ++] = job->auth_uid;
cupsdDeleteJob(cupsd_job_t *job, /* I - Job */
cupsd_jobaction_t action)/* I - Action */
{
+ int i; /* Looping var */
char filename[1024]; /* Job filename */
snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot,
job->id);
- unlink(filename);
+ if (Classification)
+ cupsdRemoveFile(filename);
+ else
+ unlink(filename);
}
cupsdClearString(&job->username);
cupsdClearString(&job->dest);
- cupsdClearString(&job->auth_username);
- cupsdClearString(&job->auth_domain);
- cupsdClearString(&job->auth_password);
+ for (i = 0;
+ i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
+ i ++)
+ cupsdClearString(job->auth_env + i);
cupsdClearString(&job->auth_uid);
if (job->num_files > 0)
free(job->compressions);
free(job->filetypes);
- while (job->num_files > 0)
+ if (action == CUPSD_JOB_PURGE)
{
- snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
- job->id, job->num_files);
- unlink(filename);
+ while (job->num_files > 0)
+ {
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
+ job->id, job->num_files);
+ if (Classification)
+ cupsdRemoveFile(filename);
+ else
+ unlink(filename);
- job->num_files --;
+ job->num_files --;
+ }
}
+ else
+ job->num_files = 0;
}
if (job->history)
for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0;
job;
job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
- if (job->dest && !strcasecmp(job->dest, dest))
+ if (job->dest && !_cups_strcasecmp(job->dest, dest))
count ++;
return (count);
for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0;
job;
job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
- if (!strcasecmp(job->username, username))
+ if (!_cups_strcasecmp(job->username, username))
count ++;
return (count);
int /* O - 1 on success, 0 on failure */
cupsdLoadJob(cupsd_job_t *job) /* I - Job */
{
+ int i; /* Looping var */
char jobfile[1024]; /* Job filename */
cups_file_t *fp; /* Job file */
int fileid; /* Current file ID */
snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id);
if ((fp = cupsFileOpen(jobfile, "r")) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to open job control file \"%s\" - %s!",
- job->id, jobfile, strerror(errno));
- goto error;
+ char newfile[1024]; /* New job filename */
+
+ snprintf(newfile, sizeof(newfile), "%s/c%05d.N", RequestRoot, job->id);
+ if ((fp = cupsFileOpen(newfile, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Job %d] Unable to open job control file \"%s\": %s",
+ job->id, jobfile, strerror(errno));
+ goto error;
+ }
+
+ unlink(jobfile);
+ rename(newfile, jobfile);
}
if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to read job control file \"%s\"!", job->id,
+ "[Job %d] Unable to read job control file \"%s\".", job->id,
jobfile);
cupsFileClose(fp);
goto error;
{
snprintf(jobfile, sizeof(jobfile), "%s/a%05d", RequestRoot, job->id);
- cupsdClearString(&job->auth_username);
- cupsdClearString(&job->auth_domain);
- cupsdClearString(&job->auth_password);
+ for (i = 0;
+ i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
+ i ++)
+ cupsdClearString(job->auth_env + i);
cupsdClearString(&job->auth_uid);
if ((fp = cupsFileOpen(jobfile, "r")) != NULL)
{
- int i, /* Looping var */
- bytes; /* Size of auth data */
- char line[255], /* Line from file */
- data[255]; /* Decoded data */
+ int bytes; /* Size of auth data */
+ char line[65536], /* Line from file */
+ data[65536]; /* Decoded data */
for (i = 0;
i < destptr->num_auth_info_required &&
+ i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])) &&
cupsFileGets(fp, line, sizeof(line));
i ++)
{
httpDecode64_2(data, &bytes, line);
if (!strcmp(destptr->auth_info_required[i], "username"))
- cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s", data);
+ cupsdSetStringf(job->auth_env + i, "AUTH_USERNAME=%s", data);
else if (!strcmp(destptr->auth_info_required[i], "domain"))
- cupsdSetStringf(&job->auth_domain, "AUTH_DOMAIN=%s", data);
+ cupsdSetStringf(job->auth_env + i, "AUTH_DOMAIN=%s", data);
else if (!strcmp(destptr->auth_info_required[i], "password"))
- cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", data);
- else if (!strcmp(destptr->auth_info_required[i], "negotiate") &&
- isdigit(line[0] & 255))
- cupsdSetStringf(&job->auth_uid, "AUTH_UID=%s", line);
+ cupsdSetStringf(job->auth_env + i, "AUTH_PASSWORD=%s", data);
+ else if (!strcmp(destptr->auth_info_required[i], "negotiate"))
+ cupsdSetStringf(job->auth_env + i, "AUTH_NEGOTIATE=%s", line);
}
if (cupsFileGets(fp, line, sizeof(line)) && isdigit(line[0] & 255))
job->num_files = 0;
- unlink(jobfile);
+ if (Classification)
+ cupsdRemoveFile(jobfile);
+ else
+ unlink(jobfile);
return (0);
}
cupsdSaveAllJobs(void)
{
int i; /* Looping var */
- cups_file_t *fp; /* Job cache file */
- char temp[1024]; /* Temporary string */
+ cups_file_t *fp; /* job.cache file */
+ char filename[1024], /* job.cache filename */
+ temp[1024]; /* Temporary string */
cupsd_job_t *job; /* Current job */
time_t curtime; /* Current time */
struct tm *curdate; /* Current date */
- snprintf(temp, sizeof(temp), "%s/job.cache", CacheDir);
- if ((fp = cupsFileOpen(temp, "w")) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create job cache file \"%s\" - %s",
- temp, strerror(errno));
+ snprintf(filename, sizeof(filename), "%s/job.cache", CacheDir);
+ if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
return;
- }
- cupsdLogMessage(CUPSD_LOG_INFO, "Saving job cache file \"%s\"...", temp);
-
- /*
- * Restrict access to the file...
- */
-
- fchown(cupsFileNumber(fp), getuid(), Group);
- fchmod(cupsFileNumber(fp), ConfigFilePerm);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Saving job.cache...");
/*
* Write a small header to the file...
cupsFilePuts(fp, "</Job>\n");
}
- cupsFileClose(fp);
+ cupsdCloseCreatedConfFile(fp, filename);
}
void
cupsdSaveJob(cupsd_job_t *job) /* I - Job */
{
- char filename[1024]; /* Job control filename */
+ char filename[1024], /* Job control filename */
+ newfile[1024]; /* New job control filename */
cups_file_t *fp; /* Job file */
job, job->id, job->attrs);
snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
+ snprintf(newfile, sizeof(newfile), "%s/c%05d.N", RequestRoot, job->id);
- if ((fp = cupsFileOpen(filename, "w")) == NULL)
+ if ((fp = cupsFileOpen(newfile, "w")) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to create job control file \"%s\" - %s.",
- job->id, filename, strerror(errno));
+ "[Job %d] Unable to create job control file \"%s\": %s",
+ job->id, newfile, strerror(errno));
return;
}
if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
job->attrs) != IPP_DATA)
+ {
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to write job control file!", job->id);
-
- cupsFileClose(fp);
+ "[Job %d] Unable to write job control file.", job->id);
+ cupsFileClose(fp);
+ unlink(newfile);
+ return;
+ }
- job->dirty = 0;
+ if (cupsFileClose(fp))
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Job %d] Unable to close job control file: %s",
+ job->id, strerror(errno));
+ else
+ {
+ unlink(filename);
+ if (rename(newfile, filename))
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Job %d] Unable to finalize job control file: %s",
+ job->id, strerror(errno));
+ else
+ job->dirty = 0;
+ }
}
if (!cupsdLoadJob(job))
return;
- /*
- * Don't do anything if the state is unchanged and we aren't purging the
- * job...
- */
+ /*
+ * Don't do anything if the state is unchanged and we aren't purging the
+ * job...
+ */
- oldstate = job->state_value;
- if (newstate == oldstate && action != CUPSD_JOB_PURGE)
- return;
+ oldstate = job->state_value;
+ if (newstate == oldstate && action != CUPSD_JOB_PURGE)
+ return;
/*
* Stop any processes that are working on the current job...
"Unable to remove authentication cache: %s",
strerror(errno));
- cupsdClearString(&job->auth_username);
- cupsdClearString(&job->auth_domain);
- cupsdClearString(&job->auth_password);
+ for (i = 0;
+ i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
+ i ++)
+ cupsdClearString(job->auth_env + i);
+
cupsdClearString(&job->auth_uid);
/*
{
snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
job->id, i);
- unlink(filename);
+ if (Classification)
+ cupsdRemoveFile(filename);
+ else
+ unlink(filename);
}
if (job->num_files > 0)
int diff; /* Difference */
+ (void)data;
+
if ((diff = ((cupsd_job_t *)second)->priority -
((cupsd_job_t *)first)->priority) != 0)
return (diff);
void *second, /* I - Second job */
void *data) /* I - App data (not used) */
{
+ (void)data;
+
return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id);
}
int exit_code; /* Exit code from backend */
-
/*
* Convert the status to an exit code. Due to the way the W* macros are
* implemented on MacOS X (bug?), we have to store the exit status in a
* Update the printer and job state.
*/
- if (job_state != job->state_value)
+ if (set_job_state && job_state != job->state_value)
cupsdSetJobState(job, job_state, CUPSD_JOB_DEFAULT, "%s", message);
cupsdSetPrinterState(job->printer, printer_state,
if (job->history)
{
- if (job->status)
+ if (job->status &&
+ (job->state_value == IPP_JOB_ABORTED ||
+ job->state_value == IPP_JOB_STOPPED))
dump_job_history(job);
else
free_job_history(job);
* Then allocate/reallocate the option buffer as needed...
*/
+ if (newlength == 0) /* This can never happen, but Clang */
+ newlength = 1; /* thinks it can... */
+
if (newlength > optlength || !options)
{
if (!options)
!strncmp(attr->name, "number-up", 9) ||
!strcmp(attr->name, "page-ranges") ||
!strcmp(attr->name, "page-set") ||
- !strcasecmp(attr->name, "AP_FIRSTPAGE_InputSlot") ||
- !strcasecmp(attr->name, "AP_FIRSTPAGE_ManualFeed") ||
- !strcasecmp(attr->name, "com.apple.print.PrintSettings."
+ !_cups_strcasecmp(attr->name, "AP_FIRSTPAGE_InputSlot") ||
+ !_cups_strcasecmp(attr->name, "AP_FIRSTPAGE_ManualFeed") ||
+ !_cups_strcasecmp(attr->name, "com.apple.print.PrintSettings."
"PMTotalSidesImaged..n.") ||
- !strcasecmp(attr->name, "com.apple.print.PrintSettings."
+ !_cups_strcasecmp(attr->name, "com.apple.print.PrintSettings."
"PMTotalBeginPages..n.")) &&
banner_page)
continue;
* Open the job.cache file...
*/
- if ((fp = cupsFileOpen(filename, "r")) == NULL)
+ if ((fp = cupsdOpenConfFile(filename)) == NULL)
{
- if (errno != ENOENT)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to open job cache file \"%s\": %s",
- filename, strerror(errno));
-
load_request_root();
-
return;
}
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
{
- if (!strcasecmp(line, "NextJobId"))
+ if (!_cups_strcasecmp(line, "NextJobId"))
{
if (value)
NextJobId = atoi(value);
}
- else if (!strcasecmp(line, "<Job"))
+ else if (!_cups_strcasecmp(line, "<Job"))
{
if (job)
{
snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, jobid);
if (access(jobfile, 0))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away!",
- jobid);
- continue;
+ snprintf(jobfile, sizeof(jobfile), "%s/c%05d.N", RequestRoot, jobid);
+ if (access(jobfile, 0))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away!",
+ jobid);
+ continue;
+ }
}
job = calloc(1, sizeof(cupsd_job_t));
"Missing <Job #> directive on line %d!", linenum);
continue;
}
- else if (!strcasecmp(line, "</Job>"))
+ else if (!_cups_strcasecmp(line, "</Job>"))
{
cupsArrayAdd(Jobs, job);
cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d!", linenum);
continue;
}
- else if (!strcasecmp(line, "State"))
+ else if (!_cups_strcasecmp(line, "State"))
{
job->state_value = (ipp_jstate_t)atoi(value);
else if (job->state_value > IPP_JOB_COMPLETED)
job->state_value = IPP_JOB_COMPLETED;
}
- else if (!strcasecmp(line, "HoldUntil"))
+ else if (!_cups_strcasecmp(line, "HoldUntil"))
{
job->hold_until = atoi(value);
}
- else if (!strcasecmp(line, "Priority"))
+ else if (!_cups_strcasecmp(line, "Priority"))
{
job->priority = atoi(value);
}
- else if (!strcasecmp(line, "Username"))
+ else if (!_cups_strcasecmp(line, "Username"))
{
cupsdSetString(&job->username, value);
}
- else if (!strcasecmp(line, "Destination"))
+ else if (!_cups_strcasecmp(line, "Destination"))
{
cupsdSetString(&job->dest, value);
}
- else if (!strcasecmp(line, "DestType"))
+ else if (!_cups_strcasecmp(line, "DestType"))
{
job->dtype = (cups_ptype_t)atoi(value);
}
- else if (!strcasecmp(line, "NumFiles"))
+ else if (!_cups_strcasecmp(line, "NumFiles"))
{
job->num_files = atoi(value);
}
}
}
- else if (!strcasecmp(line, "File"))
+ else if (!_cups_strcasecmp(line, "File"))
{
int number, /* File number */
compression; /* Compression value */
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
{
- if (!strcasecmp(line, "NextJobId"))
+ if (!_cups_strcasecmp(line, "NextJobId"))
{
if (value)
{
if (!cupsdLoadJob(job))
return;
+ if (job->printer_message)
+ cupsdSetString(&(job->printer_message->values[0].string.text), "");
+
cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
cupsdSetPrinterState(printer, IPP_PRINTER_PROCESSING, 0);
cupsdSetPrinterReasons(printer, "-cups-remote-pending,"
job->status_buffer = cupsdStatBufNew(job->status_pipes[0], NULL);
job->status_level = CUPSD_LOG_INFO;
- if (job->printer_message)
- cupsdSetString(&(job->printer_message->values[0].string.text), "");
-
/*
* Create the backchannel pipes and make them non-blocking...
*/
if (job->sheets)
{
- if (!strncasecmp(message, "total ", 6))
+ if (!_cups_strncasecmp(message, "total ", 6))
{
/*
* Got a total count of pages from a backend or filter...