/*
- * "$Id$"
- *
* Line Printer Daemon interface for CUPS.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2016 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
- * 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/".
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
*/
/*
* Include necessary headers...
*/
+#define _CUPS_NO_DEPRECATED
#include <cups/cups-private.h>
#include <syslog.h>
#include <unistd.h>
# include <inttypes.h>
#endif /* HAVE_INTTYPES_H */
#ifdef __APPLE__
-# include <vproc.h>
+# include <xpc/xpc.h>
#endif /* __APPLE__ */
* Prototypes...
*/
-static int create_job(http_t *http, const char *dest, const char *title,
- const char *docname, const char *user,
- int num_options, cups_option_t *options);
+static int create_job(http_t *http, const char *dest, const char *title, const char *user, int num_options, cups_option_t *options);
static int get_printer(http_t *http, const char *name, char *dest,
size_t destsize, cups_option_t **options,
int *accepting, int *shared, ipp_pstate_t *state);
static int send_state(const char *name, const char *list,
int longstatus);
static char *smart_gets(char *s, int len, FILE *fp);
+static void smart_strlcpy(char *dst, const char *src, size_t dstsize);
/*
hostip[256], /* IP address */
*hostfamily; /* Address family */
int hostlookups; /* Do hostname lookups? */
+
+
#ifdef __APPLE__
- vproc_transaction_t vtran = vproc_transaction_begin(NULL);
+ xpc_transaction_begin();
#endif /* __APPLE__ */
-
/*
* Don't buffer the output...
*/
putchar(1);
#ifdef __APPLE__
- vproc_transaction_end(NULL, vtran);
+ xpc_transaction_end();
#endif /* __APPLE__ */
return (1);
closelog();
#ifdef __APPLE__
- vproc_transaction_end(NULL, vtran);
+ xpc_transaction_end();
#endif /* __APPLE__ */
return (status);
create_job(http_t *http, /* I - HTTP connection */
const char *dest, /* I - Destination name */
const char *title, /* I - job-name */
- const char *docname, /* I - Name of job file */
- const char *user, /* I - requesting-user-name */
+ const char *user, /* I - requesting-user-name */
int num_options, /* I - Number of options for job */
cups_option_t *options) /* I - Options for job */
{
* Setup the Create-Job request...
*/
- request = ippNewRequest(IPP_CREATE_JOB);
+ request = ippNewRequest(IPP_OP_CREATE_JOB);
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", 0, "/printers/%s", dest);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
NULL, title);
- if (docname[0])
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
- NULL, docname);
-
cupsEncodeOptions(request, num_options, options);
/*
response = cupsDoRequest(http, request, uri);
- if (!response || cupsLastError() > IPP_OK_CONFLICT)
+ if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING)
{
syslog(LOG_ERR, "Unable to create job - %s", cupsLastErrorString());
if (shared)
*shared = 0;
if (state)
- *state = IPP_PRINTER_STOPPED;
+ *state = IPP_PSTATE_STOPPED;
if (options)
*options = NULL;
* Setup the Get-Printer-Attributes request...
*/
- request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", 0, "/printers/%s", dest);
response = cupsDoRequest(http, request, "/");
- if (!response || cupsLastError() > IPP_OK_CONFLICT)
+ if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING)
{
/*
* If we can't find the printer by name, look up the printer-name
* Setup the CUPS-Get-Printers request...
*/
- request = ippNewRequest(CUPS_GET_PRINTERS);
+ request = ippNewRequest(IPP_OP_CUPS_GET_PRINTERS);
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes",
response = cupsDoRequest(http, request, "/");
- if (!response || cupsLastError() > IPP_OK_CONFLICT)
+ if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING)
{
syslog(LOG_ERR, "Unable to get list of printers - %s",
cupsLastErrorString());
* Setup the Send-Document request...
*/
- request = ippNewRequest(IPP_SEND_DOCUMENT);
+ request = ippNewRequest(IPP_OP_SEND_DOCUMENT);
snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", id);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippDelete(cupsDoFileRequest(http, request, uri, filename));
- if (cupsLastError() > IPP_OK_CONFLICT)
+ if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
{
syslog(LOG_ERR, "Unable to send document - %s", cupsLastErrorString());
* Connect to the server...
*/
- http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+ http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
if (!http)
{
syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno));
switch (line[0])
{
case 'J' : /* Job name */
- strlcpy(title, line + 1, sizeof(title));
+ smart_strlcpy(title, line + 1, sizeof(title));
break;
case 'N' : /* Document name */
- strlcpy(docname, line + 1, sizeof(docname));
+ smart_strlcpy(docname, line + 1, sizeof(docname));
break;
case 'P' : /* User identification */
- strlcpy(user, line + 1, sizeof(user));
+ smart_strlcpy(user, line + 1, sizeof(user));
break;
case 'L' : /* Print banner page */
* Create the job...
*/
- if ((id = create_job(http, dest, title, docname, user, num_options,
- options)) < 0)
+ if ((id = create_job(http, dest, title, user, num_options, options)) < 0)
status = 1;
else
{
switch (line[0])
{
case 'N' : /* Document name */
- strlcpy(docname, line + 1, sizeof(docname));
+ smart_strlcpy(docname, line + 1, sizeof(docname));
break;
case 'c' : /* Plot CIF file */
* Try connecting to the local server...
*/
- if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
- cupsEncryption())) == NULL)
+ if ((http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL)
{
syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(),
strerror(errno));
list ++;
/*
- * Build an IPP_CANCEL_JOB request, which requires the following
+ * Build an IPP_OP_CANCEL_JOB request, which requires the following
* attributes:
*
* attributes-charset
* requesting-user-name
*/
- request = ippNewRequest(IPP_CANCEL_JOB);
+ request = ippNewRequest(IPP_OP_CANCEL_JOB);
sprintf(uri, "ipp://localhost/jobs/%d", id);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippDelete(cupsDoRequest(http, request, "/jobs"));
- if (cupsLastError() > IPP_OK_CONFLICT)
+ if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
{
syslog(LOG_WARNING, "Cancel of job ID %d failed: %s\n", id,
cupsLastErrorString());
* Try connecting to the local server...
*/
- if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
- cupsEncryption())) == NULL)
+ if ((http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL)
{
syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(),
strerror(errno));
switch (state)
{
- case IPP_PRINTER_IDLE :
+ case IPP_PSTATE_IDLE :
printf("%s is ready\n", dest);
break;
- case IPP_PRINTER_PROCESSING :
+ case IPP_PSTATE_PROCESSING :
printf("%s is ready and printing\n", dest);
break;
- case IPP_PRINTER_STOPPED :
+ case IPP_PSTATE_STOPPED :
printf("%s is not ready\n", dest);
break;
}
/*
- * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
+ * Build an IPP_OP_GET_JOBS or IPP_OP_GET_JOB_ATTRIBUTES request, which requires
* the following attributes:
*
* attributes-charset
id = atoi(list);
- request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS);
+ request = ippNewRequest(id ? IPP_OP_GET_JOB_ATTRIBUTES : IPP_OP_GET_JOBS);
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", 0, "/printers/%s", dest);
jobcount = 0;
response = cupsDoRequest(http, request, "/");
- if (cupsLastError() > IPP_OK_CONFLICT)
+ if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
{
printf("get-jobs failed: %s\n", cupsLastErrorString());
ippDelete(response);
jobid = 0;
jobsize = 0;
- jobstate = IPP_JOB_PENDING;
+ jobstate = IPP_JSTATE_PENDING;
jobname = "untitled";
jobuser = NULL;
jobdest = NULL;
* Display the job...
*/
- if (jobstate == IPP_JOB_PROCESSING)
+ if (jobstate == IPP_JSTATE_PROCESSING)
strlcpy(rankstr, "active", sizeof(rankstr));
else
{
/*
- * End of "$Id$".
+ * 'smart_strlcpy()' - Copy a string and convert from ISO-8859-1 to UTF-8 as needed.
*/
+
+static void
+smart_strlcpy(char *dst, /* I - Output buffer */
+ const char *src, /* I - Input string */
+ size_t dstsize) /* I - Size of output buffer */
+{
+ const unsigned char *srcptr; /* Pointer into input string */
+ unsigned char *dstptr, /* Pointer into output buffer */
+ *dstend; /* End of output buffer */
+ int saw_8859 = 0; /* Saw an extended character that was not UTF-8? */
+
+
+ for (srcptr = (unsigned char *)src, dstptr = (unsigned char *)dst, dstend = dstptr + dstsize - 1; *srcptr;)
+ {
+ if (*srcptr < 0x80)
+ *dstptr++ = *srcptr++; /* ASCII */
+ else if (saw_8859)
+ {
+ /*
+ * Map ISO-8859-1 (most likely character set for legacy LPD clients) to
+ * UTF-8...
+ */
+
+ if (dstptr > (dstend - 2))
+ break;
+
+ *dstptr++ = 0xc0 | (*srcptr >> 6);
+ *dstptr++ = 0x80 | (*srcptr++ & 0x3f);
+ }
+ else if ((*srcptr & 0xe0) == 0xc0 && (srcptr[1] & 0xc0) == 0x80)
+ {
+ /*
+ * 2-byte UTF-8 sequence...
+ */
+
+ if (dstptr > (dstend - 2))
+ break;
+
+ *dstptr++ = *srcptr++;
+ *dstptr++ = *srcptr++;
+ }
+ else if ((*srcptr & 0xf0) == 0xe0 && (srcptr[1] & 0xc0) == 0x80 && (srcptr[2] & 0xc0) == 0x80)
+ {
+ /*
+ * 3-byte UTF-8 sequence...
+ */
+
+ if (dstptr > (dstend - 3))
+ break;
+
+ *dstptr++ = *srcptr++;
+ *dstptr++ = *srcptr++;
+ *dstptr++ = *srcptr++;
+ }
+ else if ((*srcptr & 0xf8) == 0xf0 && (srcptr[1] & 0xc0) == 0x80 && (srcptr[2] & 0xc0) == 0x80 && (srcptr[3] & 0xc0) == 0x80)
+ {
+ /*
+ * 4-byte UTF-8 sequence...
+ */
+
+ if (dstptr > (dstend - 4))
+ break;
+
+ *dstptr++ = *srcptr++;
+ *dstptr++ = *srcptr++;
+ *dstptr++ = *srcptr++;
+ *dstptr++ = *srcptr++;
+ }
+ else
+ {
+ /*
+ * Bad UTF-8 sequence, this must be an ISO-8859-1 string...
+ */
+
+ saw_8859 = 1;
+
+ if (dstptr > (dstend - 2))
+ break;
+
+ *dstptr++ = 0xc0 | (*srcptr >> 6);
+ *dstptr++ = 0x80 | (*srcptr++ & 0x3f);
+ }
+ }
+
+ *dstptr = '\0';
+}