summaryrefslogtreecommitdiff
path: root/scheduler
diff options
context:
space:
mode:
Diffstat (limited to 'scheduler')
-rw-r--r--scheduler/classes.c3
-rw-r--r--scheduler/dirsvc.c4
-rw-r--r--scheduler/ipp.c36
-rw-r--r--scheduler/job.c27
-rw-r--r--scheduler/printers.c3
-rw-r--r--scheduler/select.c221
6 files changed, 187 insertions, 107 deletions
diff --git a/scheduler/classes.c b/scheduler/classes.c
index 5b06ff739..192c4d01d 100644
--- a/scheduler/classes.c
+++ b/scheduler/classes.c
@@ -256,6 +256,9 @@ cupsdFindAvailablePrinter(
return (NULL);
}
+ if (c->num_printers == 0)
+ return (NULL);
+
/*
* Make sure that the last printer is also a valid index into the printer
* array. If not, reset the last printer to 0...
diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
index dd08c4b17..5303bf898 100644
--- a/scheduler/dirsvc.c
+++ b/scheduler/dirsvc.c
@@ -202,7 +202,7 @@ cupsdDeregisterPrinter(
* Announce the deletion...
*/
- if ((BrowseLocalProtocols & BROWSE_CUPS))
+ if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
{
cups_ptype_t savedtype = p->type; /* Saved printer type */
@@ -866,7 +866,7 @@ cupsdSendBrowseList(void)
p->browse_time = time(NULL);
- if (BrowseLocalProtocols & BROWSE_CUPS)
+ if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
send_cups_browse(p);
#ifdef HAVE_LIBSLP
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index e2b517e88..690a08732 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1274,7 +1274,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
con, con->http.fd, printer, printer->name,
- filetype, filetype->super, filetype->type);
+ filetype, filetype ? filetype->super : "none",
+ filetype ? filetype->type : "none");
/*
* Check remote printing to non-shared printer...
@@ -3158,6 +3159,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */
cupsd_job_t *job; /* Job information */
cups_ptype_t dtype; /* Destination type (printer/class) */
cupsd_printer_t *printer; /* Printer data */
+ int purge; /* Purge the job? */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con,
@@ -3266,6 +3268,16 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */
}
/*
+ * Look for the "purge-job" attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "purge-job",
+ IPP_TAG_BOOLEAN)) != NULL)
+ purge = attr->values[0].boolean;
+ else
+ purge = 0;
+
+ /*
* See if the job exists...
*/
@@ -3294,7 +3306,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */
* we can't cancel...
*/
- if (job->state_value >= IPP_JOB_CANCELED)
+ if (job->state_value >= IPP_JOB_CANCELED && !purge)
{
switch (job->state_value)
{
@@ -3324,11 +3336,15 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */
* Cancel the job and return...
*/
- cupsdCancelJob(job, 0, IPP_JOB_CANCELED);
+ cupsdCancelJob(job, purge, IPP_JOB_CANCELED);
cupsdCheckJobs();
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Canceled by \"%s\".", jobid,
- username);
+ if (purge)
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Purged by \"%s\".", jobid,
+ username);
+ else
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Canceled by \"%s\".", jobid,
+ username);
con->response->request.status.status_code = IPP_OK;
}
@@ -6089,6 +6105,12 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: job->id = %d", job->id);
+ if (!job->dest || !job->username)
+ cupsdLoadJob(job);
+
+ if (!job->dest || !job->username)
+ continue;
+
if ((dest && strcmp(job->dest, dest)) &&
(!job->printer || !dest || strcmp(job->printer->name, dest)))
continue;
@@ -8493,9 +8515,7 @@ save_krb5_creds(cupsd_client_t *con, /* I - Client connection */
krb5_error_code error; /* Kerberos error code */
OM_uint32 major_status, /* Major status code */
minor_status; /* Minor status code */
-# ifdef HAVE_KRB5_CC_NEW_UNIQUE
krb5_principal principal; /* Kerberos principal */
-# endif /* HAVE_KRB5_CC_NEW_UNIQUE */
# ifdef __APPLE__
@@ -8524,7 +8544,7 @@ save_krb5_creds(cupsd_client_t *con, /* I - Client connection */
if ((error = krb5_cc_new_unique(KerberosContext, "FILE", NULL,
&(job->ccache))) != 0)
# else /* HAVE_HEIMDAL */
- if ((error = krb5_cc_gen_new(krb_context, &krb5_fcc_ops,
+ if ((error = krb5_cc_gen_new(KerberosContext, &krb5_fcc_ops,
&(job->ccache))) != 0)
# endif /* HAVE_KRB5_CC_NEW_UNIQUE */
{
diff --git a/scheduler/job.c b/scheduler/job.c
index 4639b336a..9169b4485 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -250,7 +250,7 @@ cupsdCancelJob(cupsd_job_t *job, /* I - Job to cancel */
job->current_file = 0;
- if (!JobHistory || !JobFiles || purge || (job->dtype & CUPS_PRINTER_REMOTE))
+ if (!JobHistory || !JobFiles || purge)
{
for (i = 1; i <= job->num_files; i ++)
{
@@ -270,7 +270,7 @@ cupsdCancelJob(cupsd_job_t *job, /* I - Job to cancel */
}
}
- if (JobHistory && !purge && !(job->dtype & CUPS_PRINTER_REMOTE))
+ if (JobHistory && !purge)
{
/*
* Save job state info...
@@ -318,6 +318,13 @@ cupsdCancelJobs(const char *dest, /* I - Destination to cancel */
for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
job;
job = (cupsd_job_t *)cupsArrayNext(Jobs))
+ {
+ if (!job->dest || !job->username)
+ cupsdLoadJob(job);
+
+ if (!job->dest || !job->username)
+ continue;
+
if ((dest == NULL || !strcmp(job->dest, dest)) &&
(username == NULL || !strcmp(job->username, username)))
{
@@ -327,6 +334,7 @@ cupsdCancelJobs(const char *dest, /* I - Destination to cancel */
cupsdCancelJob(job, purge, IPP_JOB_CANCELED);
}
+ }
cupsdCheckJobs();
}
@@ -2437,7 +2445,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
title[IPP_MAX_NAME],
/* Job title string */
copies[255], /* # copies string */
- *envp[MAX_ENV + 15],
+ *envp[MAX_ENV + 16],
/* Environment variables */
charset[255], /* CHARSET env variable */
class_name[255],/* CLASS env variable */
@@ -2450,6 +2458,10 @@ start_job(cupsd_job_t *job, /* I - Job ID */
final_content_type[1024],
/* FINAL_CONTENT_TYPE env variable */
lang[255], /* LANG env variable */
+#ifdef __APPLE__
+ apple_language[255],
+ /* APPLE_LANGUAGE env variable */
+#endif /* __APPLE__ */
ppd[1024], /* PPD env variable */
printer_name[255],
/* PRINTER env variable */
@@ -2992,6 +3004,12 @@ start_job(cupsd_job_t *job, /* I - Job ID */
attr = ippFindAttribute(job->attrs, "attributes-natural-language",
IPP_TAG_LANGUAGE);
+#ifdef __APPLE__
+ strcpy(apple_language, "APPLE_LANGUAGE");
+ _cupsAppleLanguage(attr->values[0].string.text,
+ apple_language + 15, sizeof(apple_language) - 15);
+#endif /* __APPLE__ */
+
switch (strlen(attr->values[0].string.text))
{
default :
@@ -3052,6 +3070,9 @@ start_job(cupsd_job_t *job, /* I - Job ID */
envp[envc ++] = charset;
envp[envc ++] = lang;
+#ifdef __APPLE__
+ envp[envc ++] = apple_language;
+#endif /* __APPLE__ */
envp[envc ++] = ppd;
envp[envc ++] = rip_max_cache;
envp[envc ++] = content_type;
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 4f69babbe..3571454f5 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -2640,7 +2640,8 @@ cupsdSetPrinterState(
if (old_state != s)
{
- cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE_CHANGED, p, NULL,
+ cupsdAddEvent(s == IPP_PRINTER_STOPPED ? CUPSD_EVENT_PRINTER_STOPPED :
+ CUPSD_EVENT_PRINTER_STATE_CHANGED, p, NULL,
"%s \"%s\" state changed.",
(p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer",
p->name);
diff --git a/scheduler/select.c b/scheduler/select.c
index c6f278e36..a2e1925d1 100644
--- a/scheduler/select.c
+++ b/scheduler/select.c
@@ -33,6 +33,7 @@
#ifdef HAVE_EPOLL
# include <sys/epoll.h>
+# include <sys/poll.h>
#elif defined(HAVE_KQUEUE)
# include <sys/event.h>
# include <sys/time.h>
@@ -167,8 +168,8 @@
*
* In tests using the "make test" target with option 0 (keep cupsd
* running) and the "testspeed" program with "-c 50 -r 1000", epoll()
- * performed 5.5% slower select(), followed by kqueue() at 16% slower
- * than select() and poll() at 18% slower than select(). Similar
+ * performed 5.5% slower than select(), followed by kqueue() at 16%
+ * slower than select() and poll() at 18% slower than select(). Similar
* results were seen with twice the number of client connections.
*
* The epoll() and kqueue() performance is likely limited by the
@@ -214,10 +215,7 @@ static cups_array_t *cupsd_inactive_fds = NULL;
static int cupsd_in_select = 0;
#endif /* HAVE_EPOLL || HAVE_KQUEUE */
-#ifdef HAVE_EPOLL
-static int cupsd_epoll_fd = -1;
-static struct epoll_event *cupsd_epoll_events = NULL;
-#elif defined(HAVE_KQUEUE)
+#ifdef HAVE_KQUEUE
static int cupsd_kqueue_fd = -1,
cupsd_kqueue_changes = 0;
static struct kevent *cupsd_kqueue_events = NULL;
@@ -225,12 +223,16 @@ static struct kevent *cupsd_kqueue_events = NULL;
static int cupsd_alloc_pollfds = 0,
cupsd_update_pollfds = 0;
static struct pollfd *cupsd_pollfds = NULL;
+# ifdef HAVE_EPOLL
+static int cupsd_epoll_fd = -1;
+static struct epoll_event *cupsd_epoll_events = NULL;
+# endif /* HAVE_EPOLL */
#else /* select() */
static fd_set cupsd_global_input,
cupsd_global_output,
cupsd_current_input,
cupsd_current_output;
-#endif /* HAVE_EPOLL */
+#endif /* HAVE_KQUEUE */
/*
@@ -299,26 +301,7 @@ cupsdAddSelect(int fd, /* I - File descriptor */
else
added = 0;
-#ifdef HAVE_EPOLL
- {
- struct epoll_event event; /* Event data */
-
-
- event.events = 0;
-
- if (read_cb)
- event.events |= EPOLLIN;
-
- if (write_cb)
- event.events |= EPOLLOUT;
-
- event.data.ptr = fdptr;
-
- epoll_ctl(cupsd_epoll_fd, added ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd,
- &event);
- }
-
-#elif defined(HAVE_KQUEUE)
+#ifdef HAVE_KQUEUE
{
struct kevent event; /* Event data */
struct timespec timeout; /* Timeout value */
@@ -361,6 +344,33 @@ cupsdAddSelect(int fd, /* I - File descriptor */
}
#elif defined(HAVE_POLL)
+# ifdef HAVE_EPOLL
+ if (cupsd_epoll_fd >= 0)
+ {
+ struct epoll_event event; /* Event data */
+
+
+ event.events = 0;
+
+ if (read_cb)
+ event.events |= EPOLLIN;
+
+ if (write_cb)
+ event.events |= EPOLLOUT;
+
+ event.data.ptr = fdptr;
+
+ if (epoll_ctl(cupsd_epoll_fd, added ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd,
+ &event))
+ {
+ close(cupsd_epoll_fd);
+ cupsd_epoll_fd = -1;
+ cupsd_update_pollfds = 1;
+ }
+ }
+ else
+# endif /* HAVE_EPOLL */
+
cupsd_update_pollfds = 1;
#else /* select() */
@@ -396,7 +406,7 @@ cupsdAddSelect(int fd, /* I - File descriptor */
FD_CLR(fd, &cupsd_global_output);
FD_CLR(fd, &cupsd_current_output);
}
-#endif /* HAVE_EPOLL */
+#endif /* HAVE_KQUEUE */
/*
* Save the (new) read and write callbacks...
@@ -419,53 +429,7 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
{
int nfds; /* Number of file descriptors */
_cupsd_fd_t *fdptr; /* Current file descriptor */
-#ifdef HAVE_EPOLL
- int i; /* Looping var */
- struct epoll_event *event; /* Current event */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdDoSelect: polling %d fds for %ld seconds...",
- cupsArrayCount(cupsd_fds), timeout);
-
- cupsd_in_select = 1;
-
- if (timeout >= 0 && timeout < 86400)
- nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs,
- timeout * 1000);
- else
- nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs, -1);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: epoll() returned %d...",
- nfds);
-
- for (i = nfds, event = cupsd_epoll_events; i > 0; i --, event ++)
- {
- fdptr = (_cupsd_fd_t *)event->data.ptr;
-
- if (cupsArrayFind(cupsd_inactive_fds, fdptr))
- continue;
-
- retain_fd(fdptr);
-
- if (fdptr->read_cb && (event->events & (EPOLLIN | EPOLLERR | EPOLLHUP)))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Read on fd %d...",
- fdptr->fd);
- (*(fdptr->read_cb))(fdptr->data);
- }
-
- if (fdptr->write_cb && (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...",
- fdptr->fd);
- (*(fdptr->write_cb))(fdptr->data);
- }
-
- release_fd(fdptr);
- }
-
-#elif defined(HAVE_KQUEUE)
+#ifdef HAVE_KQUEUE
int i; /* Looping var */
struct kevent *event; /* Current event */
struct timespec ktimeout; /* kevent() timeout */
@@ -528,6 +492,66 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
int count; /* Number of file descriptors */
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "cupsdDoSelect: polling %d fds for %ld seconds...",
+ cupsArrayCount(cupsd_fds), timeout);
+
+# ifdef HAVE_EPOLL
+ cupsd_in_select = 1;
+
+ if (cupsd_epoll_fd >= 0)
+ {
+ int i; /* Looping var */
+ struct epoll_event *event; /* Current event */
+
+
+ if (timeout >= 0 && timeout < 86400)
+ nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs,
+ timeout * 1000);
+ else
+ nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs, -1);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: epoll() returned %d...",
+ nfds);
+
+ if (nfds < 0 && errno != EINTR)
+ {
+ close(cupsd_epoll_fd);
+ cupsd_epoll_fd = -1;
+ }
+ else
+ {
+ for (i = nfds, event = cupsd_epoll_events; i > 0; i --, event ++)
+ {
+ fdptr = (_cupsd_fd_t *)event->data.ptr;
+
+ if (cupsArrayFind(cupsd_inactive_fds, fdptr))
+ continue;
+
+ retain_fd(fdptr);
+
+ if (fdptr->read_cb && (event->events & (EPOLLIN | EPOLLERR | EPOLLHUP)))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Read on fd %d...",
+ fdptr->fd);
+ (*(fdptr->read_cb))(fdptr->data);
+ }
+
+ if (fdptr->write_cb && (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...",
+ fdptr->fd);
+ (*(fdptr->write_cb))(fdptr->data);
+ }
+
+ release_fd(fdptr);
+ }
+
+ goto release_inactive;
+ }
+ }
+# endif /* HAVE_EPOLL */
+
count = cupsArrayCount(cupsd_fds);
if (cupsd_update_pollfds)
@@ -706,13 +730,17 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
}
}
-#endif /* HAVE_EPOLL */
+#endif /* HAVE_KQUEUE */
#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE)
/*
* Release all inactive file descriptors...
*/
+# ifndef HAVE_KQUEUE
+ release_inactive:
+# endif /* !HAVE_KQUEUE */
+
cupsd_in_select = 0;
for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_inactive_fds);
@@ -781,7 +809,12 @@ cupsdRemoveSelect(int fd) /* I - File descriptor */
return;
#ifdef HAVE_EPOLL
- epoll_ctl(cupsd_epoll_fd, EPOLL_CTL_DEL, fd, &event);
+ if (epoll_ctl(cupsd_epoll_fd, EPOLL_CTL_DEL, fd, &event))
+ {
+ close(cupsd_epoll_fd);
+ cupsd_epoll_fd = -1;
+ cupsd_update_pollfds = 1;
+ }
#elif defined(HAVE_KQUEUE)
timeout.tv_sec = 0;
@@ -862,8 +895,9 @@ cupsdStartSelect(void)
#endif /* HAVE_EPOLL || HAVE_KQUEUE */
#ifdef HAVE_EPOLL
- cupsd_epoll_fd = epoll_create(MaxFDs);
- cupsd_epoll_events = calloc(MaxFDs, sizeof(struct epoll_event));
+ cupsd_epoll_fd = epoll_create(MaxFDs);
+ cupsd_epoll_events = calloc(MaxFDs, sizeof(struct epoll_event));
+ cupsd_update_pollfds = 0;
#elif defined(HAVE_KQUEUE)
cupsd_kqueue_fd = kqueue();
@@ -903,20 +937,7 @@ cupsdStopSelect(void)
cupsd_inactive_fds = NULL;
#endif /* HAVE_EPOLL || HAVE_KQUEUE */
-#ifdef HAVE_EPOLL
- if (cupsd_epoll_events)
- {
- free(cupsd_epoll_events);
- cupsd_epoll_events = NULL;
- }
-
- if (cupsd_epoll_fd >= 0)
- {
- close(cupsd_epoll_fd);
- cupsd_epoll_fd = -1;
- }
-
-#elif defined(HAVE_KQUEUE)
+#ifdef HAVE_KQUEUE
if (cupsd_kqueue_events)
{
free(cupsd_kqueue_events);
@@ -932,6 +953,20 @@ cupsdStopSelect(void)
cupsd_kqueue_changes = 0;
#elif defined(HAVE_POLL)
+# ifdef HAVE_EPOLL
+ if (cupsd_epoll_events)
+ {
+ free(cupsd_epoll_events);
+ cupsd_epoll_events = NULL;
+ }
+
+ if (cupsd_epoll_fd >= 0)
+ {
+ close(cupsd_epoll_fd);
+ cupsd_epoll_fd = -1;
+ }
+# endif /* HAVE_EPOLL */
+
if (cupsd_pollfds)
{
free(cupsd_pollfds);