/*
- * "$Id$"
- *
* IPP routines for the CUPS scheduler.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2016 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
cups_array_t *exclude);
static int copy_banner(cupsd_client_t *con, cupsd_job_t *job,
const char *name);
-static int copy_file(const char *from, const char *to);
+static int copy_file(const char *from, const char *to, mode_t mode);
static int copy_model(cupsd_client_t *con, const char *from,
const char *to);
static void copy_job_attrs(cupsd_client_t *con,
cups_array_t *ra,
cups_array_t *exclude);
static void create_job(cupsd_client_t *con, ipp_attribute_t *uri);
+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);
static void delete_printer(cupsd_client_t *con, ipp_attribute_t *uri);
get_notifications(con);
break;
+ case IPP_OP_CUPS_CREATE_LOCAL_PRINTER :
+ create_local_printer(con);
+ break;
+
default :
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Operation %04X (%s) not supported",
pclass->accepting ? "Now" : "No longer");
}
- if ((attr = ippFindAttribute(con->request, "printer-is-shared",
- IPP_TAG_BOOLEAN)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "printer-is-shared", IPP_TAG_BOOLEAN)) != NULL)
{
- if (pclass->shared && !attr->values[0].boolean)
+ if (pclass->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Cannot re-share remote printers.
+ */
+
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Cannot change printer-is-shared for remote queues."));
+ return;
+ }
+
+ if (pclass->shared && !ippGetBoolean(attr, 0))
cupsdDeregisterPrinter(pclass, 1);
cupsdLogMessage(CUPSD_LOG_INFO,
"Setting %s printer-is-shared to %d (was %d.)",
pclass->name, attr->values[0].boolean, pclass->shared);
- pclass->shared = attr->values[0].boolean;
+ pclass->shared = ippGetBoolean(attr, 0);
}
if ((attr = ippFindAttribute(con->request, "printer-state",
attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
"job-hold-until", NULL, val);
}
- if (attr && strcmp(attr->values[0].string.text, "no-hold"))
+
+ if (printer->holding_new_jobs)
+ {
+ /*
+ * Hold all new jobs on this printer...
+ */
+
+ if (attr && strcmp(attr->values[0].string.text, "no-hold"))
+ cupsdSetJobHoldUntil(job, ippGetString(attr, 0, NULL), 0);
+ else
+ cupsdSetJobHoldUntil(job, "indefinite", 0);
+
+ job->state->values[0].integer = IPP_JOB_HELD;
+ job->state_value = IPP_JOB_HELD;
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-held-on-create");
+ }
+ else if (attr && strcmp(attr->values[0].string.text, "no-hold"))
{
/*
* Hold job until specified time...
char srcfile[1024], /* Source Script/PPD file */
dstfile[1024]; /* Destination Script/PPD file */
int modify; /* Non-zero if we are modifying */
- int changed_driver, /* Changed the PPD/interface script? */
+ int changed_driver, /* Changed the PPD? */
need_restart_job, /* Need to restart job? */
set_device_uri, /* Did we set the device URI? */
set_port_monitor; /* Did we set the port monitor? */
changed_driver = 0;
need_restart_job = 0;
+ if ((attr = ippFindAttribute(con->request, "printer-is-temporary", IPP_TAG_BOOLEAN)) != NULL)
+ printer->temporary = ippGetBoolean(attr, 0);
+
if ((attr = ippFindAttribute(con->request, "printer-location",
IPP_TAG_TEXT)) != NULL)
cupsdSetString(&printer->location, attr->values[0].string.text);
printer->accepting ? "Now" : "No longer");
}
- if ((attr = ippFindAttribute(con->request, "printer-is-shared",
- IPP_TAG_BOOLEAN)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "printer-is-shared", IPP_TAG_BOOLEAN)) != NULL)
{
- if (attr->values[0].boolean &&
+ if (ippGetBoolean(attr, 0) &&
printer->num_auth_info_required == 1 &&
!strcmp(printer->auth_info_required[0], "negotiate"))
{
return;
}
- if (printer->shared && !attr->values[0].boolean)
+ if (printer->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Cannot re-share remote printers.
+ */
+
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Cannot change printer-is-shared for remote queues."));
+ return;
+ }
+
+ if (printer->shared && !ippGetBoolean(attr, 0))
cupsdDeregisterPrinter(printer, 1);
cupsdLogMessage(CUPSD_LOG_INFO,
"Setting %s printer-is-shared to %d (was %d.)",
printer->name, attr->values[0].boolean, printer->shared);
- printer->shared = attr->values[0].boolean;
+ printer->shared = ippGetBoolean(attr, 0);
+ if (printer->shared && printer->temporary)
+ printer->temporary = 0;
}
if ((attr = ippFindAttribute(con->request, "printer-state",
cupsdSetString(&printer->device_uri, "file:///dev/null");
/*
- * See if we have an interface script or PPD file attached to the request...
+ * See if we have a PPD file attached to the request...
*/
if (con->filename)
* Then see what kind of file it is...
*/
- snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
- printer->name);
-
- if (!strncmp(line, "*PPD-Adobe", 10))
- {
- /*
- * The new file is a PPD file, so remove any old interface script
- * that might be lying around...
- */
-
- unlink(dstfile);
- }
- else
+ if (strncmp(line, "*PPD-Adobe", 10))
{
- /*
- * This must be an interface script, so move the file over to the
- * interfaces directory and make it executable...
- */
-
- if (copy_file(srcfile, dstfile))
- {
- send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("Unable to copy interface script - %s"),
- strerror(errno));
- return;
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Copied interface script successfully");
- chmod(dstfile, 0755);
+ send_ipp_status(con, IPP_STATUS_ERROR_DOCUMENT_FORMAT_NOT_SUPPORTED, _("Bad PPD file."));
+ return;
}
snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
printer->name);
- if (!strncmp(line, "*PPD-Adobe", 10))
- {
- /*
- * The new file is a PPD file, so move the file over to the
- * ppd directory and make it readable by all...
- */
-
- if (copy_file(srcfile, dstfile))
- {
- send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("Unable to copy PPD file - %s"),
- strerror(errno));
- return;
- }
+ /*
+ * The new file is a PPD file, so move the file over to the ppd
+ * directory...
+ */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Copied PPD file successfully");
- chmod(dstfile, 0644);
- }
- else
+ if (copy_file(srcfile, dstfile, ConfigFilePerm))
{
- /*
- * This must be an interface script, so remove any old PPD file that
- * may be lying around...
- */
-
- unlink(dstfile);
+ send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file - %s"), strerror(errno));
+ return;
}
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Copied PPD file successfully");
}
}
- else if ((attr = ippFindAttribute(con->request, "ppd-name",
- IPP_TAG_NAME)) != NULL)
+ else if ((attr = ippFindAttribute(con->request, "ppd-name", IPP_TAG_NAME)) != NULL)
{
+ const char *ppd_name = ippGetString(attr, 0, NULL);
+ /* ppd-name value */
+
need_restart_job = 1;
changed_driver = 1;
- if (!strcmp(attr->values[0].string.text, "raw"))
+ if (!strcmp(ppd_name, "raw"))
{
/*
- * Raw driver, remove any existing PPD or interface script files.
+ * Raw driver, remove any existing PPD file.
*/
- snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
- printer->name);
- unlink(dstfile);
-
- snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, printer->name);
unlink(dstfile);
}
+ else if (strstr(ppd_name, "../"))
+ {
+ send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("Invalid ppd-name value."));
+ return;
+ }
else
{
/*
* PPD model file...
*/
- snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
- printer->name);
- unlink(dstfile);
-
- snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, printer->name);
- if (copy_model(con, attr->values[0].string.text, dstfile))
+ if (copy_model(con, ppd_name, dstfile))
{
send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file."));
return;
}
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Copied PPD file successfully");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Copied PPD file successfully");
}
}
if (changed_driver)
{
/*
- * If we changed the PPD/interface script, then remove the printer's cache
- * file and clear the printer-state-reasons...
+ * If we changed the PPD, then remove the printer's cache file and clear the
+ * printer-state-reasons...
*/
char cache_name[1024]; /* Cache filename for printer attrs */
*/
cupsdSetPrinterAttrs(printer);
- cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
+ if (!printer->temporary)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
if (need_restart_job && printer->job)
{
/*
- * 'copy_file()' - Copy a PPD file or interface script...
+ * 'copy_file()' - Copy a PPD file...
*/
static int /* O - 0 = success, -1 = error */
copy_file(const char *from, /* I - Source file */
- const char *to) /* I - Destination file */
+ const char *to, /* I - Destination file */
+ mode_t mode) /* I - Permissions */
{
cups_file_t *src, /* Source file */
*dst; /* Destination file */
if ((src = cupsFileOpen(from, "rb")) == NULL)
return (-1);
- if ((dst = cupsFileOpen(to, "wb")) == NULL)
+ if ((dst = cupsdCreateConfFile(to, mode)) == NULL)
{
cupsFileClose(src);
return (-1);
cupsFileClose(src);
- return (cupsFileClose(dst));
+ return (cupsdCloseCreatedConfFile(dst, to));
}
/* 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\")", con, from, to);
/*
* Run cups-driverd to get the PPD file...
if (!ra || cupsArrayFind(ra, "printer-is-shared"))
ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared", (char)printer->shared);
+ if (!ra || cupsArrayFind(ra, "printer-is-temporary"))
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-temporary", (char)printer->temporary);
+
if (!ra || cupsArrayFind(ra, "printer-more-info"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
}
+/*
+ * 'create_local_bg_thread()' - Background thread for creating a local print queue.
+ */
+
+static void * /* O - Exit status */
+create_local_bg_thread(
+ cupsd_printer_t *printer) /* I - Printer */
+{
+ cups_file_t *from, /* Source file */
+ *to; /* Destination file */
+ char fromppd[1024], /* Source PPD */
+ toppd[1024], /* Destination PPD */
+ scheme[32], /* URI scheme */
+ userpass[256], /* User:pass */
+ host[256], /* Hostname */
+ resource[1024], /* Resource path */
+ line[1024]; /* Line from PPD */
+ int port; /* Port number */
+ 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 */
+ ipp_attribute_t *attr; /* Attribute in response */
+
+
+ /*
+ * Try connecting to the printer...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Generating PPD file from \"%s\"...", printer->name, printer->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)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Bad device URI \"%s\".", printer->name, printer->device_uri);
+ return (NULL);
+ }
+
+ if (!strcmp(scheme, "ipps") || port == 443)
+ encryption = HTTP_ENCRYPTION_ALWAYS;
+ else
+ encryption = HTTP_ENCRYPTION_IF_REQUESTED;
+
+ 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);
+ }
+
+ /*
+ * Query the printer for its capabilities...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Connected to %s:%d, sending Get-Printer-Attributes request...", printer->name, host, port);
+
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer->device_uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "all");
+
+ response = cupsDoRequest(http, request, resource);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Get-Printer-Attributes returned %s", printer->name, ippErrorString(cupsLastError()));
+
+ // TODO: Grab printer icon file...
+ httpClose(http);
+
+ /*
+ * Write the PPD for the queue...
+ */
+
+ if (_ppdCreateFromIPP(fromppd, sizeof(fromppd), response))
+ {
+ if ((!printer->info || !*(printer->info)) && (attr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT)) != NULL)
+ cupsdSetString(&printer->info, ippGetString(attr, 0, NULL));
+
+ if ((!printer->location || !*(printer->location)) && (attr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != NULL)
+ cupsdSetString(&printer->location, ippGetString(attr, 0, NULL));
+
+ if ((!printer->geo_location || !*(printer->geo_location)) && (attr = ippFindAttribute(response, "printer-geo-location", IPP_TAG_URI)) != NULL)
+ cupsdSetString(&printer->geo_location, ippGetString(attr, 0, NULL));
+
+ if ((from = cupsFileOpen(fromppd, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to read generated PPD: %s", printer->name, strerror(errno));
+ return (NULL);
+ }
+
+ 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));
+ cupsFileClose(from);
+ return (NULL);
+ }
+
+ while (cupsFileGets(from, line, sizeof(line)))
+ cupsFilePrintf(to, "%s\n", line);
+
+ cupsFileClose(from);
+ if (!cupsdCloseCreatedConfFile(to, toppd))
+ {
+ printer->config_time = time(NULL);
+ printer->state = IPP_PSTATE_IDLE;
+ printer->accepting = 1;
+
+ cupsdSetPrinterAttrs(printer);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_CONFIG, printer, NULL, "Printer \"%s\" is now available.", printer->name);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" is now available.", printer->name);
+ }
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: PPD creation failed.", printer->name);
+
+ return (NULL);
+}
+
+
+/*
+ * 'create_local_printer()' - Create a local (temporary) print queue.
+ */
+
+static void
+create_local_printer(
+ cupsd_client_t *con) /* I - Client connection */
+{
+ ipp_attribute_t *device_uri, /* device-uri attribute */
+ *printer_geo_location, /* printer-geo-location attribute */
+ *printer_info, /* printer-info attribute */
+ *printer_location, /* printer-location attribute */
+ *printer_name; /* printer-name attribute */
+ cupsd_printer_t *printer; /* New printer */
+ http_status_t status; /* Policy status */
+ char name[128], /* Sanitized printer name */
+ *nameptr, /* Pointer into name */
+ uri[1024]; /* printer-uri-supported value */
+ const char *ptr; /* Pointer into attribute value */
+
+
+ /*
+ * Require local access to create a local printer...
+ */
+
+ if (!httpAddrLocalhost(httpGetAddress(con->http)))
+ {
+ send_ipp_status(con, IPP_STATUS_ERROR_FORBIDDEN, _("Only local users can create a local printer."));
+ return;
+ }
+
+ /*
+ * Check any other policy limits...
+ */
+
+ if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+ {
+ send_http_error(con, status, NULL);
+ return;
+ }
+
+ /*
+ * Grab needed attributes...
+ */
+
+ if ((printer_name = ippFindAttribute(con->request, "printer-name", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(printer_name) != IPP_TAG_PRINTER || ippGetValueTag(printer_name) != IPP_TAG_NAME)
+ {
+ if (!printer_name)
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("Missing required attribute \"%s\"."), "printer-name");
+ else if (ippGetGroupTag(printer_name) != IPP_TAG_PRINTER)
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("Attribute \"%s\" is in the wrong group."), "printer-name");
+ else
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("Attribute \"%s\" is the wrong value type."), "printer-name");
+
+ return;
+ }
+
+ for (nameptr = name, ptr = ippGetString(printer_name, 0, NULL); *ptr && nameptr < (name + sizeof(name) - 1); ptr ++)
+ {
+ /*
+ * Sanitize the printer name...
+ */
+
+ if (_cups_isalnum(*ptr))
+ *nameptr++ = *ptr;
+ else if (nameptr == name || nameptr[-1] != '_')
+ *nameptr++ = '_';
+ }
+
+ *nameptr = '\0';
+
+ if ((device_uri = ippFindAttribute(con->request, "device-uri", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(device_uri) != IPP_TAG_PRINTER || ippGetValueTag(device_uri) != IPP_TAG_URI)
+ {
+ if (!device_uri)
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("Missing required attribute \"%s\"."), "device-uri");
+ else if (ippGetGroupTag(device_uri) != IPP_TAG_PRINTER)
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("Attribute \"%s\" is in the wrong group."), "device-uri");
+ else
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("Attribute \"%s\" is the wrong value type."), "device-uri");
+
+ return;
+ }
+
+ printer_geo_location = ippFindAttribute(con->request, "printer-geo-location", IPP_TAG_URI);
+ printer_info = ippFindAttribute(con->request, "printer-info", IPP_TAG_TEXT);
+ printer_location = ippFindAttribute(con->request, "printer-location", IPP_TAG_TEXT);
+
+ /*
+ * See if the printer already exists...
+ */
+
+ if ((printer = cupsdFindDest(name)) != NULL)
+ {
+ send_ipp_status(con, IPP_STATUS_ERROR_NOT_POSSIBLE, _("Printer \"%s\" already exists."), name);
+ goto add_printer_attributes;
+ }
+
+ /*
+ * Create the printer...
+ */
+
+ if ((printer = cupsdAddPrinter(name)) == NULL)
+ {
+ send_ipp_status(con, IPP_STATUS_ERROR_INTERNAL, _("Unable to create printer."));
+ return;
+ }
+
+ cupsdSetDeviceURI(printer, ippGetString(device_uri, 0, NULL));
+
+ if (printer_geo_location)
+ cupsdSetString(&printer->geo_location, ippGetString(printer_geo_location, 0, NULL));
+ if (printer_info)
+ cupsdSetString(&printer->info, ippGetString(printer_info, 0, NULL));
+ if (printer_location)
+ cupsdSetString(&printer->location, ippGetString(printer_location, 0, NULL));
+
+ cupsdSetPrinterAttrs(printer);
+
+ /*
+ * Run a background thread to create the PPD...
+ */
+
+ _cupsThreadCreate((_cups_thread_func_t)create_local_bg_thread, printer);
+
+ /*
+ * 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);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", 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);
+}
+
+
/*
* 'create_requested_array()' - Create an array for the requested-attributes.
*/
cups_ptype_t dtype; /* Destination type (printer/class) */
cupsd_printer_t *printer; /* Printer/class */
char filename[1024]; /* Script/PPD filename */
+ int temporary; /* Temporary queue? */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "delete_printer(%p[%d], %s)", con,
* Remove any old PPD or script files...
*/
- snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot,
- printer->name);
- unlink(filename);
- snprintf(filename, sizeof(filename), "%s/interfaces/%s.O", ServerRoot,
- printer->name);
- unlink(filename);
-
snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
printer->name);
unlink(filename);
cupsdUnregisterColor(printer);
+ temporary = printer->temporary;
+
if (dtype & CUPS_PRINTER_CLASS)
{
cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" deleted by \"%s\".",
printer->name, get_username(con));
cupsdDeletePrinter(printer, 0);
- cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
+ if (!temporary)
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
}
else
{
cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".",
printer->name, get_username(con));
- if (cupsdDeletePrinter(printer, 0))
+ if (cupsdDeletePrinter(printer, 0) && !temporary)
cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
- cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
+ if (!temporary)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
+ if (!temporary)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
/*
* Return with no errors...
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", con,
con->number, uri, uri->name, uri->values[0].string.text);
- if (!strcmp(uri->name, "ppd-name"))
+ if (!strcmp(ippGetName(uri), "ppd-name"))
{
/*
* Return a PPD file from cups-driverd...
*/
- char command[1024], /* cups-driverd command */
- options[1024], /* Options to pass to command */
- ppd_name[1024]; /* ppd-name */
-
+ const char *ppd_name = ippGetString(uri, 0, NULL);
+ /* ppd-name value */
+ char command[1024], /* cups-driverd command */
+ options[1024], /* Options to pass to command */
+ oppd_name[1024]; /* Escaped ppd-name */
/*
* Check policy...
return;
}
+ /*
+ * Check ppd-name value...
+ */
+
+ if (strstr(ppd_name, "../"))
+ {
+ send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("Invalid ppd-name value."));
+ return;
+ }
+
/*
* Run cups-driverd command with the given options...
*/
snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin);
- url_encode_string(uri->values[0].string.text, ppd_name, sizeof(ppd_name));
- snprintf(options, sizeof(options), "get+%d+%s",
- con->request->request.op.request_id, ppd_name);
+ url_encode_string(ppd_name, oppd_name, sizeof(oppd_name));
+ snprintf(options, sizeof(options), "get+%d+%s", ippGetRequestId(con->request), oppd_name);
if (cupsdSendCommand(con, command, options, 0))
{
* went wrong...
*/
- send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("cups-driverd failed to execute."));
+ send_ipp_status(con, IPP_INTERNAL_ERROR, _("cups-driverd failed to execute."));
}
}
- else if (!strcmp(uri->name, "printer-uri") &&
- cupsdValidateDest(uri->values[0].string.text, &dtype, &dest))
+ else if (!strcmp(ippGetName(uri), "printer-uri") && cupsdValidateDest(ippGetString(uri, 0, NULL), &dtype, &dest))
{
int i; /* Looping var */
char filename[1024]; /* PPD filename */
-
/*
* Check policy...
*/
* See if we need the PPD for a class or remote printer...
*/
- snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
- dest->name);
+ snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, dest->name);
if ((dtype & CUPS_PRINTER_REMOTE) && access(filename, 0))
{
- con->response->request.status.status_code = CUPS_SEE_OTHER;
- ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, dest->uri);
+ send_ipp_status(con, IPP_STATUS_CUPS_SEE_OTHER, _("See remote printer."));
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, dest->uri);
return;
}
else if (dtype & CUPS_PRINTER_CLASS)
for (i = 0; i < dest->num_printers; i ++)
if (!(dest->printers[i]->type & CUPS_PRINTER_CLASS))
{
- snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
- dest->printers[i]->name);
+ snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, dest->printers[i]->name);
if (!access(filename, 0))
break;
dest = dest->printers[i];
else
{
- con->response->request.status.status_code = CUPS_SEE_OTHER;
- ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, dest->printers[0]->uri);
+ send_ipp_status(con, IPP_STATUS_CUPS_SEE_OTHER, _("See remote printer."));
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, dest->printers[0]->uri);
return;
}
}
if ((con->file = open(filename, O_RDONLY)) < 0)
{
- send_ipp_status(con, IPP_NOT_FOUND,
- _("The PPD file \"%s\" could not be opened: %s"),
- uri->values[0].string.text, strerror(errno));
+ send_ipp_status(con, IPP_STATUS_ERROR_NOT_FOUND, _("The PPD file \"%s\" could not be opened: %s"), ippGetString(uri, 0, NULL), strerror(errno));
return;
}
con->pipe_pid = 0;
- con->response->request.status.status_code = IPP_OK;
+ ippSetStatusCode(con->response, IPP_STATUS_OK);
}
else
- send_ipp_status(con, IPP_NOT_FOUND,
- _("The PPD file \"%s\" could not be found."),
- uri->values[0].string.text);
+ send_ipp_status(con, IPP_STATUS_ERROR_NOT_FOUND, _("The PPD file \"%s\" could not be found."), ippGetString(uri, 0, NULL));
}
"get_subscription_attrs(con=%p[%d], sub_id=%d)",
con, con->number, sub_id);
+ /*
+ * Expire subscriptions as needed...
+ */
+
+ cupsdExpireSubscriptions(NULL, NULL);
+
/*
* Is the subscription ID valid?
*/
return;
}
+ /*
+ * Expire subscriptions as needed...
+ */
+
+ cupsdExpireSubscriptions(NULL, NULL);
+
/*
* Copy the subscription attributes to the response using the
* requested-attributes attribute that may be provided by the client.
"Printer \"%s\" now printing pending/new jobs (\"%s\").",
printer->name, get_username(con));
+ cupsdCheckJobs();
+
/*
* Everything was ok, so return OK status...
*/
return (cupsdCheckPolicy(printer ? printer->op_policy_ptr : DefaultPolicyPtr,
con, owner) == HTTP_OK);
}
-
-
-/*
- * End of "$Id$".
- */