X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=cups%2Futil.c;h=ebc54d3cf92b2f9c17f525b60b5227dd91cab794;hb=e310189747c161ac6e737eedadf8f45d11bf2253;hp=c070cce4c36b64acdc78bcb514f0c94c8c4a620b;hpb=c5b24bfa983a8b50262d8c3dd037e0181cfaae61;p=thirdparty%2Fcups.git diff --git a/cups/util.c b/cups/util.c index c070cce4c..ebc54d3cf 100644 --- a/cups/util.c +++ b/cups/util.c @@ -1,54 +1,10 @@ /* - * "$Id: util.c 7850 2008-08-20 00:07:25Z mike $" + * Printing utilities for CUPS. * - * Printing utilities for CUPS. + * Copyright 2007-2017 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * cupsCancelJob() - Cancel a print job on the default server. - * cupsCancelJob2() - Cancel or purge a print job. - * cupsCreateJob() - Create an empty job for streaming. - * cupsFinishDocument() - Finish sending a document. - * cupsFreeJobs() - Free memory used by job data. - * cupsGetClasses() - Get a list of printer classes from the default - * server. - * cupsGetDefault() - Get the default printer or class for the default - * server. - * cupsGetDefault2() - Get the default printer or class for the specified - * server. - * cupsGetJobs() - Get the jobs from the default server. - * cupsGetJobs2() - Get the jobs from the specified server. - * cupsGetPPD() - Get the PPD file for a printer on the default - * server. - * cupsGetPPD2() - Get the PPD file for a printer from the specified - * server. - * cupsGetPPD3() - Get the PPD file for a printer on the specified - * server if it has changed. - * cupsGetPrinters() - Get a list of printers from the default server. - * cupsGetServerPPD() - Get an available PPD file from the server. - * cupsPrintFile() - Print a file to a printer or class on the default - * server. - * cupsPrintFile2() - Print a file to a printer or class on the - * specified server. - * cupsPrintFiles() - Print one or more files to a printer or class on - * the default server. - * cupsPrintFiles2() - Print one or more files to a printer or class on - * the specified server. - * cupsStartDocument() - Add a document to a job created with - * cupsCreateJob(). - * cups_get_printer_uri() - Get the printer-uri-supported attribute for the - * first printer in a class. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -66,13 +22,16 @@ /* - * Local functions... + * Enumeration data and callback... */ -static int cups_get_printer_uri(http_t *http, const char *name, - char *host, int hostsize, int *port, - char *resource, int resourcesize, - int depth); +typedef struct _cups_createdata_s +{ + const char *name; /* Destination name */ + cups_dest_t *dest; /* Matching destination */ +} _cups_createdata_t; + +static int cups_create_cb(_cups_createdata_t *data, unsigned flags, cups_dest_t *dest); /* @@ -83,6 +42,8 @@ static int cups_get_printer_uri(http_t *http, const char *name, * * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get * the cause of any failure. + * + * @exclude all@ */ int /* O - 1 on success, 0 on failure */ @@ -90,7 +51,7 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */ int job_id) /* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */ { return (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0) - < IPP_REDIRECTION_OTHER_SITE); + < IPP_STATUS_REDIRECTION_OTHER_SITE); } @@ -106,7 +67,7 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */ * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get * the cause of any failure. * - * @since CUPS 1.4/OS X 10.6@ + * @since CUPS 1.4/macOS 10.6@ @exclude all@ */ ipp_status_t /* O - IPP status */ @@ -125,7 +86,7 @@ cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ if (job_id < -1 || (!name && job_id == 0)) { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (0); } @@ -135,7 +96,7 @@ cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ if (!http) if ((http = _cupsConnect()) == NULL) - return (IPP_SERVICE_UNAVAILABLE); + return (IPP_STATUS_ERROR_SERVICE_UNAVAILABLE); /* * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following @@ -148,7 +109,7 @@ cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ * [purge-job] or [purge-jobs] */ - request = ippNewRequest(job_id < 0 ? IPP_PURGE_JOBS : IPP_CANCEL_JOB); + request = ippNewRequest(job_id < 0 ? IPP_OP_PURGE_JOBS : IPP_OP_CANCEL_JOB); if (name) { @@ -194,7 +155,7 @@ cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ * print, use the @link cupsPrintFile2@ or @link cupsPrintFiles2@ function * instead. * - * @since CUPS 1.4/OS X 10.6@ + * @since CUPS 1.4/macOS 10.6@ @exclude all@ */ int /* O - Job ID or 0 on error */ @@ -205,17 +166,13 @@ cupsCreateJob( int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { - char printer_uri[1024], /* Printer URI */ - resource[1024]; /* Printer resource */ - ipp_t *request, /* Create-Job request */ - *response; /* Create-Job response */ - ipp_attribute_t *attr; /* job-id attribute */ int job_id = 0; /* job-id value */ + ipp_status_t status; /* Create-Job status */ + _cups_createdata_t data; /* Enumeration data */ + cups_dinfo_t *info; /* Destination information */ - DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", " - "num_options=%d, options=%p)", - http, name, title, num_options, options)); + DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", num_options=%d, options=%p)", (void *)http, name, title, num_options, (void *)options)); /* * Range check input... @@ -223,51 +180,52 @@ cupsCreateJob( if (!name) { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (0); } /* - * Build a Create-Job request... + * Lookup the destination... */ - if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL) + data.name = name; + data.dest = NULL; + + cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data); + + if (!data.dest) { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); + DEBUG_puts("1cupsCreateJob: Destination not found."); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); return (0); } - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", - NULL, "localhost", ippPort(), "/printers/%s", name); - snprintf(resource, sizeof(resource), "/printers/%s", name); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", - NULL, printer_uri); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, cupsUser()); - if (title) - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, - title); - cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); - cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB); - cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION); - /* - * Send the request and get the job-id... + * Query dest information and create the job... */ - response = cupsDoRequest(http, request, resource); + DEBUG_puts("1cupsCreateJob: Querying destination info."); + if ((info = cupsCopyDestInfo(http, data.dest)) == NULL) + { + DEBUG_puts("1cupsCreateJob: Query failed."); + cupsFreeDests(1, data.dest); + return (0); + } - if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) - job_id = attr->values[0].integer; + status = cupsCreateDestJob(http, data.dest, info, &job_id, title, num_options, options); + DEBUG_printf(("1cupsCreateJob: cupsCreateDestJob returned %04x (%s)", status, ippErrorString(status))); - ippDelete(response); + cupsFreeDestInfo(info); + cupsFreeDests(1, data.dest); /* - * Return it... + * Return the job... */ - return (job_id); + if (status >= IPP_STATUS_REDIRECTION_OTHER_SITE) + return (0); + else + return (job_id); } @@ -276,7 +234,7 @@ cupsCreateJob( * * The document must have been started using @link cupsStartDocument@. * - * @since CUPS 1.4/OS X 10.6@ + * @since CUPS 1.4/macOS 10.6@ @exclude all@ */ ipp_status_t /* O - Status of document submission */ @@ -324,92 +282,19 @@ cupsFreeJobs(int num_jobs, /* I - Number of jobs */ /* * 'cupsGetClasses()' - Get a list of printer classes from the default server. * - * This function is deprecated - use @link cupsGetDests@ instead. + * This function is deprecated and no longer returns a list of printer + * classes - use @link cupsGetDests@ instead. * - * @deprecated@ + * @deprecated@ @exclude all@ */ int /* O - Number of classes */ cupsGetClasses(char ***classes) /* O - Classes */ { - int n; /* Number of classes */ - ipp_t *request, /* IPP Request */ - *response; /* IPP Response */ - ipp_attribute_t *attr; /* Current attribute */ - char **temp; /* Temporary pointer */ - http_t *http; /* Connection to server */ - - - if (!classes) - { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); - - return (0); - } - - *classes = NULL; - - if ((http = _cupsConnect()) == NULL) - return (0); - - /* - * Build a CUPS_GET_CLASSES request, which requires the following - * attributes: - * - * attributes-charset - * attributes-natural-language - * requested-attributes - */ - - request = ippNewRequest(CUPS_GET_CLASSES); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", NULL, "printer-name"); - - /* - * Do the request and get back a response... - */ - - n = 0; + if (classes) + *classes = NULL; - if ((response = cupsDoRequest(http, request, "/")) != NULL) - { - for (attr = response->attrs; attr != NULL; attr = attr->next) - if (attr->name != NULL && - _cups_strcasecmp(attr->name, "printer-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - { - if (n == 0) - temp = malloc(sizeof(char *)); - else - temp = realloc(*classes, sizeof(char *) * (n + 1)); - - if (temp == NULL) - { - /* - * Ran out of memory! - */ - - while (n > 0) - { - n --; - free((*classes)[n]); - } - - free(*classes); - ippDelete(response); - return (0); - } - - *classes = temp; - temp[n] = strdup(attr->values[0].string.text); - n ++; - } - - ippDelete(response); - } - - return (n); + return (0); } @@ -422,6 +307,8 @@ cupsGetClasses(char ***classes) /* O - Classes */ * Applications should use the @link cupsGetDests@ and @link cupsGetDest@ * functions to get the user-defined default printer, as this function does * not support the lpoptions-defined default printer. + * + * @exclude all@ */ const char * /* O - Default printer or @code NULL@ */ @@ -445,7 +332,7 @@ cupsGetDefault(void) * functions to get the user-defined default printer, as this function does * not support the lpoptions-defined default printer. * - * @since CUPS 1.1.21/OS X 10.4@ + * @since CUPS 1.1.21/macOS 10.4@ @exclude all@ */ const char * /* O - Default printer or @code NULL@ */ @@ -480,7 +367,7 @@ cupsGetDefault2(http_t *http) /* I - Connection to server or @code CUPS_HTTP_DE * attributes-natural-language */ - request = ippNewRequest(CUPS_GET_DEFAULT); + request = ippNewRequest(IPP_OP_CUPS_GET_DEFAULT); /* * Do the request and get back a response... @@ -511,6 +398,8 @@ cupsGetDefault2(http_t *http) /* I - Connection to server or @code CUPS_HTTP_DE * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns * jobs that are stopped, canceled, aborted, or completed. + * + * @exclude all@ */ int /* O - Number of jobs */ @@ -536,7 +425,7 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */ * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns * jobs that are stopped, canceled, aborted, or completed. * - * @since CUPS 1.1.21/OS X 10.4@ + * @since CUPS 1.1.21/macOS 10.4@ */ int /* O - Number of jobs */ @@ -586,7 +475,7 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D if (!jobs) { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (-1); } @@ -598,9 +487,11 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D if (name) { if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) + "localhost", 0, "/printers/%s", + name) < HTTP_URI_STATUS_OK) { - _cupsSetError(IPP_INTERNAL_ERROR, _("Unable to create printer-uri"), 1); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, + _("Unable to create printer-uri"), 1); return (-1); } @@ -625,7 +516,7 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D * requested-attributes */ - request = ippNewRequest(IPP_GET_JOBS); + request = ippNewRequest(IPP_OP_GET_JOBS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); @@ -675,7 +566,7 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D id = 0; size = 0; priority = 50; - state = IPP_JOB_PENDING; + state = IPP_JSTATE_PENDING; user = "unknown"; dest = NULL; format = "application/octet-stream"; @@ -746,7 +637,7 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D if (n == 0) temp = malloc(sizeof(cups_job_t)); else - temp = realloc(*jobs, sizeof(cups_job_t) * (n + 1)); + temp = realloc(*jobs, sizeof(cups_job_t) * (size_t)(n + 1)); if (!temp) { @@ -754,7 +645,7 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D * Ran out of memory! */ - _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0); cupsFreeJobs(n, *jobs); *jobs = NULL; @@ -791,565 +682,36 @@ cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_D ippDelete(response); } - if (n == 0 && cg->last_error >= IPP_BAD_REQUEST) + if (n == 0 && cg->last_error >= IPP_STATUS_ERROR_BAD_REQUEST) return (-1); else return (n); } -/* - * 'cupsGetPPD()' - Get the PPD file for a printer on the default server. - * - * For classes, @code cupsGetPPD@ returns the PPD file for the first printer - * in the class. - * - * The returned filename is stored in a static buffer and is overwritten with - * each call to @code cupsGetPPD@ or @link cupsGetPPD2@. The caller "owns" the - * file that is created and must @code unlink@ the returned filename. - */ - -const char * /* O - Filename for PPD file */ -cupsGetPPD(const char *name) /* I - Destination name */ -{ - _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ - time_t modtime = 0; /* Modification time */ - - - /* - * Return the PPD file... - */ - - cg->ppd_filename[0] = '\0'; - - if (cupsGetPPD3(CUPS_HTTP_DEFAULT, name, &modtime, cg->ppd_filename, - sizeof(cg->ppd_filename)) == HTTP_OK) - return (cg->ppd_filename); - else - return (NULL); -} - - -/* - * 'cupsGetPPD2()' - Get the PPD file for a printer from the specified server. - * - * For classes, @code cupsGetPPD2@ returns the PPD file for the first printer - * in the class. - * - * The returned filename is stored in a static buffer and is overwritten with - * each call to @link cupsGetPPD@ or @code cupsGetPPD2@. The caller "owns" the - * file that is created and must @code unlink@ the returned filename. - * - * @since CUPS 1.1.21/OS X 10.4@ - */ - -const char * /* O - Filename for PPD file */ -cupsGetPPD2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ - const char *name) /* I - Destination name */ -{ - _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ - time_t modtime = 0; /* Modification time */ - - - cg->ppd_filename[0] = '\0'; - - if (cupsGetPPD3(http, name, &modtime, cg->ppd_filename, - sizeof(cg->ppd_filename)) == HTTP_OK) - return (cg->ppd_filename); - else - return (NULL); -} - - -/* - * 'cupsGetPPD3()' - Get the PPD file for a printer on the specified - * server if it has changed. - * - * The "modtime" parameter contains the modification time of any - * locally-cached content and is updated with the time from the PPD file on - * the server. - * - * The "buffer" parameter contains the local PPD filename. If it contains - * the empty string, a new temporary file is created, otherwise the existing - * file will be overwritten as needed. The caller "owns" the file that is - * created and must @code unlink@ the returned filename. - * - * On success, @code HTTP_OK@ is returned for a new PPD file and - * @code HTTP_NOT_MODIFIED@ if the existing PPD file is up-to-date. Any other - * status is an error. - * - * For classes, @code cupsGetPPD3@ returns the PPD file for the first printer - * in the class. - * - * @since CUPS 1.4/OS X 10.6@ - */ - -http_status_t /* O - HTTP status */ -cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */ - const char *name, /* I - Destination name */ - time_t *modtime, /* IO - Modification time */ - char *buffer, /* I - Filename buffer */ - size_t bufsize) /* I - Size of filename buffer */ -{ - int http_port; /* Port number */ - char http_hostname[HTTP_MAX_HOST]; - /* Hostname associated with connection */ - http_t *http2; /* Alternate HTTP connection */ - int fd; /* PPD file */ - char localhost[HTTP_MAX_URI],/* Local hostname */ - hostname[HTTP_MAX_URI], /* Hostname */ - resource[HTTP_MAX_URI]; /* Resource name */ - int port; /* Port number */ - http_status_t status; /* HTTP status from server */ - char tempfile[1024] = ""; /* Temporary filename */ - _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ - - - /* - * Range check input... - */ - - DEBUG_printf(("cupsGetPPD3(http=%p, name=\"%s\", modtime=%p(%d), buffer=%p, " - "bufsize=%d)", http, name, modtime, - modtime ? (int)*modtime : 0, buffer, (int)bufsize)); - - if (!name) - { - _cupsSetError(IPP_INTERNAL_ERROR, _("No printer name"), 1); - return (HTTP_NOT_ACCEPTABLE); - } - - if (!modtime) - { - _cupsSetError(IPP_INTERNAL_ERROR, _("No modification time"), 1); - return (HTTP_NOT_ACCEPTABLE); - } - - if (!buffer || bufsize <= 1) - { - _cupsSetError(IPP_INTERNAL_ERROR, _("Bad filename buffer"), 1); - return (HTTP_NOT_ACCEPTABLE); - } - -#ifndef WIN32 - /* - * See if the PPD file is available locally... - */ - - if (http) - httpGetHostname(http, hostname, sizeof(hostname)); - else - { - strlcpy(hostname, cupsServer(), sizeof(hostname)); - if (hostname[0] == '/') - strlcpy(hostname, "localhost", sizeof(hostname)); - } - - if (!_cups_strcasecmp(hostname, "localhost")) - { - char ppdname[1024]; /* PPD filename */ - struct stat ppdinfo; /* PPD file information */ - - - snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", cg->cups_serverroot, - name); - if (!stat(ppdname, &ppdinfo)) - { - /* - * OK, the file exists, use it! - */ - - if (buffer[0]) - { - unlink(buffer); - - if (symlink(ppdname, buffer) && errno != EEXIST) - { - _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); - - return (HTTP_SERVER_ERROR); - } - } - else - { - int tries; /* Number of tries */ - const char *tmpdir; /* TMPDIR environment variable */ - struct timeval curtime; /* Current time */ - - /* - * Previously we put root temporary files in the default CUPS temporary - * directory under /var/spool/cups. However, since the scheduler cleans - * out temporary files there and runs independently of the user apps, we - * don't want to use it unless specifically told to by cupsd. - */ - - if ((tmpdir = getenv("TMPDIR")) == NULL) -# ifdef __APPLE__ - tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */ -# else - tmpdir = "/tmp"; -# endif /* __APPLE__ */ - - /* - * Make the temporary name using the specified directory... - */ - - tries = 0; - - do - { - /* - * Get the current time of day... - */ - - gettimeofday(&curtime, NULL); - - /* - * Format a string using the hex time values... - */ - - snprintf(buffer, bufsize, "%s/%08lx%05lx", tmpdir, - (unsigned long)curtime.tv_sec, - (unsigned long)curtime.tv_usec); - - /* - * Try to make a symlink... - */ - - if (!symlink(ppdname, buffer)) - break; - - tries ++; - } - while (tries < 1000); - - if (tries >= 1000) - { - _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); - - return (HTTP_SERVER_ERROR); - } - } - - if (*modtime >= ppdinfo.st_mtime) - return (HTTP_NOT_MODIFIED); - else - { - *modtime = ppdinfo.st_mtime; - return (HTTP_OK); - } - } - } -#endif /* !WIN32 */ - - /* - * Try finding a printer URI for this printer... - */ - - if (!http) - if ((http = _cupsConnect()) == NULL) - return (HTTP_SERVICE_UNAVAILABLE); - - if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port, - resource, sizeof(resource), 0)) - return (HTTP_NOT_FOUND); - - DEBUG_printf(("2cupsGetPPD3: Printer hostname=\"%s\", port=%d", hostname, - port)); - - /* - * Remap local hostname to localhost... - */ - - httpGetHostname(NULL, localhost, sizeof(localhost)); - - DEBUG_printf(("2cupsGetPPD3: Local hostname=\"%s\"", localhost)); - - if (!_cups_strcasecmp(localhost, hostname)) - strlcpy(hostname, "localhost", sizeof(hostname)); - - /* - * Get the hostname and port number we are connected to... - */ - - httpGetHostname(http, http_hostname, sizeof(http_hostname)); - http_port = httpAddrPort(http->hostaddr); - - DEBUG_printf(("2cupsGetPPD3: Connection hostname=\"%s\", port=%d", - http_hostname, http_port)); - - /* - * Reconnect to the correct server as needed... - */ - - if (!_cups_strcasecmp(http_hostname, hostname) && port == http_port) - http2 = http; - else if ((http2 = httpConnectEncrypt(hostname, port, - cupsEncryption())) == NULL) - { - DEBUG_puts("1cupsGetPPD3: Unable to connect to server"); - - return (HTTP_SERVICE_UNAVAILABLE); - } - - /* - * Get a temp file... - */ - - if (buffer[0]) - fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0600); - else - fd = cupsTempFd(tempfile, sizeof(tempfile)); - - if (fd < 0) - { - /* - * Can't open file; close the server connection and return NULL... - */ - - _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); - - if (http2 != http) - httpClose(http2); - - return (HTTP_SERVER_ERROR); - } - - /* - * And send a request to the HTTP server... - */ - - strlcat(resource, ".ppd", sizeof(resource)); - - if (*modtime > 0) - httpSetField(http2, HTTP_FIELD_IF_MODIFIED_SINCE, - httpGetDateString(*modtime)); - - status = cupsGetFd(http2, resource, fd); - - close(fd); - - /* - * See if we actually got the file or an error... - */ - - if (status == HTTP_OK) - { - *modtime = httpGetDateTime(httpGetField(http2, HTTP_FIELD_DATE)); - - if (tempfile[0]) - strlcpy(buffer, tempfile, bufsize); - } - else if (status != HTTP_NOT_MODIFIED) - { - _cupsSetHTTPError(status); - - if (buffer[0]) - unlink(buffer); - else if (tempfile[0]) - unlink(tempfile); - } - else if (tempfile[0]) - unlink(tempfile); - - if (http2 != http) - httpClose(http2); - - /* - * Return the PPD file... - */ - - DEBUG_printf(("1cupsGetPPD3: Returning status %d", status)); - - return (status); -} - - /* * 'cupsGetPrinters()' - Get a list of printers from the default server. * - * This function is deprecated - use @link cupsGetDests@ instead. + * This function is deprecated and no longer returns a list of printers - use + * @link cupsGetDests@ instead. * - * @deprecated@ + * @deprecated@ @exclude all@ */ int /* O - Number of printers */ cupsGetPrinters(char ***printers) /* O - Printers */ { - int n; /* Number of printers */ - ipp_t *request, /* IPP Request */ - *response; /* IPP Response */ - ipp_attribute_t *attr; /* Current attribute */ - char **temp; /* Temporary pointer */ - http_t *http; /* Connection to server */ - - - /* - * Range check input... - */ - - if (!printers) - { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); - - return (0); - } - - *printers = NULL; - - /* - * Try to connect to the server... - */ - - if ((http = _cupsConnect()) == NULL) - return (0); - - /* - * Build a CUPS_GET_PRINTERS request, which requires the following - * attributes: - * - * attributes-charset - * attributes-natural-language - * requested-attributes - */ - - request = ippNewRequest(CUPS_GET_PRINTERS); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", NULL, "printer-name"); - - ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, - "printer-type", 0); - - ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, - "printer-type-mask", CUPS_PRINTER_CLASS); - - /* - * Do the request and get back a response... - */ - - n = 0; - - if ((response = cupsDoRequest(http, request, "/")) != NULL) - { - for (attr = response->attrs; attr != NULL; attr = attr->next) - if (attr->name != NULL && - _cups_strcasecmp(attr->name, "printer-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - { - if (n == 0) - temp = malloc(sizeof(char *)); - else - temp = realloc(*printers, sizeof(char *) * (n + 1)); - - if (temp == NULL) - { - /* - * Ran out of memory! - */ - - while (n > 0) - { - n --; - free((*printers)[n]); - } - - free(*printers); - ippDelete(response); - return (0); - } - - *printers = temp; - temp[n] = strdup(attr->values[0].string.text); - n ++; - } - - ippDelete(response); - } - - return (n); -} - - -/* - * 'cupsGetServerPPD()' - Get an available PPD file from the server. - * - * This function returns the named PPD file from the server. The - * list of available PPDs is provided by the IPP @code CUPS_GET_PPDS@ - * operation. - * - * You must remove (unlink) the PPD file when you are finished with - * it. The PPD filename is stored in a static location that will be - * overwritten on the next call to @link cupsGetPPD@, @link cupsGetPPD2@, - * or @link cupsGetServerPPD@. - * - * @since CUPS 1.3/OS X 10.5@ - */ - -char * /* O - Name of PPD file or @code NULL@ on error */ -cupsGetServerPPD(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ - const char *name) /* I - Name of PPD file ("ppd-name") */ -{ - int fd; /* PPD file descriptor */ - ipp_t *request; /* IPP request */ - _cups_globals_t *cg = _cupsGlobals(); - /* Pointer to library globals */ - - - /* - * Range check input... - */ - - if (!name) - { - _cupsSetError(IPP_INTERNAL_ERROR, _("No PPD name"), 1); - - return (NULL); - } - - if (!http) - if ((http = _cupsConnect()) == NULL) - return (NULL); - - /* - * Get a temp file... - */ - - if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0) - { - /* - * Can't open file; close the server connection and return NULL... - */ - - _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); - - return (NULL); - } - - /* - * Get the PPD file... - */ - - request = ippNewRequest(CUPS_GET_PPD); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name", NULL, - name); - - ippDelete(cupsDoIORequest(http, request, "/", -1, fd)); - - close(fd); + if (printers) + *printers = NULL; - if (cupsLastError() != IPP_OK) - { - unlink(cg->ppd_filename); - return (NULL); - } - else - return (cg->ppd_filename); + return (0); } /* * 'cupsPrintFile()' - Print a file to a printer or class on the default server. + * + * @exclude all@ */ int /* O - Job ID or 0 on error */ @@ -1359,9 +721,7 @@ cupsPrintFile(const char *name, /* I - Destination name */ int num_options,/* I - Number of options */ cups_option_t *options) /* I - Options */ { - DEBUG_printf(("cupsPrintFile(name=\"%s\", filename=\"%s\", " - "title=\"%s\", num_options=%d, options=%p)", - name, filename, title, num_options, options)); + DEBUG_printf(("cupsPrintFile(name=\"%s\", filename=\"%s\", title=\"%s\", num_options=%d, options=%p)", name, filename, title, num_options, (void *)options)); return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, 1, &filename, title, num_options, options)); @@ -1372,7 +732,7 @@ cupsPrintFile(const char *name, /* I - Destination name */ * 'cupsPrintFile2()' - Print a file to a printer or class on the specified * server. * - * @since CUPS 1.1.21/OS X 10.4@ + * @since CUPS 1.1.21/macOS 10.4@ @exclude all@ */ int /* O - Job ID or 0 on error */ @@ -1384,9 +744,7 @@ cupsPrintFile2( int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { - DEBUG_printf(("cupsPrintFile2(http=%p, name=\"%s\", filename=\"%s\", " - "title=\"%s\", num_options=%d, options=%p)", - http, name, filename, title, num_options, options)); + DEBUG_printf(("cupsPrintFile2(http=%p, name=\"%s\", filename=\"%s\", title=\"%s\", num_options=%d, options=%p)", (void *)http, name, filename, title, num_options, (void *)options)); return (cupsPrintFiles2(http, name, 1, &filename, title, num_options, options)); @@ -1396,6 +754,8 @@ cupsPrintFile2( /* * 'cupsPrintFiles()' - Print one or more files to a printer or class on the * default server. + * + * @exclude all@ */ int /* O - Job ID or 0 on error */ @@ -1407,9 +767,7 @@ cupsPrintFiles( int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { - DEBUG_printf(("cupsPrintFiles(name=\"%s\", num_files=%d, " - "files=%p, title=\"%s\", num_options=%d, options=%p)", - name, num_files, files, title, num_options, options)); + DEBUG_printf(("cupsPrintFiles(name=\"%s\", num_files=%d, files=%p, title=\"%s\", num_options=%d, options=%p)", name, num_files, (void *)files, title, num_options, (void *)options)); /* * Print the file(s)... @@ -1424,7 +782,7 @@ cupsPrintFiles( * 'cupsPrintFiles2()' - Print one or more files to a printer or class on the * specified server. * - * @since CUPS 1.1.21/OS X 10.4@ + * @since CUPS 1.1.21/macOS 10.4@ @exclude all@ */ int /* O - Job ID or 0 on error */ @@ -1450,9 +808,7 @@ cupsPrintFiles2( char *cancel_message; /* Error message to preserve */ - DEBUG_printf(("cupsPrintFiles2(http=%p, name=\"%s\", num_files=%d, " - "files=%p, title=\"%s\", num_options=%d, options=%p)", - http, name, num_files, files, title, num_options, options)); + DEBUG_printf(("cupsPrintFiles2(http=%p, name=\"%s\", num_files=%d, files=%p, title=\"%s\", num_options=%d, options=%p)", (void *)http, name, num_files, (void *)files, title, num_options, (void *)options)); /* * Range check input... @@ -1460,7 +816,7 @@ cupsPrintFiles2( if (!name || num_files < 1 || !files) { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (0); } @@ -1499,20 +855,20 @@ cupsPrintFiles2( * Unable to open print file, cancel the job and return... */ - _cupsSetError(IPP_DOCUMENT_ACCESS_ERROR, NULL, 0); + _cupsSetError(IPP_STATUS_ERROR_DOCUMENT_ACCESS, NULL, 0); goto cancel_job; } status = cupsStartDocument(http, name, job_id, docname, format, i == (num_files - 1)); - while (status == HTTP_CONTINUE && + while (status == HTTP_STATUS_CONTINUE && (bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) - status = cupsWriteRequestData(http, buffer, bytes); + status = cupsWriteRequestData(http, buffer, (size_t)bytes); cupsFileClose(fp); - if (status != HTTP_CONTINUE || cupsFinishDocument(http, name) != IPP_OK) + if (status != HTTP_STATUS_CONTINUE || cupsFinishDocument(http, name) != IPP_STATUS_OK) { /* * Unable to queue, cancel the job and return... @@ -1556,7 +912,7 @@ cupsPrintFiles2( * @code CUPS_FORMAT_TEXT@ are provided for the "format" argument, although * any supported MIME type string can be supplied. * - * @since CUPS 1.4/OS X 10.6@ + * @since CUPS 1.4/macOS 10.6@ @exclude all@ */ http_status_t /* O - HTTP status of request */ @@ -1578,10 +934,10 @@ cupsStartDocument( * Create a Send-Document request... */ - if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL) + if ((request = ippNewRequest(IPP_OP_SEND_DOCUMENT)) == NULL) { - _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); - return (HTTP_ERROR); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); + return (HTTP_STATUS_ERROR); } httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", @@ -1599,7 +955,7 @@ cupsStartDocument( if (format) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format); - ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document); + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", (char)last_document); /* * Send and delete the request, then return the status... @@ -1614,236 +970,23 @@ cupsStartDocument( /* - * 'cups_get_printer_uri()' - Get the printer-uri-supported attribute for the - * first printer in a class. + * 'cups_create_cb()' - Find the destination for printing. */ -static int /* O - 1 on success, 0 on failure */ -cups_get_printer_uri( - http_t *http, /* I - Connection to server */ - const char *name, /* I - Name of printer or class */ - char *host, /* I - Hostname buffer */ - int hostsize, /* I - Size of hostname buffer */ - int *port, /* O - Port number */ - char *resource, /* I - Resource buffer */ - int resourcesize, /* I - Size of resource buffer */ - int depth) /* I - Depth of query */ +static int /* O - 0 on match */ +cups_create_cb( + _cups_createdata_t *data, /* I - Data from cupsCreateJob call */ + unsigned flags, /* I - Enumeration flags */ + cups_dest_t *dest) /* I - Destination */ { - int i; /* Looping var */ - int http_port; /* Port number */ - http_t *http2; /* Alternate HTTP connection */ - ipp_t *request, /* IPP request */ - *response; /* IPP response */ - ipp_attribute_t *attr; /* Current attribute */ - char uri[HTTP_MAX_URI], /* printer-uri attribute */ - scheme[HTTP_MAX_URI], /* Scheme name */ - username[HTTP_MAX_URI], /* Username:password */ - classname[255], /* Temporary class name */ - http_hostname[HTTP_MAX_HOST]; - /* Hostname associated with connection */ - static const char * const requested_attrs[] = - { /* Requested attributes */ - "device-uri", - "member-uris", - "printer-uri-supported", - "printer-type" - }; + DEBUG_printf(("2cups_create_cb(data=%p(%s), flags=%08x, dest=%p(%s))", (void *)data, data->name, flags, (void *)dest, dest->name)); + (void)flags; - DEBUG_printf(("7cups_get_printer_uri(http=%p, name=\"%s\", host=%p, " - "hostsize=%d, resource=%p, resourcesize=%d, depth=%d)", - http, name, host, hostsize, resource, resourcesize, depth)); + if (dest->instance || strcasecmp(data->name, dest->name)) + return (1); - /* - * Setup the printer URI... - */ - - if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) - { - _cupsSetError(IPP_INTERNAL_ERROR, _("Unable to create printer-uri"), 1); - - *host = '\0'; - *resource = '\0'; - - return (0); - } - - DEBUG_printf(("9cups_get_printer_uri: printer-uri=\"%s\"", uri)); - - /* - * Get the hostname and port number we are connected to... - */ - - httpGetHostname(http, http_hostname, sizeof(http_hostname)); - http_port = httpAddrPort(http->hostaddr); - - /* - * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following - * attributes: - * - * attributes-charset - * attributes-natural-language - * printer-uri - * requested-attributes - */ - - request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", - NULL, uri); - - ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, - "requested-attributes", - sizeof(requested_attrs) / sizeof(requested_attrs[0]), - NULL, requested_attrs); - - /* - * Do the request and get back a response... - */ - - snprintf(resource, resourcesize, "/printers/%s", name); - - if ((response = cupsDoRequest(http, request, resource)) != NULL) - { - const char *device_uri = NULL; /* device-uri value */ - - if ((attr = ippFindAttribute(response, "device-uri", - IPP_TAG_URI)) != NULL) - device_uri = attr->values[0].string.text; - - if (device_uri && - (!strncmp(device_uri, "ipp://", 6) || - !strncmp(device_uri, "ipps://", 7) || - ((strstr(device_uri, "._ipp.") != NULL || - strstr(device_uri, "._ipps.") != NULL) && - !strcmp(device_uri + strlen(device_uri) - 5, "/cups")))) - { - /* - * Statically-configured shared printer. - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, - _httpResolveURI(device_uri, uri, sizeof(uri), - _HTTP_RESOLVE_DEFAULT, NULL, NULL), - scheme, sizeof(scheme), username, sizeof(username), - host, hostsize, port, resource, resourcesize); - ippDelete(response); - - return (1); - } - else if ((attr = ippFindAttribute(response, "member-uris", - IPP_TAG_URI)) != NULL) - { - /* - * Get the first actual printer name in the class... - */ - - for (i = 0; i < attr->num_values; i ++) - { - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, - scheme, sizeof(scheme), username, sizeof(username), - host, hostsize, port, resource, resourcesize); - if (!strncmp(resource, "/printers/", 10)) - { - /* - * Found a printer! - */ - - ippDelete(response); - - return (1); - } - } - - /* - * No printers in this class - try recursively looking for a printer, - * but not more than 3 levels deep... - */ - - if (depth < 3) - { - for (i = 0; i < attr->num_values; i ++) - { - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, - scheme, sizeof(scheme), username, sizeof(username), - host, hostsize, port, resource, resourcesize); - if (!strncmp(resource, "/classes/", 9)) - { - /* - * Found a class! Connect to the right server... - */ - - if (!_cups_strcasecmp(http_hostname, host) && *port == http_port) - http2 = http; - else if ((http2 = httpConnectEncrypt(host, *port, - cupsEncryption())) == NULL) - { - DEBUG_puts("8cups_get_printer_uri: Unable to connect to server"); - - continue; - } - - /* - * Look up printers on that server... - */ - - strlcpy(classname, resource + 9, sizeof(classname)); - - cups_get_printer_uri(http2, classname, host, hostsize, port, - resource, resourcesize, depth + 1); - - /* - * Close the connection as needed... - */ - - if (http2 != http) - httpClose(http2); - - if (*host) - return (1); - } - } - } - } - else if ((attr = ippFindAttribute(response, "printer-uri-supported", - IPP_TAG_URI)) != NULL) - { - httpSeparateURI(HTTP_URI_CODING_ALL, - _httpResolveURI(attr->values[0].string.text, uri, - sizeof(uri), _HTTP_RESOLVE_DEFAULT, - NULL, NULL), - scheme, sizeof(scheme), username, sizeof(username), - host, hostsize, port, resource, resourcesize); - ippDelete(response); - - if (!strncmp(resource, "/classes/", 9)) - { - _cupsSetError(IPP_INTERNAL_ERROR, - _("No printer-uri found for class"), 1); - - *host = '\0'; - *resource = '\0'; - - return (0); - } - - return (1); - } - - ippDelete(response); - } - - if (cupsLastError() != IPP_NOT_FOUND) - _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found"), 1); - - *host = '\0'; - *resource = '\0'; + cupsCopyDest(dest, 0, &data->dest); return (0); } - - -/* - * End of "$Id: util.c 7850 2008-08-20 00:07:25Z mike $". - */