diff options
Diffstat (limited to 'scheduler')
-rw-r--r-- | scheduler/classes.c | 3 | ||||
-rw-r--r-- | scheduler/dirsvc.c | 4 | ||||
-rw-r--r-- | scheduler/ipp.c | 36 | ||||
-rw-r--r-- | scheduler/job.c | 27 | ||||
-rw-r--r-- | scheduler/printers.c | 3 | ||||
-rw-r--r-- | scheduler/select.c | 221 |
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); |