summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>2019-03-20 21:59:20 -0400
committerMichael R Sweet <michael.r.sweet@gmail.com>2019-03-20 21:59:20 -0400
commit92dad945590fdfed38707355cefcf5c30cdbe50c (patch)
tree0b15d3badf1f4e63cb8141226390f64b7f344d8a /test
parent8a4ed632e8948f64eb2ae0069d966f6f9317cdb7 (diff)
downloadcups-92dad945590fdfed38707355cefcf5c30cdbe50c.tar.gz
Save work, take ippeveprinter out of the regular build until it is
compiling again...
Diffstat (limited to 'test')
-rw-r--r--test/Makefile5
-rw-r--r--test/ippeveprinter.c934
2 files changed, 560 insertions, 379 deletions
diff --git a/test/Makefile b/test/Makefile
index 8d4c506f5..d0450afda 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -51,10 +51,10 @@ OBJS = \
ippfind.o \
ipptool.o
TARGETS = \
- ippeveprinter \
$(IPPFIND_BIN) \
ipptool \
$(LOCALTARGET)
+# ippeveprinter \
#
@@ -179,7 +179,8 @@ uninstall:
# Local programs (not built when cross-compiling...)
#
-local: ippeveprinter-static ipptool-static
+#local: ippeveprinter-static ipptool-static
+local: ipptool-static
#
diff --git a/test/ippeveprinter.c b/test/ippeveprinter.c
index e85689117..93ba8c6bd 100644
--- a/test/ippeveprinter.c
+++ b/test/ippeveprinter.c
@@ -5,22 +5,21 @@
*
* Licensed under Apache License v2.0. See the file "LICENSE" for more
* information.
+ *
+ * Note: This program began life as the "ippserver" sample code that first
+ * appeared in CUPS 1.4. The name has been changed in order to distinguish it
+ * from the PWG's much more ambitious "ippserver" program, which supports
+ * different kinds of IPP services and multiple services per instance - the
+ * "ippeveprinter" program exposes a single print service conforming to the
+ * current IPP Everywhere specification.
*/
/*
* Include necessary headers...
*/
-#include <config.h> /* CUPS configuration header */
-#include <cups/cups.h> /* Public API */
-#include <cups/ppd.h> /* PPD API */
-#include <cups/string-private.h> /* CUPS string functions */
-#include <cups/thread-private.h> /* For multithreading functions */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
+#include <cups/cups-private.h>
+#include <cups/ppd-private.h> /* PPD API */
#include <limits.h>
#include <sys/stat.h>
@@ -116,9 +115,9 @@ static const char * const ippeve_preason_strings[] =
typedef enum ippeve_media_class_e
{
- IPPEVE_GENERAL, /* General-purpose size */
+ IPPEVE_GENERAL, /* General-purpose size */
IPPEVE_PHOTO_ONLY, /* Photo-only size */
- IPPEVE_ENV_ONLY /* Envelope-only size */
+ IPPEVE_ENV_ONLY /* Envelope-only size */
} ippeve_media_class_t;
typedef enum ippeve_media_size_e
@@ -222,7 +221,7 @@ static const char * const media_type_supported[] =
typedef enum ippeve_supply_e
{
IPPEVE_SUPPLY_CYAN, /* Cyan Toner */
- IPPEVE_SUPPLY_MAGENTA, /* Magenta Toner */
+ IPPEVE_SUPPLY_MAGENTA, /* Magenta Toner */
IPPEVE_SUPPLY_YELLOW, /* Yellow Toner */
IPPEVE_SUPPLY_BLACK, /* Black Toner */
IPPEVE_SUPPLY_WASTE /* Waste Toner */
@@ -352,36 +351,20 @@ typedef struct ippeve_client_s /**** Client data ****/
static void clean_jobs(ippeve_printer_t *printer);
static int compare_jobs(ippeve_job_t *a, ippeve_job_t *b);
-static void copy_attributes(ipp_t *to, ipp_t *from, cups_array_t *ra,
- ipp_tag_t group_tag, int quickcopy);
-static void copy_job_attributes(ippeve_client_t *client,
- ippeve_job_t *job, cups_array_t *ra);
+static void copy_attributes(ipp_t *to, ipp_t *from, cups_array_t *ra, ipp_tag_t group_tag, int quickcopy);
+static void copy_job_attributes(ippeve_client_t *client, ippeve_job_t *job, cups_array_t *ra);
static ippeve_client_t *create_client(ippeve_printer_t *printer, int sock);
static ippeve_job_t *create_job(ippeve_client_t *client);
-static int create_listener(int family, int port);
+static int create_listener(const char *name, int family, int port);
static ipp_t *create_media_col(const char *media, const char *source, const char *type, int width, int length, int margins);
static ipp_t *create_media_size(int width, int length);
-static ippeve_printer_t *create_printer(const char *servername,
- const char *name, const char *location,
- const char *icon,
- const char *docformats, int port,
- const char *subtype,
- const char *directory,
- const char *command,
- const char *attrfile);
-static void debug_attributes(const char *title, ipp_t *ipp,
- int response);
+static ippeve_printer_t *create_printer(const char *servername, int serverport, const char *name, const char *location, const char *icon, const char *docformats, const char *subtypes, const char *directory, const char *command, ipp_t *attrs);
+static void debug_attributes(const char *title, ipp_t *ipp, int response);
static void delete_client(ippeve_client_t *client);
static void delete_job(ippeve_job_t *job);
static void delete_printer(ippeve_printer_t *printer);
#ifdef HAVE_DNSSD
-static void DNSSD_API dnssd_callback(DNSServiceRef sdRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- const char *name,
- const char *regtype,
- const char *domain,
- ippeve_printer_t *printer);
+static void DNSSD_API dnssd_callback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, ippeve_printer_t *printer);
#elif defined(HAVE_AVAHI)
static void dnssd_callback(AvahiEntryGroup *p, AvahiEntryGroupState state, void *context);
static void dnssd_client_cb(AvahiClient *c, AvahiClientState state, void *userdata);
@@ -391,12 +374,10 @@ static int filter_cb(ippeve_filter_t *filter, ipp_t *dst, ipp_attribute_t *attr
static ippeve_job_t *find_job(ippeve_client_t *client);
static ipp_t *get_collection(FILE *fp, const char *filename, int *linenum);
static char *get_token(FILE *fp, char *buf, int buflen, int *linenum);
-static void html_escape(ippeve_client_t *client, const char *s,
- size_t slen);
+static void html_escape(ippeve_client_t *client, const char *s, size_t slen);
static void html_footer(ippeve_client_t *client);
static void html_header(ippeve_client_t *client, const char *title);
-static void html_printf(ippeve_client_t *client, const char *format,
- ...) _CUPS_FORMAT(2, 3);
+static void html_printf(ippeve_client_t *client, const char *format, ...) _CUPS_FORMAT(2, 3);
static void ipp_cancel_job(ippeve_client_t *client);
static void ipp_close_job(ippeve_client_t *client);
static void ipp_create_job(ippeve_client_t *client);
@@ -409,9 +390,9 @@ static void ipp_print_uri(ippeve_client_t *client);
static void ipp_send_document(ippeve_client_t *client);
static void ipp_send_uri(ippeve_client_t *client);
static void ipp_validate_job(ippeve_client_t *client);
-static void load_attributes(const char *filename, ipp_t *attrs);
-static char *make_ppd_attributes(const char *ppdfile, char *buffer, size_t bufsize);
-static char *make_std_attributes(const char *make, const char *model, int ppm, int ppm_color, int duplex, char *buffer, size_t bufsize);
+static ipp_t *load_ippserver_attributes(const char *servername, int serverport, const char *filename);
+static ipp_t *load_ppd_attributes(const char *ppdfile);
+static ipp_t *load_std_attributes(const char *make, const char *model, const char *formats, int ppm, int ppm_color, int duplex);
static int parse_options(ippeve_client_t *client, cups_option_t **options);
static void process_attr_message(ippeve_job_t *job, char *message);
static void *process_client(ippeve_client_t *client);
@@ -419,14 +400,10 @@ static int process_http(ippeve_client_t *client);
static int process_ipp(ippeve_client_t *client);
static void *process_job(ippeve_job_t *job);
static void process_state_message(ippeve_job_t *job, char *message);
-static int register_printer(ippeve_printer_t *printer, const char *location, const char *make, const char *model, const char *formats, const char *adminurl, const char *uuid, int color, int duplex, const char *regtype);
-static int respond_http(ippeve_client_t *client, http_status_t code,
- const char *content_coding,
- const char *type, size_t length);
-static void respond_ipp(ippeve_client_t *client, ipp_status_t status,
- const char *message, ...) _CUPS_FORMAT(3, 4);
-static void respond_unsupported(ippeve_client_t *client,
- ipp_attribute_t *attr);
+static int register_printer(ippeve_printer_t *printer, const char *subtypes);
+static int respond_http(ippeve_client_t *client, http_status_t code, const char *content_coding, const char *type, size_t length);
+static void respond_ipp(ippeve_client_t *client, ipp_status_t status, const char *message, ...) _CUPS_FORMAT(3, 4);
+static void respond_unsupported(ippeve_client_t *client, ipp_attribute_t *attr);
static void run_printer(ippeve_printer_t *printer);
static char *time_string(time_t tv, char *buffer, size_t bufsize);
static void usage(int status) _CUPS_NORETURN;
@@ -445,9 +422,9 @@ static AvahiThreadedPoll *DNSSDMaster = NULL;
static AvahiClient *DNSSDClient = NULL;
#endif /* HAVE_DNSSD */
-static int KeepFiles = 0,
- MaxVersion = 20,
- Verbosity = 0;
+static int KeepFiles = 0, /* Keep spooled job files? */
+ MaxVersion = 20,/* Maximum IPP version (20 = 2.0, 11 = 1.1, etc.) */
+ Verbosity = 0; /* Verbosity level */
/*
@@ -473,7 +450,7 @@ main(int argc, /* I - Number of command-line args */
#ifdef HAVE_SSL
const char *keypath = NULL; /* Keychain path */
#endif /* HAVE_SSL */
- const char *subtype = "_print"; /* Bonjour service subtype */
+ const char *subtypes = "_print"; /* DNS-SD service subtype */
int port = 0, /* Port number (0 = auto) */
duplex = 0, /* Duplex mode */
ppm = 10, /* Pages per minute for mono */
@@ -1168,8 +1145,9 @@ static void create_job_filename(
*/
static int /* O - Listener socket or -1 on error */
-create_listener(int family, /* I - Address family */
- int port) /* I - Port number */
+create_listener(const char *name, /* I - Host name (`NULL` for default) */
+ int family, /* I - Address family */
+ int port) /* I - Port number */
{
int sock; /* Listener socket */
http_addrlist_t *addrlist; /* Listen address */
@@ -1177,7 +1155,7 @@ create_listener(int family, /* I - Address family */
snprintf(service, sizeof(service), "%d", port);
- if ((addrlist = httpAddrGetList(NULL, family, service)) == NULL)
+ if ((addrlist = httpAddrGetList(name, family, service)) == NULL)
return (-1);
sock = httpAddrListen(&(addrlist->addr), port);
@@ -1265,15 +1243,15 @@ create_media_size(int width, /* I - x-dimension in 2540ths */
static ippeve_printer_t * /* O - Printer */
create_printer(const char *servername, /* I - Server hostname (NULL for default) */
- const char *name, /* I - printer-name */
+ int port, /* I - Port for listeners or 0 for auto */
+ const char *name, /* I - printer-name */
const char *location, /* I - printer-location */
const char *icon, /* I - printer-icons */
const char *docformats, /* I - document-format-supported */
- int port, /* I - Port for listeners or 0 for auto */
- const char *subtype, /* I - Bonjour service subtype(s) */
+ const char *subtypes, /* I - Bonjour service subtype(s) */
const char *directory, /* I - Spool directory */
const char *command, /* I - Command to run on job files */
- const char *attrfile) /* I - Attributes file */
+ ipp_t *attrs) /* I - Capability attributes */
{
int i, j; /* Looping vars */
ippeve_printer_t *printer; /* Printer */
@@ -1312,19 +1290,10 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
struct statfs spoolinfo; /* FS info for spool directory */
double spoolsize; /* FS size */
#endif /* HAVE_STATVFS */
- static const int orients[4] = /* orientation-requested-supported values */
- {
- IPP_ORIENT_PORTRAIT,
- IPP_ORIENT_LANDSCAPE,
- IPP_ORIENT_REVERSE_LANDSCAPE,
- IPP_ORIENT_REVERSE_PORTRAIT
- };
static const char * const versions[] =/* ipp-versions-supported values */
{
"1.1",
- "2.0",
- "2.1",
- "2.2"
+ "2.0"
};
static const char * const features[] =/* ipp-features-supported values */
{
@@ -1368,8 +1337,6 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
{ /* job-creation-attributes-supported values */
"copies",
"ipp-attribute-fidelity",
- "job-account-id",
- "job-accounting-user-id",
"job-name",
"job-password",
"job-priority",
@@ -1390,11 +1357,6 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"media-top-margin",
"media-type"
};
- static const int media_xxx_margin_supported[] =
- { /* media-xxx-margin-supported values */
- 0,
- 635
- };
static const char * const multiple_document_handling[] =
{ /* multiple-document-handling-supported values */
"separate-documents-uncollated-copies",
@@ -1405,31 +1367,6 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
"document-number",
"pages"
};
- static const char * const print_color_mode_supported[] =
- { /* print-color-mode-supported values */
- "auto",
- "color",
- "monochrome"
- };
- static const int print_quality_supported[] =
- { /* print-quality-supported values */
- IPP_QUALITY_DRAFT,
- IPP_QUALITY_NORMAL,
- IPP_QUALITY_HIGH
- };
- static const int pwg_raster_document_resolution_supported[] =
- {
- 150,
- 300
- };
- 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",
@@ -1439,23 +1376,6 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
, "https"
#endif /* HAVE_SSL */
};
- static const char * const sides_supported[] =
- { /* sides-supported values */
- "one-sided",
- "two-sided-long-edge",
- "two-sided-short-edge"
- };
- static const char * const urf_supported[] =
- { /* urf-supported values */
- "CP1",
- "IS1-5-7",
- "MT1-2-3-4-5-6-8-9-10-11-12-13",
- "RS300",
- "SRGB24",
- "V1.4",
- "W8",
- "DM1"
- };
#ifdef HAVE_SSL
static const char * const uri_authentication_supported[] =
{ /* uri-authentication-supported values */
@@ -2162,7 +2082,7 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
* Register the printer with Bonjour...
*/
- if (!register_printer(printer, location, make, model, docformats, adminurl, uuid + 9, ppm_color > 0, duplex, subtype))
+ if (!register_printer(printer, subtypes))
goto bad_printer;
/*
@@ -4773,321 +4693,581 @@ ipp_validate_job(ippeve_client_t *client) /* I - Client */
/*
- * 'load_attributes()' - Load printer attributes from a file.
- *
- * Syntax is based on ipptool format:
- *
- * ATTR value-tag name value
+ * 'ippserver_attr_cb()' - Determine whether an attribute should be loaded.
*/
-static void
-load_attributes(const char *filename, /* I - File to load */
- ipp_t *attrs) /* I - Printer attributes */
+static int /* O - 1 to use, 0 to ignore */
+ippserver_attr_cb(
+ _ipp_file_t *f, /* I - IPP file */
+ void *user_data, /* I - User data pointer (unused) */
+ const char *attr) /* I - Attribute name */
{
- int linenum = 0; /* Current line number */
- FILE *fp = NULL; /* Test file */
- char attr[128], /* Attribute name */
- token[1024], /* Token from file */
- *tokenptr; /* Pointer into token */
- ipp_tag_t value; /* Current value type */
- ipp_attribute_t *attrptr, /* Attribute pointer */
- *lastcol = NULL; /* Last collection attribute */
+ int i, /* Current element */
+ result; /* Result of comparison */
+ static const char * const ignored[] =
+ { /* Ignored attributes */
+ "attributes-charset",
+ "attributes-natural-language",
+ "charset-configured",
+ "charset-supported",
+ "device-service-count",
+ "device-uuid",
+ "document-format-varying-attributes",
+ "generated-natural-language-supported",
+ "ippget-event-life",
+ "job-hold-until-supported",
+ "job-hold-until-time-supported",
+ "job-ids-supported",
+ "job-k-octets-supported",
+ "job-settable-attributes-supported",
+ "multiple-document-jobs-supported",
+ "multiple-operation-time-out",
+ "multiple-operation-time-out-action",
+ "natural-language-configured",
+ "notify-attributes-supported",
+ "notify-events-default",
+ "notify-events-supported",
+ "notify-lease-duration-default",
+ "notify-lease-duration-supported",
+ "notify-max-events-supported",
+ "notify-pull-method-supported",
+ "operations-supported",
+ "printer-alert",
+ "printer-alert-description",
+ "printer-camera-image-uri",
+ "printer-charge-info",
+ "printer-charge-info-uri",
+ "printer-config-change-date-time",
+ "printer-config-change-time",
+ "printer-current-time",
+ "printer-detailed-status-messages",
+ "printer-dns-sd-name",
+ "printer-fax-log-uri",
+ "printer-get-attributes-supported",
+ "printer-icons",
+ "printer-id",
+ "printer-info",
+ "printer-is-accepting-jobs",
+ "printer-message-date-time",
+ "printer-message-from-operator",
+ "printer-message-time",
+ "printer-more-info",
+ "printer-service-type",
+ "printer-settable-attributes-supported",
+ "printer-state",
+ "printer-state-message",
+ "printer-state-reasons",
+ "printer-static-resource-directory-uri",
+ "printer-static-resource-k-octets-free",
+ "printer-static-resource-k-octets-supported",
+ "printer-strings-languages-supported",
+ "printer-strings-uri",
+ "printer-supply-info-uri",
+ "printer-up-time",
+ "printer-uri-supported",
+ "printer-xri-supported",
+ "queued-job-count",
+ "reference-uri-scheme-supported",
+ "uri-authentication-supported",
+ "uri-security-supported",
+ "which-jobs-supported",
+ "xri-authentication-supported",
+ "xri-security-supported",
+ "xri-uri-scheme-supported"
+ };
+
+ (void)f;
+ (void)user_data;
- if ((fp = fopen(filename, "r")) == NULL)
+ for (i = 0, result = 1; i < (int)(sizeof(ignored) / sizeof(ignored[0])); i ++)
{
- fprintf(stderr, "ippserver: Unable to open \"%s\": %s\n", filename, strerror(errno));
- exit(1);
+ if ((result = strcmp(attr, ignored[i])) <= 0)
+ break;
}
- while (get_token(fp, token, sizeof(token), &linenum) != NULL)
+ return (result != 0);
+}
+
+
+/*
+ * 'ippserver_error_cb()' - Log an error message.
+ */
+
+static int /* O - 1 to continue, 0 to stop */
+ippserver_error_cb(
+ _ipp_file_t *f, /* I - IPP file data */
+ void *user_data, /* I - User data pointer (unused) */
+ const char *error) /* I - Error message */
+{
+ (void)f;
+ (void)user_data;
+
+ _cupsLangPrintf(stderr, "%s\n", error);
+
+ return (1);
+}
+
+
+/*
+ * 'ippserver_token_cb()' - Process ippserver-specific config file tokens.
+ */
+
+static int /* O - 1 to continue, 0 to stop */
+ippserver_token_cb(
+ _ipp_file_t *f, /* I - IPP file data */
+ _ipp_vars_t *vars, /* I - IPP variables */
+ void *user_data, /* I - User data pointer (unused) */
+ const char *token) /* I - Current token */
+{
+ char temp[1024], /* Temporary string */
+ value[1024]; /* Value string */
+
+
+ (void)user_data;
+
+ if (!token)
{
- if (!_cups_strcasecmp(token, "ATTR"))
- {
- /*
- * Attribute...
- */
+ /*
+ * NULL token means do the initial setup - create an empty IPP message and
+ * return...
+ */
- if (!get_token(fp, token, sizeof(token), &linenum))
- {
- fprintf(stderr, "ippserver: Missing ATTR value tag on line %d of \"%s\".\n", linenum, filename);
- exit(1);
- }
+ f->attrs = ippNew();
+ f->group_tag = IPP_TAG_PRINTER;
+ }
+ else
+ {
+ _cupsLangPrintf(stderr, _("Unknown directive \"%s\" on line %d of \"%s\" ignored."), token, f->linenum, f->filename);
+ }
- if ((value = ippTagValue(token)) == IPP_TAG_ZERO)
- {
- fprintf(stderr, "ippserver: Bad ATTR value tag \"%s\" on line %d of \"%s\".\n", token, linenum, filename);
- exit(1);
- }
+ return (1);
+}
- if (!get_token(fp, attr, sizeof(attr), &linenum))
- {
- fprintf(stderr, "ippserver: Missing ATTR name on line %d of \"%s\".\n", linenum, filename);
- exit(1);
- }
- if (!get_token(fp, token, sizeof(token), &linenum))
- {
- fprintf(stderr, "ippserver: Missing ATTR value on line %d of \"%s\".\n", linenum, filename);
- exit(1);
- }
+/*
+ * 'load_ippserver_attributes()' - Load IPP attributes from an ippserver file.
+ */
- attrptr = NULL;
+static ipp_t * /* O - IPP attributes or `NULL` on error */
+load_ippserver_attributes(
+ const char *servername, /* I - Server name or `NULL` for default */
+ int port, /* I - Port number */
+ const char *filename) /* I - ippserver attribute filename */
+{
+ ipp_t *attrs; /* IPP attributes */
+ _ipp_vars_t vars; /* IPP variables */
+ char temp[256]; /* Temporary string */
- switch (value)
- {
- case IPP_TAG_BOOLEAN :
- if (!_cups_strcasecmp(token, "true"))
- attrptr = ippAddBoolean(attrs, IPP_TAG_PRINTER, attr, 1);
- else
- attrptr = ippAddBoolean(attrs, IPP_TAG_PRINTER, attr, (char)atoi(token));
- break;
- case IPP_TAG_INTEGER :
- case IPP_TAG_ENUM :
- if (!strchr(token, ','))
- attrptr = ippAddInteger(attrs, IPP_TAG_PRINTER, value, attr, (int)strtol(token, &tokenptr, 0));
- else
- {
- int values[100], /* Values */
- num_values = 1; /* Number of values */
+ /*
+ * Setup callbacks and variables for the printer configuration file...
+ *
+ * The following additional variables are supported:
+ *
+ * - SERVERNAME: The host name of the server.
+ * - SERVERPORT: The default port of the server.
+ */
- values[0] = (int)strtol(token, &tokenptr, 10);
- while (tokenptr && *tokenptr &&
- num_values < (int)(sizeof(values) / sizeof(values[0])))
- {
- if (*tokenptr == ',')
- tokenptr ++;
- else if (!isdigit(*tokenptr & 255) && *tokenptr != '-')
- break;
+ _ippVarsInit(&vars, (_ipp_fattr_cb_t)ippserver_attr_cb, (_ipp_ferror_cb_t)ippserver_error_cb, (_ipp_ftoken_cb_t)ippserver_token_cb);
- values[num_values] = (int)strtol(tokenptr, &tokenptr, 0);
- num_values ++;
- }
+ if (servername)
+ {
+ _ippVarsSet(&vars, "SERVERNAME", servername);
+ }
+ else
+ {
+ httpGetHostname(NULL, temp, sizeof(temp));
+ _ippVarsSet(&vars, "SERVERNAME", temp);
+ }
- attrptr = ippAddIntegers(attrs, IPP_TAG_PRINTER, value, attr, num_values, values);
- }
+ snprintf(temp, sizeof(temp), "%d", serverport);
+ _ippVarsSet(&vars, "SERVERPORT", temp);
- if (!tokenptr || *tokenptr)
- {
- fprintf(stderr, "ippserver: Bad %s value \"%s\" on line %d of \"%s\".\n", ippTagString(value), token, linenum, filename);
- exit(1);
- }
- break;
+ /*
+ * Load attributes and values for the printer...
+ */
- case IPP_TAG_RESOLUTION :
- {
- int xres, /* X resolution */
- yres; /* Y resolution */
- ipp_res_t units; /* Units */
- char *start, /* Start of value */
- *ptr, /* Pointer into value */
- *next = NULL; /* Next value */
+ attrs = _ippFileParse(&vars, filename, NULL);
- for (start = token; start; start = next)
- {
- xres = yres = (int)strtol(start, (char **)&ptr, 10);
- if (ptr > start && xres > 0)
- {
- if (*ptr == 'x')
- yres = (int)strtol(ptr + 1, (char **)&ptr, 10);
- }
+ /*
+ * Free memory and return...
+ */
- if (ptr && (next = strchr(ptr, ',')) != NULL)
- *next++ = '\0';
+ _ippVarsDeinit(&vars);
- if (ptr <= start || xres <= 0 || yres <= 0 || !ptr ||
- (_cups_strcasecmp(ptr, "dpi") &&
- _cups_strcasecmp(ptr, "dpc") &&
- _cups_strcasecmp(ptr, "dpcm") &&
- _cups_strcasecmp(ptr, "other")))
- {
- fprintf(stderr, "ippserver: Bad resolution value \"%s\" on line %d of \"%s\".\n", token, linenum, filename);
- exit(1);
- }
+ return (attrs);
+}
- if (!_cups_strcasecmp(ptr, "dpc") || !_cups_strcasecmp(ptr, "dpcm"))
- units = IPP_RES_PER_CM;
- else
- units = IPP_RES_PER_INCH;
- if (attrptr)
- ippSetResolution(attrs, &attrptr, ippGetCount(attrptr), units, xres, yres);
- else
- attrptr = ippAddResolution(attrs, IPP_TAG_PRINTER, attr, units, xres, yres);
- }
- }
- break;
+/*
+ * 'load_ppd_attributes()' - Load IPP attributes from a PPD file.
+ */
- case IPP_TAG_RANGE :
- {
- int lowers[4], /* Lower value */
- uppers[4], /* Upper values */
- num_vals; /* Number of values */
+static ipp_t * /* O - IPP attributes or `NULL` on error */
+load_ppd_attributes(
+ const char *ppdfile) /* I - PPD filename */
+{
+}
- num_vals = sscanf(token, "%d-%d,%d-%d,%d-%d,%d-%d",
- lowers + 0, uppers + 0,
- lowers + 1, uppers + 1,
- lowers + 2, uppers + 2,
- lowers + 3, uppers + 3);
+/*
+ * 'load_std_attributes()' - Load IPP attributes using the old ippserver
+ * options.
+ */
- if ((num_vals & 1) || num_vals == 0)
- {
- fprintf(stderr, "ippserver: Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", token, linenum, filename);
- exit(1);
- }
+static ipp_t * /* O - IPP attributes or `NULL` on error */
+load_std_attributes(
+ const char *make, /* I - Manufacturer name */
+ const char *model, /* I - Model name */
+ const char *formats, /* I - Document formats */
+ int ppm, /* I - pages-per-minute */
+ int ppm_color, /* I - pages-per-minute-color */
+ int duplex) /* I - Duplex support? */
+{
+ ipp_t *attrs; /* IPP attributes */
+ char device_id[1024],/* printer-device-id */
+ make_model[128];/* printer-make-and-model */
+ static const int orientation_requested_supported[4] =
+ { /* orientation-requested-supported values */
+ IPP_ORIENT_PORTRAIT,
+ IPP_ORIENT_LANDSCAPE,
+ IPP_ORIENT_REVERSE_LANDSCAPE,
+ IPP_ORIENT_REVERSE_PORTRAIT
+ };
+ static const char * const print_color_mode_supported[] =
+ { /* print-color-mode-supported values */
+ "auto",
+ "color",
+ "monochrome"
+ };
+ static const int print_quality_supported[] =
+ { /* print-quality-supported values */
+ IPP_QUALITY_DRAFT,
+ IPP_QUALITY_NORMAL,
+ IPP_QUALITY_HIGH
+ };
+ static const int pwg_raster_document_resolution_supported[] =
+ {
+ 150,
+ 300
+ };
+ static const char * const pwg_raster_document_type_supported[] =
+ {
+ "black_1",
+ "cmyk_8",
+ "sgray_8",
+ "srgb_8",
+ "srgb_16"
+ };
+ static const char * const sides_supported[] =
+ { /* sides-supported values */
+ "one-sided",
+ "two-sided-long-edge",
+ "two-sided-short-edge"
+ };
+ static const char * const urf_supported[] =
+ { /* urf-supported values */
+ "CP1",
+ "IS1-5-7",
+ "MT1-2-3-4-5-6-8-9-10-11-12-13",
+ "RS300",
+ "SRGB24",
+ "V1.4",
+ "W8",
+ "DM1"
+ };
- attrptr = ippAddRanges(attrs, IPP_TAG_PRINTER, attr, num_vals / 2, lowers,
- uppers);
- }
- break;
- case IPP_TAG_BEGIN_COLLECTION :
- if (!strcmp(token, "{"))
- {
- ipp_t *col = get_collection(fp, filename, &linenum);
- /* Collection value */
+ attrs = ippNew();
- if (col)
- {
- attrptr = lastcol = ippAddCollection(attrs, IPP_TAG_PRINTER, attr, col);
- ippDelete(col);
- }
- else
- exit(1);
- }
- else
- {
- fprintf(stderr, "ippserver: Bad ATTR collection value on line %d of \"%s\".\n", linenum, filename);
- exit(1);
- }
+ /* color-supported */
+ ippAddBoolean(attrs, IPP_TAG_PRINTER, "color-supported", ppm_color > 0);
- do
- {
- ipp_t *col; /* Collection value */
- long pos = ftell(fp); /* Save position of file */
+ /* copies-default */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", 1);
- if (!get_token(fp, token, sizeof(token), &linenum))
- break;
+ /* copies-supported */
+ ippAddRange(attrs, IPP_TAG_PRINTER, "copies-supported", 1, strstr(formats, "application/pdf") != NULL ? 999 : 1);
- if (strcmp(token, ","))
- {
- fseek(fp, pos, SEEK_SET);
- break;
- }
+ /* finishings-default */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "finishings-default", IPP_FINISHINGS_NONE);
- if (!get_token(fp, token, sizeof(token), &linenum) || strcmp(token, "{"))
- {
- fprintf(stderr, "ippserver: Unexpected \"%s\" on line %d of \"%s\".\n", token, linenum, filename);
- exit(1);
- }
+ /* finishings-supported */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "finishings-supported", IPP_FINISHINGS_NONE);
- if ((col = get_collection(fp, filename, &linenum)) == NULL)
- break;
+ /* media-bottom-margin-supported */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin-supported", 635);
- ippSetCollection(attrs, &attrptr, ippGetCount(attrptr), col);
- }
- while (!strcmp(token, "{"));
+ /* media-col-database */
+ if (!ippFindAttribute(attrs, "media-col-database", IPP_TAG_ZERO))
+ {
+ for (num_database = 0, i = 0;
+ i < (int)(sizeof(media_col_sizes) / sizeof(media_col_sizes[0]));
+ i ++)
+ {
+ if (media_col_sizes[i][2] == IPPEVE_ENV_ONLY)
+ num_database += 3; /* auto + manual + envelope */
+ else if (media_col_sizes[i][2] == IPPEVE_PHOTO_ONLY)
+ num_database += 6 * 3; /* auto + photographic-* from auto, manual, and photo */
+ else
+ num_database += 2; /* Regular + borderless */
+ }
+
+ media_col_database = ippAddCollections(attrs, IPP_TAG_PRINTER, "media-col-database", num_database, NULL);
+ for (media_col_index = 0, i = 0;
+ i < (int)(sizeof(media_col_sizes) / sizeof(media_col_sizes[0]));
+ i ++)
+ {
+ switch (media_col_sizes[i][2])
+ {
+ case IPPEVE_GENERAL :
+ /*
+ * Regular + borderless for the general class; no source/type
+ * selectors...
+ */
+
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], NULL, NULL, media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[1]));
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], NULL, NULL, media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[0]));
break;
- case IPP_TAG_STRING :
- attrptr = ippAddOctetString(attrs, IPP_TAG_PRINTER, attr, token, (int)strlen(token));
+ case IPPEVE_ENV_ONLY :
+ /*
+ * Regular margins for "auto", "manual", and "envelope" sources.
+ */
+
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], "auto", "envelope", media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[1]));
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], "manual", "envelope", media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[1]));
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], "envelope", "envelope", media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[1]));
break;
+ case IPPEVE_PHOTO_ONLY :
+ /*
+ * Photos have specific media types and can only be printed via
+ * the auto, manual, and photo sources...
+ */
- default :
- fprintf(stderr, "ippserver: Unsupported ATTR value tag %s on line %d of \"%s\".\n", ippTagString(value), linenum, filename);
- exit(1);
-
- case IPP_TAG_TEXTLANG :
- case IPP_TAG_NAMELANG :
- case IPP_TAG_TEXT :
- case IPP_TAG_NAME :
- case IPP_TAG_KEYWORD :
- case IPP_TAG_URI :
- case IPP_TAG_URISCHEME :
- case IPP_TAG_CHARSET :
- case IPP_TAG_LANGUAGE :
- case IPP_TAG_MIMETYPE :
- if (!strchr(token, ','))
- attrptr = ippAddString(attrs, IPP_TAG_PRINTER, value, attr, NULL, token);
- else
+ for (j = 0;
+ j < (int)(sizeof(media_type_supported) /
+ sizeof(media_type_supported[0]));
+ j ++)
{
- /*
- * Multiple string values...
- */
+ if (strcmp(media_type_supported[j], "auto") && strncmp(media_type_supported[j], "photographic-", 13))
+ continue;
- int num_values; /* Number of values */
- char *values[100], /* Values */
- *ptr; /* Pointer to next value */
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], "auto", media_type_supported[j], media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[0]));
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], "manual", media_type_supported[j], media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[0]));
+ ippSetCollection(attrs, &media_col_database, media_col_index ++, create_media_col(media_supported[i], "photo", media_type_supported[j], media_col_sizes[i][0], media_col_sizes[i][1], media_xxx_margin_supported[0]));
+ }
+ break;
+ }
+ }
+ }
+ /* media-col-default */
+ if (!ippFindAttribute(attrs, "media-col-default", IPP_TAG_ZERO))
+ {
+ media_col_default = create_media_col(media_supported[0], media_source_supported[0], media_type_supported[0], media_col_sizes[0][0], media_col_sizes[0][1],media_xxx_margin_supported[1]);
- values[0] = token;
- num_values = 1;
+ ippAddCollection(attrs, IPP_TAG_PRINTER, "media-col-default",
+ media_col_default);
+ ippDelete(media_col_default);
+ }
- for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ','))
- {
- if (ptr > token && ptr[-1] == '\\')
- _cups_strcpy(ptr - 1, ptr);
- else
- {
- *ptr++ = '\0';
- values[num_values] = ptr;
- num_values ++;
- if (num_values >= (int)(sizeof(values) / sizeof(values[0])))
- break;
- }
- }
+ /* media-col-supported */
+ if (!ippFindAttribute(attrs, "media-col-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-col-supported", (int)(sizeof(media_col_supported) / sizeof(media_col_supported[0])), NULL, media_col_supported);
- attrptr = ippAddStrings(attrs, IPP_TAG_PRINTER, value, attr, num_values, NULL, (const char **)values);
- }
- break;
- }
+ /* media-default */
+ if (!ippFindAttribute(attrs, "media-default", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-default", NULL, media_supported[0]);
- if (!attrptr)
- {
- fprintf(stderr, "ippserver: Unable to add attribute on line %d of \"%s\": %s\n", linenum, filename, cupsLastErrorString());
- exit(1);
- }
- }
- else
+ /* media-left-margin-supported */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin-supported", 635);
+
+ /* media-right-margin-supported */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin-supported", 635);
+
+ /* media-supported */
+ if (!ippFindAttribute(attrs, "media-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-supported", (int)(sizeof(media_supported) / sizeof(media_supported[0])), NULL, media_supported);
+
+ /* media-size-supported */
+ if (!ippFindAttribute(attrs, "media-size-supported", IPP_TAG_ZERO))
+ {
+ media_size_supported = ippAddCollections(attrs, IPP_TAG_PRINTER, "media-size-supported", (int)(sizeof(media_col_sizes) / sizeof(media_col_sizes[0])), NULL);
+
+ for (i = 0;
+ i < (int)(sizeof(media_col_sizes) / sizeof(media_col_sizes[0]));
+ i ++)
{
- fprintf(stderr, "ippserver: Unknown directive \"%s\" on line %d of \"%s\".\n", token, linenum, filename);
- exit(1);
+ ipp_t *size = create_media_size(media_col_sizes[i][0], media_col_sizes[i][1]);
+
+ ippSetCollection(attrs, &media_size_supported, i, size);
+ ippDelete(size);
}
}
- fclose(fp);
-}
+ /* media-source-supported */
+ if (!ippFindAttribute(attrs, "media-source-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-source-supported", (int)(sizeof(media_source_supported) / sizeof(media_source_supported[0])), NULL, media_source_supported);
+ /* media-top-margin-supported */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin-supported", 635);
-/*
- * 'make_ppd_attributes()' - Make a temporary IPP attributes file from a PPD.
- */
+ /* media-type-supported */
+ if (!ippFindAttribute(attrs, "media-type-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-type-supported", (int)(sizeof(media_type_supported) / sizeof(media_type_supported[0])), NULL, media_type_supported);
-static char * /* O - Temporary filename or `NULL` */
-make_ppd_attributes(const char *ppdfile,/* I - PPD filename */
- char *buffer, /* I - Temporary filename buffer */
- size_t bufsize) /* I - Size of buffer */
-{
-}
+ /* multiple-document-handling-supported */
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "multiple-document-handling-supported", sizeof(multiple_document_handling) / sizeof(multiple_document_handling[0]), NULL, multiple_document_handling);
+ /* multiple-document-jobs-supported */
+ ippAddBoolean(attrs, IPP_TAG_PRINTER, "multiple-document-jobs-supported", 0);
-/*
- * 'make_std_attributes()' - Make a temporary IPP attributes file from the old
- * ippserver options.
- */
+ /* multiple-operation-time-out */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "multiple-operation-time-out", 60);
-static char * /* O - Temporary filename or `NULL` */
-make_std_attributes(
- const char *make, /* I - Manufacturer name */
- const char *model, /* I - Model name */
- int ppm, /* I - pages-per-minute */
- int ppm_color, /* I - pages-per-minute-color */
- int duplex, /* I - Duplex support? */
- char *buffer, /* I - Temporary filename buffer */
- size_t bufsize) /* I - Size of buffer */
-{
+ /* multiple-operation-time-out-action */
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "multiple-operation-time-out-action", NULL, "abort-job");
+
+ /* natural-language-configured */
+ ippAddString(attrs, IPP_TAG_PRINTER,
+ IPP_CONST_TAG(IPP_TAG_LANGUAGE),
+ "natural-language-configured", NULL, "en");
+
+ /* number-up-default */
+ if (!ippFindAttribute(attrs, "number-up-default", IPP_TAG_ZERO))
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "number-up-default", 1);
+
+ /* number-up-supported */
+ if (!ippFindAttribute(attrs, "number-up-supported", IPP_TAG_ZERO))
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "number-up-supported", 1);
+
+ /* operations-supported */
+ ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "operations-supported", sizeof(ops) / sizeof(ops[0]), ops);
+
+ /* orientation-requested-default */
+ if (!ippFindAttribute(attrs, "orientation-requested-default", IPP_TAG_ZERO))
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, "orientation-requested-default", 0);
+
+ /* orientation-requested-supported */
+ if (!ippFindAttribute(attrs, "orientation-requested-supported", IPP_TAG_ZERO))
+ ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "orientation-requested-supported", 4, orients);
+
+ /* output-bin-default */
+ if (!ippFindAttribute(attrs, "output-bin-default", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "output-bin-default", NULL, "face-down");
+
+ /* output-bin-supported */
+ if (!ippFindAttribute(attrs, "output-bin-supported", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "output-bin-supported", NULL, "face-down");
+
+ /* overrides-supported */
+ if (!ippFindAttribute(attrs, "overrides-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "overrides-supported", (int)(sizeof(overrides) / sizeof(overrides[0])), NULL, overrides);
+
+ /* page-ranges-supported */
+ if (!ippFindAttribute(attrs, "page-ranges-supported", IPP_TAG_ZERO))
+ ippAddBoolean(attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1);
+
+ /* pages-per-minute */
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "pages-per-minute", ppm);
+
+ /* pages-per-minute-color */
+ if (ppm_color > 0)
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "pages-per-minute-color", ppm_color);
+
+ /* pdl-override-supported */
+ if (!ippFindAttribute(attrs, "pdl-override-supported", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "pdl-override-supported", NULL, "attempted");
+
+ /* preferred-attributes-supported */
+ ippAddBoolean(attrs, IPP_TAG_PRINTER, "preferred-attributes-supported", 0);
+
+ /* print-color-mode-default */
+ if (!ippFindAttribute(attrs, "print-color-mode-default", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-color-mode-default", NULL, "auto");
+
+ /* print-color-mode-supported */
+ if (!ippFindAttribute(attrs, "print-color-mode-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-color-mode-supported", (int)(sizeof(print_color_mode_supported) / sizeof(print_color_mode_supported[0])), NULL, print_color_mode_supported);
+
+ /* print-content-optimize-default */
+ if (!ippFindAttribute(attrs, "print-content-optimize-default", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-content-optimize-default", NULL, "auto");
+
+ /* print-content-optimize-supported */
+ if (!ippFindAttribute(attrs, "print-content-optimize-supported", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-content-optimize-supported", NULL, "auto");
+
+ /* print-rendering-intent-default */
+ if (!ippFindAttribute(attrs, "print-rendering-intent-default", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-rendering-intent-default", NULL, "auto");
+
+ /* print-rendering-intent-supported */
+ if (!ippFindAttribute(attrs, "print-rendering-intent-supported", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-rendering-intent-supported", NULL, "auto");
+
+ /* print-quality-default */
+ if (!ippFindAttribute(attrs, "print-quality-default", IPP_TAG_ZERO))
+ ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "print-quality-default", IPP_QUALITY_NORMAL);
+
+ /* print-quality-supported */
+ if (!ippFindAttribute(attrs, "print-quality-supported", IPP_TAG_ZERO))
+ ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "print-quality-supported", (int)(sizeof(print_quality_supported) / sizeof(print_quality_supported[0])), print_quality_supported);
+
+ /* printer-device-id */
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-device-id", NULL, device_id);
+
+ /* printer-make-and-model */
+ snprintf(make_model, sizeof(make_model), "%s %s", make, model);
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-make-and-model", NULL, make_model);
+
+ /* printer-resolution-default */
+ if (!ippFindAttribute(attrs, "printer-resolution-default", IPP_TAG_ZERO))
+ ippAddResolution(attrs, IPP_TAG_PRINTER, "printer-resolution-default", IPP_RES_PER_INCH, 600, 600);
+
+ /* printer-resolution-supported */
+ if (!ippFindAttribute(attrs, "printer-resolutions-supported", IPP_TAG_ZERO))
+ ippAddResolution(attrs, IPP_TAG_PRINTER, "printer-resolution-supported", IPP_RES_PER_INCH, 600, 600);
+
+ /* printer-supply-description */
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_TEXT), "printer-supply-description", (int)(sizeof(printer_supplies) / sizeof(printer_supplies[0])), NULL, printer_supplies);
+
+ /* pwg-raster-document-xxx-supported */
+ for (i = 0; i < num_formats; i ++)
+ if (!strcasecmp(formats[i], "image/pwg-raster"))
+ break;
+
+ if (i < num_formats)
+ {
+ if (!ippFindAttribute(attrs, "pwg-raster-document-resolution-supported", IPP_TAG_ZERO))
+ ippAddResolutions(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);
+ if (!ippFindAttribute(attrs, "pwg-raster-document-sheet-back", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "pwg-raster-document-sheet-back", NULL, "normal");
+ if (!ippFindAttribute(attrs, "pwg-raster-document-type-supported", IPP_TAG_ZERO))
+ ippAddStrings(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);
+ }
+
+ /* sides-default */
+ if (!ippFindAttribute(attrs, "sides-default", IPP_TAG_ZERO))
+ ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "sides-default", NULL, "one-sided");
+
+ /* sides-supported */
+ if (!ippFindAttribute(attrs, "sides-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "sides-supported", duplex ? 3 : 1, NULL, sides_supported);
+
+ /* urf-supported */
+ for (i = 0; i < num_formats; i ++)
+ if (!strcasecmp(formats[i], "image/urf"))
+ break;
+
+ if (i < num_formats && !ippFindAttribute(attrs, "urf-supported", IPP_TAG_ZERO))
+ ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "urf-supported", (int)(sizeof(urf_supported) / sizeof(urf_supported[0])) - !duplex, NULL, urf_supported);
+
+ return (attrs);
}
@@ -5099,7 +5279,7 @@ make_std_attributes(
static int /* O - Number of options */
parse_options(ippeve_client_t *client, /* I - Client */
- cups_option_t **options) /* O - Options */
+ cups_option_t **options)/* O - Options */
{
char *name, /* Name */
*value, /* Value */