summaryrefslogtreecommitdiff
path: root/test/ippserver.c
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2013-06-12 14:23:32 +0200
committerDidier Raboud <odyx@debian.org>2013-06-12 14:23:32 +0200
commit6b7ae334dc7e1350c89247a3aea31c844128b970 (patch)
tree07473a9c942897c8ae5c29048e9a29dddca96e07 /test/ippserver.c
parentea5667a811b20e235ce1975e763469edd1f7f0de (diff)
downloadcups-6b7ae334dc7e1350c89247a3aea31c844128b970.tar.gz
Imported Upstream version 1.7~b1upstream/1.7_b1
Diffstat (limited to 'test/ippserver.c')
-rw-r--r--test/ippserver.c2174
1 files changed, 1061 insertions, 1113 deletions
diff --git a/test/ippserver.c b/test/ippserver.c
index cce95848..a5c62733 100644
--- a/test/ippserver.c
+++ b/test/ippserver.c
@@ -1,9 +1,9 @@
/*
- * "$Id: ippserver.c 10777 2012-12-17 22:18:10Z mike $"
+ * "$Id: ippserver.c 10851 2013-01-31 16:06:14Z mike $"
*
* Sample IPP/2.0 server for CUPS.
*
- * Copyright 2010-2012 by Apple Inc.
+ * Copyright 2010-2013 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -73,15 +73,31 @@
*/
/*
+ * Disable private and deprecated stuff so we can verify that the public API
+ * is sufficient to implement a server.
+ */
+
+#define _IPP_PRIVATE_STRUCTURES 0 /* Disable private IPP stuff */
+#define _CUPS_NO_DEPRECATED 1 /* Disable deprecated stuff */
+
+
+/*
* Include necessary headers...
*/
-#include <cups/cups-private.h>
+#include <cups/cups.h> /* Public API */
+#include <config.h> /* CUPS configuration header */
+#include <cups/string-private.h> /* For string functions */
+#include <cups/thread-private.h> /* For multithreading functions */
+
+#include <sys/wait.h>
+
#ifdef HAVE_DNSSD
# include <dns_sd.h>
#endif /* HAVE_DNSSD */
#include <limits.h>
#include <sys/stat.h>
+#include <sys/fcntl.h>
#include <poll.h>
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
@@ -103,29 +119,29 @@
enum _ipp_preasons_e /* printer-state-reasons bit values */
{
- _IPP_PRINTER_NONE = 0x0000, /* none */
- _IPP_PRINTER_OTHER = 0x0001, /* other */
- _IPP_PRINTER_COVER_OPEN = 0x0002, /* cover-open */
- _IPP_PRINTER_INPUT_TRAY_MISSING = 0x0004,
+ _IPP_PSTATE_NONE = 0x0000, /* none */
+ _IPP_PSTATE_OTHER = 0x0001, /* other */
+ _IPP_PSTATE_COVER_OPEN = 0x0002, /* cover-open */
+ _IPP_PSTATE_INPUT_TRAY_MISSING = 0x0004,
/* input-tray-missing */
- _IPP_PRINTER_MARKER_SUPPLY_EMPTY = 0x0008,
+ _IPP_PSTATE_MARKER_SUPPLY_EMPTY = 0x0008,
/* marker-supply-empty */
- _IPP_PRINTER_MARKER_SUPPLY_LOW = 0x0010,
+ _IPP_PSTATE_MARKER_SUPPLY_LOW = 0x0010,
/* marker-suply-low */
- _IPP_PRINTER_MARKER_WASTE_ALMOST_FULL = 0x0020,
+ _IPP_PSTATE_MARKER_WASTE_ALMOST_FULL = 0x0020,
/* marker-waste-almost-full */
- _IPP_PRINTER_MARKER_WASTE_FULL = 0x0040,
+ _IPP_PSTATE_MARKER_WASTE_FULL = 0x0040,
/* marker-waste-full */
- _IPP_PRINTER_MEDIA_EMPTY = 0x0080, /* media-empty */
- _IPP_PRINTER_MEDIA_JAM = 0x0100, /* media-jam */
- _IPP_PRINTER_MEDIA_LOW = 0x0200, /* media-low */
- _IPP_PRINTER_MEDIA_NEEDED = 0x0400, /* media-needed */
- _IPP_PRINTER_MOVING_TO_PAUSED = 0x0800,
+ _IPP_PSTATE_MEDIA_EMPTY = 0x0080, /* media-empty */
+ _IPP_PSTATE_MEDIA_JAM = 0x0100, /* media-jam */
+ _IPP_PSTATE_MEDIA_LOW = 0x0200, /* media-low */
+ _IPP_PSTATE_MEDIA_NEEDED = 0x0400, /* media-needed */
+ _IPP_PSTATE_MOVING_TO_PAUSED = 0x0800,
/* moving-to-paused */
- _IPP_PRINTER_PAUSED = 0x1000, /* paused */
- _IPP_PRINTER_SPOOL_AREA_FULL = 0x2000,/* spool-area-full */
- _IPP_PRINTER_TONER_EMPTY = 0x4000, /* toner-empty */
- _IPP_PRINTER_TONER_LOW = 0x8000 /* toner-low */
+ _IPP_PSTATE_PAUSED = 0x1000, /* paused */
+ _IPP_PSTATE_SPOOL_AREA_FULL = 0x2000,/* spool-area-full */
+ _IPP_PSTATE_TONER_EMPTY = 0x4000, /* toner-empty */
+ _IPP_PSTATE_TONER_LOW = 0x8000 /* toner-low */
};
typedef unsigned int _ipp_preasons_t; /* Bitfield for printer-state-reasons */
@@ -196,6 +212,9 @@ typedef struct _ipp_printer_s /**** Printer data ****/
#ifdef HAVE_DNSSD
DNSServiceRef common_ref, /* Shared service connection */
ipp_ref, /* Bonjour IPP service */
+# ifdef HAVE_SSL
+ ipps_ref, /* Bonjour IPPS service */
+# endif /* HAVE_SSL */
http_ref, /* Bonjour HTTP service */
printer_ref; /* Bonjour LPD service */
TXTRecordRef ipp_txt; /* Bonjour IPP TXT record */
@@ -205,7 +224,8 @@ typedef struct _ipp_printer_s /**** Printer data ****/
*icon, /* Icon filename */
*directory, /* Spool directory */
*hostname, /* Hostname */
- *uri; /* printer-uri-supported */
+ *uri, /* printer-uri-supported */
+ *command; /* Command to run with job file */
int port; /* Port */
size_t urilen; /* Length of printer URI */
ipp_t *attrs; /* Static attributes */
@@ -220,7 +240,7 @@ typedef struct _ipp_printer_s /**** Printer data ****/
struct _ipp_job_s /**** Job data ****/
{
int id; /* Job ID */
- char *name, /* job-name */
+ const char *name, /* job-name */
*username, /* job-originating-user-name */
*format; /* document-format */
ipp_jstate_t state; /* job-state value */
@@ -235,7 +255,7 @@ struct _ipp_job_s /**** Job data ****/
typedef struct _ipp_client_s /**** Client data ****/
{
- http_t http; /* HTTP connection */
+ http_t *http; /* HTTP connection */
ipp_t *request, /* IPP request */
*response; /* IPP response */
time_t start; /* Request start time */
@@ -243,6 +263,7 @@ typedef struct _ipp_client_s /**** Client data ****/
ipp_op_t operation_id; /* IPP operation-id */
char uri[1024]; /* Request URI */
http_addr_t addr; /* Client address */
+ char hostname[256]; /* Client hostname */
_ipp_printer_t *printer; /* Printer */
_ipp_job_t *job; /* Current job, if any */
} _ipp_client_t;
@@ -270,11 +291,12 @@ static _ipp_printer_t *create_printer(const char *servername,
const char *icon,
const char *docformats, int ppm,
int ppm_color, int duplex, int port,
+ int pin,
#ifdef HAVE_DNSSD
- const char *regtype,
+ const char *subtype,
#endif /* HAVE_DNSSD */
- const char *directory);
-static cups_array_t *create_requested_array(_ipp_client_t *client);
+ const char *directory,
+ const char *command);
static void debug_attributes(const char *title, ipp_t *ipp,
int response);
static void delete_client(_ipp_client_t *client);
@@ -317,6 +339,7 @@ static int register_printer(_ipp_printer_t *printer,
int duplex, const char *regtype);
#endif /* HAVE_DNSSD */
static int respond_http(_ipp_client_t *client, http_status_t code,
+ const char *content_coding,
const char *type, size_t length);
static void respond_ipp(_ipp_client_t *client, ipp_status_t status,
const char *message, ...)
@@ -347,21 +370,23 @@ main(int argc, /* I - Number of command-line args */
{
int i; /* Looping var */
const char *opt, /* Current option character */
+ *command = NULL, /* Command to run with job files */
*servername = NULL, /* Server host name */
*name = NULL, /* Printer name */
*location = "", /* Location of printer */
*make = "Test", /* Manufacturer */
*model = "Printer", /* Model */
*icon = "printer.png", /* Icon file */
- *formats = "application/pdf,image/jpeg";
+ *formats = "application/pdf,image/jpeg,image/pwg-raster";
/* Supported formats */
#ifdef HAVE_DNSSD
- const char *regtype = "_ipp._tcp"; /* Bonjour service type */
+ const char *subtype = "_print"; /* Bonjour service subtype */
#endif /* HAVE_DNSSD */
- int port = 8631, /* Port number (0 = auto) TODO: FIX */
+ int port = 8631, /* Port number (0 = auto) */
duplex = 0, /* Duplex mode */
ppm = 10, /* Pages per minute for mono */
- ppm_color = 0; /* Pages per minute for color */
+ ppm_color = 0, /* Pages per minute for color */
+ pin = 0; /* PIN printing mode? */
char directory[1024] = ""; /* Spool directory */
_ipp_printer_t *printer; /* Printer object */
@@ -387,6 +412,18 @@ main(int argc, /* I - Number of command-line args */
make = argv[i];
break;
+ case 'P' : /* -P (PIN printing mode) */
+ pin = 1;
+ break;
+
+ case 'c' : /* -c command */
+ i ++;
+ if (i >= argc)
+ usage(1);
+
+ command = argv[i];
+ break;
+
case 'd' : /* -d spool-directory */
i ++;
if (i >= argc)
@@ -445,11 +482,11 @@ main(int argc, /* I - Number of command-line args */
break;
#ifdef HAVE_DNSSD
- case 'r' : /* -r regtype */
+ case 'r' : /* -r subtype */
i ++;
if (i >= argc)
usage(1);
- regtype = argv[i];
+ subtype = argv[i];
break;
#endif /* HAVE_DNSSD */
@@ -508,11 +545,11 @@ main(int argc, /* I - Number of command-line args */
*/
if ((printer = create_printer(servername, name, location, make, model, icon,
- formats, ppm, ppm_color, duplex, port,
+ formats, ppm, ppm_color, duplex, port, pin,
#ifdef HAVE_DNSSD
- regtype,
+ subtype,
#endif /* HAVE_DNSSD */
- directory)) == NULL)
+ directory, command)) == NULL)
return (1);
/*
@@ -591,17 +628,22 @@ copy_attributes(ipp_t *to, /* I - Destination request */
if (!to || !from)
return;
- for (fromattr = from->attrs; fromattr; fromattr = fromattr->next)
+ for (fromattr = ippFirstAttribute(from);
+ fromattr;
+ fromattr = ippNextAttribute(from))
{
/*
* Filter attributes as needed...
*/
- if ((group_tag != IPP_TAG_ZERO && fromattr->group_tag != group_tag &&
- fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name)
+ ipp_tag_t fromgroup = ippGetGroupTag(fromattr);
+ const char *fromname = ippGetName(fromattr);
+
+ if ((group_tag != IPP_TAG_ZERO && fromgroup != group_tag &&
+ fromgroup != IPP_TAG_ZERO) || !fromname)
continue;
- if (!ra || cupsArrayFind(ra, fromattr->name))
+ if (!ra || cupsArrayFind(ra, (void *)fromname))
ippCopyAttribute(to, fromattr, quickcopy);
}
}
@@ -631,59 +673,59 @@ copy_job_attributes(
{
switch (job->state)
{
- case IPP_JOB_PENDING :
+ case IPP_JSTATE_PENDING :
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST, "job-state-reasons",
NULL, "none");
break;
- case IPP_JOB_HELD :
+ case IPP_JSTATE_HELD :
if (job->fd >= 0)
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
- NULL, "job-incoming");
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "job-state-reasons", NULL, "job-incoming");
else if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_ZERO))
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
- NULL, "job-hold-until-specified");
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "job-state-reasons", NULL, "job-hold-until-specified");
else
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
- NULL, "job-data-insufficient");
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "job-state-reasons", NULL, "job-data-insufficient");
break;
- case IPP_JOB_PROCESSING :
+ case IPP_JSTATE_PROCESSING :
if (job->cancel)
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
- NULL, "processing-to-stop-point");
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "job-state-reasons", NULL, "processing-to-stop-point");
else
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
- NULL, "job-printing");
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "job-state-reasons", NULL, "job-printing");
break;
- case IPP_JOB_STOPPED :
+ case IPP_JSTATE_STOPPED :
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST, "job-state-reasons",
NULL, "job-stopped");
break;
- case IPP_JOB_CANCELED :
+ case IPP_JSTATE_CANCELED :
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST, "job-state-reasons",
NULL, "job-canceled-by-user");
break;
- case IPP_JOB_ABORTED :
+ case IPP_JSTATE_ABORTED :
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST, "job-state-reasons",
NULL, "aborted-by-system");
break;
- case IPP_JOB_COMPLETED :
+ case IPP_JSTATE_COMPLETED :
ippAddString(client->response, IPP_TAG_JOB,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST, "job-state-reasons",
NULL, "job-completed-successfully");
break;
}
@@ -711,8 +753,6 @@ create_client(_ipp_printer_t *printer, /* I - Printer */
int sock) /* I - Listen socket */
{
_ipp_client_t *client; /* Client */
- int val; /* Parameter value */
- socklen_t addrlen; /* Length of address */
if ((client = calloc(1, sizeof(_ipp_client_t))) == NULL)
@@ -721,20 +761,13 @@ create_client(_ipp_printer_t *printer, /* I - Printer */
return (NULL);
}
- client->printer = printer;
- client->http.activity = time(NULL);
- client->http.hostaddr = &(client->addr);
- client->http.blocking = 1;
- client->http.wait_value = 60000;
+ client->printer = printer;
/*
* Accept the client and get the remote address...
*/
- addrlen = sizeof(http_addr_t);
-
- if ((client->http.fd = accept(sock, (struct sockaddr *)&(client->addr),
- &addrlen)) < 0)
+ if ((client->http = httpAcceptConnection(sock, 1)) == NULL)
{
perror("Unable to accept client connection");
@@ -743,23 +776,10 @@ create_client(_ipp_printer_t *printer, /* I - Printer */
return (NULL);
}
- httpAddrString(&(client->addr), client->http.hostname,
- sizeof(client->http.hostname));
+ httpGetHostname(client->http, client->hostname, sizeof(client->hostname));
if (Verbosity)
- fprintf(stderr, "Accepted connection from %s (%s)\n", client->http.hostname,
- client->http.hostaddr->addr.sa_family == AF_INET ? "IPv4" : "IPv6");
-
- /*
- * Using TCP_NODELAY improves responsiveness, especially on systems
- * with a slow loopback interface. Since we write large buffers
- * when sending print files and requests, there shouldn't be any
- * performance penalty for this...
- */
-
- val = 1;
- setsockopt(client->http.fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val,
- sizeof(val));
+ fprintf(stderr, "Accepted connection from %s\n", client->hostname);
return (client);
}
@@ -780,7 +800,7 @@ create_job(_ipp_client_t *client) /* I - Client */
_cupsRWLockWrite(&(client->printer->rwlock));
if (client->printer->active_job &&
- client->printer->active_job->state < IPP_JOB_CANCELED)
+ client->printer->active_job->state < IPP_JSTATE_CANCELED)
{
/*
* Only accept a single job at a time...
@@ -802,7 +822,7 @@ create_job(_ipp_client_t *client) /* I - Client */
job->printer = client->printer;
job->attrs = client->request;
- job->state = IPP_JOB_HELD;
+ job->state = IPP_JSTATE_HELD;
job->fd = -1;
client->request = NULL;
@@ -810,8 +830,12 @@ create_job(_ipp_client_t *client) /* I - Client */
* Set all but the first two attributes to the job attributes group...
*/
- for (attr = job->attrs->attrs->next->next; attr; attr = attr->next)
- attr->group_tag = IPP_TAG_JOB;
+ for (ippFirstAttribute(job->attrs),
+ ippNextAttribute(job->attrs),
+ attr = ippNextAttribute(job->attrs);
+ attr;
+ attr = ippNextAttribute(job->attrs))
+ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
/*
* Get the requesting-user-name, document format, and priority...
@@ -819,22 +843,20 @@ create_job(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(job->attrs, "requesting-user-name",
IPP_TAG_NAME)) != NULL)
- {
- _cupsStrFree(attr->name);
- attr->name = _cupsStrAlloc("job-originating-user-name");
- }
+ ippSetName(job->attrs, &attr, "job-originating-user-name");
else
- attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME | IPP_TAG_COPY,
+ attr = ippAddString(job->attrs, IPP_TAG_JOB,
+ IPP_TAG_NAME | IPP_TAG_CUPS_CONST,
"job-originating-user-name", NULL, "anonymous");
if (attr)
- job->username = attr->values[0].string.text;
+ job->username = ippGetString(attr, 0, NULL);
else
job->username = "anonymous";
if ((attr = ippFindAttribute(job->attrs, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
- job->format = attr->values[0].string.text;
+ job->format = ippGetString(attr, 0, NULL);
else
job->format = "application/octet-stream";
@@ -870,57 +892,24 @@ static int /* O - Listener socket or -1 on error */
create_listener(int family, /* I - Address family */
int *port) /* IO - Port number */
{
- int sock, /* Listener socket */
- val; /* Socket value */
- http_addr_t address; /* Listen address */
- socklen_t addrlen; /* Length of listen address */
-
-
- if ((sock = socket(family, SOCK_STREAM, 0)) < 0)
- return (-1);
+ int sock; /* Listener socket */
+ http_addrlist_t *addrlist; /* Listen address */
+ char service[255]; /* Service port */
- val = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
-
-#ifdef IPV6_V6ONLY
- if (family == AF_INET6)
- setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
-#endif /* IPV6_V6ONLY */
if (!*port)
{
- /*
- * Get the auto-assigned port number for the IPv4 socket...
- */
-
- /* TODO: This code does not appear to work - port is always 0... */
- addrlen = sizeof(address);
- if (getsockname(sock, (struct sockaddr *)&address, &addrlen))
- {
- perror("getsockname() failed");
- *port = 8631;
- }
- else
- *port = _httpAddrPort(&address);
-
+ *port = 8000 + (getuid() % 1000);
fprintf(stderr, "Listening on port %d.\n", *port);
}
- memset(&address, 0, sizeof(address));
- address.addr.sa_family = family;
- _httpAddrSetPort(&address, *port);
-
- if (bind(sock, (struct sockaddr *)&address, httpAddrLength(&address)))
- {
- close(sock);
+ snprintf(service, sizeof(service), "%d", *port);
+ if ((addrlist = httpAddrGetList(NULL, family, service)) == NULL)
return (-1);
- }
- if (listen(sock, 5))
- {
- close(sock);
- return (-1);
- }
+ sock = httpAddrListen(&(addrlist->addr), *port);
+
+ httpAddrFreeList(addrlist);
return (sock);
}
@@ -1003,10 +992,12 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
int ppm_color, /* I - Pages per minute in color (0 for gray) */
int duplex, /* I - 1 = duplex, 0 = simplex */
int port, /* I - Port for listeners or 0 for auto */
+ int pin, /* I - Require PIN printing */
#ifdef HAVE_DNSSD
- const char *regtype, /* I - Bonjour service type */
+ const char *subtype, /* I - Bonjour service subtype */
#endif /* HAVE_DNSSD */
- const char *directory) /* I - Spool directory */
+ const char *directory, /* I - Spool directory */
+ const char *command) /* I - Command to run on job files */
{
int i, j; /* Looping vars */
_ipp_printer_t *printer; /* Printer */
@@ -1028,8 +1019,7 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
/* media-size-supported value */
ipp_t *media_col_default;
/* media-col-default value */
- _ipp_value_t *media_col_value;
- /* Current media-col-database value */
+ int media_col_index;/* Current media-col-database value */
int k_supported; /* Maximum file size supported */
#ifdef HAVE_STATVFS
struct statvfs spoolinfo; /* FS info for spool directory */
@@ -1040,10 +1030,10 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
#endif /* HAVE_STATVFS */
static const int orients[4] = /* orientation-requested-supported values */
{
- IPP_PORTRAIT,
- IPP_LANDSCAPE,
- IPP_REVERSE_LANDSCAPE,
- IPP_REVERSE_PORTRAIT
+ IPP_ORIENT_PORTRAIT,
+ IPP_ORIENT_LANDSCAPE,
+ IPP_ORIENT_REVERSE_LANDSCAPE,
+ IPP_ORIENT_REVERSE_PORTRAIT
};
static const char * const versions[] =/* ipp-versions-supported values */
{
@@ -1053,27 +1043,38 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
};
static const int ops[] = /* operations-supported values */
{
- IPP_PRINT_JOB,
- IPP_PRINT_URI,
- IPP_VALIDATE_JOB,
- IPP_CREATE_JOB,
- IPP_SEND_DOCUMENT,
- IPP_SEND_URI,
- IPP_CANCEL_JOB,
- IPP_GET_JOB_ATTRIBUTES,
- IPP_GET_JOBS,
- IPP_GET_PRINTER_ATTRIBUTES
+ IPP_OP_PRINT_JOB,
+ IPP_OP_PRINT_URI,
+ IPP_OP_VALIDATE_JOB,
+ IPP_OP_CREATE_JOB,
+ IPP_OP_SEND_DOCUMENT,
+ IPP_OP_SEND_URI,
+ IPP_OP_CANCEL_JOB,
+ IPP_OP_GET_JOB_ATTRIBUTES,
+ IPP_OP_GET_JOBS,
+ IPP_OP_GET_PRINTER_ATTRIBUTES
};
static const char * const charsets[] =/* charset-supported values */
{
"us-ascii",
"utf-8"
};
+ static const char * const compressions[] =/* compression-supported values */
+ {
+#ifdef HAVE_LIBZ
+ "deflate",
+ "gzip",
+#endif /* HAVE_LIBZ */
+ "none"
+ };
static const char * const job_creation[] =
{ /* job-creation-attributes-supported values */
"copies",
"ipp-attribute-fidelity",
+ "job-account-id",
+ "job-accounting-user-id",
"job-name",
+ "job-password",
"job-priority",
"media",
"media-col",
@@ -1107,6 +1108,20 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
IPP_QUALITY_NORMAL,
IPP_QUALITY_HIGH
};
+ static const int pwg_raster_document_resolution_supported[] =
+ {
+ 150,
+ 300,
+ 600
+ };
+ static const char * const pwg_raster_document_type_supported[] =
+ {
+ "black-1",
+ "cmyk-8",
+ "sgray-8",
+ "srgb-8",
+ "srgb-16"
+ };
static const char * const reference_uri_schemes_supported[] =
{ /* reference-uri-schemes-supported */
"file",
@@ -1148,25 +1163,29 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
printer->ipv4 = -1;
printer->ipv6 = -1;
- printer->name = _cupsStrAlloc(name);
+ printer->name = strdup(name);
#ifdef HAVE_DNSSD
- printer->dnssd_name = _cupsStrRetain(printer->name);
+ printer->dnssd_name = strdup(printer->name);
#endif /* HAVE_DNSSD */
- printer->directory = _cupsStrAlloc(directory);
- printer->hostname = _cupsStrAlloc(servername ? servername :
+ printer->command = command ? strdup(command) : NULL;
+ printer->directory = strdup(directory);
+ printer->hostname = strdup(servername ? servername :
httpGetHostname(NULL, hostname,
sizeof(hostname)));
printer->port = port;
- printer->state = IPP_PRINTER_IDLE;
- printer->state_reasons = _IPP_PRINTER_NONE;
+ printer->state = IPP_PSTATE_IDLE;
+ printer->state_reasons = _IPP_PSTATE_NONE;
printer->jobs = cupsArrayNew((cups_array_func_t)compare_jobs, NULL);
printer->next_job_id = 1;
httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- printer->hostname, printer->port, "/ipp");
- printer->uri = _cupsStrAlloc(uri);
+ printer->hostname, printer->port, "/ipp/print");
+ printer->uri = strdup(uri);
printer->urilen = strlen(uri);
+ if (icon)
+ printer->icon = strdup(icon);
+
_cupsRWInit(&(printer->rwlock));
/*
@@ -1274,11 +1293,13 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
printer->attrs = ippNew();
/* charset-configured */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_CHARSET | IPP_TAG_CUPS_CONST,
"charset-configured", NULL, "utf-8");
/* charset-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_CHARSET | IPP_TAG_CUPS_CONST,
"charset-supported", sizeof(charsets) / sizeof(charsets[0]),
NULL, charsets);
@@ -1287,8 +1308,11 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
ppm_color > 0);
/* compression-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
- "compression-supported", NULL, "none");
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "compression-supported",
+ (int)(sizeof(compressions) / sizeof(compressions[0])), NULL,
+ compressions);
/* copies-default */
ippAddInteger(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
@@ -1315,16 +1339,26 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"finishings-supported", IPP_FINISHINGS_NONE);
/* generated-natural-language-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_LANGUAGE | IPP_TAG_CUPS_CONST,
"generated-natural-language-supported", NULL, "en");
/* ipp-versions-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"ipp-versions-supported",
sizeof(versions) / sizeof(versions[0]), NULL, versions);
+ /* job-account-id-supported */
+ ippAddBoolean(printer->attrs, IPP_TAG_PRINTER, "job-account-id-supported", 1);
+
+ /* job-accounting-user-id-supported */
+ ippAddBoolean(printer->attrs, IPP_TAG_PRINTER,
+ "job-accounting-user-id-supported", 1);
+
/* job-creation-attributes-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"job-creation-attributes-supported",
sizeof(job_creation) / sizeof(job_creation[0]),
NULL, job_creation);
@@ -1333,6 +1367,10 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
ippAddRange(printer->attrs, IPP_TAG_PRINTER, "job-k-octets-supported", 0,
k_supported);
+ /* job-password-supported */
+ ippAddInteger(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-password-supported", 4);
+
/* job-priority-default */
ippAddInteger(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"job-priority-default", 50);
@@ -1342,11 +1380,13 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"job-priority-supported", 100);
/* job-sheets-default */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_NAME | IPP_TAG_CUPS_CONST,
"job-sheets-default", NULL, "none");
/* job-sheets-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_NAME | IPP_TAG_CUPS_CONST,
"job-sheets-supported", NULL, "none");
/* media-bottom-margin-supported */
@@ -1374,7 +1414,7 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
media_col_database = ippAddCollections(printer->attrs, IPP_TAG_PRINTER,
"media-col-database", num_database,
NULL);
- for (media_col_value = media_col_database->values, i = 0;
+ for (media_col_index = 0, i = 0;
i < (int)(sizeof(media_col_sizes) / sizeof(media_col_sizes[0]));
i ++)
{
@@ -1392,11 +1432,13 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
strncmp(media_type_supported[j], "photographic-", 13))
continue;
- media_col_value->collection =
- create_media_col(media_supported[i], media_type_supported[j],
- media_col_sizes[i][0], media_col_sizes[i][1],
- media_xxx_margin_supported[1]);
- media_col_value ++;
+ ippSetCollection(printer->attrs, &media_col_database, media_col_index,
+ create_media_col(media_supported[i],
+ media_type_supported[j],
+ media_col_sizes[i][0],
+ media_col_sizes[i][1],
+ media_xxx_margin_supported[1]));
+ media_col_index ++;
if (media_col_sizes[i][2] != _IPP_ENV_ONLY &&
(!strcmp(media_type_supported[j], "auto") ||
@@ -1406,11 +1448,13 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
* Add borderless version for this combination...
*/
- media_col_value->collection =
- create_media_col(media_supported[i], media_type_supported[j],
- media_col_sizes[i][0], media_col_sizes[i][1],
- media_xxx_margin_supported[0]);
- media_col_value ++;
+ ippSetCollection(printer->attrs, &media_col_database, media_col_index,
+ create_media_col(media_supported[i],
+ media_type_supported[j],
+ media_col_sizes[i][0],
+ media_col_sizes[i][1],
+ media_xxx_margin_supported[0]));
+ media_col_index ++;
}
}
}
@@ -1427,14 +1471,16 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
ippDelete(media_col_default);
/* media-col-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"media-col-supported",
(int)(sizeof(media_col_supported) /
sizeof(media_col_supported[0])), NULL,
media_col_supported);
/* media-default */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"media-default", NULL, media_supported[0]);
/* media-left-margin-supported */
@@ -1452,7 +1498,8 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
media_xxx_margin_supported);
/* media-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"media-supported",
(int)(sizeof(media_supported) / sizeof(media_supported[0])),
NULL, media_supported);
@@ -1466,8 +1513,9 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
for (i = 0;
i < (int)(sizeof(media_col_sizes) / sizeof(media_col_sizes[0]));
i ++)
- media_size_supported->values[i].collection =
- create_media_size(media_col_sizes[i][0], media_col_sizes[i][1]);
+ ippSetCollection(printer->attrs, &media_size_supported, i,
+ create_media_size(media_col_sizes[i][0],
+ media_col_sizes[i][1]));
/* media-top-margin-supported */
ippAddIntegers(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
@@ -1477,14 +1525,16 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
media_xxx_margin_supported);
/* media-type-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"media-type-supported",
(int)(sizeof(media_type_supported) /
sizeof(media_type_supported[0])),
NULL, media_type_supported);
/* multiple-document-handling-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"multiple-document-handling-supported",
sizeof(multiple_document_handling) /
sizeof(multiple_document_handling[0]), NULL,
@@ -1495,7 +1545,8 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"multiple-document-jobs-supported", 0);
/* natural-language-configured */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_LANGUAGE | IPP_TAG_CUPS_CONST,
"natural-language-configured", NULL, "en");
/* number-up-default */
@@ -1519,11 +1570,13 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"orientation-requested-supported", 4, orients);
/* output-bin-default */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"output-bin-default", NULL, "face-down");
/* output-bin-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"output-bin-supported", NULL, "face-down");
/* pages-per-minute */
@@ -1536,7 +1589,8 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"pages-per-minute-color", ppm_color);
/* pdl-override-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"pdl-override-supported", NULL, "attempted");
/* print-quality-default */
@@ -1574,6 +1628,20 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
"printer-make-and-model", NULL, make_model);
+ /* printer-mandatory-job-attributes */
+ if (pin)
+ {
+ static const char * const names[] =
+ {
+ "job-accounting-user-id",
+ "job-password"
+ };
+
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-mandatory-job-attributes",
+ (int)(sizeof(names) / sizeof(names[0])), NULL, names);
+ }
+
/* printer-more-info */
ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
"printer-more-info", NULL, adminurl);
@@ -1594,32 +1662,60 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
"printer-uri-supported", NULL, uri);
+ /* pwg-raster-document-xxx-supported */
+ for (i = 0; i < num_formats; i ++)
+ if (!_cups_strcasecmp(formats[i], "image/pwg-raster"))
+ break;
+
+ if (i < num_formats)
+ {
+ ippAddResolutions(printer->attrs, IPP_TAG_PRINTER,
+ "pwg-raster-document-resolution-supported",
+ (int)(sizeof(pwg_raster_document_resolution_supported) /
+ sizeof(pwg_raster_document_resolution_supported[0])),
+ IPP_RES_PER_INCH,
+ pwg_raster_document_resolution_supported,
+ pwg_raster_document_resolution_supported);
+ ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "pwg-raster-document-sheet-back", NULL, "normal");
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "pwg-raster-document-type-supported",
+ (int)(sizeof(pwg_raster_document_type_supported) /
+ sizeof(pwg_raster_document_type_supported[0])), NULL,
+ pwg_raster_document_type_supported);
+ }
+
/* reference-uri-scheme-supported */
ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
- IPP_TAG_URISCHEME | IPP_TAG_COPY,
+ IPP_TAG_URISCHEME | IPP_TAG_CUPS_CONST,
"reference-uri-schemes-supported",
(int)(sizeof(reference_uri_schemes_supported) /
sizeof(reference_uri_schemes_supported[0])),
NULL, reference_uri_schemes_supported);
/* sides-default */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"sides-default", NULL, "one-sided");
/* sides-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"sides-supported", duplex ? 3 : 1, NULL, sides_supported);
/* uri-authentication-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"uri-authentication-supported", NULL, "none");
/* uri-security-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"uri-security-supported", NULL, "none");
/* which-jobs-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
"which-jobs-supported",
sizeof(which_jobs) / sizeof(which_jobs[0]), NULL, which_jobs);
@@ -1633,7 +1729,7 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
*/
if (!register_printer(printer, location, make, model, docformats, adminurl,
- ppm_color > 0, duplex, regtype))
+ ppm_color > 0, duplex, subtype))
goto bad_printer;
#endif /* HAVE_DNSSD */
@@ -1656,208 +1752,6 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
/*
- * 'create_requested_array()' - Create an array for requested-attributes.
- */
-
-static cups_array_t * /* O - requested-attributes array */
-create_requested_array(
- _ipp_client_t *client) /* I - Client */
-{
- int i; /* Looping var */
- ipp_attribute_t *requested; /* requested-attributes attribute */
- cups_array_t *ra; /* Requested attributes array */
- char *value; /* Current value */
-
-
- /*
- * Get the requested-attributes attribute, and return NULL if we don't
- * have one...
- */
-
- if ((requested = ippFindAttribute(client->request, "requested-attributes",
- IPP_TAG_KEYWORD)) == NULL)
- return (NULL);
-
- /*
- * If the attribute contains a single "all" keyword, return NULL...
- */
-
- if (requested->num_values == 1 &&
- !strcmp(requested->values[0].string.text, "all"))
- return (NULL);
-
- /*
- * Create an array using "strcmp" as the comparison function...
- */
-
- ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
-
- for (i = 0; i < requested->num_values; i ++)
- {
- value = requested->values[i].string.text;
-
- if (!strcmp(value, "job-template"))
- {
- cupsArrayAdd(ra, "copies");
- cupsArrayAdd(ra, "copies-default");
- cupsArrayAdd(ra, "copies-supported");
- cupsArrayAdd(ra, "finishings");
- cupsArrayAdd(ra, "finishings-default");
- cupsArrayAdd(ra, "finishings-supported");
- cupsArrayAdd(ra, "job-hold-until");
- cupsArrayAdd(ra, "job-hold-until-default");
- cupsArrayAdd(ra, "job-hold-until-supported");
- cupsArrayAdd(ra, "job-priority");
- cupsArrayAdd(ra, "job-priority-default");
- cupsArrayAdd(ra, "job-priority-supported");
- cupsArrayAdd(ra, "job-sheets");
- cupsArrayAdd(ra, "job-sheets-default");
- cupsArrayAdd(ra, "job-sheets-supported");
- cupsArrayAdd(ra, "media");
- cupsArrayAdd(ra, "media-col");
- cupsArrayAdd(ra, "media-col-default");
- cupsArrayAdd(ra, "media-col-supported");
- cupsArrayAdd(ra, "media-default");
- cupsArrayAdd(ra, "media-source-supported");
- cupsArrayAdd(ra, "media-supported");
- cupsArrayAdd(ra, "media-type-supported");
- cupsArrayAdd(ra, "multiple-document-handling");
- cupsArrayAdd(ra, "multiple-document-handling-default");
- cupsArrayAdd(ra, "multiple-document-handling-supported");
- cupsArrayAdd(ra, "number-up");
- cupsArrayAdd(ra, "number-up-default");
- cupsArrayAdd(ra, "number-up-supported");
- cupsArrayAdd(ra, "orientation-requested");
- cupsArrayAdd(ra, "orientation-requested-default");
- cupsArrayAdd(ra, "orientation-requested-supported");
- cupsArrayAdd(ra, "page-ranges");
- cupsArrayAdd(ra, "page-ranges-supported");
- cupsArrayAdd(ra, "printer-resolution");
- cupsArrayAdd(ra, "printer-resolution-default");
- cupsArrayAdd(ra, "printer-resolution-supported");
- cupsArrayAdd(ra, "print-quality");
- cupsArrayAdd(ra, "print-quality-default");
- cupsArrayAdd(ra, "print-quality-supported");
- cupsArrayAdd(ra, "sides");
- cupsArrayAdd(ra, "sides-default");
- cupsArrayAdd(ra, "sides-supported");
- }
- else if (!strcmp(value, "job-description"))
- {
- cupsArrayAdd(ra, "date-time-at-completed");
- cupsArrayAdd(ra, "date-time-at-creation");
- cupsArrayAdd(ra, "date-time-at-processing");
- cupsArrayAdd(ra, "job-detailed-status-message");
- cupsArrayAdd(ra, "job-document-access-errors");
- cupsArrayAdd(ra, "job-id");
- cupsArrayAdd(ra, "job-impressions");
- cupsArrayAdd(ra, "job-impressions-completed");
- cupsArrayAdd(ra, "job-k-octets");
- cupsArrayAdd(ra, "job-k-octets-processed");
- cupsArrayAdd(ra, "job-media-sheets");
- cupsArrayAdd(ra, "job-media-sheets-completed");
- cupsArrayAdd(ra, "job-message-from-operator");
- cupsArrayAdd(ra, "job-more-info");
- cupsArrayAdd(ra, "job-name");
- cupsArrayAdd(ra, "job-originating-user-name");
- cupsArrayAdd(ra, "job-printer-up-time");
- cupsArrayAdd(ra, "job-printer-uri");
- cupsArrayAdd(ra, "job-state");
- cupsArrayAdd(ra, "job-state-message");
- cupsArrayAdd(ra, "job-state-reasons");
- cupsArrayAdd(ra, "job-uri");
- cupsArrayAdd(ra, "number-of-documents");
- cupsArrayAdd(ra, "number-of-intervening-jobs");
- cupsArrayAdd(ra, "output-device-assigned");
- cupsArrayAdd(ra, "time-at-completed");
- cupsArrayAdd(ra, "time-at-creation");
- cupsArrayAdd(ra, "time-at-processing");
- }
- else if (!strcmp(value, "printer-description"))
- {
- cupsArrayAdd(ra, "charset-configured");
- cupsArrayAdd(ra, "charset-supported");
- cupsArrayAdd(ra, "color-supported");
- cupsArrayAdd(ra, "compression-supported");
- cupsArrayAdd(ra, "document-format-default");
- cupsArrayAdd(ra, "document-format-supported");
- cupsArrayAdd(ra, "generated-natural-language-supported");
- cupsArrayAdd(ra, "ipp-versions-supported");
- cupsArrayAdd(ra, "job-impressions-supported");
- cupsArrayAdd(ra, "job-k-octets-supported");
- cupsArrayAdd(ra, "job-media-sheets-supported");
- cupsArrayAdd(ra, "multiple-document-jobs-supported");
- cupsArrayAdd(ra, "multiple-operation-time-out");
- cupsArrayAdd(ra, "natural-language-configured");
- cupsArrayAdd(ra, "notify-attributes-supported");
- cupsArrayAdd(ra, "notify-lease-duration-default");
- cupsArrayAdd(ra, "notify-lease-duration-supported");
- cupsArrayAdd(ra, "notify-max-events-supported");
- cupsArrayAdd(ra, "notify-events-default");
- cupsArrayAdd(ra, "notify-events-supported");
- cupsArrayAdd(ra, "notify-pull-method-supported");
- cupsArrayAdd(ra, "notify-schemes-supported");
- cupsArrayAdd(ra, "operations-supported");
- cupsArrayAdd(ra, "pages-per-minute");
- cupsArrayAdd(ra, "pages-per-minute-color");
- cupsArrayAdd(ra, "pdl-override-supported");
- cupsArrayAdd(ra, "printer-alert");
- cupsArrayAdd(ra, "printer-alert-description");
- cupsArrayAdd(ra, "printer-current-time");
- cupsArrayAdd(ra, "printer-driver-installer");
- cupsArrayAdd(ra, "printer-info");
- cupsArrayAdd(ra, "printer-is-accepting-jobs");
- cupsArrayAdd(ra, "printer-location");
- cupsArrayAdd(ra, "printer-make-and-model");
- cupsArrayAdd(ra, "printer-message-from-operator");
- cupsArrayAdd(ra, "printer-more-info");
- cupsArrayAdd(ra, "printer-more-info-manufacturer");
- cupsArrayAdd(ra, "printer-name");
- cupsArrayAdd(ra, "printer-state");
- cupsArrayAdd(ra, "printer-state-message");
- cupsArrayAdd(ra, "printer-state-reasons");
- cupsArrayAdd(ra, "printer-up-time");
- cupsArrayAdd(ra, "printer-uri-supported");
- cupsArrayAdd(ra, "queued-job-count");
- cupsArrayAdd(ra, "reference-uri-schemes-supported");
- cupsArrayAdd(ra, "uri-authentication-supported");
- cupsArrayAdd(ra, "uri-security-supported");
- }
- else if (!strcmp(value, "printer-defaults"))
- {
- cupsArrayAdd(ra, "copies-default");
- cupsArrayAdd(ra, "document-format-default");
- cupsArrayAdd(ra, "finishings-default");
- cupsArrayAdd(ra, "job-hold-until-default");
- cupsArrayAdd(ra, "job-priority-default");
- cupsArrayAdd(ra, "job-sheets-default");
- cupsArrayAdd(ra, "media-default");
- cupsArrayAdd(ra, "media-col-default");
- cupsArrayAdd(ra, "number-up-default");
- cupsArrayAdd(ra, "orientation-requested-default");
- cupsArrayAdd(ra, "sides-default");
- }
- else if (!strcmp(value, "subscription-template"))
- {
- cupsArrayAdd(ra, "notify-attributes");
- cupsArrayAdd(ra, "notify-charset");
- cupsArrayAdd(ra, "notify-events");
- cupsArrayAdd(ra, "notify-lease-duration");
- cupsArrayAdd(ra, "notify-natural-language");
- cupsArrayAdd(ra, "notify-pull-method");
- cupsArrayAdd(ra, "notify-recipient-uri");
- cupsArrayAdd(ra, "notify-time-interval");
- cupsArrayAdd(ra, "notify-user-data");
- }
- else
- cupsArrayAdd(ra, value);
- }
-
- return (ra);
-}
-
-
-/*
* 'debug_attributes()' - Print attributes in a request or response.
*/
@@ -1869,38 +1763,39 @@ debug_attributes(const char *title, /* I - Title */
ipp_tag_t group_tag; /* Current group */
ipp_attribute_t *attr; /* Current attribute */
char buffer[2048]; /* String buffer for value */
+ int major, minor; /* Version */
if (Verbosity <= 1)
return;
fprintf(stderr, "%s:\n", title);
- fprintf(stderr, " version=%d.%d\n", ipp->request.any.version[0],
- ipp->request.any.version[1]);
+ major = ippGetVersion(ipp, &minor);
+ fprintf(stderr, " version=%d.%d\n", major, minor);
if (type == 1)
fprintf(stderr, " operation-id=%s(%04x)\n",
- ippOpString(ipp->request.op.operation_id),
- ipp->request.op.operation_id);
+ ippOpString(ippGetOperation(ipp)), ippGetOperation(ipp));
else if (type == 2)
fprintf(stderr, " status-code=%s(%04x)\n",
- ippErrorString(ipp->request.status.status_code),
- ipp->request.status.status_code);
- fprintf(stderr, " request-id=%d\n\n", ipp->request.any.request_id);
+ ippErrorString(ippGetStatusCode(ipp)), ippGetStatusCode(ipp));
+ fprintf(stderr, " request-id=%d\n\n", ippGetRequestId(ipp));
- for (attr = ipp->attrs, group_tag = IPP_TAG_ZERO; attr; attr = attr->next)
+ for (attr = ippFirstAttribute(ipp), group_tag = IPP_TAG_ZERO;
+ attr;
+ attr = ippNextAttribute(ipp))
{
- if (attr->group_tag != group_tag)
+ if (ippGetGroupTag(attr) != group_tag)
{
- group_tag = attr->group_tag;
+ group_tag = ippGetGroupTag(attr);
fprintf(stderr, " %s\n", ippTagString(group_tag));
}
- if (attr->name)
+ if (ippGetName(attr))
{
ippAttributeString(attr, buffer, sizeof(buffer));
- fprintf(stderr, " %s (%s%s) %s\n", attr->name,
- attr->num_values > 1 ? "1setOf " : "",
- ippTagString(attr->value_tag), buffer);
+ fprintf(stderr, " %s (%s%s) %s\n", ippGetName(attr),
+ ippGetCount(attr) > 1 ? "1setOf " : "",
+ ippTagString(ippGetValueTag(attr)), buffer);
}
}
}
@@ -1915,27 +1810,21 @@ static void
delete_client(_ipp_client_t *client) /* I - Client */
{
if (Verbosity)
- fprintf(stderr, "Closing connection from %s (%s)\n", client->http.hostname,
- client->http.hostaddr->addr.sa_family == AF_INET ? "IPv4" : "IPv6");
+ fprintf(stderr, "Closing connection from %s\n", client->hostname);
/*
* Flush pending writes before closing...
*/
- httpFlushWrite(&(client->http));
-
- if (client->http.fd >= 0)
- close(client->http.fd);
+ httpFlushWrite(client->http);
/*
* Free memory...
*/
- httpClearCookie(&(client->http));
- httpClearFields(&(client->http));
+ httpClose(client->http);
ippDelete(client->request);
-
ippDelete(client->response);
free(client);
@@ -1988,6 +1877,10 @@ delete_printer(_ipp_printer_t *printer) /* I - Printer */
if (printer->ipp_ref)
DNSServiceRefDeallocate(printer->ipp_ref);
+# ifdef HAVE_SSL
+ if (printer->ipps_ref)
+ DNSServiceRefDeallocate(printer->ipps_ref);
+# endif /* HAVE_SSL */
if (printer->http_ref)
DNSServiceRefDeallocate(printer->http_ref);
@@ -1997,19 +1890,21 @@ delete_printer(_ipp_printer_t *printer) /* I - Printer */
TXTRecordDeallocate(&(printer->ipp_txt));
if (printer->dnssd_name)
- _cupsStrFree(printer->dnssd_name);
+ free(printer->dnssd_name);
#endif /* HAVE_DNSSD */
if (printer->name)
- _cupsStrFree(printer->name);
+ free(printer->name);
if (printer->icon)
- _cupsStrFree(printer->icon);
+ free(printer->icon);
+ if (printer->command)
+ free(printer->command);
if (printer->directory)
- _cupsStrFree(printer->directory);
+ free(printer->directory);
if (printer->hostname)
- _cupsStrFree(printer->hostname);
+ free(printer->hostname);
if (printer->uri)
- _cupsStrFree(printer->uri);
+ free(printer->uri);
ippDelete(printer->attrs);
cupsArrayDelete(printer->jobs);
@@ -2045,8 +1940,8 @@ dnssd_callback(
fprintf(stderr, "Now using DNS-SD service name \"%s\".\n", name);
/* No lock needed since only the main thread accesses/changes this */
- _cupsStrFree(printer->dnssd_name);
- printer->dnssd_name = _cupsStrAlloc(name);
+ free(printer->dnssd_name);
+ printer->dnssd_name = strdup(name);
}
}
#endif /* HAVE_DNSSD */
@@ -2069,14 +1964,15 @@ find_job(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(client->request, "job-uri",
IPP_TAG_URI)) != NULL)
{
- if (!strncmp(attr->values[0].string.text, client->printer->uri,
- client->printer->urilen) &&
- attr->values[0].string.text[client->printer->urilen] == '/')
- key.id = atoi(attr->values[0].string.text + client->printer->urilen + 1);
+ const char *uri = ippGetString(attr, 0, NULL);
+
+ if (!strncmp(uri, client->printer->uri, client->printer->urilen) &&
+ uri[client->printer->urilen] == '/')
+ key.id = atoi(uri + client->printer->urilen + 1);
}
else if ((attr = ippFindAttribute(client->request, "job-id",
IPP_TAG_INTEGER)) != NULL)
- key.id = attr->values[0].integer;
+ key.id = ippGetInteger(attr, 0);
_cupsRWLockRead(&(client->printer->rwlock));
job = (_ipp_job_t *)cupsArrayFind(client->printer->jobs, &key);
@@ -2107,12 +2003,12 @@ html_escape(_ipp_client_t *client, /* I - Client */
if (*s == '&' || *s == '<')
{
if (s > start)
- httpWrite2(&(client->http), start, s - start);
+ httpWrite2(client->http, start, s - start);
if (*s == '&')
- httpWrite2(&(client->http), "&amp;", 5);
+ httpWrite2(client->http, "&amp;", 5);
else
- httpWrite2(&(client->http), "&lt;", 4);
+ httpWrite2(client->http, "&lt;", 4);
start = s + 1;
}
@@ -2121,7 +2017,7 @@ html_escape(_ipp_client_t *client, /* I - Client */
}
if (s > start)
- httpWrite2(&(client->http), start, s - start);
+ httpWrite2(client->http, start, s - start);
}
@@ -2158,14 +2054,14 @@ html_printf(_ipp_client_t *client, /* I - Client */
if (*format == '%')
{
if (format > start)
- httpWrite2(&(client->http), start, format - start);
+ httpWrite2(client->http, start, format - start);
tptr = tformat;
*tptr++ = *format++;
if (*format == '%')
{
- httpWrite2(&(client->http), "%", 1);
+ httpWrite2(client->http, "%", 1);
format ++;
continue;
}
@@ -2278,7 +2174,7 @@ html_printf(_ipp_client_t *client, /* I - Client */
sprintf(temp, tformat, va_arg(ap, double));
- httpWrite2(&(client->http), temp, strlen(temp));
+ httpWrite2(client->http, temp, strlen(temp));
break;
case 'B' : /* Integer formats */
@@ -2302,7 +2198,7 @@ html_printf(_ipp_client_t *client, /* I - Client */
else
sprintf(temp, tformat, va_arg(ap, int));
- httpWrite2(&(client->http), temp, strlen(temp));
+ httpWrite2(client->http, temp, strlen(temp));
break;
case 'p' : /* Pointer value */
@@ -2311,7 +2207,7 @@ html_printf(_ipp_client_t *client, /* I - Client */
sprintf(temp, tformat, va_arg(ap, void *));
- httpWrite2(&(client->http), temp, strlen(temp));
+ httpWrite2(client->http, temp, strlen(temp));
break;
case 'c' : /* Character or character array */
@@ -2338,7 +2234,7 @@ html_printf(_ipp_client_t *client, /* I - Client */
}
if (format > start)
- httpWrite2(&(client->http), start, format - start);
+ httpWrite2(client->http, start, format - start);
va_end(ap);
}
@@ -2360,7 +2256,7 @@ ipp_cancel_job(_ipp_client_t *client) /* I - Client */
if ((job = find_job(client)) == NULL)
{
- respond_ipp(client, IPP_NOT_FOUND, "Job does not exist.");
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
return;
}
@@ -2371,18 +2267,18 @@ ipp_cancel_job(_ipp_client_t *client) /* I - Client */
switch (job->state)
{
- case IPP_JOB_CANCELED :
- respond_ipp(client, IPP_NOT_POSSIBLE,
+ case IPP_JSTATE_CANCELED :
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE,
"Job #%d is already canceled - can\'t cancel.", job->id);
break;
- case IPP_JOB_ABORTED :
- respond_ipp(client, IPP_NOT_POSSIBLE,
+ case IPP_JSTATE_ABORTED :
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE,
"Job #%d is already aborted - can\'t cancel.", job->id);
break;
- case IPP_JOB_COMPLETED :
- respond_ipp(client, IPP_NOT_POSSIBLE,
+ case IPP_JSTATE_COMPLETED :
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE,
"Job #%d is already completed - can\'t cancel.", job->id);
break;
@@ -2393,18 +2289,18 @@ ipp_cancel_job(_ipp_client_t *client) /* I - Client */
_cupsRWLockWrite(&(client->printer->rwlock));
- if (job->state == IPP_JOB_PROCESSING ||
- (job->state == IPP_JOB_HELD && job->fd >= 0))
+ if (job->state == IPP_JSTATE_PROCESSING ||
+ (job->state == IPP_JSTATE_HELD && job->fd >= 0))
job->cancel = 1;
else
{
- job->state = IPP_JOB_CANCELED;
+ job->state = IPP_JSTATE_CANCELED;
job->completed = time(NULL);
}
_cupsRWUnlock(&(client->printer->rwlock));
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
break;
}
}
@@ -2427,7 +2323,7 @@ ipp_create_job(_ipp_client_t *client) /* I - Client */
if (!valid_job_attributes(client))
{
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -2435,9 +2331,9 @@ ipp_create_job(_ipp_client_t *client) /* I - Client */
* Do we have a file to print?
*/
- if (client->http.state == HTTP_POST_RECV)
+ if (httpGetState(client->http) == HTTP_STATE_POST_RECV)
{
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Unexpected document data following request.");
return;
}
@@ -2448,7 +2344,8 @@ ipp_create_job(_ipp_client_t *client) /* I - Client */
if ((job = create_job(client)) == NULL)
{
- respond_ipp(client, IPP_PRINTER_BUSY, "Currently printing another job.");
+ respond_ipp(client, IPP_STATUS_ERROR_BUSY,
+ "Currently printing another job.");
return;
}
@@ -2456,7 +2353,7 @@ ipp_create_job(_ipp_client_t *client) /* I - Client */
* Return the job info...
*/
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
cupsArrayAdd(ra, "job-id");
@@ -2483,13 +2380,13 @@ ipp_get_job_attributes(
if ((job = find_job(client)) == NULL)
{
- respond_ipp(client, IPP_NOT_FOUND, "Job not found.");
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job not found.");
return;
}
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
- ra = create_requested_array(client);
+ ra = ippCreateRequestedArray(client->request);
copy_job_attributes(client, job, ra);
cupsArrayDelete(ra);
}
@@ -2503,6 +2400,8 @@ static void
ipp_get_jobs(_ipp_client_t *client) /* I - Client */
{
ipp_attribute_t *attr; /* Current attribute */
+ const char *which_jobs = NULL;
+ /* which-jobs values */
int job_comparison; /* Job comparison */
ipp_jstate_t job_state; /* job-state value */
int first_job_id, /* First job ID */
@@ -2519,61 +2418,62 @@ ipp_get_jobs(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(client->request, "which-jobs",
IPP_TAG_KEYWORD)) != NULL)
- fprintf(stderr, "%s Get-Jobs which-jobs=%s", client->http.hostname,
- attr->values[0].string.text);
+ {
+ which_jobs = ippGetString(attr, 0, NULL);
+ fprintf(stderr, "%s Get-Jobs which-jobs=%s", client->hostname, which_jobs);
+ }
- if (!attr || !strcmp(attr->values[0].string.text, "not-completed"))
+ if (!which_jobs || !strcmp(which_jobs, "not-completed"))
{
job_comparison = -1;
- job_state = IPP_JOB_STOPPED;
+ job_state = IPP_JSTATE_STOPPED;
}
- else if (!strcmp(attr->values[0].string.text, "completed"))
+ else if (!strcmp(which_jobs, "completed"))
{
job_comparison = 1;
- job_state = IPP_JOB_CANCELED;
+ job_state = IPP_JSTATE_CANCELED;
}
- else if (!strcmp(attr->values[0].string.text, "aborted"))
+ else if (!strcmp(which_jobs, "aborted"))
{
job_comparison = 0;
- job_state = IPP_JOB_ABORTED;
+ job_state = IPP_JSTATE_ABORTED;
}
- else if (!strcmp(attr->values[0].string.text, "all"))
+ else if (!strcmp(which_jobs, "all"))
{
job_comparison = 1;
- job_state = IPP_JOB_PENDING;
+ job_state = IPP_JSTATE_PENDING;
}
- else if (!strcmp(attr->values[0].string.text, "canceled"))
+ else if (!strcmp(which_jobs, "canceled"))
{
job_comparison = 0;
- job_state = IPP_JOB_CANCELED;
+ job_state = IPP_JSTATE_CANCELED;
}
- else if (!strcmp(attr->values[0].string.text, "pending"))
+ else if (!strcmp(which_jobs, "pending"))
{
job_comparison = 0;
- job_state = IPP_JOB_PENDING;
+ job_state = IPP_JSTATE_PENDING;
}
- else if (!strcmp(attr->values[0].string.text, "pending-held"))
+ else if (!strcmp(which_jobs, "pending-held"))
{
job_comparison = 0;
- job_state = IPP_JOB_HELD;
+ job_state = IPP_JSTATE_HELD;
}
- else if (!strcmp(attr->values[0].string.text, "processing"))
+ else if (!strcmp(which_jobs, "processing"))
{
job_comparison = 0;
- job_state = IPP_JOB_PROCESSING;
+ job_state = IPP_JSTATE_PROCESSING;
}
- else if (!strcmp(attr->values[0].string.text, "processing-stopped"))
+ else if (!strcmp(which_jobs, "processing-stopped"))
{
job_comparison = 0;
- job_state = IPP_JOB_STOPPED;
+ job_state = IPP_JSTATE_STOPPED;
}
else
{
- respond_ipp(client, IPP_ATTRIBUTES,
- "The which-jobs value \"%s\" is not supported.",
- attr->values[0].string.text);
+ respond_ipp(client, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES,
+ "The which-jobs value \"%s\" is not supported.", which_jobs);
ippAddString(client->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
- "which-jobs", NULL, attr->values[0].string.text);
+ "which-jobs", NULL, which_jobs);
return;
}
@@ -2584,9 +2484,9 @@ ipp_get_jobs(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(client->request, "limit",
IPP_TAG_INTEGER)) != NULL)
{
- limit = attr->values[0].integer;
+ limit = ippGetInteger(attr, 0);
- fprintf(stderr, "%s Get-Jobs limit=%d", client->http.hostname, limit);
+ fprintf(stderr, "%s Get-Jobs limit=%d", client->hostname, limit);
}
else
limit = 0;
@@ -2594,9 +2494,9 @@ ipp_get_jobs(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(client->request, "first-job-id",
IPP_TAG_INTEGER)) != NULL)
{
- first_job_id = attr->values[0].integer;
+ first_job_id = ippGetInteger(attr, 0);
- fprintf(stderr, "%s Get-Jobs first-job-id=%d", client->http.hostname,
+ fprintf(stderr, "%s Get-Jobs first-job-id=%d", client->hostname,
first_job_id);
}
else
@@ -2611,23 +2511,25 @@ ipp_get_jobs(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(client->request, "my-jobs",
IPP_TAG_BOOLEAN)) != NULL)
{
- fprintf(stderr, "%s Get-Jobs my-jobs=%s\n", client->http.hostname,
- attr->values[0].boolean ? "true" : "false");
+ int my_jobs = ippGetBoolean(attr, 0);
+
+ fprintf(stderr, "%s Get-Jobs my-jobs=%s\n", client->hostname,
+ my_jobs ? "true" : "false");
- if (attr->values[0].boolean)
+ if (my_jobs)
{
if ((attr = ippFindAttribute(client->request, "requesting-user-name",
IPP_TAG_NAME)) == NULL)
{
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Need requesting-user-name with my-jobs.");
return;
}
- username = attr->values[0].string.text;
+ username = ippGetString(attr, 0, NULL);
fprintf(stderr, "%s Get-Jobs requesting-user-name=\"%s\"\n",
- client->http.hostname, username);
+ client->hostname, username);
}
}
@@ -2635,21 +2537,9 @@ ipp_get_jobs(_ipp_client_t *client) /* I - Client */
* OK, build a list of jobs for this printer...
*/
- if ((ra = create_requested_array(client)) == NULL &&
- !ippFindAttribute(client->request, "requested-attributes",
- IPP_TAG_KEYWORD))
- {
- /*
- * IPP conformance - Get-Jobs has a default requested-attributes value of
- * "job-id" and "job-uri".
- */
-
- ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
- cupsArrayAdd(ra, "job-id");
- cupsArrayAdd(ra, "job-uri");
- }
+ ra = ippCreateRequestedArray(client->request);
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
_cupsRWLockRead(&(client->printer->rwlock));
@@ -2665,7 +2555,8 @@ ipp_get_jobs(_ipp_client_t *client) /* I - Client */
(job_comparison == 0 && job->state != job_state) ||
(job_comparison > 0 && job->state < job_state) ||
job->id < first_job_id ||
- (username && job->username && _cups_strcasecmp(username, job->username)))
+ (username && job->username &&
+ _cups_strcasecmp(username, job->username)))
continue;
if (count > 0)
@@ -2697,15 +2588,15 @@ ipp_get_printer_attributes(
* Send the attributes...
*/
- ra = create_requested_array(client);
+ ra = ippCreateRequestedArray(client->request);
printer = client->printer;
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
_cupsRWLockRead(&(printer->rwlock));
copy_attributes(client->response, printer->attrs, ra, IPP_TAG_ZERO,
- IPP_TAG_COPY);
+ IPP_TAG_CUPS_CONST);
if (!ra || cupsArrayFind(ra, "printer-state"))
ippAddInteger(client->response, IPP_TAG_PRINTER, IPP_TAG_ENUM,
@@ -2713,51 +2604,51 @@ ipp_get_printer_attributes(
if (!ra || cupsArrayFind(ra, "printer-state-reasons"))
{
- if (printer->state_reasons == _IPP_PRINTER_NONE)
+ if (printer->state_reasons == _IPP_PSTATE_NONE)
ippAddString(client->response, IPP_TAG_PRINTER,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "printer-state-reasons",
- NULL, "none");
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "printer-state-reasons", NULL, "none");
else
{
int num_reasons = 0;/* Number of reasons */
const char *reasons[32]; /* Reason strings */
- if (printer->state_reasons & _IPP_PRINTER_OTHER)
+ if (printer->state_reasons & _IPP_PSTATE_OTHER)
reasons[num_reasons ++] = "other";
- if (printer->state_reasons & _IPP_PRINTER_COVER_OPEN)
+ if (printer->state_reasons & _IPP_PSTATE_COVER_OPEN)
reasons[num_reasons ++] = "cover-open";
- if (printer->state_reasons & _IPP_PRINTER_INPUT_TRAY_MISSING)
+ if (printer->state_reasons & _IPP_PSTATE_INPUT_TRAY_MISSING)
reasons[num_reasons ++] = "input-tray-missing";
- if (printer->state_reasons & _IPP_PRINTER_MARKER_SUPPLY_EMPTY)
+ if (printer->state_reasons & _IPP_PSTATE_MARKER_SUPPLY_EMPTY)
reasons[num_reasons ++] = "marker-supply-empty-warning";
- if (printer->state_reasons & _IPP_PRINTER_MARKER_SUPPLY_LOW)
+ if (printer->state_reasons & _IPP_PSTATE_MARKER_SUPPLY_LOW)
reasons[num_reasons ++] = "marker-supply-low-report";
- if (printer->state_reasons & _IPP_PRINTER_MARKER_WASTE_ALMOST_FULL)
+ if (printer->state_reasons & _IPP_PSTATE_MARKER_WASTE_ALMOST_FULL)
reasons[num_reasons ++] = "marker-waste-almost-full-report";
- if (printer->state_reasons & _IPP_PRINTER_MARKER_WASTE_FULL)
+ if (printer->state_reasons & _IPP_PSTATE_MARKER_WASTE_FULL)
reasons[num_reasons ++] = "marker-waste-full-warning";
- if (printer->state_reasons & _IPP_PRINTER_MEDIA_EMPTY)
+ if (printer->state_reasons & _IPP_PSTATE_MEDIA_EMPTY)
reasons[num_reasons ++] = "media-empty-warning";
- if (printer->state_reasons & _IPP_PRINTER_MEDIA_JAM)
+ if (printer->state_reasons & _IPP_PSTATE_MEDIA_JAM)
reasons[num_reasons ++] = "media-jam-warning";
- if (printer->state_reasons & _IPP_PRINTER_MEDIA_LOW)
+ if (printer->state_reasons & _IPP_PSTATE_MEDIA_LOW)
reasons[num_reasons ++] = "media-low-report";
- if (printer->state_reasons & _IPP_PRINTER_MEDIA_NEEDED)
+ if (printer->state_reasons & _IPP_PSTATE_MEDIA_NEEDED)
reasons[num_reasons ++] = "media-needed-report";
- if (printer->state_reasons & _IPP_PRINTER_MOVING_TO_PAUSED)
+ if (printer->state_reasons & _IPP_PSTATE_MOVING_TO_PAUSED)
reasons[num_reasons ++] = "moving-to-paused";
- if (printer->state_reasons & _IPP_PRINTER_PAUSED)
+ if (printer->state_reasons & _IPP_PSTATE_PAUSED)
reasons[num_reasons ++] = "paused";
- if (printer->state_reasons & _IPP_PRINTER_SPOOL_AREA_FULL)
+ if (printer->state_reasons & _IPP_PSTATE_SPOOL_AREA_FULL)
reasons[num_reasons ++] = "spool-area-full";
- if (printer->state_reasons & _IPP_PRINTER_TONER_EMPTY)
+ if (printer->state_reasons & _IPP_PSTATE_TONER_EMPTY)
reasons[num_reasons ++] = "toner-empty-warning";
- if (printer->state_reasons & _IPP_PRINTER_TONER_LOW)
+ if (printer->state_reasons & _IPP_PSTATE_TONER_LOW)
reasons[num_reasons ++] = "toner-low-report";
ippAddStrings(client->response, IPP_TAG_PRINTER,
- IPP_TAG_KEYWORD | IPP_TAG_COPY, "printer-state-reasons",
- num_reasons, NULL, reasons);
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST,
+ "printer-state-reasons", num_reasons, NULL, reasons);
}
}
@@ -2769,7 +2660,7 @@ ipp_get_printer_attributes(
ippAddInteger(client->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"queued-job-count",
printer->active_job &&
- printer->active_job->state < IPP_JOB_CANCELED);
+ printer->active_job->state < IPP_JSTATE_CANCELED);
_cupsRWUnlock(&(printer->rwlock));
@@ -2797,7 +2688,7 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
if (!valid_job_attributes(client))
{
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -2805,9 +2696,9 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
* Do we have a file to print?
*/
- if (client->http.state == HTTP_POST_SEND)
+ if (httpGetState(client->http) == HTTP_STATE_POST_SEND)
{
- respond_ipp(client, IPP_BAD_REQUEST, "No file in request.");
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "No file in request.");
return;
}
@@ -2817,7 +2708,8 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
if ((job = create_job(client)) == NULL)
{
- respond_ipp(client, IPP_PRINTER_BUSY, "Currently printing another job.");
+ respond_ipp(client, IPP_STATUS_ERROR_BUSY,
+ "Currently printing another job.");
return;
}
@@ -2831,6 +2723,9 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
else if (!_cups_strcasecmp(job->format, "image/png"))
snprintf(filename, sizeof(filename), "%s/%d.png",
client->printer->directory, job->id);
+ else if (!_cups_strcasecmp(job->format, "image/pwg-raster"))
+ snprintf(filename, sizeof(filename), "%s/%d.ras",
+ client->printer->directory, job->id);
else if (!_cups_strcasecmp(job->format, "application/pdf"))
snprintf(filename, sizeof(filename), "%s/%d.pdf",
client->printer->directory, job->id);
@@ -2843,27 +2738,27 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
if ((job->fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
{
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to create print file: %s", strerror(errno));
return;
}
- while ((bytes = httpRead2(&(client->http), buffer, sizeof(buffer))) > 0)
+ while ((bytes = httpRead2(client->http, buffer, sizeof(buffer))) > 0)
{
if (write(job->fd, buffer, bytes) < bytes)
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to write print file: %s", strerror(error));
return;
}
@@ -2875,14 +2770,15 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
* Got an error while reading the print data, so abort this job.
*/
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to read print file.");
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
+ "Unable to read print file.");
return;
}
@@ -2890,19 +2786,19 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to write print file: %s",
- strerror(error));
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
+ "Unable to write print file: %s", strerror(error));
return;
}
job->fd = -1;
job->filename = strdup(filename);
- job->state = IPP_JOB_PENDING;
+ job->state = IPP_JSTATE_PENDING;
/*
* Process the job...
@@ -2911,8 +2807,8 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
#if 0
if (!_cupsThreadCreate((_cups_thread_func_t)process_job, job))
{
- job->state = IPP_JOB_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to process job.");
+ job->state = IPP_JSTATE_ABORTED;
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL, "Unable to process job.");
return;
}
@@ -2924,7 +2820,7 @@ ipp_print_job(_ipp_client_t *client) /* I - Client */
* Return the job info...
*/
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
cupsArrayAdd(ra, "job-id");
@@ -2979,7 +2875,7 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
if (!valid_job_attributes(client))
{
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -2987,9 +2883,9 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
* Do we have a file to print?
*/
- if (client->http.state == HTTP_POST_RECV)
+ if (httpGetState(client->http) == HTTP_STATE_POST_RECV)
{
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Unexpected document data following request.");
return;
}
@@ -3001,24 +2897,25 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
if ((uri = ippFindAttribute(client->request, "document-uri",
IPP_TAG_URI)) == NULL)
{
- respond_ipp(client, IPP_BAD_REQUEST, "Missing document-uri.");
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Missing document-uri.");
return;
}
- if (uri->num_values != 1)
+ if (ippGetCount(uri) != 1)
{
- respond_ipp(client, IPP_BAD_REQUEST, "Too many document-uri values.");
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
+ "Too many document-uri values.");
return;
}
- uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text,
+ uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, ippGetString(uri, 0, NULL),
scheme, sizeof(scheme), userpass,
sizeof(userpass), hostname, sizeof(hostname),
&port, resource, sizeof(resource));
- if (uri_status < HTTP_URI_OK)
+ if (uri_status < HTTP_URI_STATUS_OK)
{
- respond_ipp(client, IPP_BAD_REQUEST, "Bad document-uri: %s",
- uri_status_strings[uri_status - HTTP_URI_OVERFLOW]);
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Bad document-uri: %s",
+ uri_status_strings[uri_status - HTTP_URI_STATUS_OVERFLOW]);
return;
}
@@ -3028,15 +2925,15 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
#endif /* HAVE_SSL */
strcmp(scheme, "http"))
{
- respond_ipp(client, IPP_URI_SCHEME, "URI scheme \"%s\" not supported.",
- scheme);
+ respond_ipp(client, IPP_STATUS_ERROR_URI_SCHEME,
+ "URI scheme \"%s\" not supported.", scheme);
return;
}
if (!strcmp(scheme, "file") && access(resource, R_OK))
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to access URI: %s",
- strerror(errno));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to access URI: %s", strerror(errno));
return;
}
@@ -3046,7 +2943,8 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
if ((job = create_job(client)) == NULL)
{
- respond_ipp(client, IPP_PRINTER_BUSY, "Currently printing another job.");
+ respond_ipp(client, IPP_STATUS_ERROR_BUSY,
+ "Currently printing another job.");
return;
}
@@ -3072,9 +2970,9 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
if ((job->fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
{
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to create print file: %s", strerror(errno));
return;
}
@@ -3083,8 +2981,8 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
{
if ((infile = open(resource, O_RDONLY)) < 0)
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to access URI: %s",
- strerror(errno));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to access URI: %s", strerror(errno));
return;
}
@@ -3097,7 +2995,7 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3105,7 +3003,7 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
unlink(filename);
close(infile);
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to write print file: %s", strerror(error));
return;
}
@@ -3118,17 +3016,18 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
{
#ifdef HAVE_SSL
if (port == 443 || !strcmp(scheme, "https"))
- encryption = HTTP_ENCRYPT_ALWAYS;
+ encryption = HTTP_ENCRYPTION_ALWAYS;
else
#endif /* HAVE_SSL */
- encryption = HTTP_ENCRYPT_IF_REQUESTED;
+ encryption = HTTP_ENCRYPTION_IF_REQUESTED;
- if ((http = httpConnectEncrypt(hostname, port, encryption)) == NULL)
+ if ((http = httpConnect2(hostname, port, NULL, AF_UNSPEC, encryption,
+ 1, 30000, NULL)) == NULL)
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
"Unable to connect to %s: %s", hostname,
cupsLastErrorString());
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3141,10 +3040,10 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
if (httpGet(http, resource))
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to GET URI: %s",
- strerror(errno));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to GET URI: %s", strerror(errno));
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3154,14 +3053,14 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
return;
}
- while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+ while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
- if (status != HTTP_OK)
+ if (status != HTTP_STATUS_OK)
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to GET URI: %s",
- httpStatus(status));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to GET URI: %s", httpStatus(status));
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3177,7 +3076,7 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3185,7 +3084,7 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
unlink(filename);
httpClose(http);
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to write print file: %s", strerror(error));
return;
}
@@ -3198,19 +3097,19 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to write print file: %s",
- strerror(error));
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
+ "Unable to write print file: %s", strerror(error));
return;
}
job->fd = -1;
job->filename = strdup(filename);
- job->state = IPP_JOB_PENDING;
+ job->state = IPP_JSTATE_PENDING;
/*
* Process the job...
@@ -3219,8 +3118,8 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
#if 0
if (!_cupsThreadCreate((_cups_thread_func_t)process_job, job))
{
- job->state = IPP_JOB_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to process job.");
+ job->state = IPP_JSTATE_ABORTED;
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL, "Unable to process job.");
return;
}
@@ -3232,7 +3131,7 @@ ipp_print_uri(_ipp_client_t *client) /* I - Client */
* Return the job info...
*/
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
cupsArrayAdd(ra, "job-id");
@@ -3267,8 +3166,8 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
if ((job = find_job(client)) == NULL)
{
- respond_ipp(client, IPP_NOT_FOUND, "Job does not exist.");
- httpFlush(&(client->http));
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
+ httpFlush(client->http);
return;
}
@@ -3277,33 +3176,34 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
* in a non-pending state...
*/
- if (job->state > IPP_JOB_HELD)
+ if (job->state > IPP_JSTATE_HELD)
{
- respond_ipp(client, IPP_NOT_POSSIBLE, "Job is not in a pending state.");
- httpFlush(&(client->http));
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE,
+ "Job is not in a pending state.");
+ httpFlush(client->http);
return;
}
else if (job->filename || job->fd >= 0)
{
- respond_ipp(client, IPP_MULTIPLE_JOBS_NOT_SUPPORTED,
+ respond_ipp(client, IPP_STATUS_ERROR_MULTIPLE_JOBS_NOT_SUPPORTED,
"Multiple document jobs are not supported.");
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
if ((attr = ippFindAttribute(client->request, "last-document",
IPP_TAG_ZERO)) == NULL)
{
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Missing required last-document attribute.");
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
- else if (attr->value_tag != IPP_TAG_BOOLEAN || attr->num_values != 1 ||
- !attr->values[0].boolean)
+ else if (ippGetValueTag(attr) != IPP_TAG_BOOLEAN || ippGetCount(attr) != 1 ||
+ !ippGetBoolean(attr, 0))
{
respond_unsupported(client, attr);
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -3313,7 +3213,7 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
if (!valid_doc_attributes(client))
{
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -3325,7 +3225,7 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
if ((attr = ippFindAttribute(job->attrs, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
- job->format = attr->values[0].string.text;
+ job->format = ippGetString(attr, 0, NULL);
else
job->format = "application/octet-stream";
@@ -3355,27 +3255,27 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
if (job->fd < 0)
{
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to create print file: %s", strerror(errno));
return;
}
- while ((bytes = httpRead2(&(client->http), buffer, sizeof(buffer))) > 0)
+ while ((bytes = httpRead2(client->http, buffer, sizeof(buffer))) > 0)
{
if (write(job->fd, buffer, bytes) < bytes)
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to write print file: %s", strerror(error));
return;
}
@@ -3387,14 +3287,15 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
* Got an error while reading the print data, so abort this job.
*/
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to read print file.");
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
+ "Unable to read print file.");
return;
}
@@ -3402,13 +3303,13 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to write print file: %s",
- strerror(error));
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
+ "Unable to write print file: %s", strerror(error));
return;
}
@@ -3416,7 +3317,7 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
job->fd = -1;
job->filename = strdup(filename);
- job->state = IPP_JOB_PENDING;
+ job->state = IPP_JSTATE_PENDING;
_cupsRWUnlock(&(client->printer->rwlock));
@@ -3427,8 +3328,8 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
#if 0
if (!_cupsThreadCreate((_cups_thread_func_t)process_job, job))
{
- job->state = IPP_JOB_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to process job.");
+ job->state = IPP_JSTATE_ABORTED;
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL, "Unable to process job.");
return;
}
@@ -3440,7 +3341,7 @@ ipp_send_document(_ipp_client_t *client)/* I - Client */
* Return the job info...
*/
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
cupsArrayAdd(ra, "job-id");
@@ -3497,8 +3398,8 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
if ((job = find_job(client)) == NULL)
{
- respond_ipp(client, IPP_NOT_FOUND, "Job does not exist.");
- httpFlush(&(client->http));
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
+ httpFlush(client->http);
return;
}
@@ -3507,33 +3408,34 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
* in a non-pending state...
*/
- if (job->state > IPP_JOB_HELD)
+ if (job->state > IPP_JSTATE_HELD)
{
- respond_ipp(client, IPP_NOT_POSSIBLE, "Job is not in a pending state.");
- httpFlush(&(client->http));
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE,
+ "Job is not in a pending state.");
+ httpFlush(client->http);
return;
}
else if (job->filename || job->fd >= 0)
{
- respond_ipp(client, IPP_MULTIPLE_JOBS_NOT_SUPPORTED,
+ respond_ipp(client, IPP_STATUS_ERROR_MULTIPLE_JOBS_NOT_SUPPORTED,
"Multiple document jobs are not supported.");
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
if ((attr = ippFindAttribute(client->request, "last-document",
IPP_TAG_ZERO)) == NULL)
{
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Missing required last-document attribute.");
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
- else if (attr->value_tag != IPP_TAG_BOOLEAN || attr->num_values != 1 ||
- !attr->values[0].boolean)
+ else if (ippGetValueTag(attr) != IPP_TAG_BOOLEAN || ippGetCount(attr) != 1 ||
+ !ippGetBoolean(attr, 0))
{
respond_unsupported(client, attr);
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -3543,7 +3445,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
if (!valid_doc_attributes(client))
{
- httpFlush(&(client->http));
+ httpFlush(client->http);
return;
}
@@ -3551,9 +3453,9 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
* Do we have a file to print?
*/
- if (client->http.state == HTTP_POST_RECV)
+ if (httpGetState(client->http) == HTTP_STATE_POST_RECV)
{
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Unexpected document data following request.");
return;
}
@@ -3565,24 +3467,25 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
if ((uri = ippFindAttribute(client->request, "document-uri",
IPP_TAG_URI)) == NULL)
{
- respond_ipp(client, IPP_BAD_REQUEST, "Missing document-uri.");
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Missing document-uri.");
return;
}
- if (uri->num_values != 1)
+ if (ippGetCount(uri) != 1)
{
- respond_ipp(client, IPP_BAD_REQUEST, "Too many document-uri values.");
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
+ "Too many document-uri values.");
return;
}
- uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text,
+ uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, ippGetString(uri, 0, NULL),
scheme, sizeof(scheme), userpass,
sizeof(userpass), hostname, sizeof(hostname),
&port, resource, sizeof(resource));
- if (uri_status < HTTP_URI_OK)
+ if (uri_status < HTTP_URI_STATUS_OK)
{
- respond_ipp(client, IPP_BAD_REQUEST, "Bad document-uri: %s",
- uri_status_strings[uri_status - HTTP_URI_OVERFLOW]);
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Bad document-uri: %s",
+ uri_status_strings[uri_status - HTTP_URI_STATUS_OVERFLOW]);
return;
}
@@ -3592,15 +3495,15 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
#endif /* HAVE_SSL */
strcmp(scheme, "http"))
{
- respond_ipp(client, IPP_URI_SCHEME, "URI scheme \"%s\" not supported.",
- scheme);
+ respond_ipp(client, IPP_STATUS_ERROR_URI_SCHEME,
+ "URI scheme \"%s\" not supported.", scheme);
return;
}
if (!strcmp(scheme, "file") && access(resource, R_OK))
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to access URI: %s",
- strerror(errno));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to access URI: %s", strerror(errno));
return;
}
@@ -3612,7 +3515,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
if ((attr = ippFindAttribute(job->attrs, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
- job->format = attr->values[0].string.text;
+ job->format = ippGetString(attr, 0, NULL);
else
job->format = "application/octet-stream";
@@ -3642,9 +3545,9 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
if (job->fd < 0)
{
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to create print file: %s", strerror(errno));
return;
}
@@ -3653,8 +3556,8 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
{
if ((infile = open(resource, O_RDONLY)) < 0)
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to access URI: %s",
- strerror(errno));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to access URI: %s", strerror(errno));
return;
}
@@ -3667,7 +3570,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3675,7 +3578,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
unlink(filename);
close(infile);
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to write print file: %s", strerror(error));
return;
}
@@ -3688,17 +3591,18 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
{
#ifdef HAVE_SSL
if (port == 443 || !strcmp(scheme, "https"))
- encryption = HTTP_ENCRYPT_ALWAYS;
+ encryption = HTTP_ENCRYPTION_ALWAYS;
else
#endif /* HAVE_SSL */
- encryption = HTTP_ENCRYPT_IF_REQUESTED;
+ encryption = HTTP_ENCRYPTION_IF_REQUESTED;
- if ((http = httpConnectEncrypt(hostname, port, encryption)) == NULL)
+ if ((http = httpConnect2(hostname, port, NULL, AF_UNSPEC, encryption,
+ 1, 30000, NULL)) == NULL)
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
"Unable to connect to %s: %s", hostname,
cupsLastErrorString());
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3711,10 +3615,10 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
if (httpGet(http, resource))
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to GET URI: %s",
- strerror(errno));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to GET URI: %s", strerror(errno));
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3724,14 +3628,14 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
return;
}
- while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+ while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
- if (status != HTTP_OK)
+ if (status != HTTP_STATUS_OK)
{
- respond_ipp(client, IPP_DOCUMENT_ACCESS_ERROR, "Unable to GET URI: %s",
- httpStatus(status));
+ respond_ipp(client, IPP_STATUS_ERROR_DOCUMENT_ACCESS,
+ "Unable to GET URI: %s", httpStatus(status));
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3747,7 +3651,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
close(job->fd);
job->fd = -1;
@@ -3755,7 +3659,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
unlink(filename);
httpClose(http);
- respond_ipp(client, IPP_INTERNAL_ERROR,
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
"Unable to write print file: %s", strerror(error));
return;
}
@@ -3768,13 +3672,13 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
{
int error = errno; /* Write error */
- job->state = IPP_JOB_ABORTED;
+ job->state = IPP_JSTATE_ABORTED;
job->fd = -1;
unlink(filename);
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to write print file: %s",
- strerror(error));
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL,
+ "Unable to write print file: %s", strerror(error));
return;
}
@@ -3782,7 +3686,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
job->fd = -1;
job->filename = strdup(filename);
- job->state = IPP_JOB_PENDING;
+ job->state = IPP_JSTATE_PENDING;
_cupsRWUnlock(&(client->printer->rwlock));
@@ -3793,8 +3697,8 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
#if 0
if (!_cupsThreadCreate((_cups_thread_func_t)process_job, job))
{
- job->state = IPP_JOB_ABORTED;
- respond_ipp(client, IPP_INTERNAL_ERROR, "Unable to process job.");
+ job->state = IPP_JSTATE_ABORTED;
+ respond_ipp(client, IPP_STATUS_ERROR_INTERNAL, "Unable to process job.");
return;
}
@@ -3806,7 +3710,7 @@ ipp_send_uri(_ipp_client_t *client) /* I - Client */
* Return the job info...
*/
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
cupsArrayAdd(ra, "job-id");
@@ -3827,7 +3731,7 @@ static void
ipp_validate_job(_ipp_client_t *client) /* I - Client */
{
if (valid_job_attributes(client))
- respond_ipp(client, IPP_OK, NULL);
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
@@ -3842,7 +3746,7 @@ process_client(_ipp_client_t *client) /* I - Client */
* Loop until we are out of requests or timeout (30 seconds)...
*/
- while (httpWait(&(client->http), 30000))
+ while (httpWait(client->http, 30000))
if (!process_http(client))
break;
@@ -3863,175 +3767,127 @@ process_client(_ipp_client_t *client) /* I - Client */
int /* O - 1 on success, 0 on failure */
process_http(_ipp_client_t *client) /* I - Client connection */
{
- char line[4096], /* Line from client... */
- operation[64], /* Operation code from socket */
- uri[1024], /* URI */
- version[64], /* HTTP version number string */
- *ptr; /* Pointer into strings */
- int major, minor; /* HTTP version numbers */
- http_status_t status; /* Transfer status */
- ipp_state_t state; /* State of IPP transfer */
-
-
- /*
- * Abort if we have an error on the connection...
- */
+ char uri[1024]; /* URI */
+ http_state_t http_state; /* HTTP state */
+ http_status_t http_status; /* HTTP status */
+ ipp_state_t ipp_state; /* State of IPP transfer */
+ char scheme[32], /* Method/scheme */
+ userpass[128], /* Username:password */
+ hostname[HTTP_MAX_HOST];
+ /* Hostname */
+ int port; /* Port number */
+ const char *encoding; /* Content-Encoding value */
+ static const char * const http_states[] =
+ { /* Strings for logging HTTP method */
+ "WAITING",
+ "OPTIONS",
+ "GET",
+ "GET_SEND",
+ "HEAD",
+ "POST",
+ "POST_RECV",
+ "POST_SEND",
+ "PUT",
+ "PUT_RECV",
+ "DELETE",
+ "TRACE",
+ "CONNECT",
+ "STATUS",
+ "UNKNOWN_METHOD",
+ "UNKNOWN_VERSION"
+ };
- if (client->http.error)
- return (0);
/*
* Clear state variables...
*/
- httpClearFields(&(client->http));
ippDelete(client->request);
ippDelete(client->response);
- client->http.activity = time(NULL);
- client->http.version = HTTP_1_1;
- client->http.keep_alive = HTTP_KEEPALIVE_OFF;
- client->http.data_encoding = HTTP_ENCODE_LENGTH;
- client->http.data_remaining = 0;
- client->request = NULL;
- client->response = NULL;
- client->operation = HTTP_WAITING;
+ client->request = NULL;
+ client->response = NULL;
+ client->operation = HTTP_STATE_WAITING;
/*
* Read a request from the connection...
*/
- while ((ptr = httpGets(line, sizeof(line) - 1, &(client->http))) != NULL)
- if (*ptr)
- break;
-
- if (!ptr)
- return (0);
+ while ((http_state = httpReadRequest(client->http, uri,
+ sizeof(uri))) == HTTP_STATE_WAITING)
+ usleep(1);
/*
* Parse the request line...
*/
- fprintf(stderr, "%s %s\n", client->http.hostname, line);
-
- switch (sscanf(line, "%63s%1023s%63s", operation, uri, version))
+ if (http_state == HTTP_STATE_ERROR)
{
- case 1 :
- fprintf(stderr, "%s Bad request line.\n", client->http.hostname);
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
- return (0);
-
- case 2 :
- client->http.version = HTTP_0_9;
- break;
-
- case 3 :
- if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2)
- {
- fprintf(stderr, "%s Bad HTTP version.\n", client->http.hostname);
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
- return (0);
- }
+ if (httpError(client->http) == EPIPE)
+ fprintf(stderr, "%s Client closed connection.\n", client->hostname);
+ else
+ fprintf(stderr, "%s Bad request line (%s).\n", client->hostname,
+ strerror(httpError(client->http)));
- if (major < 2)
- {
- client->http.version = (http_version_t)(major * 100 + minor);
- if (client->http.version == HTTP_1_1)
- client->http.keep_alive = HTTP_KEEPALIVE_ON;
- else
- client->http.keep_alive = HTTP_KEEPALIVE_OFF;
- }
- else
- {
- respond_http(client, HTTP_NOT_SUPPORTED, NULL, 0);
- return (0);
- }
- break;
+ return (0);
}
-
- /*
- * Handle full URLs in the request line...
- */
-
- if (!strncmp(client->uri, "http:", 5) || !strncmp(client->uri, "ipp:", 4))
+ else if (http_state == HTTP_STATE_UNKNOWN_METHOD)
{
- char scheme[32], /* Method/scheme */
- userpass[128], /* Username:password */
- hostname[HTTP_MAX_HOST];/* Hostname */
- int port; /* Port number */
-
- /*
- * Separate the URI into its components...
- */
-
- if (httpSeparateURI(HTTP_URI_CODING_MOST, uri, scheme, sizeof(scheme),
- userpass, sizeof(userpass),
- hostname, sizeof(hostname), &port,
- client->uri, sizeof(client->uri)) < HTTP_URI_OK)
- {
- fprintf(stderr, "%s Bad URI \"%s\".\n", client->http.hostname, uri);
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
- return (0);
- }
+ fprintf(stderr, "%s Bad/unknown operation.\n", client->hostname);
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
+ return (0);
}
- else
+ else if (http_state == HTTP_STATE_UNKNOWN_VERSION)
{
- /*
- * Decode URI
- */
-
- if (!_httpDecodeURI(client->uri, uri, sizeof(client->uri)))
- {
- fprintf(stderr, "%s Bad URI \"%s\".\n", client->http.hostname, uri);
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
- return (0);
- }
+ fprintf(stderr, "%s Bad HTTP version.\n", client->hostname);
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
+ return (0);
}
+ fprintf(stderr, "%s %s %s\n", client->hostname, http_states[http_state],
+ uri);
+
/*
- * Process the request...
+ * Separate the URI into its components...
*/
- if (!strcmp(operation, "GET"))
- client->http.state = HTTP_GET;
- else if (!strcmp(operation, "POST"))
- client->http.state = HTTP_POST;
- else if (!strcmp(operation, "OPTIONS"))
- client->http.state = HTTP_OPTIONS;
- else if (!strcmp(operation, "HEAD"))
- client->http.state = HTTP_HEAD;
- else
+ if (httpSeparateURI(HTTP_URI_CODING_MOST, uri, scheme, sizeof(scheme),
+ userpass, sizeof(userpass),
+ hostname, sizeof(hostname), &port,
+ client->uri, sizeof(client->uri)) < HTTP_URI_STATUS_OK)
{
- fprintf(stderr, "%s Bad operation \"%s\".\n", client->http.hostname,
- operation);
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
+ fprintf(stderr, "%s Bad URI \"%s\".\n", client->hostname, uri);
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
return (0);
}
- client->start = time(NULL);
- client->operation = client->http.state;
- client->http.status = HTTP_OK;
+ /*
+ * Process the request...
+ */
+
+ client->start = time(NULL);
+ client->operation = httpGetState(client->http);
/*
* Parse incoming parameters until the status changes...
*/
- while ((status = httpUpdate(&(client->http))) == HTTP_CONTINUE);
+ while ((http_status = httpUpdate(client->http)) == HTTP_STATUS_CONTINUE);
- if (status != HTTP_OK)
+ if (http_status != HTTP_STATUS_OK)
{
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
return (0);
}
- if (!client->http.fields[HTTP_FIELD_HOST][0] &&
- client->http.version >= HTTP_1_1)
+ if (!httpGetField(client->http, HTTP_FIELD_HOST)[0] &&
+ httpGetVersion(client->http) >= HTTP_VERSION_1_1)
{
/*
* HTTP/1.1 and higher require the "Host:" field...
*/
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
return (0);
}
@@ -4039,9 +3895,10 @@ process_http(_ipp_client_t *client) /* I - Client connection */
* Handle HTTP Upgrade...
*/
- if (!_cups_strcasecmp(client->http.fields[HTTP_FIELD_CONNECTION], "Upgrade"))
+ if (!_cups_strcasecmp(httpGetField(client->http, HTTP_FIELD_CONNECTION),
+ "Upgrade"))
{
- if (!respond_http(client, HTTP_NOT_IMPLEMENTED, NULL, 0))
+ if (!respond_http(client, HTTP_STATUS_NOT_IMPLEMENTED, NULL, NULL, 0))
return (0);
}
@@ -4049,16 +3906,17 @@ process_http(_ipp_client_t *client) /* I - Client connection */
* Handle HTTP Expect...
*/
- if (client->http.expect &&
- (client->operation == HTTP_POST || client->operation == HTTP_PUT))
+ if (httpGetExpect(client->http) &&
+ (client->operation == HTTP_STATE_POST ||
+ client->operation == HTTP_STATE_PUT))
{
- if (client->http.expect == HTTP_CONTINUE)
+ if (httpGetExpect(client->http) == HTTP_STATUS_CONTINUE)
{
/*
* Send 100-continue header...
*/
- if (!respond_http(client, HTTP_CONTINUE, NULL, 0))
+ if (!respond_http(client, HTTP_STATUS_CONTINUE, NULL, NULL, 0))
return (0);
}
else
@@ -4067,13 +3925,8 @@ process_http(_ipp_client_t *client) /* I - Client connection */
* Send 417-expectation-failed header...
*/
- if (!respond_http(client, HTTP_EXPECTATION_FAILED, NULL, 0))
+ if (!respond_http(client, HTTP_STATUS_EXPECTATION_FAILED, NULL, NULL, 0))
return (0);
-
- httpPrintf(&(client->http), "Content-Length: 0\r\n");
- httpPrintf(&(client->http), "\r\n");
- httpFlushWrite(&(client->http));
- client->http.data_encoding = HTTP_ENCODE_LENGTH;
}
}
@@ -4081,25 +3934,27 @@ process_http(_ipp_client_t *client) /* I - Client connection */
* Handle new transfers...
*/
+ encoding = httpGetContentEncoding(client->http);
+
switch (client->operation)
{
- case HTTP_OPTIONS :
+ case HTTP_STATE_OPTIONS :
/*
* Do HEAD/OPTIONS command...
*/
- return (respond_http(client, HTTP_OK, NULL, 0));
+ return (respond_http(client, HTTP_STATUS_OK, NULL, NULL, 0));
- case HTTP_HEAD :
+ case HTTP_STATE_HEAD :
if (!strcmp(client->uri, "/icon.png"))
- return (respond_http(client, HTTP_OK, "image/png", 0));
+ return (respond_http(client, HTTP_STATUS_OK, NULL, "image/png", 0));
else if (!strcmp(client->uri, "/"))
- return (respond_http(client, HTTP_OK, "text/html", 0));
+ return (respond_http(client, HTTP_STATUS_OK, NULL, "text/html", 0));
else
- return (respond_http(client, HTTP_NOT_FOUND, NULL, 0));
+ return (respond_http(client, HTTP_STATUS_NOT_FOUND, NULL, NULL, 0));
break;
- case HTTP_GET :
+ case HTTP_STATE_GET :
if (!strcmp(client->uri, "/icon.png"))
{
/*
@@ -4111,24 +3966,27 @@ process_http(_ipp_client_t *client) /* I - Client connection */
char buffer[4096]; /* Copy buffer */
ssize_t bytes; /* Bytes */
+ fprintf(stderr, "Icon file is \"%s\".\n", client->printer->icon);
+
if (!stat(client->printer->icon, &fileinfo) &&
(fd = open(client->printer->icon, O_RDONLY)) >= 0)
{
- if (!respond_http(client, HTTP_OK, "image/png", fileinfo.st_size))
+ if (!respond_http(client, HTTP_STATUS_OK, NULL, "image/png",
+ fileinfo.st_size))
{
close(fd);
return (0);
}
while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
- httpWrite2(&(client->http), buffer, bytes);
+ httpWrite2(client->http, buffer, bytes);
- httpFlushWrite(&(client->http));
+ httpFlushWrite(client->http);
close(fd);
}
else
- return (respond_http(client, HTTP_NOT_FOUND, NULL, 0));
+ return (respond_http(client, HTTP_STATUS_NOT_FOUND, NULL, NULL, 0));
}
else if (!strcmp(client->uri, "/"))
{
@@ -4136,7 +3994,7 @@ process_http(_ipp_client_t *client) /* I - Client connection */
* Show web status page...
*/
- if (!respond_http(client, HTTP_OK, "text/html", 0))
+ if (!respond_http(client, HTTP_STATUS_OK, encoding, "text/html", 0))
return (0);
html_printf(client,
@@ -4150,43 +4008,32 @@ process_http(_ipp_client_t *client) /* I - Client connection */
"</head>\n"
"<body>\n"
"</body>\n"
- "<h1>%s</h1>\n"
+ "<h1><img align=\"right\" src=\"/icon.png\">%s</h1>\n"
"<p>%s, %d job(s).</p>\n"
"</body>\n"
"</html>\n",
client->printer->name, client->printer->name,
- client->printer->state == IPP_PRINTER_IDLE ? "Idle" :
- client->printer->state == IPP_PRINTER_PROCESSING ?
+ client->printer->state == IPP_PSTATE_IDLE ? "Idle" :
+ client->printer->state == IPP_PSTATE_PROCESSING ?
"Printing" : "Stopped",
cupsArrayCount(client->printer->jobs));
- httpWrite2(&(client->http), "", 0);
+ httpWrite2(client->http, "", 0);
return (1);
}
else
- return (respond_http(client, HTTP_NOT_FOUND, NULL, 0));
+ return (respond_http(client, HTTP_STATUS_NOT_FOUND, NULL, NULL, 0));
break;
- case HTTP_POST :
- if (client->http.data_remaining < 0 ||
- (!client->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
- client->http.data_encoding == HTTP_ENCODE_LENGTH))
- {
- /*
- * Negative content lengths are invalid...
- */
-
- return (respond_http(client, HTTP_BAD_REQUEST, NULL, 0));
- }
-
- if (strcmp(client->http.fields[HTTP_FIELD_CONTENT_TYPE],
+ case HTTP_STATE_POST :
+ if (strcmp(httpGetField(client->http, HTTP_FIELD_CONTENT_TYPE),
"application/ipp"))
{
/*
* Not an IPP request...
*/
- return (respond_http(client, HTTP_BAD_REQUEST, NULL, 0));
+ return (respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0));
}
/*
@@ -4195,14 +4042,17 @@ process_http(_ipp_client_t *client) /* I - Client connection */
client->request = ippNew();
- while ((state = ippRead(&(client->http), client->request)) != IPP_DATA)
- if (state == IPP_ERROR)
+ while ((ipp_state = ippRead(client->http,
+ client->request)) != IPP_STATE_DATA)
+ {
+ if (ipp_state == IPP_STATE_ERROR)
{
- fprintf(stderr, "%s IPP read error (%s).\n", client->http.hostname,
+ fprintf(stderr, "%s IPP read error (%s).\n", client->hostname,
cupsLastErrorString());
- respond_http(client, HTTP_BAD_REQUEST, NULL, 0);
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
return (0);
}
+ }
/*
* Now that we have the IPP request, process the request...
@@ -4230,6 +4080,8 @@ process_ipp(_ipp_client_t *client) /* I - Client */
ipp_attribute_t *charset; /* Character set attribute */
ipp_attribute_t *language; /* Language attribute */
ipp_attribute_t *uri; /* Printer URI attribute */
+ int major, minor; /* Version number */
+ const char *name; /* Name of attribute */
debug_attributes("Request", client->request, 1);
@@ -4238,37 +4090,30 @@ process_ipp(_ipp_client_t *client) /* I - Client */
* First build an empty response message for this request...
*/
- client->operation_id = client->request->request.op.operation_id;
- client->response = ippNew();
-
- client->response->request.status.version[0] =
- client->request->request.op.version[0];
- client->response->request.status.version[1] =
- client->request->request.op.version[1];
- client->response->request.status.request_id =
- client->request->request.op.request_id;
+ client->operation_id = ippGetOperation(client->request);
+ client->response = ippNewResponse(client->request);
/*
* Then validate the request header and required attributes...
*/
- if (client->request->request.any.version[0] < 1 ||
- client->request->request.any.version[0] > 2)
+ major = ippGetVersion(client->request, &minor);
+
+ if (major < 1 || major > 2)
{
/*
* Return an error, since we only support IPP 1.x and 2.x.
*/
- respond_ipp(client, IPP_VERSION_NOT_SUPPORTED,
- "Bad request version number %d.%d.",
- client->request->request.any.version[0],
- client->request->request.any.version[1]);
+ respond_ipp(client, IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED,
+ "Bad request version number %d.%d.", major, minor);
}
- else if (client->request->request.any.request_id <= 0)
- respond_ipp(client, IPP_BAD_REQUEST, "Bad request-id %d.",
- client->request->request.any.request_id);
- else if (!client->request->attrs)
- respond_ipp(client, IPP_BAD_REQUEST, "No attributes in request.");
+ else if (ippGetRequestId(client->request) <= 0)
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Bad request-id %d.",
+ ippGetRequestId(client->request));
+ else if (!ippFirstAttribute(client->request))
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
+ "No attributes in request.");
else
{
/*
@@ -4276,22 +4121,25 @@ process_ipp(_ipp_client_t *client) /* I - Client */
* don't repeat groups...
*/
- for (attr = client->request->attrs, group = attr->group_tag;
+ for (attr = ippFirstAttribute(client->request),
+ group = ippGetGroupTag(attr);
attr;
- attr = attr->next)
- if (attr->group_tag < group && attr->group_tag != IPP_TAG_ZERO)
+ attr = ippNextAttribute(client->request))
+ {
+ if (ippGetGroupTag(attr) < group && ippGetGroupTag(attr) != IPP_TAG_ZERO)
{
/*
* Out of order; return an error...
*/
- respond_ipp(client, IPP_BAD_REQUEST,
- "Attribute groups are out of order (%x < %x).",
- attr->group_tag, group);
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
+ "Attribute groups are out of order (%x < %x).",
+ ippGetGroupTag(attr), group);
break;
}
else
- group = attr->group_tag;
+ group = ippGetGroupTag(attr);
+ }
if (!attr)
{
@@ -4303,20 +4151,19 @@ process_ipp(_ipp_client_t *client) /* I - Client */
* printer-uri/job-uri
*/
- attr = client->request->attrs;
- if (attr && attr->name &&
- !strcmp(attr->name, "attributes-charset") &&
- (attr->value_tag & IPP_TAG_MASK) == IPP_TAG_CHARSET)
+ attr = ippFirstAttribute(client->request);
+ name = ippGetName(attr);
+ if (attr && name && !strcmp(name, "attributes-charset") &&
+ ippGetValueTag(attr) == IPP_TAG_CHARSET)
charset = attr;
else
charset = NULL;
- if (attr)
- attr = attr->next;
+ attr = ippNextAttribute(client->request);
+ name = ippGetName(attr);
- if (attr && attr->name &&
- !strcmp(attr->name, "attributes-natural-language") &&
- (attr->value_tag & IPP_TAG_MASK) == IPP_TAG_LANGUAGE)
+ if (attr && name && !strcmp(name, "attributes-natural-language") &&
+ ippGetValueTag(attr) == IPP_TAG_LANGUAGE)
language = attr;
else
language = NULL;
@@ -4330,25 +4177,17 @@ process_ipp(_ipp_client_t *client) /* I - Client */
else
uri = NULL;
- ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL,
- charset ? charset->values[0].string.text : "utf-8");
-
- ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL,
- language ? language->values[0].string.text : "en");
-
if (charset &&
- _cups_strcasecmp(charset->values[0].string.text, "us-ascii") &&
- _cups_strcasecmp(charset->values[0].string.text, "utf-8"))
+ _cups_strcasecmp(ippGetString(charset, 0, NULL), "us-ascii") &&
+ _cups_strcasecmp(ippGetString(charset, 0, NULL), "utf-8"))
{
/*
* Bad character set...
*/
- respond_ipp(client, IPP_BAD_REQUEST,
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
"Unsupported character set \"%s\".",
- charset->values[0].string.text);
+ ippGetString(charset, 0, NULL));
}
else if (!charset || !language || !uri)
{
@@ -4358,14 +4197,15 @@ process_ipp(_ipp_client_t *client) /* I - Client */
* for all operations.
*/
- respond_ipp(client, IPP_BAD_REQUEST, "Missing required attributes.");
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
+ "Missing required attributes.");
}
- else if (strcmp(uri->values[0].string.text, client->printer->uri) &&
- strncmp(uri->values[0].string.text, client->printer->uri,
+ else if (strcmp(ippGetString(uri, 0, NULL), client->printer->uri) &&
+ strncmp(ippGetString(uri, 0, NULL), client->printer->uri,
client->printer->urilen))
{
- respond_ipp(client, IPP_NOT_FOUND, "%s %s not found.", uri->name,
- uri->values[0].string.text);
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "%s %s not found.",
+ ippGetName(uri), ippGetString(uri, 0, NULL));
}
else
{
@@ -4373,60 +4213,62 @@ process_ipp(_ipp_client_t *client) /* I - Client */
* Try processing the operation...
*/
- if (client->http.expect == HTTP_CONTINUE)
+#if 0 /* Already doing this in process_http()... */
+ if (httpGetExpect(client->http) == HTTP_STATUS_CONTINUE)
{
/*
* Send 100-continue header...
*/
- if (!respond_http(client, HTTP_CONTINUE, NULL, 0))
+ if (!respond_http(client, HTTP_STATUS_CONTINUE, NULL, NULL, 0))
return (0);
}
+#endif /* 0 */
- switch (client->request->request.op.operation_id)
+ switch (ippGetOperation(client->request))
{
- case IPP_PRINT_JOB :
+ case IPP_OP_PRINT_JOB :
ipp_print_job(client);
break;
- case IPP_PRINT_URI :
+ case IPP_OP_PRINT_URI :
ipp_print_uri(client);
break;
- case IPP_VALIDATE_JOB :
+ case IPP_OP_VALIDATE_JOB :
ipp_validate_job(client);
break;
- case IPP_CREATE_JOB :
+ case IPP_OP_CREATE_JOB :
ipp_create_job(client);
break;
- case IPP_SEND_DOCUMENT :
+ case IPP_OP_SEND_DOCUMENT :
ipp_send_document(client);
break;
- case IPP_SEND_URI :
+ case IPP_OP_SEND_URI :
ipp_send_uri(client);
break;
- case IPP_CANCEL_JOB :
+ case IPP_OP_CANCEL_JOB :
ipp_cancel_job(client);
break;
- case IPP_GET_JOB_ATTRIBUTES :
+ case IPP_OP_GET_JOB_ATTRIBUTES :
ipp_get_job_attributes(client);
break;
- case IPP_GET_JOBS :
+ case IPP_OP_GET_JOBS :
ipp_get_jobs(client);
break;
- case IPP_GET_PRINTER_ATTRIBUTES :
+ case IPP_OP_GET_PRINTER_ATTRIBUTES :
ipp_get_printer_attributes(client);
break;
default :
- respond_ipp(client, IPP_OPERATION_NOT_SUPPORTED,
+ respond_ipp(client, IPP_STATUS_ERROR_OPERATION_NOT_SUPPORTED,
"Operation not supported.");
break;
}
@@ -4438,10 +4280,10 @@ process_ipp(_ipp_client_t *client) /* I - Client */
* Send the HTTP header and return...
*/
- if (client->http.state != HTTP_POST_SEND)
- httpFlush(&(client->http)); /* Flush trailing (junk) data */
+ if (httpGetState(client->http) != HTTP_STATE_POST_SEND)
+ httpFlush(client->http); /* Flush trailing (junk) data */
- return (respond_http(client, HTTP_OK, "application/ipp",
+ return (respond_http(client, HTTP_STATUS_OK, NULL, "application/ipp",
ippLength(client->response)));
}
@@ -4453,18 +4295,92 @@ process_ipp(_ipp_client_t *client) /* I - Client */
static void * /* O - Thread exit status */
process_job(_ipp_job_t *job) /* I - Job */
{
- job->state = IPP_JOB_PROCESSING;
- job->printer->state = IPP_PRINTER_PROCESSING;
+ job->state = IPP_JSTATE_PROCESSING;
+ job->printer->state = IPP_PSTATE_PROCESSING;
- sleep(5);
+ if (job->printer->command)
+ {
+ /*
+ * Execute a command with the job spool file and wait for it to complete...
+ */
+
+ int pid, /* Process ID */
+ status; /* Exit status */
+ time_t start, /* Start time */
+ end; /* End time */
+
+ fprintf(stderr, "Running command \"%s %s\".\n", job->printer->command,
+ job->filename);
+ time(&start);
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ execlp(job->printer->command, job->printer->command, job->filename,
+ (void *)NULL);
+ exit(errno);
+ }
+ else if (pid < 0)
+ {
+ /*
+ * Unable to fork process...
+ */
+
+ perror("Unable to start job processing command");
+ }
+ else
+ {
+ /*
+ * Wait for child to complete...
+ */
+
+#ifdef HAVE_WAITPID
+ while (waitpid(pid, &status, 0) < 0);
+#else
+ while (wait(&status) < 0);
+#endif /* HAVE_WAITPID */
+
+ if (status)
+ {
+ if (WIFEXITED(status))
+ fprintf(stderr, "Command \"%s\" exited with status %d.\n",
+ job->printer->command, WEXITSTATUS(status));
+ else
+ fprintf(stderr, "Command \"%s\" terminated with signal %d.\n",
+ job->printer->command, WTERMSIG(status));
+ }
+ else
+ fprintf(stderr, "Command \"%s\" completed successfully.\n",
+ job->printer->command);
+ }
+
+ /*
+ * Make sure processing takes at least 5 seconds...
+ */
+
+ time(&end);
+ if ((end - start) < 5)
+ sleep(5);
+ }
+ else
+ {
+ /*
+ * Sleep for a random amount of time to simulate job processing.
+ */
+
+ sleep(5 + (rand() % 11));
+ }
if (job->cancel)
- job->state = IPP_JOB_CANCELED;
+ job->state = IPP_JSTATE_CANCELED;
else
- job->state = IPP_JOB_COMPLETED;
+ job->state = IPP_JSTATE_COMPLETED;
job->completed = time(NULL);
- job->printer->state = IPP_PRINTER_IDLE;
+ job->printer->state = IPP_PSTATE_IDLE;
job->printer->active_job = NULL;
return (NULL);
@@ -4486,11 +4402,12 @@ register_printer(
const char *adminurl, /* I - Web interface URL */
int color, /* I - 1 = color, 0 = monochrome */
int duplex, /* I - 1 = duplex, 0 = simplex */
- const char *regtype) /* I - Service type */
+ const char *subtype) /* I - Service subtype */
{
DNSServiceErrorType error; /* Error from Bonjour */
char make_model[256],/* Make and model together */
- product[256]; /* Product string */
+ product[256], /* Product string */
+ regtype[256]; /* Bonjour service type */
/*
@@ -4501,16 +4418,14 @@ register_printer(
snprintf(product, sizeof(product), "(%s)", model);
TXTRecordCreate(&(printer->ipp_txt), 1024, NULL);
- TXTRecordSetValue(&(printer->ipp_txt), "txtvers", 1, "1");
- TXTRecordSetValue(&(printer->ipp_txt), "qtotal", 1, "1");
TXTRecordSetValue(&(printer->ipp_txt), "rp", 3, "ipp");
TXTRecordSetValue(&(printer->ipp_txt), "ty", (uint8_t)strlen(make_model),
make_model);
TXTRecordSetValue(&(printer->ipp_txt), "adminurl", (uint8_t)strlen(adminurl),
adminurl);
- TXTRecordSetValue(&(printer->ipp_txt), "note", (uint8_t)strlen(location),
- location);
- TXTRecordSetValue(&(printer->ipp_txt), "priority", 1, "0");
+ if (*location)
+ TXTRecordSetValue(&(printer->ipp_txt), "note", (uint8_t)strlen(location),
+ location);
TXTRecordSetValue(&(printer->ipp_txt), "product", (uint8_t)strlen(product),
product);
TXTRecordSetValue(&(printer->ipp_txt), "pdl", (uint8_t)strlen(formats),
@@ -4521,7 +4436,6 @@ register_printer(
make);
TXTRecordSetValue(&(printer->ipp_txt), "usb_MDL", (uint8_t)strlen(model),
model);
- TXTRecordSetValue(&(printer->ipp_txt), "air", 4, "none");
/*
* Create a shared service reference for Bonjour...
@@ -4562,6 +4476,11 @@ register_printer(
printer->ipp_ref = printer->common_ref;
+ if (subtype && *subtype)
+ snprintf(regtype, sizeof(regtype), "_ipp._tcp,%s", subtype);
+ else
+ strlcpy(regtype, "_ipp._tcp", sizeof(regtype));
+
if ((error = DNSServiceRegister(&(printer->ipp_ref),
kDNSServiceFlagsShareConnection,
0 /* interfaceIndex */, printer->dnssd_name,
@@ -4577,6 +4496,35 @@ register_printer(
return (0);
}
+# ifdef HAVE_SSL
+ /*
+ * Then register the _ipps._tcp (IPP) service type with the real port number to
+ * advertise our IPP printer...
+ */
+
+ printer->ipps_ref = printer->common_ref;
+
+ if (subtype && *subtype)
+ snprintf(regtype, sizeof(regtype), "_ipps._tcp,%s", subtype);
+ else
+ strlcpy(regtype, "_ipps._tcp", sizeof(regtype));
+
+ if ((error = DNSServiceRegister(&(printer->ipps_ref),
+ kDNSServiceFlagsShareConnection,
+ 0 /* interfaceIndex */, printer->dnssd_name,
+ regtype, NULL /* domain */,
+ NULL /* host */, htons(printer->port),
+ TXTRecordGetLength(&(printer->ipp_txt)),
+ TXTRecordGetBytesPtr(&(printer->ipp_txt)),
+ (DNSServiceRegisterReply)dnssd_callback,
+ printer)) != kDNSServiceErr_NoError)
+ {
+ fprintf(stderr, "Unable to register \"%s.%s\": %d\n",
+ printer->dnssd_name, regtype, error);
+ return (0);
+ }
+# endif /* HAVE_SSL */
+
/*
* Similarly, register the _http._tcp,_printer (HTTP) service type with the
* real port number to advertise our IPP printer...
@@ -4608,32 +4556,32 @@ register_printer(
*/
int /* O - 1 on success, 0 on failure */
-respond_http(_ipp_client_t *client, /* I - Client */
- http_status_t code, /* I - HTTP status of response */
- const char *type, /* I - MIME type of response */
- size_t length) /* I - Length of response */
+respond_http(
+ _ipp_client_t *client, /* I - Client */
+ http_status_t code, /* I - HTTP status of response */
+ const char *content_encoding, /* I - Content-Encoding of response */
+ const char *type, /* I - MIME media type of response */
+ size_t length) /* I - Length of response */
{
char message[1024]; /* Text message */
- fprintf(stderr, "%s %s\n", client->http.hostname, httpStatus(code));
+ fprintf(stderr, "%s %s\n", client->hostname, httpStatus(code));
- if (code == HTTP_CONTINUE)
+ if (code == HTTP_STATUS_CONTINUE)
{
/*
* 100-continue doesn't send any headers...
*/
- return (httpPrintf(&(client->http), "HTTP/%d.%d 100 Continue\r\n\r\n",
- client->http.version / 100,
- client->http.version % 100) > 0);
+ return (httpWriteResponse(client->http, HTTP_STATUS_CONTINUE) == 0);
}
/*
* Format an error message...
*/
- if (!type && !length && code != HTTP_OK)
+ if (!type && !length && code != HTTP_STATUS_OK)
{
snprintf(message, sizeof(message), "%d - %s\n", code, httpStatus(code));
@@ -4644,60 +4592,30 @@ respond_http(_ipp_client_t *client, /* I - Client */
message[0] = '\0';
/*
- * Send the HTTP status header...
- */
-
- httpFlushWrite(&(client->http));
-
- client->http.data_encoding = HTTP_ENCODE_FIELDS;
-
- if (httpPrintf(&(client->http), "HTTP/%d.%d %d %s\r\n", client->http.version / 100,
- client->http.version % 100, code, httpStatus(code)) < 0)
- return (0);
-
- /*
- * Follow the header with the response fields...
+ * Send the HTTP response header...
*/
- if (httpPrintf(&(client->http), "Date: %s\r\n", httpGetDateString(time(NULL))) < 0)
- return (0);
-
- if (client->http.keep_alive && client->http.version >= HTTP_1_0)
- {
- if (httpPrintf(&(client->http),
- "Connection: Keep-Alive\r\n"
- "Keep-Alive: timeout=10\r\n") < 0)
- return (0);
- }
+ httpClearFields(client->http);
- if (code == HTTP_METHOD_NOT_ALLOWED || client->operation == HTTP_OPTIONS)
- {
- if (httpPrintf(&(client->http), "Allow: GET, HEAD, OPTIONS, POST\r\n") < 0)
- return (0);
- }
+ if (code == HTTP_STATUS_METHOD_NOT_ALLOWED ||
+ client->operation == HTTP_STATE_OPTIONS)
+ httpSetField(client->http, HTTP_FIELD_ALLOW, "GET, HEAD, OPTIONS, POST");
if (type)
{
if (!strcmp(type, "text/html"))
- {
- if (httpPrintf(&(client->http),
- "Content-Type: text/html; charset=utf-8\r\n") < 0)
- return (0);
- }
- else if (httpPrintf(&(client->http), "Content-Type: %s\r\n", type) < 0)
- return (0);
- }
+ httpSetField(client->http, HTTP_FIELD_CONTENT_TYPE,
+ "text/html; charset=utf-8");
+ else
+ httpSetField(client->http, HTTP_FIELD_CONTENT_TYPE, type);
- if (length == 0 && !message[0])
- {
- if (httpPrintf(&(client->http), "Transfer-Encoding: chunked\r\n\r\n") < 0)
- return (0);
+ if (content_encoding)
+ httpSetField(client->http, HTTP_FIELD_CONTENT_ENCODING, content_encoding);
}
- else if (httpPrintf(&(client->http), "Content-Length: " CUPS_LLFMT "\r\n\r\n",
- CUPS_LLCAST length) < 0)
- return (0);
- if (httpFlushWrite(&(client->http)) < 0)
+ httpSetLength(client->http, length);
+
+ if (httpWriteResponse(client->http, code) < 0)
return (0);
/*
@@ -4710,7 +4628,10 @@ respond_http(_ipp_client_t *client, /* I - Client */
* Send a plain text message.
*/
- if (httpPrintf(&(client->http), "%s", message) < 0)
+ if (httpPrintf(client->http, "%s", message) < 0)
+ return (0);
+
+ if (httpWrite2(client->http, "", 0) < 0)
return (0);
}
else if (client->response)
@@ -4721,21 +4642,13 @@ respond_http(_ipp_client_t *client, /* I - Client */
debug_attributes("Response", client->response, 2);
- client->http.data_encoding = HTTP_ENCODE_LENGTH;
- client->http.data_remaining = (off_t)ippLength(client->response);
- client->response->state = IPP_IDLE;
+ ippSetState(client->response, IPP_STATE_IDLE);
- if (ippWrite(&(client->http), client->response) != IPP_DATA)
+ if (ippWrite(client->http, client->response) != IPP_STATE_DATA)
return (0);
}
- else
- client->http.data_encoding = HTTP_ENCODE_CHUNKED;
-
- /*
- * Flush the data and return...
- */
- return (httpFlushWrite(&(client->http)) >= 0);
+ return (1);
}
@@ -4749,36 +4662,35 @@ respond_ipp(_ipp_client_t *client, /* I - Client */
const char *message, /* I - printf-style status-message */
...) /* I - Additional args as needed */
{
- va_list ap; /* Pointer to additional args */
- char formatted[1024]; /* Formatted errror message */
+ const char *formatted = NULL; /* Formatted message */
- client->response->request.status.status_code = status;
-
- if (!client->response->attrs)
- {
- ippAddString(client->response, IPP_TAG_OPERATION,
- IPP_TAG_CHARSET | IPP_TAG_COPY, "attributes-charset", NULL,
- "utf-8");
- ippAddString(client->response, IPP_TAG_OPERATION,
- IPP_TAG_LANGUAGE | IPP_TAG_COPY, "attributes-natural-language",
- NULL, "en-us");
- }
+ ippSetStatusCode(client->response, status);
if (message)
{
+ va_list ap; /* Pointer to additional args */
+ ipp_attribute_t *attr; /* New status-message attribute */
+
va_start(ap, message);
- vsnprintf(formatted, sizeof(formatted), message, ap);
+ if ((attr = ippFindAttribute(client->response, "status-message",
+ IPP_TAG_TEXT)) != NULL)
+ ippSetStringfv(client->response, &attr, 0, message, ap);
+ else
+ attr = ippAddStringfv(client->response, IPP_TAG_OPERATION, IPP_TAG_TEXT,
+ "status-message", NULL, message, ap);
va_end(ap);
- ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_TEXT,
- "status-message", NULL, formatted);
+ formatted = ippGetString(attr, 0, NULL);
}
- else
- formatted[0] = '\0';
- fprintf(stderr, "%s %s %s (%s)\n", client->http.hostname,
- ippOpString(client->operation_id), ippErrorString(status), formatted);
+ if (formatted)
+ fprintf(stderr, "%s %s %s (%s)\n", client->hostname,
+ ippOpString(client->operation_id), ippErrorString(status),
+ formatted);
+ else
+ fprintf(stderr, "%s %s %s\n", client->hostname,
+ ippOpString(client->operation_id), ippErrorString(status));
}
@@ -4794,12 +4706,10 @@ respond_unsupported(
ipp_attribute_t *temp; /* Copy of attribute */
- if (!client->response->attrs)
- respond_ipp(client, IPP_ATTRIBUTES, "Unsupported %s %s%s value.",
- attr->name, attr->num_values > 1 ? "1setOf " : "",
- ippTagString(attr->value_tag));
- else
- ippSetStatusCode(client->response, IPP_ATTRIBUTES);
+ respond_ipp(client, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES,
+ "Unsupported %s %s%s value.", ippGetName(attr),
+ ippGetCount(attr) > 1 ? "1setOf " : "",
+ ippTagString(ippGetValueTag(attr)));
temp = ippCopyAttribute(client->response, attr, 0);
ippSetGroupTag(client->response, &temp, IPP_TAG_UNSUPPORTED_GROUP);
@@ -4900,7 +4810,8 @@ usage(int status) /* O - Exit status */
{
if (!status)
{
- puts(CUPS_SVERSION " - Copyright 2010 by Apple Inc. All rights reserved.");
+ puts(CUPS_SVERSION " - Copyright 2010-2012 by Apple Inc. All rights "
+ "reserved.");
puts("");
}
@@ -4919,7 +4830,7 @@ usage(int status) /* O - Exit status */
puts("-m model Model name (default=Printer)");
puts("-n hostname Hostname for printer");
puts("-p port Port number (default=auto)");
- puts("-r regtype Bonjour service type (default=_ipp._tcp)");
+ puts("-r subtype Bonjour service subtype (default=_print)");
puts("-s speed[,color-speed] Speed in pages per minute (default=10,0)");
puts("-v[vvv] Be (very) verbose");
@@ -4939,10 +4850,16 @@ static int /* O - 1 if valid, 0 if not */
valid_doc_attributes(
_ipp_client_t *client) /* I - Client */
{
- int i; /* Looping var */
+ int valid = 1; /* Valid attributes? */
+ ipp_op_t op = ippGetOperation(client->request);
+ /* IPP operation */
+ const char *op_name = ippOpString(op);
+ /* IPP operation name */
ipp_attribute_t *attr, /* Current attribute */
- *supported; /* document-format-supported */
- const char *format = NULL; /* document-format value */
+ *supported; /* xxx-supported attribute */
+ const char *compression = NULL,
+ /* compression value */
+ *format = NULL; /* document-format value */
/*
@@ -4953,17 +4870,31 @@ valid_doc_attributes(
IPP_TAG_ZERO)) != NULL)
{
/*
- * If compression is specified, only accept "none"...
+ * If compression is specified, only accept a supported value in a Print-Job
+ * or Send-Document request...
*/
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_KEYWORD ||
- strcmp(attr->values[0].string.text, "none"))
+ compression = ippGetString(attr, 0, NULL);
+ supported = ippFindAttribute(client->printer->attrs,
+ "compression-supported", IPP_TAG_KEYWORD);
+
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_KEYWORD ||
+ ippGetGroupTag(attr) != IPP_TAG_OPERATION ||
+ (op != IPP_OP_PRINT_JOB && op != IPP_OP_SEND_DOCUMENT &&
+ op != IPP_OP_VALIDATE_JOB) ||
+ !ippContainsString(supported, compression))
+ {
respond_unsupported(client, attr);
+ valid = 0;
+ }
else
+ {
fprintf(stderr, "%s %s compression=\"%s\"\n",
- client->http.hostname,
- ippOpString(client->request->request.op.operation_id),
- attr->values[0].string.text);
+ client->hostname, op_name, compression);
+
+ if (strcmp(compression, "none"))
+ httpSetField(client->http, HTTP_FIELD_CONTENT_ENCODING, compression);
+ }
}
/*
@@ -4973,23 +4904,30 @@ valid_doc_attributes(
if ((attr = ippFindAttribute(client->request, "document-format",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_MIMETYPE)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_MIMETYPE ||
+ ippGetGroupTag(attr) != IPP_TAG_OPERATION)
+ {
respond_unsupported(client, attr);
+ valid = 0;
+ }
else
{
- format = attr->values[0].string.text;
+ format = ippGetString(attr, 0, NULL);
fprintf(stderr, "%s %s document-format=\"%s\"\n",
- client->http.hostname,
- ippOpString(client->request->request.op.operation_id), format);
+ client->hostname, op_name, format);
}
}
else
+ {
format = "application/octet-stream";
+ attr = ippAddString(client->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+ "document-format", NULL, format);
+ }
if (!strcmp(format, "application/octet-stream") &&
- (client->request->request.op.operation_id == IPP_PRINT_JOB ||
- client->request->request.op.operation_id == IPP_SEND_DOCUMENT))
+ (ippGetOperation(client->request) == IPP_OP_PRINT_JOB ||
+ ippGetOperation(client->request) == IPP_OP_SEND_DOCUMENT))
{
/*
* Auto-type the file using the first 4 bytes of the file...
@@ -4998,7 +4936,7 @@ valid_doc_attributes(
unsigned char header[4]; /* First 4 bytes of file */
memset(header, 0, sizeof(header));
- _httpPeek(&(client->http), (char *)header, sizeof(header));
+ httpPeek(client->http, (char *)header, sizeof(header));
if (!memcmp(header, "%PDF", 4))
format = "application/pdf";
@@ -5012,35 +4950,26 @@ valid_doc_attributes(
if (format)
fprintf(stderr, "%s %s Auto-typed document-format=\"%s\"\n",
- client->http.hostname,
- ippOpString(client->request->request.op.operation_id), format);
+ client->hostname, op_name, format);
if (!attr)
attr = ippAddString(client->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
"document-format", NULL, format);
else
- {
- _cupsStrFree(attr->values[0].string.text);
- attr->values[0].string.text = _cupsStrAlloc(format);
- }
+ ippSetString(client->request, &attr, 0, format);
}
- if (client->request->request.op.operation_id != IPP_CREATE_JOB &&
+ if (op != IPP_OP_CREATE_JOB &&
(supported = ippFindAttribute(client->printer->attrs,
"document-format-supported",
- IPP_TAG_MIMETYPE)) != NULL)
+ IPP_TAG_MIMETYPE)) != NULL &&
+ !ippContainsString(supported, format))
{
- for (i = 0; i < supported->num_values; i ++)
- if (!_cups_strcasecmp(format, supported->values[i].string.text))
- break;
-
- if (i >= supported->num_values && attr)
- respond_unsupported(client, attr);
+ respond_unsupported(client, attr);
+ valid = 0;
}
- return (!client->response->attrs ||
- !client->response->attrs->next ||
- !client->response->attrs->next->next);
+ return (valid);
}
@@ -5055,7 +4984,8 @@ static int /* O - 1 if valid, 0 if not */
valid_job_attributes(
_ipp_client_t *client) /* I - Client */
{
- int i; /* Looping var */
+ int i, /* Looping var */
+ valid = 1; /* Valid attributes? */
ipp_attribute_t *attr, /* Current attribute */
*supported; /* xxx-supported attribute */
@@ -5064,7 +4994,7 @@ valid_job_attributes(
* Check operation attributes...
*/
- valid_doc_attributes(client);
+ valid = valid_doc_attributes(client);
/*
* Check the various job template attributes...
@@ -5073,90 +5003,98 @@ valid_job_attributes(
if ((attr = ippFindAttribute(client->request, "copies",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_INTEGER ||
- attr->values[0].integer < 1 || attr->values[0].integer > 999)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_INTEGER ||
+ ippGetInteger(attr, 0) < 1 || ippGetInteger(attr, 0) > 999)
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "ipp-attribute-fidelity",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_BOOLEAN)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_BOOLEAN)
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "job-hold-until",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 ||
- (attr->value_tag != IPP_TAG_NAME &&
- attr->value_tag != IPP_TAG_NAMELANG &&
- attr->value_tag != IPP_TAG_KEYWORD) ||
- strcmp(attr->values[0].string.text, "no-hold"))
+ if (ippGetCount(attr) != 1 ||
+ (ippGetValueTag(attr) != IPP_TAG_NAME &&
+ ippGetValueTag(attr) != IPP_TAG_NAMELANG &&
+ ippGetValueTag(attr) != IPP_TAG_KEYWORD) ||
+ strcmp(ippGetString(attr, 0, NULL), "no-hold"))
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "job-name",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 ||
- (attr->value_tag != IPP_TAG_NAME &&
- attr->value_tag != IPP_TAG_NAMELANG))
+ if (ippGetCount(attr) != 1 ||
+ (ippGetValueTag(attr) != IPP_TAG_NAME &&
+ ippGetValueTag(attr) != IPP_TAG_NAMELANG))
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "job-priority",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_INTEGER ||
- attr->values[0].integer < 1 || attr->values[0].integer > 100)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_INTEGER ||
+ ippGetInteger(attr, 0) < 1 || ippGetInteger(attr, 0) > 100)
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "job-sheets",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 ||
- (attr->value_tag != IPP_TAG_NAME &&
- attr->value_tag != IPP_TAG_NAMELANG &&
- attr->value_tag != IPP_TAG_KEYWORD) ||
- strcmp(attr->values[0].string.text, "none"))
+ if (ippGetCount(attr) != 1 ||
+ (ippGetValueTag(attr) != IPP_TAG_NAME &&
+ ippGetValueTag(attr) != IPP_TAG_NAMELANG &&
+ ippGetValueTag(attr) != IPP_TAG_KEYWORD) ||
+ strcmp(ippGetString(attr, 0, NULL), "none"))
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "media",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 ||
- (attr->value_tag != IPP_TAG_NAME &&
- attr->value_tag != IPP_TAG_NAMELANG &&
- attr->value_tag != IPP_TAG_KEYWORD))
+ if (ippGetCount(attr) != 1 ||
+ (ippGetValueTag(attr) != IPP_TAG_NAME &&
+ ippGetValueTag(attr) != IPP_TAG_NAMELANG &&
+ ippGetValueTag(attr) != IPP_TAG_KEYWORD))
{
respond_unsupported(client, attr);
+ valid = 0;
}
else
{
for (i = 0;
i < (int)(sizeof(media_supported) / sizeof(media_supported[0]));
i ++)
- if (!strcmp(attr->values[0].string.text, media_supported[i]))
+ if (!strcmp(ippGetString(attr, 0, NULL), media_supported[i]))
break;
if (i >= (int)(sizeof(media_supported) / sizeof(media_supported[0])))
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
}
@@ -5164,9 +5102,11 @@ valid_job_attributes(
if ((attr = ippFindAttribute(client->request, "media-col",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_BEGIN_COLLECTION)
+ if (ippGetCount(attr) != 1 ||
+ ippGetValueTag(attr) != IPP_TAG_BEGIN_COLLECTION)
{
respond_unsupported(client, attr);
+ valid = 0;
}
/* TODO: check for valid media-col */
}
@@ -5174,24 +5114,26 @@ valid_job_attributes(
if ((attr = ippFindAttribute(client->request, "multiple-document-handling",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_KEYWORD ||
- (strcmp(attr->values[0].string.text,
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_KEYWORD ||
+ (strcmp(ippGetString(attr, 0, NULL),
"separate-documents-uncollated-copies") &&
- strcmp(attr->values[0].string.text,
+ strcmp(ippGetString(attr, 0, NULL),
"separate-documents-collated-copies")))
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
if ((attr = ippFindAttribute(client->request, "orientation-requested",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_ENUM ||
- attr->values[0].integer < IPP_PORTRAIT ||
- attr->values[0].integer > IPP_REVERSE_PORTRAIT)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_ENUM ||
+ ippGetInteger(attr, 0) < IPP_ORIENT_PORTRAIT ||
+ ippGetInteger(attr, 0) > IPP_ORIENT_REVERSE_PORTRAIT)
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
@@ -5199,16 +5141,18 @@ valid_job_attributes(
IPP_TAG_ZERO)) != NULL)
{
respond_unsupported(client, attr);
+ valid = 0;
}
if ((attr = ippFindAttribute(client->request, "print-quality",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_ENUM ||
- attr->values[0].integer < IPP_QUALITY_DRAFT ||
- attr->values[0].integer > IPP_QUALITY_HIGH)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_ENUM ||
+ ippGetInteger(attr, 0) < IPP_QUALITY_DRAFT ||
+ ippGetInteger(attr, 0) > IPP_QUALITY_HIGH)
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
@@ -5216,41 +5160,45 @@ valid_job_attributes(
IPP_TAG_ZERO)) != NULL)
{
respond_unsupported(client, attr);
+ valid = 0;
}
if ((attr = ippFindAttribute(client->request, "sides",
IPP_TAG_ZERO)) != NULL)
{
- if (attr->num_values != 1 || attr->value_tag != IPP_TAG_KEYWORD)
+ if (ippGetCount(attr) != 1 || ippGetValueTag(attr) != IPP_TAG_KEYWORD)
{
respond_unsupported(client, attr);
+ valid = 0;
}
if ((supported = ippFindAttribute(client->printer->attrs, "sides",
IPP_TAG_KEYWORD)) != NULL)
{
- for (i = 0; i < supported->num_values; i ++)
- if (!strcmp(attr->values[0].string.text,
- supported->values[i].string.text))
+ int count = ippGetCount(supported);
+ const char *sides = ippGetString(attr, 0, NULL);
+
+ for (i = 0; i < count; i ++)
+ if (!strcmp(sides, ippGetString(supported, i, NULL)))
break;
- if (i >= supported->num_values)
+ if (i >= count)
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
else
{
respond_unsupported(client, attr);
+ valid = 0;
}
}
- return (!client->response->attrs ||
- !client->response->attrs->next ||
- !client->response->attrs->next->next);
+ return (valid);
}
/*
- * End of "$Id: ippserver.c 10777 2012-12-17 22:18:10Z mike $".
+ * End of "$Id: ippserver.c 10851 2013-01-31 16:06:14Z mike $".
*/