/*
- * "$Id: util.c 5716 2006-07-11 17:56:57Z mike $"
+ * "$Id: util.c 7014 2007-10-10 21:57:43Z mike $"
*
* Printing utilities for the Common UNIX Printing System (CUPS).
*
+ * Copyright 2007 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products 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 missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * 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.
*
* server.
* cupsGetPPD2() - Get the PPD file for a printer on 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.
* cupsLastError() - Return the last IPP status code.
* cupsLastErrorString() - Return the last IPP status-message.
* cupsPrintFile() - Print a file to a printer or class on the default
uri[HTTP_MAX_URI]; /* Printer URI */
ipp_t *request, /* IPP request */
*response; /* IPP response */
- cups_lang_t *language; /* Language info */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
* [requesting-user-name]
*/
- request = ippNew();
-
- request->request.op.operation_id = IPP_CANCEL_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL,
- language != NULL ? language->language : "C");
-
- cupsLangFree(language);
+ request = ippNewRequest(IPP_CANCEL_JOB);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
char **temp; /* Temporary pointer */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
* requested-attributes
*/
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_CLASSES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- cupsLangFree(language);
+ request = ippNewRequest(CUPS_GET_CLASSES);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes", NULL, "printer-name");
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
const char *var; /* Environment variable */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
* attributes-natural-language
*/
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_DEFAULT;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- cupsLangFree(language);
+ request = ippNewRequest(CUPS_GET_DEFAULT);
/*
* Do the request and get back a response...
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
cups_job_t *temp; /* Temporary pointer */
int id, /* job-id */
priority, /* job-priority */
* requested-attributes
*/
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_JOBS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- cupsLangFree(language);
+ request = ippNewRequest(IPP_GET_JOBS);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
cupsGetPPD(const char *name) /* I - Printer name */
{
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
+ time_t modtime = 0; /* Modification time */
+
/*
* See if we can connect to the server...
* Return the PPD file...
*/
- return (cupsGetPPD2(cg->http, name));
+ cg->ppd_filename[0] = '\0';
+
+ if (cupsGetPPD3(cg->http, name, &modtime, cg->ppd_filename,
+ sizeof(cg->ppd_filename)) == HTTP_OK)
+ return (cg->ppd_filename);
+ else
+ return (NULL);
}
const char * /* O - Filename for PPD file */
cupsGetPPD2(http_t *http, /* I - HTTP connection */
const char *name) /* I - Printer 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.
+ *
+ * On success, HTTP_OK is returned for a new PPD file and HTTP_NOT_MODIFIED
+ * if the existing PPD file is up-to-date. Any other status is an error.
+ */
+
+http_status_t /* O - HTTP status */
+cupsGetPPD3(http_t *http, /* I - HTTP connection */
+ const char *name, /* I - Printer 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];
* Range check input...
*/
- DEBUG_printf(("cupsGetPPD2(http=%p, name=\"%s\")\n", http,
- name ? name : "(null)"));
+ DEBUG_printf(("cupsGetPPD3(http=%p, name=\"%s\", modtime=%p(%d), buffer=%p, "
+ "bufsize=%d)\n", http, name ? name : "(null)", modtime,
+ modtime ? *modtime : 0, buffer, (int)bufsize));
- if (!http || !name)
+ if (!http)
{
- if (!http)
- _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
- else
- _cupsSetError(IPP_INTERNAL_ERROR, "No printer name!");
+ _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
+ return (HTTP_NOT_ACCEPTABLE);
+ }
- return (NULL);
+ if (!name)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, "No printer name!");
+ return (HTTP_NOT_ACCEPTABLE);
+ }
+
+ if (!modtime)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, "No modification time!");
+ return (HTTP_NOT_ACCEPTABLE);
+ }
+
+ if (!buffer || bufsize <= 1)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, "Bad filename buffer!");
+ return (HTTP_NOT_ACCEPTABLE);
}
/*
if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port,
resource, sizeof(resource), 0))
- return (NULL);
+ return (HTTP_NOT_FOUND);
DEBUG_printf(("Printer hostname=\"%s\", port=%d\n", hostname, port));
{
DEBUG_puts("Unable to connect to server!");
- return (NULL);
+ return (HTTP_SERVICE_UNAVAILABLE);
}
/*
* Get a temp file...
*/
- if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0)
+ if (buffer[0])
+ fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+ else
+ fd = cupsTempFd(buffer, bufsize);
+
+ if (fd < 0)
{
/*
* Can't open file; close the server connection and return NULL...
if (http2 != http)
httpClose(http2);
- return (NULL);
+ return (HTTP_SERVER_ERROR);
}
/*
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)
+ if (status == HTTP_OK)
+ *modtime = httpGetDateTime(httpGetField(http2, HTTP_FIELD_DATE));
+ else if (status != HTTP_NOT_MODIFIED)
{
switch (status)
{
}
unlink(cg->ppd_filename);
-
- return (NULL);
}
/*
* Return the PPD file...
*/
- return (cg->ppd_filename);
+ return (status);
}
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
char **temp; /* Temporary pointer */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
* requested-attributes
*/
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_PRINTERS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- cupsLangFree(language);
+ request = ippNewRequest(CUPS_GET_PRINTERS);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes", NULL, "printer-name");
}
+/*
+ * '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 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 cupsGetPPD(), cupsGetPPD2(), or
+ * cupsGetServerPPD().
+ *
+ * @since CUPS 1.3@
+ */
+
+char * /* O - Name of PPD file or NULL on error */
+cupsGetServerPPD(http_t *http, /* I - HTTP connection */
+ 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 (!http || !name)
+ {
+ if (!http)
+ _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
+ else
+ _cupsSetError(IPP_INTERNAL_ERROR, "No PPD name!");
+
+ 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, strerror(errno));
+
+ 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 (cupsLastError() != IPP_OK)
+ {
+ unlink(cg->ppd_filename);
+ return (NULL);
+ }
+ else
+ return (cg->ppd_filename);
+}
+
+
/*
* 'cupsLastError()' - Return the last IPP status code.
*/
ipp_t *response; /* IPP response */
ipp_attribute_t *attr; /* IPP job-id attribute */
char uri[HTTP_MAX_URI]; /* Printer URI */
- cups_lang_t *language; /* Language to use */
int jobid; /* New job ID */
const char *base; /* Basename of current filename */
return (0);
}
- /*
- * Setup the request data...
- */
-
- language = cupsLangDefault();
-
/*
* Build a standard CUPS URI for the printer and fill the standard IPP
* attributes...
*/
- if ((request = ippNew()) == NULL)
+ if ((request = ippNewRequest(num_files == 1 ? IPP_PRINT_JOB :
+ IPP_CREATE_JOB)) == NULL)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
return (0);
}
- request->request.op.operation_id = num_files == 1 ? IPP_PRINT_JOB :
- IPP_CREATE_JOB;
- request->request.op.request_id = 1;
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL,
- language != NULL ? language->language : "C");
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
* attributes...
*/
- if ((request = ippNew()) == NULL)
+ if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL)
return (0);
- request->request.op.operation_id = IPP_SEND_DOCUMENT;
- request->request.op.request_id = 1;
-
snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", jobid);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL,
- language != NULL ? language->language : "C");
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
NULL, uri);
ippDelete(response);
}
- cupsLangFree(language);
-
return (jobid);
}
ippDelete(response);
}
- _cupsSetError(IPP_INTERNAL_ERROR, "No printer-uri found!");
+ if (cupsLastError() != IPP_NOT_FOUND)
+ _cupsSetError(IPP_INTERNAL_ERROR, "No printer-uri found!");
*host = '\0';
*resource = '\0';
/*
- * End of "$Id: util.c 5716 2006-07-11 17:56:57Z mike $".
+ * End of "$Id: util.c 7014 2007-10-10 21:57:43Z mike $".
*/