Projects
openEuler:24.03:SP1:Everything
cups
_service:tar_scm:backport-delay-creating-driver...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-delay-creating-driverless-printer-until-ppd-generated.patch of Package cups
From df3718b09f395d59b454e0aa233490ba7f2aa857 Mon Sep 17 00:00:00 2001 From: Michael R Sweet <msweet@msweet.org> Date: Thu, 4 Apr 2024 16:25:25 -0400 Subject: [PATCH] Update CUPS-Add-Modify-Printer and CUPS-Create-Local-Printer code to delay responding until the PPD is successfully generated (Issue #347) --- scheduler/auth.c | 15 +- scheduler/auth.h | 2 - scheduler/client.h | 2 + scheduler/cupsd.h | 9 + scheduler/ipp.c | 383 ++++++++++++++++++++++++++++--------------- scheduler/policy.h | 2 - scheduler/printers.c | 6 +- scheduler/printers.h | 2 - 8 files changed, 271 insertions(+), 150 deletions(-) --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -105,7 +105,7 @@ cupsd_authmask_t temp; /* New host/domain mask */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddIPMask(masks=%p(%p), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)", masks, *masks, address[0], address[1], address[2], address[3], netmask[0], netmask[1], netmask[2], netmask[3]); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddIPMask(masks=%p(%p), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)", (void *)masks, (void *)*masks, address[0], address[1], address[2], address[3], netmask[0], netmask[1], netmask[2], netmask[3]); temp.type = CUPSD_AUTH_IP; memcpy(temp.mask.ip.address, address, sizeof(temp.mask.ip.address)); @@ -158,7 +158,7 @@ cupsdAddName(cupsd_location_t *loc, /* I - Location to add to */ char *name) /* I - Name to add */ { - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")", loc, name); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")", (void *)loc, name); if (!loc->names) loc->names = cupsArrayNew3(NULL, NULL, NULL, 0, @@ -188,7 +188,7 @@ *ifptr; /* Pointer to end of name */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddNameMask(masks=%p(%p), name=\"%s\")", masks, *masks, name); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddNameMask(masks=%p(%p), name=\"%s\")", (void *)masks, (void *)*masks, name); if (!_cups_strcasecmp(name, "@LOCAL")) { @@ -274,7 +274,7 @@ con->best = cupsdFindBest(con->uri, httpGetState(con->http)); con->type = CUPSD_AUTH_NONE; - cupsdLogClient(con, CUPSD_LOG_DEBUG2, "con->uri=\"%s\", con->best=%p(%s)", con->uri, con->best, con->best ? con->best->location : ""); + cupsdLogClient(con, CUPSD_LOG_DEBUG2, "con->uri=\"%s\", con->best=%p(%s)", con->uri, (void *)con->best, con->best ? con->best->location : ""); if (con->best && con->best->type != CUPSD_AUTH_NONE) { @@ -1143,7 +1143,7 @@ #endif /* HAVE_MBR_UID_TO_UUID */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")", username, user, groupname); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")", username, (void *)user, groupname); /* * Validate input... @@ -1558,7 +1558,7 @@ }; - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)", con->uri, con->best, con->best ? con->best->location ? con->best->location : "(null)" : ""); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)", con->uri, (void *)con->best, con->best ? con->best->location ? con->best->location : "(null)" : ""); if (owner) cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: owner=\"%s\"", owner); @@ -2129,7 +2129,6 @@ free(snap_name); g_clear_object(&snap); - # endif // CUPS_SNAP done: @@ -2140,6 +2139,8 @@ return (ret); #else + (void)con; + // No AppArmor/snapd to deal with... return (1); #endif // HAVE_LIBAPPARMOR && HAVE_LIBSNAPDGLIB --- a/scheduler/auth.h +++ b/scheduler/auth.h @@ -98,8 +98,6 @@ http_encryption_t encryption; /* To encrypt or not to encrypt... */ } cupsd_location_t; -typedef struct cupsd_client_s cupsd_client_t; - /* * Globals... --- a/scheduler/client.h +++ b/scheduler/client.h @@ -42,6 +42,8 @@ *query_string; /* QUERY_STRING environment variable */ int file; /* Input/output file */ int file_ready; /* Input ready on file/pipe? */ + int bg_pending; /* Background response pending? */ + cupsd_printer_t *bg_printer; /* Background printer */ int pipe_pid; /* Pipe process ID (or 0 if not a pipe) */ http_status_t pipe_status; /* HTTP status from pipe process */ int sent_header, /* Non-zero if sent HTTP header */ --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -100,6 +100,15 @@ /* + * Base types... + */ + +typedef struct cupsd_client_s cupsd_client_t; +typedef struct cupsd_job_s cupsd_job_t; +typedef struct cupsd_printer_s cupsd_printer_t; + + +/* * Other stuff for the scheduler... */ --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -73,7 +73,7 @@ cups_array_t *ra, cups_array_t *exclude); static void create_job(cupsd_client_t *con, ipp_attribute_t *uri); -static void *create_local_bg_thread(cupsd_printer_t *printer); +static void *create_local_bg_thread(cupsd_client_t *con); static void create_local_printer(cupsd_client_t *con); static cups_array_t *create_requested_array(ipp_t *request); static void create_subscriptions(cupsd_client_t *con, ipp_attribute_t *uri); @@ -111,6 +111,7 @@ static void send_http_error(cupsd_client_t *con, http_status_t status, cupsd_printer_t *printer); static void send_ipp_status(cupsd_client_t *con, ipp_status_t status, const char *message, ...) _CUPS_FORMAT(3, 4); +static int send_response(cupsd_client_t *con); static void set_default(cupsd_client_t *con, ipp_attribute_t *uri); static void set_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri); static void set_printer_attrs(cupsd_client_t *con, ipp_attribute_t *uri); @@ -143,7 +144,7 @@ int valid = 1; /* Valid request? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdProcessIPPRequest(%p[%d]): operation_id=%04x(%s)", con, con->number, con->request->request.op.operation_id, ippOpString(con->request->request.op.operation_id)); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdProcessIPPRequest(%p[%d]): operation_id=%04x(%s)", (void *)con, con->number, con->request->request.op.operation_id, ippOpString(con->request->request.op.operation_id)); if (LogLevel >= CUPSD_LOG_DEBUG2) { @@ -615,68 +616,13 @@ } } - if (con->response) + if (!con->bg_pending && con->response) { /* * Sending data from the scheduler... */ - cupsdLogClient(con, con->response->request.status.status_code >= IPP_STATUS_ERROR_BAD_REQUEST && con->response->request.status.status_code != IPP_STATUS_ERROR_NOT_FOUND ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG, "Returning IPP %s for %s (%s) from %s.", ippErrorString(con->response->request.status.status_code), ippOpString(con->request->request.op.operation_id), uri ? uri->values[0].string.text : "no URI", con->http->hostname); - - httpClearFields(con->http); - -#ifdef CUPSD_USE_CHUNKING - /* - * Because older versions of CUPS (1.1.17 and older) and some IPP - * clients do not implement chunking properly, we cannot use - * chunking by default. This may become the default in future - * CUPS releases, or we might add a configuration directive for - * it. - */ - - if (con->http->version == HTTP_1_1) - { - cupsdLogClient(con, CUPSD_LOG_DEBUG, "Transfer-Encoding: chunked"); - cupsdSetLength(con->http, 0); - } - else -#endif /* CUPSD_USE_CHUNKING */ - { - size_t length; /* Length of response */ - - - length = ippLength(con->response); - - if (con->file >= 0 && !con->pipe_pid) - { - struct stat fileinfo; /* File information */ - - if (!fstat(con->file, &fileinfo)) - length += (size_t)fileinfo.st_size; - } - - cupsdLogClient(con, CUPSD_LOG_DEBUG, "Content-Length: " CUPS_LLFMT, CUPS_LLCAST length); - httpSetLength(con->http, length); - } - - if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE)) - { - /* - * Tell the caller the response header was sent successfully... - */ - - cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient, (cupsd_selfunc_t)cupsdWriteClient, con); - - return (1); - } - else - { - /* - * Tell the caller the response header could not be sent... - */ - - return (0); - } + return (send_response(con)); } else { @@ -747,7 +693,7 @@ cupsd_printer_t *printer; /* Printer data */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "accept_jobs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "accept_jobs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -832,7 +778,7 @@ int need_restart_job; /* Need to restart job? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_class(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_class(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -1142,7 +1088,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_file(con=%p[%d], job=%d, filetype=%s/%s, " - "compression=%d)", con, con ? con->number : -1, job->id, + "compression=%d)", (void *)con, con ? con->number : -1, job->id, filetype->super, filetype->type, compression); /* @@ -1245,8 +1191,8 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", - con, con->number, printer, printer->name, - filetype, filetype ? filetype->super : "none", + (void *)con, con->number, (void *)printer, printer->name, + (void *)filetype, filetype ? filetype->super : "none", filetype ? filetype->type : "none"); /* @@ -2226,7 +2172,7 @@ set_port_monitor; /* Did we set the port monitor? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -2717,8 +2663,21 @@ return; } - // Run a background thread to create the PPD... - _cupsThreadCreate((_cups_thread_func_t)create_local_bg_thread, printer); + if (!printer->printer_id) + printer->printer_id = NextPrinterId ++; + + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + cupsdSetPrinterAttrs(printer); + + /* Run a background thread to create the PPD... */ + cupsdLogClient(con, CUPSD_LOG_DEBUG, "Creating PPD in background thread."); + + con->bg_pending = 1; + con->bg_printer = printer; + + _cupsThreadCreate((_cups_thread_func_t)create_local_bg_thread, con); + return; } else if (!strcmp(ppd_name, "raw")) { @@ -2883,7 +2842,7 @@ { cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer_state_reasons(%p[%d], %p[%s])", - con, con->number, p, p->name); + (void *)con, con->number, (void *)p, p->name); if (p->num_reasons == 0) ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, @@ -2909,7 +2868,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])", - con, con->number, p, p->name); + (void *)con, con->number, (void *)p, p->name); count = cupsdGetPrinterJobCount(p->name); @@ -2999,7 +2958,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)", - con, con->number, uri->values[0].string.text); + (void *)con, con->number, uri->values[0].string.text); /* * Start with "everything is OK" status... @@ -3177,7 +3136,7 @@ cupsd_job_t *job; /* Job */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -3414,7 +3373,7 @@ cupsd_jobaction_t purge; /* Purge the job? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -3615,7 +3574,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_subscription(con=%p[%d], sub_id=%d)", - con, con->number, sub_id); + (void *)con, con->number, sub_id); /* * Is the subscription ID valid? @@ -3721,7 +3680,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])", - con, con->number, p, p->name); + (void *)con, con->number, (void *)p, p->name); /* * Figure out who is printing... @@ -3943,7 +3902,7 @@ username[256]; /* User name */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "close_job(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "close_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -4063,7 +4022,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_attrs(to=%p, from=%p, ra=%p, group=%x, quickcopy=%d)", - to, from, ra, group, quickcopy); + (void *)to, (void *)from, (void *)ra, group, quickcopy); if (!to || !from) return; @@ -4147,7 +4106,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner(con=%p[%d], job=%p[%d], name=\"%s\")", - con, con ? con->number : -1, job, job->id, + (void *)con, con ? con->number : -1, (void *)job, job->id, name ? name : "(null)"); /* @@ -4492,7 +4451,7 @@ /* cupsProtocol attribute */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_model(con=%p, from=\"%s\", to=\"%s\")", con, from, to); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_model(con=%p, from=\"%s\", to=\"%s\")", (void *)con, from, to); /* * Run cups-driverd to get the PPD file... @@ -5106,7 +5065,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_subscription_attrs(con=%p, sub=%p, ra=%p, exclude=%p)", - con, sub, ra, exclude); + (void *)con, (void *)sub, (void *)ra, (void *)exclude); /* * Copy the subscription attributes to the response using the @@ -5220,7 +5179,7 @@ }; - cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -5285,11 +5244,14 @@ static void * /* O - Exit status */ create_local_bg_thread( - cupsd_printer_t *printer) /* I - Printer */ + cupsd_client_t *con) /* I - Client */ { + cupsd_printer_t *printer = con->bg_printer; + /* Printer */ cups_file_t *from, /* Source file */ *to; /* Destination file */ - char fromppd[1024], /* Source PPD */ + char device_uri[1024], /* Device URI */ + fromppd[1024], /* Source PPD */ toppd[1024], /* Destination PPD */ scheme[32], /* URI scheme */ userpass[256], /* User:pass */ @@ -5301,7 +5263,7 @@ http_encryption_t encryption; /* Type of encryption to use */ http_t *http; /* Connection to printer */ ipp_t *request, /* Request to printer */ - *response; /* Response from printer */ + *response = NULL; /* Response from printer */ ipp_attribute_t *attr; /* Attribute in response */ ipp_status_t status; /* Status code */ static const char * const pattrs[] = /* Printer attributes we need */ @@ -5315,26 +5277,47 @@ * Try connecting to the printer... */ - cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Generating PPD file from \"%s\"...", printer->name, printer->device_uri); + _cupsRWLockRead(&printer->lock); + strlcpy(device_uri, printer->device_uri, sizeof(device_uri)); + _cupsRWUnlock(&printer->lock); + cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Generating PPD file from \"%s\"...", printer->name, device_uri); - if (strstr(printer->device_uri, "._tcp")) + if (strstr(device_uri, "._tcp")) { - cupsdLogMessage(CUPSD_LOG_DEBUG2, "%s: Resolving mDNS URI \"%s\".", printer->name, printer->device_uri); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "%s: Resolving mDNS URI \"%s\".", printer->name, device_uri); - if (!_httpResolveURI(printer->device_uri, uri, sizeof(uri), _HTTP_RESOLVE_DEFAULT, NULL, NULL)) + if (!_httpResolveURI(device_uri, uri, sizeof(uri), _HTTP_RESOLVE_DEFAULT, NULL, NULL)) { - cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Couldn't resolve mDNS URI \"%s\".", printer->name, printer->device_uri); - return (NULL); + cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Couldn't resolve mDNS URI \"%s\".", printer->name, device_uri); + + /* Force printer to timeout and be deleted */ + _cupsRWLockWrite(&printer->lock); + printer->state_time = 0; + _cupsRWUnlock(&printer->lock); + + send_ipp_status(con, IPP_STATUS_ERROR_DEVICE, _("Couldn't resolve mDNS URI \"%s\"."), printer->device_uri); + goto finish_response; } + _cupsRWLockWrite(&printer->lock); cupsdSetString(&printer->device_uri, uri); + _cupsRWUnlock(&printer->lock); + + strlcpy(device_uri, uri, sizeof(device_uri)); } - if (httpSeparateURI(HTTP_URI_CODING_ALL, printer->device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) + if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) { - cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Bad device URI \"%s\".", printer->name, printer->device_uri); - return (NULL); + cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Bad device URI \"%s\".", printer->name, device_uri); + + /* Force printer to timeout and be deleted */ + _cupsRWLockWrite(&printer->lock); + printer->state_time = 0; + _cupsRWUnlock(&printer->lock); + + send_ipp_status(con, IPP_STATUS_ERROR_DEVICE, _("Bad device URI \"%s\"."), device_uri); + goto finish_response; } if (!strcmp(scheme, "ipps") || port == 443) @@ -5345,7 +5328,14 @@ if ((http = httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to connect to %s:%d: %s", printer->name, host, port, cupsLastErrorString()); - return (NULL); + + /* Force printer to timeout and be deleted */ + _cupsRWLockWrite(&printer->lock); + printer->state_time = 0; + _cupsRWUnlock(&printer->lock); + + send_ipp_status(con, IPP_STATUS_ERROR_DEVICE, _("Unable to connect to %s:%d: %s"), host, port, cupsLastErrorString()); + goto finish_response; } /* @@ -5389,6 +5379,7 @@ * If we did not succeed to obtain the "media-col-database" attribute * try to get it separately */ + if (ippFindAttribute(response, "media-col-database", IPP_TAG_ZERO) == NULL) { @@ -5447,17 +5438,29 @@ if ((from = cupsFileOpen(fromppd, "r")) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to read generated PPD: %s", printer->name, strerror(errno)); - ippDelete(response); - return (NULL); + + /* Force printer to timeout and be deleted */ + _cupsRWLockWrite(&printer->lock); + printer->state_time = 0; + _cupsRWUnlock(&printer->lock); + + send_ipp_status(con, IPP_STATUS_ERROR_DEVICE, _("Unable to read generated PPD: %s"), strerror(errno)); + goto finish_response; } snprintf(toppd, sizeof(toppd), "%s/ppd/%s.ppd", ServerRoot, printer->name); if ((to = cupsdCreateConfFile(toppd, ConfigFilePerm)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to create PPD for printer: %s", printer->name, strerror(errno)); - ippDelete(response); cupsFileClose(from); - return (NULL); + + /* Force printer to timeout and be deleted */ + _cupsRWLockWrite(&printer->lock); + printer->state_time = 0; + _cupsRWUnlock(&printer->lock); + + send_ipp_status(con, IPP_STATUS_ERROR_DEVICE, _("Unable to create PPD for printer: %s"), strerror(errno)); + goto finish_response; } while (cupsFileGets(from, line, sizeof(line))) @@ -5466,10 +5469,14 @@ cupsFileClose(from); if (!cupsdCloseCreatedConfFile(to, toppd)) { + _cupsRWLockWrite(&printer->lock); + printer->config_time = time(NULL); printer->state = IPP_PSTATE_IDLE; printer->accepting = 1; + _cupsRWUnlock(&printer->lock); + cupsdSetPrinterAttrs(printer); cupsdAddEvent(CUPSD_EVENT_PRINTER_CONFIG, printer, NULL, "Printer \"%s\" is now available.", printer->name); @@ -5477,10 +5484,39 @@ } } else + { cupsdLogMessage(CUPSD_LOG_ERROR, "%s: PPD creation failed: %s", printer->name, cupsLastErrorString()); + /* Force printer to timeout and be deleted */ + _cupsRWLockWrite(&printer->lock); + printer->state_time = 0; + _cupsRWUnlock(&printer->lock); + + send_ipp_status(con, IPP_STATUS_ERROR_DEVICE, _("Unable to create PPD: %s"), cupsLastErrorString()); + goto finish_response; + } + + /* + * Respond to the client... + */ + + send_ipp_status(con, IPP_STATUS_OK, _("Local printer created.")); + + ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", (char)printer->accepting); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", (int)printer->state); + add_printer_state_reasons(con, printer); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), httpIsEncrypted(con->http) ? "ipps" : "ipp", NULL, con->clientname, con->clientport, "/printers/%s", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported", NULL, uri); + + finish_response: + ippDelete(response); + send_response(con); + + con->bg_pending = 0; + return (NULL); } @@ -5592,10 +5628,21 @@ if ((printer = cupsdFindDest(name)) != NULL) { - send_ipp_status(con, IPP_STATUS_ERROR_NOT_POSSIBLE, _("Printer \"%s\" already exists."), name); + printer->state_time = time(NULL); + send_ipp_status(con, IPP_STATUS_OK, _("Printer \"%s\" already exists."), name); goto add_printer_attributes; } + for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers); printer; printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + if (printer->device_uri && !strcmp(ptr, printer->device_uri)) + { + printer->state_time = time(NULL); + send_ipp_status(con, IPP_STATUS_OK, _("Printer \"%s\" already exists."), printer->name); + goto add_printer_attributes; + } + } + /* * Create the printer... */ @@ -5682,14 +5729,17 @@ * Run a background thread to create the PPD... */ - _cupsThreadCreate((_cups_thread_func_t)create_local_bg_thread, printer); + con->bg_pending = 1; + con->bg_printer = printer; + + _cupsThreadCreate((_cups_thread_func_t)create_local_bg_thread, con); + + return; /* * Return printer attributes... */ - send_ipp_status(con, IPP_STATUS_OK, _("Local printer created.")); - add_printer_attributes: ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", (char)printer->accepting); @@ -5795,7 +5845,7 @@ * Is the destination valid? */ - cupsdLogMessage(CUPSD_LOG_DEBUG, "create_subscriptions(con=%p(%d), uri=\"%s\")", con, con->number, uri->values[0].string.text); + cupsdLogMessage(CUPSD_LOG_DEBUG, "create_subscriptions(con=%p(%d), uri=\"%s\")", (void *)con, con->number, uri->values[0].string.text); httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, sizeof(scheme), userpass, sizeof(userpass), host, @@ -6143,7 +6193,7 @@ int temporary; /* Temporary queue? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "delete_printer(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "delete_printer(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -6256,7 +6306,7 @@ cups_array_t *ra; /* Requested attributes array */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_default(%p[%d])", con, con->number); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_default(%p[%d])", (void *)con, con->number); /* * Check policy... @@ -6306,7 +6356,7 @@ /* String for included schemes */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_devices(%p[%d])", con, con->number); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_devices(%p[%d])", (void *)con, con->number); /* * Check policy... @@ -6399,7 +6449,7 @@ format[1024]; /* Format for document */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_document(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_document(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -6546,7 +6596,7 @@ *exclude; /* Private attributes array */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_job_attrs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_job_attrs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -6677,7 +6727,7 @@ cupsd_policy_t *policy; /* Current policy */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", con, con->number, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -6988,7 +7038,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: job->id=%d, dest=\"%s\", username=\"%s\", " "state_value=%d, attrs=%p", job->id, job->dest, - job->username, job->state_value, job->attrs); + job->username, job->state_value, (void *)job->attrs); if (!job->dest || !job->username) cupsdLoadJob(job); @@ -7067,7 +7117,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_notifications(con=%p[%d])", - con, con->number); + (void *)con, con->number); /* * Get subscription attributes... @@ -7200,8 +7250,8 @@ cups_ptype_t dtype; /* Destination type */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", con, - con->number, uri, uri->name, uri->values[0].string.text); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", (void *)con, + con->number, (void *)uri, uri->name, uri->values[0].string.text); if (!strcmp(ippGetName(uri), "ppd-name")) { @@ -7373,7 +7423,7 @@ /* String for included schemes */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->number); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", (void *)con, con->number); /* * Check policy... @@ -7517,7 +7567,7 @@ cups_array_t *ra; /* Requested attributes array */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -7573,7 +7623,7 @@ cupsd_printer_t *printer; /* Printer/class */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_supported(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_supported(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -7643,7 +7693,7 @@ int local; /* Local connection? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", (void *)con, con->number, type); /* @@ -7804,7 +7854,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_subscription_attrs(con=%p[%d], sub_id=%d)", - con, con->number, sub_id); + (void *)con, con->number, sub_id); /* * Expire subscriptions as needed... @@ -7891,7 +7941,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_subscriptions(con=%p[%d], uri=%s)", - con, con->number, uri->values[0].string.text); + (void *)con, con->number, uri->values[0].string.text); /* * Is the destination valid? @@ -8059,7 +8109,7 @@ cupsd_job_t *job; /* Job information */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->number, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -8190,7 +8240,7 @@ cupsd_printer_t *printer; /* Printer data */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_new_jobs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_new_jobs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -8267,7 +8317,7 @@ *dprinter; /* Destination printer */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->number, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -8596,7 +8646,7 @@ int compression; /* Document compression */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->number, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -9047,7 +9097,7 @@ ipp_attribute_t *attr; /* printer-state-message text */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "reject_jobs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "reject_jobs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -9129,7 +9179,7 @@ cupsd_printer_t *printer; /* Printer data */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_held_new_jobs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_held_new_jobs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -9202,7 +9252,7 @@ cupsd_job_t *job; /* Job information */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_job(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -9339,7 +9389,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "renew_subscription(con=%p[%d], sub_id=%d)", - con, con->number, sub_id); + (void *)con, con->number, sub_id); /* * Is the subscription ID valid? @@ -9426,7 +9476,7 @@ int port; /* Port portion of URI */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "restart_job(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "restart_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -9777,7 +9827,7 @@ int start_job; /* Start the job? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_document(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_document(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -10289,6 +10339,82 @@ /* + * 'send_response()' - Send the IPP response. + */ + +static int /* O - 1 on success, 0 on failure */ +send_response(cupsd_client_t *con) /* I - Client */ +{ + ipp_attribute_t *uri; /* Target URI */ + int ret = 0; /* Return value */ + static _cups_mutex_t mutex = _CUPS_MUTEX_INITIALIZER; + /* Mutex for logging/access */ + + + _cupsMutexLock(&mutex); + + if ((uri = ippFindAttribute(con->request, "printer-uri", IPP_TAG_URI)) == NULL) + { + if ((uri = ippFindAttribute(con->request, "job-uri", IPP_TAG_URI)) == NULL) + uri = ippFindAttribute(con->request, "ppd-name", IPP_TAG_NAME); + } + + cupsdLogClient(con, con->response->request.status.status_code >= IPP_STATUS_ERROR_BAD_REQUEST && con->response->request.status.status_code != IPP_STATUS_ERROR_NOT_FOUND ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG, "Returning IPP %s for %s (%s) from %s.", ippErrorString(con->response->request.status.status_code), ippOpString(con->request->request.op.operation_id), uri ? uri->values[0].string.text : "no URI", con->http->hostname); + + httpClearFields(con->http); + +#ifdef CUPSD_USE_CHUNKING + /* + * Because older versions of CUPS (1.1.17 and older) and some IPP + * clients do not implement chunking properly, we cannot use + * chunking by default. This may become the default in future + * CUPS releases, or we might add a configuration directive for + * it. + */ + + if (con->http->version == HTTP_1_1) + { + cupsdLogClient(con, CUPSD_LOG_DEBUG, "Transfer-Encoding: chunked"); + cupsdSetLength(con->http, 0); + } + else +#endif /* CUPSD_USE_CHUNKING */ + { + size_t length; /* Length of response */ + + + length = ippLength(con->response); + + if (con->file >= 0 && !con->pipe_pid) + { + struct stat fileinfo; /* File information */ + + if (!fstat(con->file, &fileinfo)) + length += (size_t)fileinfo.st_size; + } + + cupsdLogClient(con, CUPSD_LOG_DEBUG, "Content-Length: " CUPS_LLFMT, CUPS_LLCAST length); + httpSetLength(con->http, length); + } + + if (cupsdSendHeader(con, HTTP_STATUS_OK, "application/ipp", CUPSD_AUTH_NONE)) + { + /* + * Tell the caller the response header was sent successfully... + */ + + cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient, (cupsd_selfunc_t)cupsdWriteClient, con); + + ret = 1; + } + + _cupsMutexUnlock(&mutex); + + return (ret); +} + + +/* * 'set_default()' - Set the default destination... */ @@ -10302,7 +10428,7 @@ *oldprinter; /* Old default printer */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_default(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_default(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -10384,7 +10510,7 @@ int check_jobs; /* Check jobs? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_job_attrs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_job_attrs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -10764,7 +10890,7 @@ int changed = 0; /* Was anything changed? */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_attrs(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_attrs(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -11110,7 +11236,7 @@ cupsd_printer_t *printer; /* Printer data */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_printer(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_printer(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -11192,7 +11318,7 @@ ipp_attribute_t *attr; /* printer-state-message attribute */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_printer(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_printer(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -11434,7 +11560,7 @@ cupsd_printer_t *printer; /* Printer */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_job(%p[%d], %s)", con, + cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_job(%p[%d], %s)", (void *)con, con->number, uri->values[0].string.text); /* @@ -11627,7 +11753,7 @@ cupsd_printer_t *printer; /* Printer for job */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_user(job=%d, con=%d, owner=\"%s\", username=%p, userlen=" CUPS_LLFMT ")", job->id, con ? con->number : 0, owner ? owner : "(null)", username, CUPS_LLCAST userlen); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_user(job=%d, con=%d, owner=\"%s\", username=%p, userlen=" CUPS_LLFMT ")", job->id, con ? con->number : 0, owner ? owner : "(null)", (void *)username, CUPS_LLCAST userlen); /* * Validate input... --- a/scheduler/policy.h +++ b/scheduler/policy.h @@ -22,8 +22,6 @@ *ops; /* Operations */ } cupsd_policy_t; -typedef struct cupsd_printer_s cupsd_printer_t; - /* * Globals... --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -620,7 +620,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeletePrinter(p=%p(%s), update=%d)", - p, p->name, update); + (void *)p, p->name, update); /* * Save the current position in the Printers array... @@ -782,11 +782,11 @@ "cupsdDeleteTemporaryPrinters: Removing unused temporary printers"); /* - * Allow temporary printers to stick around for 60 seconds after the last job + * Allow temporary printers to stick around for 5 minutes after the last job * completes. */ - unused_time = time(NULL) - 60; + unused_time = time(NULL) - 300; for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { @@ -2550,7 +2550,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdSetPrinterReasons(p=%p(%s),s=\"%s\"", p, p->name, s); + "cupsdSetPrinterReasons(p=%p(%s),s=\"%s\"", (void *)p, p->name, s); if (s[0] == '-' || s[0] == '+') { @@ -3396,7 +3396,7 @@ cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer_filter(p=%p(%s), filtertype=%p(%s/%s), " - "filter=\"%s\")", p, p->name, filtertype, filtertype->super, + "filter=\"%s\")", (void *)p, p->name, (void *)filtertype, filtertype->super, filtertype->type, filter); /* --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -50,8 +50,6 @@ * Printer/class information structure... */ -typedef struct cupsd_job_s cupsd_job_t; - struct cupsd_printer_s { _cups_rwlock_t lock; /* Concurrency lock for background updates */ --- a/scheduler/client.c +++ b/scheduler/client.c @@ -430,6 +430,14 @@ con->file = -1; } + if (con->bg_pending) + { + /* + * Don't close connection when there is a background thread pending + */ + partial = 1; + } + /* * Close the socket and clear the file from the input set for select()... */
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2