summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2019-06-05 08:09:40 +0200
committerDidier Raboud <odyx@debian.org>2019-06-05 08:09:40 +0200
commit40112f408f1faac0e4aef355a2277a5a0de2c1a8 (patch)
treea9b683ce7bda9eb6f4dce52ae17e7165f6ea51b8
parent5a0f071ca4c281d62f712a963a7b09bf79298a24 (diff)
New upstream version 1.24.0
-rw-r--r--INSTALL2
-rw-r--r--Makefile.am10
-rw-r--r--Makefile.in26
-rw-r--r--NEWS42
-rw-r--r--README2
-rw-r--r--backend/implicitclass.c281
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac2
-rw-r--r--cupsfilters/pdftoippprinter.c905
-rw-r--r--cupsfilters/pdftoippprinter.h7
-rw-r--r--cupsfilters/ppdgenerator.c1824
-rw-r--r--cupsfilters/ppdgenerator.h31
-rw-r--r--utils/cups-browsed.c4199
13 files changed, 5750 insertions, 1601 deletions
diff --git a/INSTALL b/INSTALL
index c29799034..6e16563db 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-INSTALL - OpenPrinting CUPS Filters v1.23.0 - 2019-05-16
+INSTALL - OpenPrinting CUPS Filters v1.24.0 - 2019-06-03
--------------------------------------------------------
This file describes how to compile and install OpenPrinting CUPS
diff --git a/Makefile.am b/Makefile.am
index 20e1d2f4b..8e586b1d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,8 +68,10 @@ beh_CFLAGS = $(CUPS_CFLAGS)
implicitclass_SOURCES = \
backend/backend-private.h \
backend/implicitclass.c
-implicitclass_LDADD = $(CUPS_LIBS)
-implicitclass_CFLAGS = $(CUPS_CFLAGS)
+implicitclass_LDADD = $(CUPS_LIBS)\
+ libcupsfilters.la
+implicitclass_CFLAGS = $(CUPS_CFLAGS)\
+ -I$(srcdir)/cupsfilters/
test1284_SOURCES = \
backend/backend-private.h \
@@ -143,7 +145,8 @@ pkgfiltersinclude_DATA = \
cupsfilters/driver.h \
cupsfilters/image.h \
cupsfilters/raster.h \
- cupsfilters/ppdgenerator.h
+ cupsfilters/ppdgenerator.h \
+ cupsfilters/pdftoippprinter.h
lib_LTLIBRARIES = libcupsfilters.la
@@ -176,6 +179,7 @@ libcupsfilters_la_SOURCES = \
cupsfilters/colormanager.c \
cupsfilters/dither.c \
cupsfilters/image.c \
+ cupsfilters/pdftoippprinter.c \
cupsfilters/image-bmp.c \
cupsfilters/image-colorspace.c \
cupsfilters/image-gif.c \
diff --git a/Makefile.in b/Makefile.in
index d02736bdc..24ad9c355 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -260,6 +260,7 @@ am_libcupsfilters_la_OBJECTS = libcupsfilters_la-attr.lo \
libcupsfilters_la-check.lo libcupsfilters_la-cmyk.lo \
libcupsfilters_la-colord.lo libcupsfilters_la-colormanager.lo \
libcupsfilters_la-dither.lo libcupsfilters_la-image.lo \
+ libcupsfilters_la-pdftoippprinter.lo \
libcupsfilters_la-image-bmp.lo \
libcupsfilters_la-image-colorspace.lo \
libcupsfilters_la-image-gif.lo libcupsfilters_la-image-jpeg.lo \
@@ -376,7 +377,7 @@ imagetoraster_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am_implicitclass_OBJECTS = implicitclass-implicitclass.$(OBJEXT)
implicitclass_OBJECTS = $(am_implicitclass_OBJECTS)
-implicitclass_DEPENDENCIES = $(am__DEPENDENCIES_1)
+implicitclass_DEPENDENCIES = $(am__DEPENDENCIES_1) libcupsfilters.la
implicitclass_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(implicitclass_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
@@ -619,6 +620,7 @@ am__depfiles_remade = ./$(DEPDIR)/aglfn13.Plo \
./$(DEPDIR)/libcupsfilters_la-image.Plo \
./$(DEPDIR)/libcupsfilters_la-lut.Plo \
./$(DEPDIR)/libcupsfilters_la-pack.Plo \
+ ./$(DEPDIR)/libcupsfilters_la-pdftoippprinter.Plo \
./$(DEPDIR)/libcupsfilters_la-ppdgenerator.Plo \
./$(DEPDIR)/libcupsfilters_la-raster.Plo \
./$(DEPDIR)/libcupsfilters_la-rgb.Plo \
@@ -1262,8 +1264,12 @@ implicitclass_SOURCES = \
backend/backend-private.h \
backend/implicitclass.c
-implicitclass_LDADD = $(CUPS_LIBS)
-implicitclass_CFLAGS = $(CUPS_CFLAGS)
+implicitclass_LDADD = $(CUPS_LIBS)\
+ libcupsfilters.la
+
+implicitclass_CFLAGS = $(CUPS_CFLAGS)\
+ -I$(srcdir)/cupsfilters/
+
test1284_SOURCES = \
backend/backend-private.h \
backend/ieee1284.c \
@@ -1326,7 +1332,8 @@ pkgfiltersinclude_DATA = \
cupsfilters/driver.h \
cupsfilters/image.h \
cupsfilters/raster.h \
- cupsfilters/ppdgenerator.h
+ cupsfilters/ppdgenerator.h \
+ cupsfilters/pdftoippprinter.h
lib_LTLIBRARIES = libcupsfilters.la libfontembed.la
# testcmyk # fails as it opens some image.ppm which is nowerhe to be found.
@@ -1349,6 +1356,7 @@ libcupsfilters_la_SOURCES = \
cupsfilters/colormanager.c \
cupsfilters/dither.c \
cupsfilters/image.c \
+ cupsfilters/pdftoippprinter.c \
cupsfilters/image-bmp.c \
cupsfilters/image-colorspace.c \
cupsfilters/image-gif.c \
@@ -2859,6 +2867,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-image.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-lut.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-pack.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-pdftoippprinter.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-ppdgenerator.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-raster.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcupsfilters_la-rgb.Plo@am__quote@ # am--include-marker
@@ -3002,6 +3011,13 @@ libcupsfilters_la-image.lo: cupsfilters/image.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-image.lo `test -f 'cupsfilters/image.c' || echo '$(srcdir)/'`cupsfilters/image.c
+libcupsfilters_la-pdftoippprinter.lo: cupsfilters/pdftoippprinter.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-pdftoippprinter.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-pdftoippprinter.Tpo -c -o libcupsfilters_la-pdftoippprinter.lo `test -f 'cupsfilters/pdftoippprinter.c' || echo '$(srcdir)/'`cupsfilters/pdftoippprinter.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-pdftoippprinter.Tpo $(DEPDIR)/libcupsfilters_la-pdftoippprinter.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cupsfilters/pdftoippprinter.c' object='libcupsfilters_la-pdftoippprinter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -c -o libcupsfilters_la-pdftoippprinter.lo `test -f 'cupsfilters/pdftoippprinter.c' || echo '$(srcdir)/'`cupsfilters/pdftoippprinter.c
+
libcupsfilters_la-image-bmp.lo: cupsfilters/image-bmp.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcupsfilters_la_CFLAGS) $(CFLAGS) -MT libcupsfilters_la-image-bmp.lo -MD -MP -MF $(DEPDIR)/libcupsfilters_la-image-bmp.Tpo -c -o libcupsfilters_la-image-bmp.lo `test -f 'cupsfilters/image-bmp.c' || echo '$(srcdir)/'`cupsfilters/image-bmp.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcupsfilters_la-image-bmp.Tpo $(DEPDIR)/libcupsfilters_la-image-bmp.Plo
@@ -5410,6 +5426,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcupsfilters_la-image.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-lut.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-pack.Plo
+ -rm -f ./$(DEPDIR)/libcupsfilters_la-pdftoippprinter.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-ppdgenerator.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-raster.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-rgb.Plo
@@ -5590,6 +5607,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcupsfilters_la-image.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-lut.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-pack.Plo
+ -rm -f ./$(DEPDIR)/libcupsfilters_la-pdftoippprinter.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-ppdgenerator.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-raster.Plo
-rm -f ./$(DEPDIR)/libcupsfilters_la-rgb.Plo
diff --git a/NEWS b/NEWS
index 346e925ae..d8393c828 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,46 @@
-NEWS - OpenPrinting CUPS Filters v1.23.0 - 2019-05-16
+NEWS - OpenPrinting CUPS Filters v1.24.0 - 2019-06-03
-----------------------------------------------------
+CHANGES IN V1.24.0
+
+ - cups-browsed: Integration of Deepak Patankar's Google Summer
+ of Code 2018 with the main goal of clustering different
+ printers and automatically selecting the destination
+ printers by job content and option/attribute settings. All
+ changes of this release are done by Deepak as parts of his
+ project.
+ - cups-browsed, implicitclass: Support for mixed clusters of
+ remote CUPS queues and IPP network printers. For this PPD
+ files of remote CUPS queues are generated by cups-browsed
+ based on IPP queries, as for native IPP printers, the number
+ of jobs for load balancing is polled in a way that it works
+ also with native IPP printers, the implicitclass backend
+ sends jobs directky to the printer instead of re-queueing
+ them via CUPS.
+ - cups-browsed: Merge IPP attributes of several printers to
+ combined attributes for the cluster to generate the
+ cluster's PPD file, including PPD constraints for option
+ combinations not fulfillable by any of the member printers,
+ and finding reasonable, non-conflicting default settings,
+ - cups-browsed: Selection algorithm for the destination
+ printer for a job sent to the cluster. Based on the job
+ settings requested such as page size, media type, print
+ quality, ... the best most suitable printer in the cluster
+ for the job will be selected.
+ - cups-browsed, implicitclass: Filter jobs to clusters already
+ locally. Due to the fact that a cluster's member printers
+ are not exclusively non-raw CUPS queues with the complete
+ filtering framework on the remote server, but also native
+ IPP printers, we need to support generic driverless printers
+ as destination. So we cannot pass on the input data
+ unfiltered but need to filter locally. We let the cluster's
+ PPD file emulate a PDF printer, letting the local CUPS queue
+ of the cluster run pdftopdf and any pre-filters to turn the
+ input into PDF and we let the implicitclass backend turn PDF
+ into a format understood by the destination printer,
+ supporting the 4 formats of driverless IPP printing: PDF,
+ PWG Raster, Apple Raster, PCLm.
+
CHANGES IN V1.23.0
- pdftops, mupdftoraster: Let pdftops call mutool directly and
diff --git a/README b/README
index 060234890..2754aa60f 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-README - OpenPrinting CUPS Filters v1.23.0 - 2019-05-16
+README - OpenPrinting CUPS Filters v1.24.0 - 2019-06-03
-------------------------------------------------------
Looking for compile instructions? Read the file "INSTALL.txt"
diff --git a/backend/implicitclass.c b/backend/implicitclass.c
index 39aa4c0f5..2268d9e70 100644
--- a/backend/implicitclass.c
+++ b/backend/implicitclass.c
@@ -22,6 +22,12 @@
#include "backend-private.h"
#include <cups/array.h>
#include <ctype.h>
+#include <cups/array.h>
+#include <ctype.h>
+#include <cups/cups.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <cupsfilters/pdftoippprinter.h>
/*
* Local globals...
@@ -31,14 +37,81 @@
the current job */
#define CUPS_BROWSED_DEST_PRINTER "cups-browsed-dest-printer"
-static int job_canceled = 0;
- /* Set to 1 on SIGTERM */
+static int job_canceled = 0; /* Set to 1 on SIGTERM */
/*
* Local functions... */
static void sigterm_handler(int sig);
+#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
+#define HAVE_CUPS_1_6 1
+#endif
+
+#ifndef HAVE_CUPS_1_6
+int
+ippGetInteger(ipp_attribute_t *attr,
+ int element)
+{
+ return (attr->values[element].integer);
+}
+#endif
+
+
+int /* O - Next delay value */
+next_delay(int current, /* I - Current delay value or 0 */
+ int *previous) /* IO - Previous delay value */
+{
+ int next; /* Next delay value */
+ if (current > 0) {
+ next = (current + *previous) % 12;
+ *previous = next < current ? 0 : current;
+ } else {
+ next = 1;
+ *previous = 0;
+ }
+ return (next);
+}
+
+/*
+ * Set an option in a string of options
+ */
+
+void /* O - 0 on success, 1 on error */
+set_option_in_str(char *buf, /* I - Buffer with option list string */
+ int buflen, /* I - Length of buffer */
+ const char *option, /* I - Option to change/add */
+ const char *value) /* I - New value for option, NULL
+ removes option */
+{
+ char *p1, *p2;
+
+ if (!buf || buflen == 0 || !option)
+ return;
+ /* Remove any occurrence of option in the string */
+ p1 = buf;
+ while (*p1 != '\0' && (p2 = strcasestr(p1, option)) != NULL) {
+ if (p2 > buf && *(p2 - 1) != ' ' && *(p2 - 1) != '\t') {
+ p1 = p2 + 1;
+ continue;
+ }
+ p1 = p2 + strlen(option);
+ if (*p1 != '=' && *p1 != ' ' && *p1 != '\t' && *p1 != '\0')
+ continue;
+ while (*p1 != ' ' && *p1 != '\t' && *p1 != '\0') p1 ++;
+ while ((*p1 == ' ' || *p1 == '\t') && *p1 != '\0') p1 ++;
+ memmove(p2, p1, strlen(buf) - (buf - p1) + 1);
+ p1 = p2;
+ }
+ /* Add option=value to the end of the string */
+ if (!value)
+ return;
+ p1 = buf + strlen(buf);
+ *p1 = ' ';
+ p1 ++;
+ snprintf(p1, buflen - (buf - p1), "%s=%s", option, value);
+ buf[buflen - 1] = '\0';
+}
/*
* 'main()' - Browse for printers.
@@ -49,16 +122,23 @@ main(int argc, /* I - Number of command-line args */
char *argv[]) /* I - Command-line arguments */
{
const char *device_uri; /* URI with which we were called */
- char scheme[32], username[10], queue_name[1024], resource[10];
+ char scheme[64], username[32], queue_name[1024], resource[32],
+ printer_uri[1024],document_format[256],resolution[16];
int port, status;
const char *ptr1 = NULL;
- char *ptr2;
+ char *ptr2,*ptr3,*ptr4;
const char *job_id;
+ char *filename, /* PDF file to convert */
+ tempfile[1024],
+ tempfile_filter[1024]; /* Temporary file */
int i;
char dest_host[1024]; /* Destination host */
ipp_t *request, *response;
ipp_attribute_t *attr;
+ int bytes; /* Bytes copied */
char uri[HTTP_MAX_URI];
+ char *argv_nt[7];
+ int outbuflen,filefd,exit_status,dup_status;
static const char *pattrs[] =
{
"printer-defaults"
@@ -89,10 +169,8 @@ main(int argc, /* I - Number of command-line args */
* Check command-line...
*/
- if (argc >= 6)
- {
- if ((device_uri = getenv("DEVICE_URI")) == NULL)
- {
+ if (argc >= 6) {
+ if ((device_uri = getenv("DEVICE_URI")) == NULL) {
if (!argv || !argv[0] || !strchr(argv[0], ':'))
return (-1);
@@ -149,7 +227,8 @@ main(int argc, /* I - Number of command-line args */
if (ptr1 != NULL)
break;
}
- fprintf(stderr, "DEBUG: Read " CUPS_BROWSED_DEST_PRINTER " option: %s\n", ptr1);
+ fprintf(stderr, "DEBUG: Read " CUPS_BROWSED_DEST_PRINTER " option: %s\n",
+ ptr1);
if (ptr1 == NULL)
goto failed;
/* Destination host is between double quotes, as double quotes are
@@ -167,15 +246,11 @@ main(int argc, /* I - Number of command-line args */
ptr1 ++;
/* Read destination host name (or message) and check whether it is
complete (second double quote) */
- strncpy(dest_host, ptr1, sizeof(dest_host));
- ptr1 = dest_host;
if ((ptr2 = strchr(ptr1, '"')) != NULL) {
*ptr2 = '\0';
- ippDelete(response);
break;
}
failed:
- ippDelete(response);
/* Pause half a second before next attempt */
usleep(500000);
}
@@ -200,33 +275,16 @@ main(int argc, /* I - Number of command-line args */
return (CUPS_BACKEND_RETRY_CURRENT);
} else {
/* We have the destination host name now, do the job */
- char server_str[1024];
const char *title;
int num_options = 0;
cups_option_t *options = NULL;
- int fd, job_id;
+ int fd;
char buffer[8192];
-
- ptr2 = strrchr(dest_host, '/');
- if (ptr2) {
- *ptr2 = '\0';
- ptr2 ++;
- } else
- ptr2 = queue_name;
- fprintf(stderr, "DEBUG: Received destination host name from cups-browsed: %s\n",
- dest_host);
- fprintf(stderr, "DEBUG: Received destination queue name from cups-browsed: %s\n",
- ptr2);
-
- /* Instead of feeding the job into the IPP backend, we re-print it into
- the server's CUPS queue. This way the job gets spooled on the server
- and we are not blocked until the job is printed. So a subsequent job
- will be immediately processed and sent out to another server */
- /* Set destination server */
- snprintf(server_str, sizeof(server_str), "%s", dest_host);
- cupsSetServer(server_str);
- /* Parse the command line option and prepare them for the new print
+ fprintf(stderr, "DEBUG: Received destination host name from cups-browsed: printer-uri %s\n",
+ ptr1);
+
+ /* Parse the command line options and prepare them for the new print
job */
cupsSetUser(argv[2]);
title = argv[3];
@@ -246,55 +304,123 @@ main(int argc, /* I - Number of command-line args */
fd = open(argv[6], O_RDONLY);
else
fd = 0; /* stdin */
-
- /* Queue the job directly on the server */
- if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, ptr2,
- title ? title : "(stdin)",
- num_options, options)) > 0) {
- http_status_t status; /* Write status */
- const char *format; /* Document format */
- ssize_t bytes; /* Bytes read */
-
- if (cupsGetOption("raw", num_options, options))
- format = CUPS_FORMAT_RAW;
- else if ((format = cupsGetOption("document-format", num_options,
- options)) == NULL)
- format = CUPS_FORMAT_AUTO;
-
- status = cupsStartDocument(CUPS_HTTP_DEFAULT, ptr2, job_id, NULL,
- format, 1);
-
- while (status == HTTP_CONTINUE &&
- (bytes = read(fd, buffer, sizeof(buffer))) > 0)
- status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes);
-
- if (status != HTTP_CONTINUE) {
- fprintf(stderr, "ERROR: %s: Unable to queue the print data - %s. Retrying.",
- argv[0], httpStatus(status));
- cupsFinishDocument(CUPS_HTTP_DEFAULT, ptr2);
- cupsCancelJob2(CUPS_HTTP_DEFAULT, ptr2, job_id, 0);
- return (CUPS_BACKEND_RETRY);
- }
- if (cupsFinishDocument(CUPS_HTTP_DEFAULT, ptr2) != IPP_OK) {
- fprintf(stderr, "ERROR: %s: Unable to complete the job - %s. Retrying.",
- argv[0], cupsLastErrorString());
- cupsCancelJob2(CUPS_HTTP_DEFAULT, ptr2, job_id, 0);
- return (CUPS_BACKEND_RETRY);
+ /* Finding the document format in which the pdftoippprinter will
+ convert the pdf file */
+ if ((ptr3 = strchr(ptr1, ' ')) != NULL) {
+ *ptr3='\0';
+ ptr3++;
+ }
+
+ /* Finding the resolution requested for the job*/
+ if ((ptr4 = strchr(ptr3, ' ')) != NULL) {
+ *ptr4='\0';
+ ptr4++;
+ }
+
+ strncpy(printer_uri, ptr1, sizeof(printer_uri));
+ strncpy(document_format, ptr3, sizeof(document_format));
+ strncpy(resolution, ptr4, sizeof(resolution));
+
+ fprintf(stderr,"DEBUG: Received job for the printer with the destination uri - %s, Final-document format for the printer - %s and requested resolution - %s\n",
+ printer_uri, document_format, resolution);
+
+ /* We need to send modified arguments to the IPP backend */
+ if (argc == 6) {
+ /* Copy stdin to a temp file...*/
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0){
+ fprintf(stderr,"Debug: Can't Read PDF file.\n");
+ return CUPS_BACKEND_FAILED;
}
+ fprintf(stderr, "Debug: implicitclass - copying to temp print file \"%s\"\n",
+ tempfile);
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ bytes = write(fd, buffer, bytes);
+ close(fd);
+ filename = tempfile;
+ } else{
+ /** Use the filename on the command-line...*/
+ filename = argv[6];
+ tempfile[0] = '\0';
}
- if (job_id < 1) {
- fprintf(stderr, "ERROR: %s: Unable to create job - %s. Retrying.",
- argv[0], cupsLastErrorString());
- return (CUPS_BACKEND_RETRY);
+ /* Copying the argument to a new char** which will be sent to the filter
+ and the ipp backend*/
+ for (i = 0; i < 5; i++)
+ argv_nt[i] = argv[i];
+
+ /* Few new options will be added to the argv[5]*/
+ outbuflen = strlen(argv[5]) + 256;
+ argv_nt[5] = calloc(outbuflen, sizeof(char));
+ strcpy(argv_nt[5], (const char*)argv[5]);
+
+ /* Filter pdftoippprinter.c will read the input from this file*/
+ argv_nt[6] = filename;
+ set_option_in_str(argv_nt[5], outbuflen, "output-format",
+ document_format);
+ set_option_in_str(argv_nt[5], outbuflen, "Resolution",resolution);
+ setenv("DEVICE_URI",printer_uri, 1);
+
+ filefd = cupsTempFd(tempfile_filter, sizeof(tempfile_filter));
+
+ /* The output of the last filter in pdftoippprinter will be
+ written to this file. We could have sent the output directly
+ to the backend, but having this temperory file will help us
+ find whether the filter worked correctly and what was the
+ document-format of the filtered output.*/
+ close(1);
+ dup_status = dup(filefd);
+ if(dup_status < 0) {
+ fprintf(stderr, "Could not write the output of pdftoippprinter printer to tmp file\n");
+ return CUPS_BACKEND_FAILED;
}
- return (CUPS_BACKEND_OK);
+ /* Calling pdftoippprinter.c filter*/
+ apply_filters(7,argv_nt);
+
+ close(filefd);
+
+ /* We will send the filtered output of the pdftoippprinter.c to
+ the IPP Backend*/
+ argv_nt[6] = tempfile_filter;
+ fprintf(stderr, "DEBUG: The filtered output of pdftoippprinter is written to file %s\n",
+ tempfile_filter);
+
+ /* Setting the final content type to the best pdl supported by
+ the printer.*/
+ if(!strcmp(document_format,"pdf"))
+ setenv("FINAL_CONTENT_TYPE", "application/pdf", 1);
+ else if(!strcmp(document_format,"raster"))
+ setenv("FINAL_CONTENT_TYPE", "image/pwg-raster", 1);
+ else if(!strcmp(document_format,"apple-raster"))
+ setenv("FINAL_CONTENT_TYPE", "image/urf", 1);
+ else if(!strcmp(document_format,"pclm"))
+ setenv("FINAL_CONTENT_TYPE", "application/PCLm", 1);
+ else if(!strcmp(document_format,"pclxl"))
+ setenv("FINAL_CONTENT_TYPE", "application/vnd.hp-pclxl", 1);
+ else if(!strcmp(document_format,"pcl"))
+ setenv("FINAL_CONTENT_TYPE", "application/pcl", 1);
+
+ ippDelete(response);
+
+ /* The implicitclass backend will send the job directly to the
+ ipp backend*/
+ pid_t pid = fork();
+ if ( pid == 0 ) {
+ fprintf(stderr, "DEBUG: Started IPP Backend with pid: %d\n",getpid());
+ execv("/usr/lib/cups/backend/ipp",argv_nt);
+ } else {
+ int status;
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status)) {
+ exit_status = WEXITSTATUS(status);
+ fprintf(stderr, "DEBUG: The IPP Backend exited with the status %d\n",
+ exit_status);
+ }
+ return exit_status;
+ }
}
- }
- else if (argc != 1)
- {
+ } else if (argc != 1) {
fprintf(stderr,
"Usage: %s job-id user title copies options [file]",
argv[0]);
@@ -323,4 +449,3 @@ sigterm_handler(int sig) /* I - Signal number (unused) */
else
job_canceled = 1;
}
-
diff --git a/configure b/configure
index 33d69747d..ff1e3d4ab 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for cups-filters 1.23.0.
+# Generated by GNU Autoconf 2.69 for cups-filters 1.24.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='cups-filters'
PACKAGE_TARNAME='cups-filters'
-PACKAGE_VERSION='1.23.0'
-PACKAGE_STRING='cups-filters 1.23.0'
+PACKAGE_VERSION='1.24.0'
+PACKAGE_STRING='cups-filters 1.24.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1500,7 +1500,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures cups-filters 1.23.0 to adapt to many kinds of systems.
+\`configure' configures cups-filters 1.24.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1571,7 +1571,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of cups-filters 1.23.0:";;
+ short | recursive ) echo "Configuration of cups-filters 1.24.0:";;
esac
cat <<\_ACEOF
@@ -1801,7 +1801,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-cups-filters configure 1.23.0
+cups-filters configure 1.24.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2439,7 +2439,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by cups-filters $as_me 1.23.0, which was
+It was created by cups-filters $as_me 1.24.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3474,7 +3474,7 @@ fi
# Define the identity of the package.
PACKAGE='cups-filters'
- VERSION='1.23.0'
+ VERSION='1.24.0'
cat >>confdefs.h <<_ACEOF
@@ -21794,7 +21794,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by cups-filters $as_me 1.23.0, which was
+This file was extended by cups-filters $as_me 1.24.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -21860,7 +21860,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-cups-filters config.status 1.23.0
+cups-filters config.status 1.24.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 9a0248c20..b9d3b2f7a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@ AC_PREREQ([2.65])
# Version informations
# ====================
m4_define([cups_filters_version_major],[1])
-m4_define([cups_filters_version_minor],[23])
+m4_define([cups_filters_version_minor],[24])
m4_define([cups_filters_version_micro],[0])
m4_define([cups_filters_version],[cups_filters_version_major.cups_filters_version_minor.cups_filters_version_micro])
diff --git a/cupsfilters/pdftoippprinter.c b/cupsfilters/pdftoippprinter.c
new file mode 100644
index 000000000..9bf0e4eb4
--- /dev/null
+++ b/cupsfilters/pdftoippprinter.c
@@ -0,0 +1,905 @@
+/*
+ * pdftoippprinter.c
+ *
+ * Function to convert PDF into PWG/Apple Raster and PCLm for printing
+ * on driverless IPP printers.
+ *
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2011-2013 by Till Kamppeter
+ *
+ * Contents:
+ *
+ * apply_filters() - Main function...
+ * cancel_job() - Flag the job as canceled.
+ * filter_present() - Is the requested filter actually installed?
+ * compare_pids() - Compare process IDs for sorting PID list
+ * exec_filter() - Execute a filter process
+ * exec_filters() - Execute a filter chain
+ * open_pipe() - Create a pipe to transfer data from filter to filter
+ * get_option_in_str() - Get an option value from a string like argv[5]
+ * set_option_in_str() - Set an option value in a string like argv[5]
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/file.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <cupsfilters/image-private.h>
+
+#define MAX_CHECK_COMMENT_LINES 20
+
+/*
+ * Type definitions
+ */
+
+typedef unsigned output_format_t;
+enum output_format_e {PDF = 0, POSTSCRIPT = 1, PWGRASTER = 2, PCLXL = 3, PCL = 4, APPLERASTER = 5, PCLM = 6};
+typedef struct filter_pid_s /* Filter in filter chain */
+{
+ char *name; /* Filter executable name */
+ int pid; /* PID of filter process */
+} filter_pid_t;
+
+/*
+ * Local functions...
+ */
+
+static void cancel_job(int sig);
+static int filter_present(const char *filter);
+static int compare_pids(filter_pid_t *a, filter_pid_t *b);
+static int exec_filter(const char *filter, char **argv,
+ int infd, int outfd);
+static int exec_filters(cups_array_t *filters, char **argv);
+static int open_pipe(int *fds);
+static char* get_option_in_str(char *buf, const char *option,
+ int return_value);
+static void set_option_in_str(char *buf, int buflen,
+ const char *option,
+ const char *value);
+
+/*
+ * Local globals...
+ */
+
+static int job_canceled = 0;
+
+
+/*
+ * 'apply_filters()' - Main function...
+ */
+
+int
+apply_filters(int argc, char *argv[])
+{
+ int i; /* Looping var */
+ output_format_t output_format; /* Output format */
+ int fd = 0; /* Copy file descriptor */
+ char *filename, /* PDF file to convert */
+ tempfile[1024]; /* Temporary file */
+ char buffer[8192]; /* Copy buffer */
+ int bytes; /* Bytes copied */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ const char *val; /* Option value */
+ char *argv_nt[8]; /* NULL-terminated array of the command
+ line arguments */
+ int optbuflen;
+ cups_array_t *filter_chain; /* Filter chain to execute */
+ int exit_status = 0; /* Exit status */
+ int color_printing; /* Do we print in color? */
+ char *filter, *p;
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+ static const char * const color_mode_option_names[] =
+ { /* Possible names for a color mode option */
+ "pwg-raster-document-type",
+ "PwgRasterDocumentType",
+ "print-color-mode",
+ "PrintColorMode",
+ "color-space",
+ "ColorSpace",
+ "color-model",
+ "ColorModel",
+ NULL
+ };
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Ignore broken pipe signals...
+ */
+
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Make sure we have the right number of arguments for CUPS!
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * Register a signal handler to cleanly cancel a job.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, cancel_job);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = cancel_job;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, cancel_job);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Copy stdin if needed...
+ */
+
+ if (argc == 6) {
+ /*
+ * Copy stdin to a temp file...
+ */
+
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) {
+ perror("DEBUG: Unable to copy PDF file");
+ return (1);
+ }
+
+ fprintf(stderr,
+ "DEBUG: sys5ippprinter - copying to temp print file \"%s\"\n",
+ tempfile);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ bytes = write(fd, buffer, bytes);
+
+ close(fd);
+
+ filename = tempfile;
+ } else {
+ /*
+ * Use the filename on the command-line...
+ */
+
+ filename = argv[6];
+ tempfile[0] = '\0';
+ }
+
+ /*
+ * Get the options from the fifth command line argument
+ */
+
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+ * Copy the command line arguments into a NULL-terminated array
+ */
+
+ for (i = 0; i < 5; i++)
+ argv_nt[i] = argv[i];
+ /* We copy the contents of argv[5] into a somewhat larger buffer so that
+ we can manipulate it */
+ optbuflen = strlen(argv[5]) + 256;
+ argv_nt[5] = calloc(optbuflen, sizeof(char));
+ strcpy(argv_nt[5], (const char*)argv[5]);
+ argv_nt[6] = filename;
+ argv_nt[7] = NULL;
+
+ /*
+ * Create filter chain
+ */
+
+ filter_chain = cupsArrayNew(NULL, NULL);
+
+ /*
+ * Add the gziptoany filter if installed
+ */
+
+ if (filter_present("gziptoany"))
+ cupsArrayAdd(filter_chain, "gziptoany");
+
+ /*
+ * Select the output format: PDF, PostScript, PWG Raster, PCL-XL, and
+ * PCL 5c/e
+ * Add the needed filters to the filter chain
+ */
+
+ if ((val = cupsGetOption("output-format", num_options, options)) != NULL) {
+ if (strcasestr(val, "raster")) {
+ output_format = PWGRASTER;
+ /* PWG Raster output */
+ set_option_in_str(argv_nt[5], optbuflen, "MediaClass", NULL);
+ set_option_in_str(argv_nt[5], optbuflen, "media-class", "pwg");
+ /* Page logging into page_log is not done by gstoraster/pdftoraster,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ if (filter_present("gstoraster") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ cupsArrayAdd(filter_chain, "gstoraster");
+ else {
+ fprintf(stderr,
+ "DEBUG: Filter gstoraster or Ghostscript (%s) missing for \"output-format=%s\", using pdftoraster.\n",
+ CUPS_GHOSTSCRIPT, val);
+ if (filter_present("pdftoraster"))
+ cupsArrayAdd(filter_chain, "pdftoraster");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter pdftoraster missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ setenv("FINAL_CONTENT_TYPE", "pwg", 1);
+ }
+ } else if (strcasestr(val, "apple-raster")) {
+ output_format = APPLERASTER;
+ /* PWG Raster output */
+ set_option_in_str(argv_nt[5], optbuflen, "MediaClass", NULL);
+ set_option_in_str(argv_nt[5], optbuflen, "media-class", "");
+ /* Page logging into page_log is not done by gstoraster/pdftoraster,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ if (filter_present("gstoraster") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ cupsArrayAdd(filter_chain, "gstoraster");
+ else {
+ fprintf(stderr,
+ "DEBUG: Filter gstoraster or Ghostscript (%s) missing for \"output-format=%s\", using pdftoraster.\n",
+ CUPS_GHOSTSCRIPT, val);
+ if (filter_present("pdftoraster"))
+ cupsArrayAdd(filter_chain, "pdftoraster");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter pdftoraster missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ if (filter_present("rastertopwg"))
+ cupsArrayAdd(filter_chain, "rastertopwg");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter rastertopwg missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ setenv("FINAL_CONTENT_TYPE", "image/urf", 1);
+ } else if (strcasestr(val, "pdf")) {
+ output_format = PDF;
+ /* Page logging into page_log has to be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ } else if (strcasestr(val, "postscript")) {
+ output_format = POSTSCRIPT;
+ /* Page logging into page_log is done by pstops, so no need by
+ pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "off");
+ if (filter_present("pdftops")) {
+ cupsArrayAdd(filter_chain, "pdftops");
+ if (access(CUPS_GHOSTSCRIPT, X_OK) != 0) {
+ fprintf(stderr,
+ "DEBUG: Ghostscript (%s) missing for \"output-format=%s\", using Poppler's pdftops instead.\n",
+ CUPS_GHOSTSCRIPT, val);
+ set_option_in_str(argv_nt[5], optbuflen, "pdftops-renderer",
+ "pdftops");
+ } else if (access(CUPS_POPPLER_PDFTOPS, X_OK) != 0) {
+ fprintf(stderr,
+ "DEBUG: Poppler's pdftops (%s) missing for \"output-format=%s\", using Ghostscript instead.\n",
+ CUPS_POPPLER_PDFTOPS, val);
+ set_option_in_str(argv_nt[5], optbuflen, "pdftops-renderer",
+ "gs");
+ } else
+ set_option_in_str(argv_nt[5], optbuflen, "pdftops-renderer",
+ "hybrid");
+ } else {
+ fprintf(stderr,
+ "ERROR: Filter pdftops missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ } else if ((p = strcasestr(val, "pcl")) != NULL) {
+ if (!strcasecmp(p, "pclxl")) {
+ output_format = PCLXL;
+ if (filter_present("gstopxl") && access(CUPS_GHOSTSCRIPT, X_OK) == 0) {
+ cupsArrayAdd(filter_chain, "gstopxl");
+ /* Page logging into page_log is not done by gstopxl,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ } else {
+ fprintf(stderr,
+ "DEBUG: Filter gstopxl or Ghostscript (%s) missing for \"output-format=%s\", falling back to PCL 5c/e.\n",
+ CUPS_GHOSTSCRIPT, val);
+ output_format = PCL;
+ }
+ } else if (!strcasecmp(p, "pclm")) {
+ output_format = PCLM;
+ /* PWG Raster output */
+ set_option_in_str(argv_nt[5], optbuflen, "MediaClass", NULL);
+ set_option_in_str(argv_nt[5], optbuflen, "media-class", "");
+ /* Page logging into page_log is not done by gstoraster/pdftoraster,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ if (filter_present("gstoraster") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ cupsArrayAdd(filter_chain, "gstoraster");
+ else {
+ fprintf(stderr,
+ "DEBUG: Filter gstoraster or Ghostscript (%s) missing for \"output-format=%s\", using pdftoraster.\n",
+ CUPS_GHOSTSCRIPT, val);
+ if (filter_present("pdftoraster"))
+ cupsArrayAdd(filter_chain, "pdftoraster");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter pdftoraster missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ if (filter_present("rastertopclm"))
+ cupsArrayAdd(filter_chain, "rastertopclm");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter rastertopclm missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ if (!strcasecmp(p, "pclxl")) {
+ output_format = PCLXL;
+ if (filter_present("gstopxl") && access(CUPS_GHOSTSCRIPT, X_OK) == 0) {
+ cupsArrayAdd(filter_chain, "gstopxl");
+ /* Page logging into page_log is not done by gstopxl,
+ so let it be done by pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "on");
+ } else {
+ fprintf(stderr,
+ "DEBUG: Filter gstopxl or Ghostscript (%s) missing for \"output-format=%s\", falling back to PCL 5c/e.\n",
+ CUPS_GHOSTSCRIPT, val);
+ output_format = PCL;
+ }
+ } else {
+ output_format = PCL;
+ }
+ } else {
+ fprintf(stderr,
+ "ERROR: Invalid value for \"output-format\": \"%s\"\n", val);
+ exit_status = 1;
+ goto error;
+ }
+ } else {
+ fprintf(stderr,
+ "ERROR: Missing option \"output-format\".\n");
+ exit_status = 1;
+ goto error;
+ }
+ if (output_format == PCL) {
+ /* We need CUPS Raster as we want to use rastertopclx with unprintable
+ margins */
+ set_option_in_str(argv_nt[5], optbuflen, "MediaClass", NULL);
+ set_option_in_str(argv_nt[5], optbuflen, "media-class", "");
+ /* Page logging into page_log is done by rastertopclx, so no need by
+ pdftopdf */
+ set_option_in_str(argv_nt[5], optbuflen, "page-logging", "off");
+ /* Does the client send info about margins? */
+ if (!get_option_in_str(argv_nt[5], "media-left-margin", 0) &&
+ !get_option_in_str(argv_nt[5], "media-right-margin", 0) &&
+ !get_option_in_str(argv_nt[5], "media-top-margin", 0) &&
+ !get_option_in_str(argv_nt[5], "media-bottom-margin", 0)) {
+ /* Set default 12pt margins if there is no info about printer's
+ unprintable margins (100th of mm units, 12.0 * 2540.0 / 72.0 = 423.33)
+ */
+ set_option_in_str(argv_nt[5], optbuflen, "media-left-margin", "423.33");
+ set_option_in_str(argv_nt[5], optbuflen, "media-right-margin", "423.33");
+ set_option_in_str(argv_nt[5], optbuflen, "media-top-margin", "423.33");
+ set_option_in_str(argv_nt[5], optbuflen, "media-bottom-margin", "423.33");
+ }
+ /* Check whether the job is requested to be printed in color and if so,
+ set the color space to RGB as this is the best color printing support
+ in PCL 5c */
+ color_printing = 0;
+ for (i = 0; color_mode_option_names[i]; i ++) {
+ p = get_option_in_str(argv_nt[5], color_mode_option_names[i], 1);
+ if (p && (strcasestr(p, "RGB") || strcasestr(p, "CMY") ||
+ strcasestr(p, "color"))) {
+ color_printing = 1;
+ break;
+ }
+ }
+ if (color_printing == 1) {
+ /* Remove unneeded color mode options */
+ for (i = 0; color_mode_option_names[i]; i ++)
+ set_option_in_str(argv_nt[5], optbuflen, color_mode_option_names[i],
+ NULL);
+ /* Set RGB as color mode */
+ set_option_in_str(argv_nt[5], optbuflen, "print-color-mode", "RGB");
+ }
+ if (filter_present("gstoraster") && access(CUPS_GHOSTSCRIPT, X_OK) == 0)
+ cupsArrayAdd(filter_chain, "gstoraster");
+ else {
+ fprintf(stderr,
+ "DEBUG: Filter gstoraster or Ghostscript (%s) missing for \"output-format=%s\", using pdftoraster.\n",
+ CUPS_GHOSTSCRIPT, val);
+ if (filter_present("pdftoraster"))
+ cupsArrayAdd(filter_chain, "pdftoraster");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter pdftoraster missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+ if (filter_present("rastertopclx"))
+ cupsArrayAdd(filter_chain, "rastertopclx");
+ else {
+ fprintf(stderr,
+ "ERROR: Filter rastertopclx missing for \"output-format=%s\"\n",
+ val);
+ exit_status = 1;
+ goto error;
+ }
+ }
+
+ fprintf(stderr,
+ "DEBUG: Printer supports output formats: %s\nDEBUG: Using following CUPS filter chain to convert input data to the %s format:",
+ val,
+ output_format == PDF ? "PDF" :
+ (output_format == POSTSCRIPT ? "Postscript" :
+ (output_format == PWGRASTER ? "PWG Raster" :
+ (output_format == PCLXL ? "PCL XL" :
+ (output_format == PCL ? "PCL 5c/e" :
+ (output_format == APPLERASTER ? "APPLE Raster" :
+ (output_format == PCLM ? "PCLm" : "unknown")))))));
+ for (filter = (char *)cupsArrayFirst(filter_chain);
+ filter;
+ filter = (char *)cupsArrayNext(filter_chain))
+ fprintf(stderr, " %s", filter);
+ fprintf(stderr, "\n");
+
+ /*
+ * Execute the filter chain
+ */
+
+ exit_status = exec_filters(filter_chain, (char **)argv_nt);
+
+ /*
+ * Cleanup and exit...
+ */
+
+ error:
+
+ if (tempfile[0])
+ unlink(tempfile);
+
+ return (exit_status);
+}
+
+
+/*
+ * 'cancel_job()' - Flag the job as canceled.
+ */
+
+static void
+cancel_job(int sig) /* I - Signal number (unused) */
+{
+ (void)sig;
+
+ job_canceled = 1;
+}
+
+
+static int
+filter_present(const char *filter) /* I - Filter name */
+{
+ char filter_path[1024]; /* Path to filter executable */
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
+
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+
+ snprintf(filter_path, sizeof(filter_path), "%s/filter/%s",
+ cups_serverbin, filter);
+
+ if (access(filter_path, X_OK) == 0)
+ return 1;
+
+ return 0;
+}
+
+
+/*
+ * 'compare_pids()' - Compare two filter PIDs...
+ */
+
+static int /* O - Result of comparison */
+compare_pids(filter_pid_t *a, /* I - First filter */
+ filter_pid_t *b) /* I - Second filter */
+{
+ return (a->pid - b->pid);
+}
+
+
+/*
+ * 'exec_filter()' - Execute a single filter.
+ */
+
+static int /* O - Process ID or -1 on error */
+exec_filter(const char *filter, /* I - Filter to execute */
+ char **argv, /* I - Original command line args */
+ int infd, /* I - Stdin file descriptor */
+ int outfd) /* I - Stdout file descriptor */
+{
+ int pid, /* Process ID */
+ fd; /* Temporary file descriptor */
+
+ if ((pid = fork()) == 0) {
+ /*
+ * Child process goes here...
+ *
+ * Update stdin/stdout/stderr as needed...
+ */
+
+ if (infd != 0) {
+ if (infd < 0)
+ infd = open("/dev/null", O_RDONLY);
+
+ if (infd > 0) {
+ dup2(infd, 0);
+ close(infd);
+ }
+ }
+
+ if (outfd != 1) {
+ if (outfd < 0)
+ outfd = open("/dev/null", O_WRONLY);
+
+ if (outfd > 1) {
+ dup2(outfd, 1);
+ close(outfd);
+ }
+ }
+
+ /* Send stderr to the Nirwana if we are running gziptoany, as
+ gziptoany emits a false "PAGE: 1 1" */
+ if (strcasestr(filter, "gziptoany")) {
+ if ((fd = open("/dev/null", O_RDWR)) > 2) {
+ dup2(fd, 2);
+ close(fd);
+ } else
+ close(fd);
+ fcntl(2, F_SETFL, O_NDELAY);
+ }
+
+ if ((fd = open("/dev/null", O_RDWR)) > 3) {
+ dup2(fd, 3);
+ close(fd);
+ }
+ else
+ close(fd);
+ fcntl(3, F_SETFL, O_NDELAY);
+
+ if ((fd = open("/dev/null", O_RDWR)) > 4) {
+ dup2(fd, 4);
+ close(fd);
+ } else
+ close(fd);
+ fcntl(4, F_SETFL, O_NDELAY);
+
+ /*
+ * Execute command...
+ */
+
+ execvp(filter, argv);
+
+ perror(filter);
+
+ exit(errno);
+ }
+
+ return (pid);
+}
+
+
+/*
+ * 'exec_filters()' - Execute filters for the given file and options.
+ */
+
+static int /* O - 0 on success, 1 on error */
+exec_filters(cups_array_t *filters, /* I - Array of filters to run */
+ char **argv) /* I - Filter options */
+{
+ int i; /* Looping var */
+ char program[1024]; /* Program to run */
+ char *filter, /* Current filter */
+ *next; /* Next filter */
+ int current, /* Current filter */
+ filterfds[2][2], /* Pipes for filters */
+ pid, /* Process ID of filter */
+ status, /* Exit status */
+ retval; /* Return value */
+ cups_array_t *pids; /* Executed filters array */
+ filter_pid_t *pid_entry, /* Entry in executed filters array */
+ key; /* Search key for filters */
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
+
+ /*
+ * Remove NULL ("-") filters...
+ */
+
+ for (filter = (char *)cupsArrayFirst(filters);
+ filter;
+ filter = (char *)cupsArrayNext(filters))
+ if (!strcmp(filter, "-"))
+ cupsArrayRemove(filters, filter);
+
+ for (i = 0; argv[i]; i ++)
+ fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
+
+ /*
+ * Execute all of the filters...
+ */
+
+ pids = cupsArrayNew((cups_array_func_t)compare_pids, NULL);
+ current = 0;
+ filterfds[0][0] = 0;
+ filterfds[0][1] = -1;
+ filterfds[1][0] = -1;
+ filterfds[1][1] = -1;
+
+ for (filter = (char *)cupsArrayFirst(filters);
+ filter;
+ filter = next, current = 1 - current) {
+ next = (char *)cupsArrayNext(filters);
+
+ if (filter[0] == '/') {
+ strncpy(program, filter, sizeof(program));
+ if (strlen(filter) > 1023)
+ program[1023] = '\0';
+ } else {
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+ snprintf(program, sizeof(program), "%s/filter/%s", cups_serverbin,
+ filter);
+ }
+
+ if (filterfds[!current][1] > 1) {
+ close(filterfds[1 - current][0]);
+ close(filterfds[1 - current][1]);
+
+ filterfds[1 - current][0] = -1;
+ filterfds[1 - current][0] = -1;
+ }
+
+ if (next)
+ open_pipe(filterfds[1 - current]);
+ else
+ filterfds[1 - current][1] = 1;
+
+ pid = exec_filter(program, argv,
+ filterfds[current][0], filterfds[1 - current][1]);
+
+ if (pid > 0) {
+ fprintf(stderr, "INFO: %s (PID %d) started.\n", filter, pid);
+
+ pid_entry = malloc(sizeof(filter_pid_t));
+ pid_entry->pid = pid;
+ pid_entry->name = filter;
+ cupsArrayAdd(pids, pid_entry);
+ } else
+ break;
+
+ argv[6] = NULL;
+ }
+
+ /*
+ * Close remaining pipes...
+ */
+
+ if (filterfds[0][1] > 1) {
+ close(filterfds[0][0]);
+ close(filterfds[0][1]);
+ }
+
+ if (filterfds[1][1] > 1) {
+ close(filterfds[1][0]);
+ close(filterfds[1][1]);
+ }
+
+ /*
+ * Wait for the children to exit...
+ */
+
+ retval = 0;
+
+ while (cupsArrayCount(pids) > 0) {
+ if ((pid = wait(&status)) < 0) {
+ if (errno == EINTR && job_canceled) {
+ fprintf(stderr, "DEBUG: Job canceled, killing filters ...\n");
+ for (pid_entry = (filter_pid_t *)cupsArrayFirst(pids);
+ pid_entry;
+ pid_entry = (filter_pid_t *)cupsArrayNext(pids))
+ kill(pid_entry->pid, SIGTERM);
+ job_canceled = 0;
+ } else
+ continue;
+ }
+
+ key.pid = pid;
+ if ((pid_entry = (filter_pid_t *)cupsArrayFind(pids, &key)) != NULL) {
+ cupsArrayRemove(pids, pid_entry);
+
+ if (status) {
+ if (WIFEXITED(status))
+ fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d\n",
+ pid_entry->name, pid, WEXITSTATUS(status));
+ else
+ fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d\n",
+ pid_entry->name, pid, WTERMSIG(status));
+
+ retval = 1;
+ } else
+ fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n",
+ pid_entry->name, pid);
+
+ free(pid_entry);
+ }
+ }
+
+ cupsArrayDelete(pids);
+
+ return (retval);
+}
+
+
+/*
+ * 'open_pipe()' - Create a pipe which is closed on exec.
+ */
+
+static int /* O - 0 on success, -1 on error */
+open_pipe(int *fds) /* O - Pipe file descriptors (2) */
+{
+ /*
+ * Create the pipe...
+ */
+
+ if (pipe(fds)) {
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return (-1);
+ }
+
+ /*
+ * Set the "close on exec" flag on each end of the pipe...
+ */
+
+ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) {
+ close(fds[0]);
+ close(fds[1]);
+
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return (-1);
+ }
+
+ if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) {
+ close(fds[0]);
+ close(fds[1]);
+
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return (-1);
+ }
+
+ /*
+ * Return 0 indicating success...
+ */
+
+ return (0);
+}
+
+
+/*
+ * Get option value in a string of options
+ */
+
+static char* /* O - Value, NULL if option not set */
+get_option_in_str(char *buf, /* I - Buffer with option list string */
+ const char *option, /* I - Option of which to get value */
+ int return_value) /* I - Return value or only check
+ presence of option? */
+{
+ char *p1, *p2;
+ char *result;
+
+ if (!buf || !option)
+ return NULL;
+ if ((p1 = strcasestr(buf, option)) == NULL)
+ return NULL;
+ if (p1 > buf && *(p1 - 1) != ' ' && *(p1 - 1) != '\t')
+ return NULL;
+ p2 = p1 + strlen(option);
+ if (*p2 == ' ' || *p2 == '\t' || *p2 == '\0')
+ return "";
+ if (*p2 != '=')
+ return NULL;
+ if (!return_value)
+ return "";
+ p1 = p2 + 1;
+ for (p2 = p1; *p2 != ' ' && *p2 != '\t' && *p2 != '\0'; p2 ++);
+ if (p2 == p1)
+ return "";
+ result = calloc(p2 - p1 + 1, sizeof(char));
+ memcpy(result, p1, p2 - p1);
+ result[p2 - p1] = '\0';
+ return result;
+}
+
+
+/*
+ * Set an option in a string of options
+ */
+
+void /* O - 0 on success, 1 on error */
+set_option_in_str(char *buf, /* I - Buffer with option list string */
+ int buflen, /* I - Length of buffer */
+ const char *option, /* I - Option to change/add */
+ const char *value) /* I - New value for option, NULL
+ removes option */
+{
+ char *p1, *p2;
+
+ if (!buf || buflen == 0 || !option)
+ return;
+ /* Remove any occurrence of option in the string */
+ p1 = buf;
+ while (*p1 != '\0' && (p2 = strcasestr(p1, option)) != NULL) {
+ if (p2 > buf && *(p2 - 1) != ' ' && *(p2 - 1) != '\t') {
+ p1 = p2 + 1;
+ continue;
+ }
+ p1 = p2 + strlen(option);
+ if (*p1 != '=' && *p1 != ' ' && *p1 != '\t' && *p1 != '\0')
+ continue;
+ while (*p1 != ' ' && *p1 != '\t' && *p1 != '\0') p1 ++;
+ while ((*p1 == ' ' || *p1 == '\t') && *p1 != '\0') p1 ++;
+ memmove(p2, p1, strlen(buf) - (buf - p1) + 1);
+ p1 = p2;
+ }
+ /* Add option=value to the end of the string */
+ if (!value)
+ return;
+ p1 = buf + strlen(buf);
+ *p1 = ' ';
+ p1 ++;
+ snprintf(p1, buflen - (buf - p1), "%s=%s", option, value);
+ buf[buflen - 1] = '\0';
+}
diff --git a/cupsfilters/pdftoippprinter.h b/cupsfilters/pdftoippprinter.h
new file mode 100644
index 000000000..a3fd14be5
--- /dev/null
+++ b/cupsfilters/pdftoippprinter.h
@@ -0,0 +1,7 @@
+#ifndef _CUPS_FILTERS_PDFTOIPPPRINTER_H
+# define _CUPS_FILTERS_PDFTOIPPPRINTER_H
+
+extern int
+apply_filters(int argc, char *argv[]);
+
+#endif
diff --git a/cupsfilters/ppdgenerator.c b/cupsfilters/ppdgenerator.c
index 934b1ce27..3c0feb7e6 100644
--- a/cupsfilters/ppdgenerator.c
+++ b/cupsfilters/ppdgenerator.c
@@ -14,17 +14,13 @@
* property of Apple Inc. and are protected by Federal copyright
* law. Distribution and use rights are outlined in the file "COPYING"
* which should have been included with this file.
- *
- * Contents:
- *
- * ppdCreateFromIPP() - Create a PPD file based on the result of an
- * get-printer-attributes IPP request
*/
#include <config.h>
#include <limits.h>
#include <cups/cups.h>
#include <cups/dir.h>
+#include <cupsfilters/ppdgenerator.h>
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
#define HAVE_CUPS_1_6 1
#endif
@@ -81,7 +77,8 @@ typedef struct _pwg_finishings_s /**** PWG finishings mapping data ****/
#define _PWG_EQUIVALENT(x, y) (abs((x)-(y)) < 2)
static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
-static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize);
+static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element,
+ int *xres, int *yres, char *name, size_t namesize);
/*
* '_cupsSetError()' - Set the last PPD generator status-message.
@@ -224,13 +221,10 @@ _cupsStrFormatd(char *buf, /* I - String */
* Next, find the decimal point...
*/
- if (loc && loc->decimal_point)
- {
+ if (loc && loc->decimal_point) {
dec = loc->decimal_point;
declen = (int)strlen(dec);
- }
- else
- {
+ } else {
dec = ".";
declen = 1;
}
@@ -244,16 +238,14 @@ _cupsStrFormatd(char *buf, /* I - String */
* Copy everything up to the decimal point...
*/
- if (tempdec)
- {
+ if (tempdec) {
for (tempptr = temp, bufptr = buf;
tempptr < tempdec && bufptr < bufend;
*bufptr++ = *tempptr++);
tempptr += declen;
- if (*tempptr && bufptr < bufend)
- {
+ if (*tempptr && bufptr < bufend) {
*bufptr++ = '.';
while (*tempptr && bufptr < bufend)
@@ -261,9 +253,7 @@ _cupsStrFormatd(char *buf, /* I - String */
}
*bufptr = '\0';
- }
- else
- {
+ } else {
strlcpy(buf, temp, (size_t)(bufend - buf + 1));
bufptr = buf + strlen(buf);
}
@@ -280,8 +270,7 @@ int /* O - Result of comparison (-1, 0, or 1) */
_cups_strcasecmp(const char *s, /* I - First string */
const char *t) /* I - Second string */
{
- while (*s != '\0' && *t != '\0')
- {
+ while (*s != '\0' && *t != '\0') {
if (_cups_tolower(*s) < _cups_tolower(*t))
return (-1);
else if (_cups_tolower(*s) > _cups_tolower(*t))
@@ -303,13 +292,13 @@ _cups_strcasecmp(const char *s, /* I - First string */
* '_cups_strncasecmp()' - Do a case-insensitive comparison on up to N chars.
*/
-int /* O - Result of comparison (-1, 0, or 1) */
-_cups_strncasecmp(const char *s, /* I - First string */
- const char *t, /* I - Second string */
- size_t n) /* I - Maximum number of characters to compare */
+int /* O - Result of comparison (-1, 0, or 1) */
+_cups_strncasecmp(const char *s, /* I - First string */
+ const char *t, /* I - Second string */
+ size_t n) /* I - Maximum number of characters to
+ compare */
{
- while (*s != '\0' && *t != '\0' && n > 0)
- {
+ while (*s != '\0' && *t != '\0' && n > 0) {
if (_cups_tolower(*s) < _cups_tolower(*t))
return (-1);
else if (_cups_tolower(*s) > _cups_tolower(*t))
@@ -362,7 +351,8 @@ pwg_copy_size(cups_size_t *size) /* I - Media size to copy */
static int /* O - 1 on success, 0 on failure */
get_url(const char *url, /* I - URL to get */
char *name, /* I - Temporary filename */
- size_t namesize) /* I - Size of temporary filename buffer */
+ size_t namesize) /* I - Size of temporary filename
+ buffer */
{
http_t *http = NULL;
char scheme[32], /* URL scheme */
@@ -375,7 +365,9 @@ get_url(const char *url, /* I - URL to get */
int fd; /* Temporary file */
- if (httpSeparateURI(HTTP_URI_CODING_ALL, url, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, url, scheme, sizeof(scheme),
+ userpass, sizeof(userpass), host, sizeof(host), &port,
+ resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
return (0);
if (port == 443 || !strcmp(scheme, "https"))
@@ -396,8 +388,7 @@ get_url(const char *url, /* I - URL to get */
close(fd);
httpClose(http);
- if (status != HTTP_STATUS_OK)
- {
+ if (status != HTTP_STATUS_OK) {
unlink(name);
*name = '\0';
return (0);
@@ -564,13 +555,15 @@ typedef struct ipp_opt_strings_s {
int
compare_choices(void *a, void *b, void *user_data)
{
- return strcasecmp(((ipp_choice_strings_t *)a)->name, ((ipp_choice_strings_t *)b)->name);
+ return strcasecmp(((ipp_choice_strings_t *)a)->name,
+ ((ipp_choice_strings_t *)b)->name);
}
int
compare_options(void *a, void *b, void *user_data)
{
- return strcasecmp(((ipp_opt_strings_t *)a)->name, ((ipp_opt_strings_t *)b)->name);
+ return strcasecmp(((ipp_opt_strings_t *)a)->name,
+ ((ipp_opt_strings_t *)b)->name);
}
void
@@ -661,7 +654,8 @@ add_opt_to_array(char *name, char *human_readable, cups_array_t *options)
}
ipp_choice_strings_t *
-add_choice_to_array(char *name, char *human_readable, char *opt_name, cups_array_t *options)
+add_choice_to_array(char *name, char *human_readable, char *opt_name,
+ cups_array_t *options)
{
ipp_choice_strings_t *choice = NULL;
ipp_opt_strings_t *opt;
@@ -723,7 +717,7 @@ lookup_choice(char *name, char *opt_name, cups_array_t *options,
(choice = find_choice_in_array(opt->choices, name)) != NULL)
return choice->human_readable;
else if ((opt = find_opt_in_array(options, opt_name)) != NULL &&
- (choice = find_choice_in_array(opt->choices, name)) != NULL)
+ (choice = find_choice_in_array(opt->choices, name)) != NULL)
return choice->human_readable;
else
return NULL;
@@ -751,7 +745,8 @@ load_opt_strings_catalog(const char *location, cups_array_t *options)
if (location == NULL || (strncasecmp(location, "http:", 5) &&
strncasecmp(location, "https:", 6))) {
if (location == NULL ||
- (stat(location, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))) /* directory? */
+ (stat(location, &statbuf) == 0 &&
+ S_ISDIR(statbuf.st_mode))) /* directory? */
filename = _findCUPSMessageCatalog(location);
else
filename = location;
@@ -939,11 +934,6 @@ load_opt_strings_catalog(const char *location, cups_array_t *options)
}
-/* Data structure for resolution (X x Y dpi) */
-typedef struct res_s {
- int x, y;
-} res_t;
-
int
compare_resolutions(void *resolution_a, void *resolution_b,
void *user_data)
@@ -1150,22 +1140,409 @@ joinResolutionArrays(cups_array_t **current, cups_array_t **new,
return retval;
}
+cups_array_t* generate_sizes(ipp_t *response,
+ ipp_attribute_t **defattr,
+ int* min_length,
+ int* min_width,
+ int* max_length,
+ int* max_width,
+ int* bottom,
+ int* left,
+ int* right,
+ int* top,
+ char* ppdname)
+{
+ cups_array_t *sizes; /* Media sizes we've added */
+ ipp_attribute_t *attr, /* xxx-supported */
+ *x_dim, *y_dim; /* Media dimensions */
+ ipp_t *media_col, /* Media collection */
+ *media_size; /* Media size collection */
+ int i,count = 0;
+ pwg_media_t *pwg; /* PWG media size */
+ int left_def,right_def,bottom_def,top_def;
+ ipp_attribute_t *margin; /* media-xxx-margin attribute */
+
+ if ((attr = ippFindAttribute(response, "media-bottom-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, *bottom = ippGetInteger(attr, 0), count = ippGetCount(attr);
+ i < count; i ++)
+ if (ippGetInteger(attr, i) > *bottom)
+ *bottom = ippGetInteger(attr, i);
+ } else
+ *bottom = 1270;
+
+ if ((attr = ippFindAttribute(response, "media-left-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, *left = ippGetInteger(attr, 0), count = ippGetCount(attr);
+ i < count; i ++)
+ if (ippGetInteger(attr, i) > *left)
+ *left = ippGetInteger(attr, i);
+ } else
+ *left = 635;
+
+ if ((attr = ippFindAttribute(response, "media-right-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, *right = ippGetInteger(attr, 0), count = ippGetCount(attr);
+ i < count; i ++)
+ if (ippGetInteger(attr, i) > *right)
+ *right = ippGetInteger(attr, i);
+ } else
+ *right = 635;
+
+ if ((attr = ippFindAttribute(response, "media-top-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, *top = ippGetInteger(attr, 0), count = ippGetCount(attr);
+ i < count; i ++)
+ if (ippGetInteger(attr, i) > *top)
+ *top = ippGetInteger(attr, i);
+ } else
+ *top = 1270;
+
+ if ((*defattr = ippFindAttribute(response, "media-col-default",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ if ((attr = ippFindAttribute(ippGetCollection(*defattr, 0), "media-size",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ media_size = ippGetCollection(attr, 0);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
+
+ if ((margin = ippFindAttribute(ippGetCollection(*defattr, 0),
+ "media-bottom-margin", IPP_TAG_INTEGER))
+ != NULL)
+ bottom_def = ippGetInteger(margin, 0);
+ else
+ bottom_def = *bottom;
+
+ if ((margin = ippFindAttribute(ippGetCollection(*defattr, 0),
+ "media-left-margin", IPP_TAG_INTEGER))
+ != NULL)
+ left_def = ippGetInteger(margin, 0);
+ else
+ left_def = *left;
+
+ if ((margin = ippFindAttribute(ippGetCollection(*defattr, 0),
+ "media-right-margin", IPP_TAG_INTEGER))
+ != NULL)
+ right_def = ippGetInteger(margin, 0);
+ else
+ right_def = *right;
+
+ if ((margin = ippFindAttribute(ippGetCollection(*defattr, 0),
+ "media-top-margin", IPP_TAG_INTEGER))
+ != NULL)
+ top_def = ippGetInteger(margin, 0);
+ else
+ top_def = *top;
+
+ if (x_dim && y_dim &&
+ (pwg = pwgMediaForSize(ippGetInteger(x_dim, 0),
+ ippGetInteger(y_dim, 0))) != NULL) {
+ if (bottom_def == 0 && left_def == 0 && right_def == 0 && top_def == 0)
+ snprintf(ppdname, PPD_MAX_NAME, "%s.Borderless", pwg->ppd);
+ else
+ strlcpy(ppdname, pwg->ppd, PPD_MAX_NAME);
+ } else
+ strlcpy(ppdname, "Unknown", PPD_MAX_NAME);
+ } else
+ strlcpy(ppdname, "Unknown", PPD_MAX_NAME);
+ } else if ((pwg =
+ pwgMediaForPWG(ippGetString(ippFindAttribute(response,
+ "media-default",
+ IPP_TAG_ZERO), 0,
+ NULL))) != NULL)
+ strlcpy(ppdname, pwg->ppd, PPD_MAX_NAME);
+ else
+ strlcpy(ppdname, "Unknown", PPD_MAX_NAME);
+
+ sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes, NULL, NULL, 0,
+ (cups_acopy_func_t)pwg_copy_size,
+ (cups_afree_func_t)free);
+
+ if ((attr = ippFindAttribute(response, "media-col-database",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ cups_size_t temp; /* Current size */
+
+ media_col = ippGetCollection(attr, i);
+ media_size =
+ ippGetCollection(ippFindAttribute(media_col, "media-size",
+ IPP_TAG_BEGIN_COLLECTION), 0);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
+ pwg = pwgMediaForSize(ippGetInteger(x_dim, 0),
+ ippGetInteger(y_dim, 0));
+
+ if (pwg) {
+ temp.width = pwg->width;
+ temp.length = pwg->length;
+
+ if ((margin = ippFindAttribute(media_col, "media-bottom-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ temp.bottom = ippGetInteger(margin, 0);
+ else
+ temp.bottom = *bottom;
+
+ if ((margin = ippFindAttribute(media_col, "media-left-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ temp.left = ippGetInteger(margin, 0);
+ else
+ temp.left = *left;
+
+ if ((margin = ippFindAttribute(media_col, "media-right-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ temp.right = ippGetInteger(margin, 0);
+ else
+ temp.right = *right;
+
+ if ((margin = ippFindAttribute(media_col, "media-top-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ temp.top = ippGetInteger(margin, 0);
+ else
+ temp.top = *top;
+
+ if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 &&
+ temp.top == 0)
+ snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
+ else
+ strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
+
+ if (!cupsArrayFind(sizes, &temp))
+ cupsArrayAdd(sizes, &temp);
+ } else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE ||
+ ippGetValueTag(y_dim) == IPP_TAG_RANGE) {
+ /*
+ * Custom size - record the min/max values...
+ */
+
+ int lower, upper; /* Range values */
+
+ if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
+ lower = ippGetRange(x_dim, 0, &upper);
+ else
+ lower = upper = ippGetInteger(x_dim, 0);
+
+ if (lower < *min_width)
+ *min_width = lower;
+ if (upper > *max_width)
+ *max_width = upper;
+
+ if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
+ lower = ippGetRange(y_dim, 0, &upper);
+ else
+ lower = upper = ippGetInteger(y_dim, 0);
+
+ if (lower < *min_length)
+ *min_length = lower;
+ if (upper > *max_length)
+ *max_length = upper;
+ }
+ }
+ }
+ if ((attr = ippFindAttribute(response, "media-size-supported",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ cups_size_t temp; /* Current size */
+
+ media_size = ippGetCollection(attr, i);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
+ pwg = pwgMediaForSize(ippGetInteger(x_dim, 0),
+ ippGetInteger(y_dim, 0));
+
+ if (pwg) {
+ temp.width = pwg->width;
+ temp.length = pwg->length;
+ temp.bottom = *bottom;
+ temp.left = *left;
+ temp.right = *right;
+ temp.top = *top;
+
+ if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 &&
+ temp.top == 0)
+ snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
+ else
+ strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
+
+ if (!cupsArrayFind(sizes, &temp))
+ cupsArrayAdd(sizes, &temp);
+ } else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE ||
+ ippGetValueTag(y_dim) == IPP_TAG_RANGE) {
+ /*
+ * Custom size - record the min/max values...
+ */
+
+ int lower, upper; /* Range values */
+
+ if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
+ lower = ippGetRange(x_dim, 0, &upper);
+ else
+ lower = upper = ippGetInteger(x_dim, 0);
+
+ if (lower < *min_width)
+ *min_width = lower;
+ if (upper > *max_width)
+ *max_width = upper;
+
+ if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
+ lower = ippGetRange(y_dim, 0, &upper);
+ else
+ lower = upper = ippGetInteger(y_dim, 0);
+
+ if (lower < *min_length)
+ *min_length = lower;
+ if (upper > *max_length)
+ *max_length = upper;
+ }
+ }
+ }
+ if ((attr = ippFindAttribute(response, "media-supported", IPP_TAG_ZERO))
+ != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ const char *pwg_size = ippGetString(attr, i, NULL);
+ /* PWG size name */
+ cups_size_t temp, *temp2; /* Current size, found size */
+
+ if ((pwg = pwgMediaForPWG(pwg_size)) != NULL) {
+ if (strstr(pwg_size, "_max_") || strstr(pwg_size, "_max.")) {
+ if (pwg->width > *max_width)
+ *max_width = pwg->width;
+ if (pwg->length > *max_length)
+ *max_length = pwg->length;
+ } else if (strstr(pwg_size, "_min_") || strstr(pwg_size, "_min.")) {
+ if (pwg->width < *min_width)
+ *min_width = pwg->width;
+ if (pwg->length < *min_length)
+ *min_length = pwg->length;
+ } else {
+ temp.width = pwg->width;
+ temp.length = pwg->length;
+ temp.bottom = *bottom;
+ temp.left = *left;
+ temp.right = *right;
+ temp.top = *top;
+
+ if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 &&
+ temp.top == 0)
+ snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
+ else
+ strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
+
+ /* Add the printer's original IPP name to an already found size */
+ if ((temp2 = cupsArrayFind(sizes, &temp)) != NULL) {
+ snprintf(temp2->media + strlen(temp2->media),
+ sizeof(temp2->media) - strlen(temp2->media),
+ " %s", pwg_size);
+ /* Check if we have also a borderless version of the size and add
+ the original IPP name also there */
+ snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
+ if ((temp2 = cupsArrayFind(sizes, &temp)) != NULL)
+ snprintf(temp2->media + strlen(temp2->media),
+ sizeof(temp2->media) - strlen(temp2->media),
+ " %s", pwg_size);
+ } else
+ cupsArrayAdd(sizes, &temp);
+ }
+ }
+ }
+ }
+ return sizes;
+}
+
+int is_colordevice(const char *keyword,ipp_attribute_t *attr)
+{
+ if (!strcasecmp(keyword, "sgray_16") || !strncmp(keyword, "W8-16", 5) ||
+ !strncmp(keyword, "W16", 3))
+ return 1;
+ else if (!strcasecmp(keyword, "srgb_8") || !strncmp(keyword, "SRGB24", 6) ||
+ !strcmp(keyword, "color"))
+ return 1;
+ else if ((!strcasecmp(keyword, "srgb_16") ||
+ !strncmp(keyword, "SRGB48", 6)) &&
+ !ippContainsString(attr, "srgb_8"))
+ return 1;
+ else if (!strcasecmp(keyword, "adobe-rgb_16") ||
+ !strncmp(keyword, "ADOBERGB48", 10) ||
+ !strncmp(keyword, "ADOBERGB24-48", 13))
+ return 1;
+ else if ((!strcasecmp(keyword, "adobe-rgb_8") ||
+ !strcmp(keyword, "ADOBERGB24")) &&
+ !ippContainsString(attr, "adobe-rgb_16"))
+ return 1;
+ else if ((!strcasecmp(keyword, "cmyk_8") &&
+ !ippContainsString(attr, "cmyk_16")) ||
+ !strcmp(keyword, "DEVCMYK32"))
+ return 1;
+ else if (!strcasecmp(keyword, "cmyk_16") ||
+ !strcmp(keyword, "DEVCMYK32-64") ||
+ !strcmp(keyword, "DEVCMYK64"))
+ return 1;
+ else if ((!strcasecmp(keyword, "rgb_8") &&
+ !ippContainsString(attr, "rgb_16"))
+ || !strcmp(keyword, "DEVRGB24"))
+ return 1;
+ else if (!strcasecmp(keyword, "rgb_16") ||
+ !strcmp(keyword, "DEVRGB24-48") ||
+ !strcmp(keyword, "DEVRGB48"))
+ return 1;
+ return 0;
+}
+
/*
* 'ppdCreateFromIPP()' - Create a PPD file describing the capabilities
- * of an IPP printer.
+ * of an IPP printer (legacy interface).
+ */
+
+char * /* O - PPD filename or NULL on
+ error */
+ppdCreateFromIPP (char *buffer, /* I - Filename buffer */
+ size_t bufsize, /* I - Size of filename
+ buffer */
+ ipp_t *response, /* I - Get-Printer-Attributes
+ response */
+ const char *make_model, /* I - Make and model from
+ DNS-SD */
+ const char *pdl, /* I - List of PDLs from
+ DNS-SD */
+ int color, /* I - Color printer? (from
+ DNS-SD) */
+ int duplex) /* I - Duplex printer? (from
+ DNS-SD) */
+{
+ return ppdCreateFromIPP2(buffer, bufsize, response, make_model, pdl,
+ color, duplex, NULL, NULL, NULL, NULL);
+}
+
+/*
+ * 'ppdCreateFromIPP2()' - Create a PPD file describing the capabilities
+ * of an IPP printer.
*/
-char * /* O - PPD filename or NULL on error */
-ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
- size_t bufsize, /* I - Size of filename buffer */
- ipp_t *response, /* I - Get-Printer-Attributes response */
- const char *make_model,/* I - Make and model from DNS-SD */
- const char *pdl, /* I - List of PDLs from DNS-SD */
- int color, /* I - Color printer? (from DNS-SD) */
- int duplex) /* I - Duplex printer? (from DNS-SD) */
+char * /* O - PPD filename or NULL on
+ error */
+ppdCreateFromIPP2(char *buffer, /* I - Filename buffer */
+ size_t bufsize, /* I - Size of filename
+ buffer */
+ ipp_t *response, /* I - Get-Printer-Attributes
+ response */
+ const char *make_model, /* I - Make and model from
+ DNS-SD */
+ const char *pdl, /* I - List of PDLs from
+ DNS-SD */
+ int color, /* I - Color printer? (from
+ DNS-SD) */
+ int duplex, /* I - Duplex printer? (from
+ DNS-SD) */
+ cups_array_t *conflicts, /* I - Array of constraints */
+ cups_array_t *sizes, /* I - Media sizes we've
+ added */
+ char* default_pagesize, /* I - Default page size*/
+ const char *default_cluster_color) /* I - cluster def
+ color (if cluster's
+ attributes are
+ returned) */
{
cups_file_t *fp; /* PPD file */
- cups_array_t *sizes; /* Media sizes we've added */
+ cups_array_t *printer_sizes; /* Media sizes we've added */
cups_size_t *size; /* Current media size */
ipp_attribute_t *attr, /* xxx-supported */
*attr2,
@@ -1237,14 +1614,12 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (buffer)
*buffer = '\0';
- if (!buffer || bufsize < 1)
- {
+ if (!buffer || bufsize < 1) {
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
return (NULL);
}
- if (!response)
- {
+ if (!response) {
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No IPP attributes."), 1);
return (NULL);
}
@@ -1253,8 +1628,7 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Open a temporary file for the PPD...
*/
- if ((fp = cupsTempFile2(buffer, (int)bufsize)) == NULL)
- {
+ if ((fp = cupsTempFile2(buffer, (int)bufsize)) == NULL) {
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
return (NULL);
}
@@ -1273,7 +1647,8 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePuts(fp, "*FileSystem: False\n");
cupsFilePuts(fp, "*PCFileName: \"drvless.ppd\"\n");
- if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL)
+ if ((attr = ippFindAttribute(response, "printer-make-and-model",
+ IPP_TAG_TEXT)) != NULL)
strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make));
else if (make_model && make_model[0] != '\0')
strlcpy(make, make_model, sizeof(make));
@@ -1281,8 +1656,7 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
strlcpy(make, "Unknown Printer", sizeof(make));
if (!_cups_strncasecmp(make, "Hewlett Packard ", 16) ||
- !_cups_strncasecmp(make, "Hewlett-Packard ", 16))
- {
+ !_cups_strncasecmp(make, "Hewlett-Packard ", 16)) {
model = make + 16;
strlcpy(make, "HP", sizeof(make));
}
@@ -1294,50 +1668,48 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make);
cupsFilePrintf(fp, "*ModelName: \"%s %s\"\n", make, model);
cupsFilePrintf(fp, "*Product: \"(%s %s)\"\n", make, model);
- cupsFilePrintf(fp, "*NickName: \"%s %s, driverless, cups-filters %s\"\n", make, model,
- VERSION);
+ cupsFilePrintf(fp, "*NickName: \"%s %s, driverless, cups-filters %s\"\n",
+ make, model, VERSION);
cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"\n", make, model);
/* Which is the default output bin? */
- if ((attr = ippFindAttribute(response, "output-bin-default", IPP_TAG_ZERO)) != NULL)
+ if ((attr = ippFindAttribute(response, "output-bin-default", IPP_TAG_ZERO))
+ != NULL)
defaultoutbin = strdup(ippGetString(attr, 0, NULL));
- /* Find out on which position of the list of output bins the default one is, if there
- is no default bin, take the first of this list */
+ /* Find out on which position of the list of output bins the default one is,
+ if there is no default bin, take the first of this list */
i = 0;
- if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL)
- {
+ if ((attr = ippFindAttribute(response, "output-bin-supported",
+ IPP_TAG_ZERO)) != NULL) {
count = ippGetCount(attr);
- for (i = 0; i < count; i ++)
- {
+ for (i = 0; i < count; i ++) {
outbin = ippGetString(attr, i, NULL);
if (outbin == NULL)
continue;
- if (defaultoutbin == NULL)
- {
+ if (defaultoutbin == NULL) {
defaultoutbin = strdup(outbin);
break;
- }
- else if (strcasecmp(outbin, defaultoutbin) == 0)
+ } else if (strcasecmp(outbin, defaultoutbin) == 0)
break;
}
}
- if ((attr = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING)) != NULL &&
- i < ippGetCount(attr))
- {
+ if ((attr = ippFindAttribute(response, "printer-output-tray",
+ IPP_TAG_STRING)) != NULL &&
+ i < ippGetCount(attr)) {
outbin_properties_octet = ippGetOctetString(attr, i, &octet_str_len);
memset(outbin_properties, 0, sizeof(outbin_properties));
memcpy(outbin_properties, outbin_properties_octet,
((size_t)octet_str_len < sizeof(outbin_properties) - 1 ?
(size_t)octet_str_len : sizeof(outbin_properties) - 1));
- if (strcasestr(outbin_properties, "pagedelivery=faceUp"))
- {
+ if (strcasestr(outbin_properties, "pagedelivery=faceUp")) {
outputorderinfofound = 1;
faceupdown = -1;
}
if (strcasestr(outbin_properties, "stackingorder=lastToFirst"))
firsttolast = -1;
}
- if (outputorderinfofound == 0 && defaultoutbin && strcasestr(defaultoutbin, "face-up"))
+ if (outputorderinfofound == 0 && defaultoutbin &&
+ strcasestr(defaultoutbin, "face-up"))
faceupdown = -1;
if (defaultoutbin)
free (defaultoutbin);
@@ -1346,31 +1718,71 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
else
cupsFilePuts(fp, "*DefaultOutputOrder: Normal\n");
- if (((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0)) || color)
- cupsFilePuts(fp, "*ColorDevice: True\n");
- else
- cupsFilePuts(fp, "*ColorDevice: False\n");
+ /* To decide whether the printer is coloured or not we see the various
+ colormodel supported by the printer*/
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD))
+ == NULL)
+ if ((attr = ippFindAttribute(response,
+ "pwg-raster-document-type-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(response, "print-color-mode-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(response, "output-mode-supported",
+ IPP_TAG_KEYWORD);
+ if (attr==NULL || !ippGetCount(attr)) {
+ if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN))
+ != NULL) {
+ if(ippGetBoolean(attr, 0))
+ cupsFilePuts(fp, "*ColorDevice: True\n");
+ else
+ cupsFilePuts(fp, "*ColorDevice: False\n");
+ } else {
+ if(color)
+ cupsFilePuts(fp, "*ColorDevice: True\n");
+ else
+ cupsFilePuts(fp, "*ColorDevice: False\n");
+ }
+ } else {
+ int colordevice = 0;
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ keyword = ippGetString(attr, i, NULL);
+ colordevice = is_colordevice(keyword,attr);
+ if (colordevice) {
+ cupsFilePuts(fp, "*ColorDevice: True\n");
+ break;
+ }
+ }
+ if(colordevice==0)
+ cupsFilePuts(fp, "*ColorDevice: False\n");
+ }
- cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
+ cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR,
+ CUPS_VERSION_MINOR);
cupsFilePuts(fp, "*cupsSNMPSupplies: False\n");
cupsFilePuts(fp, "*cupsLanguages: \"en\"\n");
- if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) != NULL)
+ if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) !=
+ NULL)
cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL));
- if ((attr = ippFindAttribute(response, "printer-charge-info-uri", IPP_TAG_URI)) != NULL)
- cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL));
+ if ((attr = ippFindAttribute(response, "printer-charge-info-uri",
+ IPP_TAG_URI)) != NULL)
+ cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0,
+ NULL));
/* Message catalogs for UI strings */
if (opt_strings_catalog == NULL) {
opt_strings_catalog = optArrayNew();
load_opt_strings_catalog(NULL, opt_strings_catalog);
}
- if ((attr = ippFindAttribute(response, "printer-strings-uri", IPP_TAG_URI)) != NULL) {
+ if ((attr = ippFindAttribute(response, "printer-strings-uri",
+ IPP_TAG_URI)) != NULL) {
printer_opt_strings_catalog = optArrayNew();
- load_opt_strings_catalog(ippGetString(attr, 0, NULL), printer_opt_strings_catalog);
+ load_opt_strings_catalog(ippGetString(attr, 0, NULL),
+ printer_opt_strings_catalog);
if (printer_opt_strings_catalog)
- cupsFilePrintf(fp, "*cupsStringsURI: \"%s\"\n", ippGetString(attr, 0, NULL));
+ cupsFilePrintf(fp, "*cupsStringsURI: \"%s\"\n", ippGetString(attr, 0,
+ NULL));
}
/*
@@ -1391,15 +1803,16 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
goto bad_ppd;
int formatfound = 0;
- if (((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) || (pdl && pdl[0] != '\0'))
- {
+ if (((attr = ippFindAttribute(response, "document-format-supported",
+ IPP_TAG_MIMETYPE)) != NULL) ||
+ (pdl && pdl[0] != '\0')) {
const char *format = pdl;
i = 0;
count = ippGetCount(attr);
while ((attr && i < count) || /* Go through formats in attribute */
- (!attr && pdl && pdl[0] != '\0' && format[0] != '\0'))
- /* Go through formats in pdl string (from DNS-SD record) */
- {
+ (!attr && pdl && pdl[0] != '\0' && format[0] != '\0')) {
+ /* Go through formats in pdl string (from DNS-SD record) */
+
/* Pick next format from attribute */
if (attr) format = ippGetString(attr, i, NULL);
/* Add format to list of supported PDLs, skip duplicates */
@@ -1449,7 +1862,9 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
is_pdf = 1;
}
if (cupsArrayFind(pdl_list, "image/pwg-raster")) {
- if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) {
+ if ((attr = ippFindAttribute(response,
+ "pwg-raster-document-resolution-supported",
+ IPP_TAG_RESOLUTION)) != NULL) {
current_def = NULL;
if ((current_res = ippResolutionListToArray(attr)) != NULL &&
joinResolutionArrays(&common_res, &current_res, &common_def,
@@ -1463,7 +1878,8 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
}
#ifdef CUPS_RASTER_HAVE_APPLERASTER
if (cupsArrayFind(pdl_list, "image/urf")) {
- if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) {
+ if ((attr = ippFindAttribute(response, "urf-supported",
+ IPP_TAG_KEYWORD)) != NULL) {
int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */
for (i = 0, count = ippGetCount(attr); i < count; i ++) {
const char *rs = ippGetString(attr, i, NULL); /* RS value */
@@ -1502,8 +1918,11 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
#endif
#ifdef QPDF_HAVE_PCLM
if (cupsArrayFind(pdl_list, "application/PCLm")) {
- if ((attr = ippFindAttribute(response, "pclm-source-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) {
- if ((defattr = ippFindAttribute(response, "pclm-source-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
+ if ((attr = ippFindAttribute(response, "pclm-source-resolution-supported",
+ IPP_TAG_RESOLUTION)) != NULL) {
+ if ((defattr = ippFindAttribute(response,
+ "pclm-source-resolution-default",
+ IPP_TAG_RESOLUTION)) != NULL)
current_def = ippResolutionToRes(defattr, 0);
else
current_def = NULL;
@@ -1569,8 +1988,10 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
/* No resolution requirements by any of the supported PDLs?
Use "printer-resolution-supported" attribute */
if (common_res == NULL) {
- if ((attr = ippFindAttribute(response, "printer-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) {
- if ((defattr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
+ if ((attr = ippFindAttribute(response, "printer-resolution-supported",
+ IPP_TAG_RESOLUTION)) != NULL) {
+ if ((defattr = ippFindAttribute(response, "printer-resolution-default",
+ IPP_TAG_RESOLUTION)) != NULL)
current_def = ippResolutionToRes(defattr, 0);
else
current_def = NULL;
@@ -1590,7 +2011,8 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
}
/* No default resolution determined yet */
if (common_def == NULL) {
- if ((defattr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL) {
+ if ((defattr = ippFindAttribute(response, "printer-resolution-default",
+ IPP_TAG_RESOLUTION)) != NULL) {
common_def = ippResolutionToRes(defattr, 0);
if (!cupsArrayFind(common_res, common_def)) {
free(common_def);
@@ -1613,29 +2035,23 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* and ppdize them one by one
*/
- if (is_pclm)
- {
+ if (is_pclm) {
attr = ippFirstAttribute(response); /* first attribute */
- while (attr) /* loop through all the attributes */
- {
- if (_cups_strncasecmp(ippGetName(attr), "pclm", 4) == 0)
- {
+ while (attr) { /* loop through all the attributes */
+ if (_cups_strncasecmp(ippGetName(attr), "pclm", 4) == 0) {
pwg_ppdize_name(ippGetName(attr), ppdname, sizeof(ppdname));
cupsFilePrintf(fp, "*cups%s: ", ppdname);
ipp_tag_t tag = ippGetValueTag(attr);
count = ippGetCount(attr);
- if (tag == IPP_TAG_RESOLUTION) /* ppdize values of type resolution */
- {
- if ((current_res = ippResolutionListToArray(attr)) != NULL)
- {
+ if (tag == IPP_TAG_RESOLUTION) { /* ppdize values of type resolution */
+ if ((current_res = ippResolutionListToArray(attr)) != NULL) {
count = cupsArrayCount(current_res);
if (count > 1)
cupsFilePuts(fp, "\"");
for (i = 0, current_def = cupsArrayFirst(current_res);
current_def;
- i ++, current_def = cupsArrayNext(current_res))
- {
+ i ++, current_def = cupsArrayNext(current_res)) {
int x = current_def->x;
int y = current_def->y;
if (x == y)
@@ -1648,13 +2064,10 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (count > 1)
cupsFilePuts(fp, "\"");
cupsFilePuts(fp, "\n");
- }
- else
+ } else
cupsFilePuts(fp, "\"\"\n");
cupsArrayDelete(current_res);
- }
- else
- {
+ } else {
ippAttributeString(attr, ppdname, sizeof(ppdname));
if (count > 1 || /* quotes around multi-valued and string
attributes */
@@ -1674,259 +2087,15 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
/*
* PageSize/PageRegion/ImageableArea/PaperDimension
*/
+ printer_sizes = generate_sizes(response, &defattr, &min_length, &min_width,
+ &max_length, &max_width,
+ &bottom, &left, &right, &top, ppdname);
+ if (sizes==NULL) {
+ sizes = printer_sizes;
+ } else
+ strcpy(ppdname, default_pagesize);
- if ((attr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL)
- {
- for (i = 1, bottom = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
- if (ippGetInteger(attr, i) > bottom)
- bottom = ippGetInteger(attr, i);
- }
- else
- bottom = 1270;
-
- if ((attr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL)
- {
- for (i = 1, left = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
- if (ippGetInteger(attr, i) > left)
- left = ippGetInteger(attr, i);
- }
- else
- left = 635;
-
- if ((attr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL)
- {
- for (i = 1, right = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
- if (ippGetInteger(attr, i) > right)
- right = ippGetInteger(attr, i);
- }
- else
- right = 635;
-
- if ((attr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL)
- {
- for (i = 1, top = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
- if (ippGetInteger(attr, i) > top)
- top = ippGetInteger(attr, i);
- }
- else
- top = 1270;
-
- if ((defattr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION)) != NULL)
- {
- if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-size", IPP_TAG_BEGIN_COLLECTION)) != NULL)
- {
- media_size = ippGetCollection(attr, 0);
- x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
- y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
-
- if (x_dim && y_dim && (pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL)
- strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
- else
- strlcpy(ppdname, "Unknown", sizeof(ppdname));
- }
- else
- strlcpy(ppdname, "Unknown", sizeof(ppdname));
- }
- else if ((pwg = pwgMediaForPWG(ippGetString(ippFindAttribute(response, "media-default", IPP_TAG_ZERO), 0, NULL))) != NULL)
- strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
- else
- strlcpy(ppdname, "Unknown", sizeof(ppdname));
-
- sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes, NULL, NULL, 0, (cups_acopy_func_t)pwg_copy_size, (cups_afree_func_t)free);
-
- if ((attr = ippFindAttribute(response, "media-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
- {
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- cups_size_t temp; /* Current size */
- ipp_attribute_t *margin; /* media-xxx-margin attribute */
-
- media_col = ippGetCollection(attr, i);
- media_size = ippGetCollection(ippFindAttribute(media_col, "media-size", IPP_TAG_BEGIN_COLLECTION), 0);
- x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
- y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
- pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
-
- if (pwg)
- {
- temp.width = pwg->width;
- temp.length = pwg->length;
-
- if ((margin = ippFindAttribute(media_col, "media-bottom-margin", IPP_TAG_INTEGER)) != NULL)
- temp.bottom = ippGetInteger(margin, 0);
- else
- temp.bottom = bottom;
-
- if ((margin = ippFindAttribute(media_col, "media-left-margin", IPP_TAG_INTEGER)) != NULL)
- temp.left = ippGetInteger(margin, 0);
- else
- temp.left = left;
-
- if ((margin = ippFindAttribute(media_col, "media-right-margin", IPP_TAG_INTEGER)) != NULL)
- temp.right = ippGetInteger(margin, 0);
- else
- temp.right = right;
-
- if ((margin = ippFindAttribute(media_col, "media-top-margin", IPP_TAG_INTEGER)) != NULL)
- temp.top = ippGetInteger(margin, 0);
- else
- temp.top = top;
-
- if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0)
- snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
- else
- strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
-
- if (!cupsArrayFind(sizes, &temp))
- cupsArrayAdd(sizes, &temp);
- }
- else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE)
- {
- /*
- * Custom size - record the min/max values...
- */
-
- int lower, upper; /* Range values */
-
- if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
- lower = ippGetRange(x_dim, 0, &upper);
- else
- lower = upper = ippGetInteger(x_dim, 0);
-
- if (lower < min_width)
- min_width = lower;
- if (upper > max_width)
- max_width = upper;
-
- if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
- lower = ippGetRange(y_dim, 0, &upper);
- else
- lower = upper = ippGetInteger(y_dim, 0);
-
- if (lower < min_length)
- min_length = lower;
- if (upper > max_length)
- max_length = upper;
- }
- }
- }
- if ((attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL)
- {
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- cups_size_t temp; /* Current size */
-
- media_size = ippGetCollection(attr, i);
- x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
- y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
- pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
-
- if (pwg)
- {
- temp.width = pwg->width;
- temp.length = pwg->length;
- temp.bottom = bottom;
- temp.left = left;
- temp.right = right;
- temp.top = top;
-
- if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0)
- snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
- else
- strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
-
- if (!cupsArrayFind(sizes, &temp))
- cupsArrayAdd(sizes, &temp);
- }
- else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE)
- {
- /*
- * Custom size - record the min/max values...
- */
-
- int lower, upper; /* Range values */
-
- if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
- lower = ippGetRange(x_dim, 0, &upper);
- else
- lower = upper = ippGetInteger(x_dim, 0);
-
- if (lower < min_width)
- min_width = lower;
- if (upper > max_width)
- max_width = upper;
-
- if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
- lower = ippGetRange(y_dim, 0, &upper);
- else
- lower = upper = ippGetInteger(y_dim, 0);
-
- if (lower < min_length)
- min_length = lower;
- if (upper > max_length)
- max_length = upper;
- }
- }
- }
- if ((attr = ippFindAttribute(response, "media-supported", IPP_TAG_ZERO)) != NULL)
- {
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- const char *pwg_size = ippGetString(attr, i, NULL);
- /* PWG size name */
- cups_size_t temp, *temp2; /* Current size, found size */
-
- if ((pwg = pwgMediaForPWG(pwg_size)) != NULL)
- {
- if (strstr(pwg_size, "_max_") || strstr(pwg_size, "_max."))
- {
- if (pwg->width > max_width)
- max_width = pwg->width;
- if (pwg->length > max_length)
- max_length = pwg->length;
- }
- else if (strstr(pwg_size, "_min_") || strstr(pwg_size, "_min."))
- {
- if (pwg->width < min_width)
- min_width = pwg->width;
- if (pwg->length < min_length)
- min_length = pwg->length;
- }
- else
- {
- temp.width = pwg->width;
- temp.length = pwg->length;
- temp.bottom = bottom;
- temp.left = left;
- temp.right = right;
- temp.top = top;
-
- if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0)
- snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
- else
- strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
-
- /* Add the printer's original IPP name to an already found size */
- if ((temp2 = cupsArrayFind(sizes, &temp)) != NULL) {
- snprintf(temp2->media + strlen(temp2->media),
- sizeof(temp2->media) - strlen(temp2->media),
- " %s", pwg_size);
- /* Check if we have also a borderless version of the size and add
- the original IPP name also there */
- snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
- if ((temp2 = cupsArrayFind(sizes, &temp)) != NULL)
- snprintf(temp2->media + strlen(temp2->media),
- sizeof(temp2->media) - strlen(temp2->media),
- " %s", pwg_size);
- } else
- cupsArrayAdd(sizes, &temp);
- }
- }
- }
- }
-
- if (cupsArrayCount(sizes) > 0)
- {
+ if (cupsArrayCount(sizes) > 0) {
/*
* List all of the standard sizes...
*/
@@ -1942,10 +2111,12 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*OpenUI *PageSize/%s: PickOne\n"
"*OrderDependency: 10 AnySetup *PageSize\n"
"*DefaultPageSize: %s\n", "Media Size", ppdname);
- for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes))
- {
- _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc);
+ for (size = (cups_size_t *)cupsArrayFirst(sizes); size;
+ size = (cups_size_t *)cupsArrayNext(sizes)) {
+ _cupsStrFormatd(twidth, twidth + sizeof(twidth),
+ size->width * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tlength, tlength + sizeof(tlength),
+ size->length * 72.0 / 2540.0, loc);
strlcpy(ppdsizename, size->media, sizeof(ppdsizename));
if ((ippsizename = strchr(ppdsizename, ' ')) != NULL) {
*ippsizename = '\0';
@@ -1953,17 +2124,20 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
}
if (ippsizename)
- human_readable = lookup_choice(ippsizename, "media", opt_strings_catalog,
+ human_readable = lookup_choice(ippsizename, "media",
+ opt_strings_catalog,
printer_opt_strings_catalog);
else
human_readable = NULL;
if (!human_readable) {
pwg = pwgMediaForSize(size->width, size->length);
if (pwg)
- human_readable = lookup_choice((char *)pwg->pwg, "media", opt_strings_catalog,
+ human_readable = lookup_choice((char *)pwg->pwg, "media",
+ opt_strings_catalog,
printer_opt_strings_catalog);
}
- cupsFilePrintf(fp, "*PageSize %s%s%s%s: \"<</PageSize[%s %s]>>setpagedevice\"\n", ppdsizename,
+ cupsFilePrintf(fp, "*PageSize %s%s%s%s: \"<</PageSize[%s %s]>>setpagedevice\"\n",
+ ppdsizename,
(human_readable ? "/" : ""),
(human_readable ? human_readable : ""),
(human_readable && strstr(ppdsizename, ".Borderless") ?
@@ -1975,10 +2149,12 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePrintf(fp, "*OpenUI *PageRegion/%s: PickOne\n"
"*OrderDependency: 10 AnySetup *PageRegion\n"
"*DefaultPageRegion: %s\n", "Media Size", ppdname);
- for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes))
- {
- _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc);
+ for (size = (cups_size_t *)cupsArrayFirst(sizes); size;
+ size = (cups_size_t *)cupsArrayNext(sizes)) {
+ _cupsStrFormatd(twidth, twidth + sizeof(twidth),
+ size->width * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tlength, tlength + sizeof(tlength),
+ size->length * 72.0 / 2540.0, loc);
strlcpy(ppdsizename, size->media, sizeof(ppdsizename));
if ((ippsizename = strchr(ppdsizename, ' ')) != NULL) {
*ippsizename = '\0';
@@ -1986,17 +2162,20 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
}
if (ippsizename)
- human_readable = lookup_choice(ippsizename, "media", opt_strings_catalog,
+ human_readable = lookup_choice(ippsizename, "media",
+ opt_strings_catalog,
printer_opt_strings_catalog);
else
human_readable = NULL;
if (!human_readable) {
pwg = pwgMediaForSize(size->width, size->length);
if (pwg)
- human_readable = lookup_choice((char *)pwg->pwg, "media", opt_strings_catalog,
+ human_readable = lookup_choice((char *)pwg->pwg, "media",
+ opt_strings_catalog,
printer_opt_strings_catalog);
}
- cupsFilePrintf(fp, "*PageRegion %s%s%s%s: \"<</PageSize[%s %s]>>setpagedevice\"\n", ppdsizename,
+ cupsFilePrintf(fp, "*PageRegion %s%s%s%s: \"<</PageSize[%s %s]>>setpagedevice\"\n",
+ ppdsizename,
(human_readable ? "/" : ""),
(human_readable ? human_readable : ""),
(human_readable && strstr(ppdsizename, ".Borderless") ?
@@ -2006,22 +2185,30 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePuts(fp, "*CloseUI: *PageRegion\n");
cupsFilePrintf(fp, "*DefaultImageableArea: %s\n"
- "*DefaultPaperDimension: %s\n", ppdname, ppdname);
-
- for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes))
- {
- _cupsStrFormatd(tleft, tleft + sizeof(tleft), size->left * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), size->bottom * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tright, tright + sizeof(tright), (size->width - size->right) * 72.0 / 2540.0, loc);
- _cupsStrFormatd(ttop, ttop + sizeof(ttop), (size->length - size->top) * 72.0 / 2540.0, loc);
- _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc);
+ "*DefaultPaperDimension: %s\n", ppdname, ppdname);
+
+ for (size = (cups_size_t *)cupsArrayFirst(sizes); size;
+ size = (cups_size_t *)cupsArrayNext(sizes)) {
+ _cupsStrFormatd(tleft, tleft + sizeof(tleft),
+ size->left * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom),
+ size->bottom * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tright, tright + sizeof(tright),
+ (size->width - size->right) * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(ttop, ttop + sizeof(ttop),
+ (size->length - size->top) * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(twidth, twidth + sizeof(twidth),
+ size->width * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tlength, tlength + sizeof(tlength),
+ size->length * 72.0 / 2540.0, loc);
strlcpy(ppdsizename, size->media, sizeof(ppdsizename));
if ((ippsizename = strchr(ppdsizename, ' ')) != NULL)
*ippsizename = '\0';
- cupsFilePrintf(fp, "*ImageableArea %s: \"%s %s %s %s\"\n", ppdsizename, tleft, tbottom, tright, ttop);
- cupsFilePrintf(fp, "*PaperDimension %s: \"%s %s\"\n", ppdsizename, twidth, tlength);
+ cupsFilePrintf(fp, "*ImageableArea %s: \"%s %s %s %s\"\n", ppdsizename,
+ tleft, tbottom, tright, ttop);
+ cupsFilePrintf(fp, "*PaperDimension %s: \"%s %s\"\n", ppdsizename,
+ twidth, tlength);
}
cupsArrayDelete(sizes);
@@ -2030,33 +2217,40 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Custom size support...
*/
- if (max_width > 0 && min_width < INT_MAX && max_length > 0 && min_length < INT_MAX)
- {
+ if (max_width > 0 && min_width < INT_MAX && max_length > 0 &&
+ min_length < INT_MAX) {
char tmax[256], tmin[256]; /* Min/max values */
_cupsStrFormatd(tleft, tleft + sizeof(tleft), left * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), bottom * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tright, tright + sizeof(tright), right * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom),
+ bottom * 72.0 / 2540.0, loc);
+ _cupsStrFormatd(tright, tright + sizeof(tright), right * 72.0 / 2540.0,
+ loc);
_cupsStrFormatd(ttop, ttop + sizeof(ttop), top * 72.0 / 2540.0, loc);
- cupsFilePrintf(fp, "*HWMargins: \"%s %s %s %s\"\n", tleft, tbottom, tright, ttop);
+ cupsFilePrintf(fp, "*HWMargins: \"%s %s %s %s\"\n", tleft, tbottom,
+ tright, ttop);
- _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_width * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_width * 72.0 / 2540.0, loc);
- cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s\n", tmin, tmax);
+ _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_width * 72.0 / 2540.0,
+ loc);
+ _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_width * 72.0 / 2540.0,
+ loc);
+ cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s\n", tmin,
+ tmax);
- _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_length * 72.0 / 2540.0, loc);
- _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_length * 72.0 / 2540.0, loc);
- cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s\n", tmin, tmax);
+ _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_length * 72.0 / 2540.0,
+ loc);
+ _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_length * 72.0 / 2540.0,
+ loc);
+ cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s\n", tmin,
+ tmax);
cupsFilePuts(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0\n");
cupsFilePuts(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0\n");
cupsFilePuts(fp, "*ParamCustomPageSize Orientation: 5 int 0 3\n");
cupsFilePuts(fp, "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\"\n");
}
- }
- else
- {
+ } else {
cupsArrayDelete(sizes);
cupsFilePrintf(fp,
"*%% Printer did not supply page size info via IPP, using defaults\n"
@@ -2128,13 +2322,15 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* InputSlot...
*/
- if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source", IPP_TAG_KEYWORD)) != NULL)
+ if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source",
+ IPP_TAG_KEYWORD)) != NULL)
pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
else
strlcpy(ppdname, "Unknown", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_KEYWORD)) != NULL && (count = ippGetCount(attr)) > 1)
- {
+ if ((attr = ippFindAttribute(response, "media-source-supported",
+ IPP_TAG_KEYWORD)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
static const char * const sources[][2] =
{ /* "media-source" strings */
{ "Auto", _("Automatic") },
@@ -2192,17 +2388,17 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
human_readable = lookup_option("media-source", opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *InputSlot/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *InputSlot\n"
- "*DefaultInputSlot: %s\n",
- (human_readable ? human_readable : "Media Source"),
- ppdname);
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
+ "*OrderDependency: 10 AnySetup *InputSlot\n"
+ "*DefaultInputSlot: %s\n",
+ (human_readable ? human_readable : "Media Source"),
+ ppdname);
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
keyword = ippGetString(attr, i, NULL);
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
- human_readable = lookup_choice((char *)keyword, "media-source", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword, "media-source",
+ opt_strings_catalog,
printer_opt_strings_catalog);
for (j = (int)(sizeof(sources) / sizeof(sources[0])) - 1; j >= 0; j --)
if (!strcmp(sources[j][0], ppdname)) {
@@ -2226,13 +2422,15 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* MediaType...
*/
- if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-type", IPP_TAG_KEYWORD)) != NULL)
+ if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-type",
+ IPP_TAG_KEYWORD)) != NULL)
pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
else
strlcpy(ppdname, "Unknown", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "media-type-supported", IPP_TAG_KEYWORD)) != NULL && (count = ippGetCount(attr)) > 1)
- {
+ if ((attr = ippFindAttribute(response, "media-type-supported",
+ IPP_TAG_KEYWORD)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
static const char * const media_types[][2] =
{ /* "media-type" strings */
{ "aluminum", _("Aluminum") },
@@ -2380,20 +2578,21 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
human_readable = lookup_option("media-type", opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *MediaType/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *MediaType\n"
- "*DefaultMediaType: %s\n",
- (human_readable ? human_readable : "Media Type"),
- ppdname);
- for (i = 0; i < count; i ++)
- {
+ "*OrderDependency: 10 AnySetup *MediaType\n"
+ "*DefaultMediaType: %s\n",
+ (human_readable ? human_readable : "Media Type"),
+ ppdname);
+ for (i = 0; i < count; i ++) {
keyword = ippGetString(attr, i, NULL);
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
- human_readable = lookup_choice((char *)keyword, "media-type", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword, "media-type",
+ opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(media_types) / sizeof(media_types[0])); j ++)
+ for (j = 0; j < (int)(sizeof(media_types) / sizeof(media_types[0]));
+ j ++)
if (!strcmp(media_types[j][0], keyword)) {
human_readable = (char *)_cupsLangString(lang, media_types[j][1]);
break;
@@ -2411,236 +2610,247 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* ColorModel...
*/
- if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL)
- if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL)
- if ((attr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD)) == NULL)
- attr = ippFindAttribute(response, "output-mode-supported", IPP_TAG_KEYWORD);
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) ==
+ NULL)
+ if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(response, "print-color-mode-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(response, "output-mode-supported",
+ IPP_TAG_KEYWORD);
human_readable = lookup_option("print-color-mode", opt_strings_catalog,
printer_opt_strings_catalog);
- if (attr && ippGetCount(attr) > 0)
- {
+ if (attr && ippGetCount(attr) > 0) {
const char *default_color = NULL; /* Default */
int first_choice = 1,
- have_bi_level = 0,
- have_mono = 0;
+ have_bi_level = 0,
+ have_mono = 0;
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- keyword = ippGetString(attr, i, NULL);
- /* Keyword for color/bit depth */
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ keyword = ippGetString(attr, i, NULL); /* Keyword for color/bit depth */
if (!have_bi_level &&
- (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level")))
- {
+ (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") ||
+ !strcmp(keyword, "process-bi-level"))) {
have_bi_level = 1;
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
- human_readable2 = lookup_choice("bi-level", "print-color-mode", opt_strings_catalog,
+ human_readable2 = lookup_choice("bi-level", "print-color-mode",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*ColorModel FastGray/%s: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- (human_readable2 ? human_readable2 :
- _cupsLangString(lang, _("Fast Grayscale"))));
+ (human_readable2 ? human_readable2 :
+ _cupsLangString(lang, _("Fast Grayscale"))));
if (!default_color)
default_color = "FastGray";
- }
- else if (!have_mono &&
- (!strcasecmp(keyword, "sgray_8") || !strncmp(keyword, "W8", 2) || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome")))
- {
+ } else if (!have_mono &&
+ (!strcasecmp(keyword, "sgray_8") ||
+ !strncmp(keyword, "W8", 2) ||
+ !strcmp(keyword, "monochrome") ||
+ !strcmp(keyword, "process-monochrome"))) {
have_mono = 1;
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
- human_readable2 = lookup_choice("monochrome", "print-color-mode", opt_strings_catalog,
+ human_readable2 = lookup_choice("monochrome", "print-color-mode",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*ColorModel Gray/%s: \"<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- (human_readable2 ? human_readable2 :
- _cupsLangString(lang, _("Grayscale"))));
+ (human_readable2 ? human_readable2 :
+ _cupsLangString(lang, _("Grayscale"))));
if (!default_color || !strcmp(default_color, "FastGray"))
default_color = "Gray";
- }
- else if (!strcasecmp(keyword, "sgray_16") || !strncmp(keyword, "W8-16", 5) || !strncmp(keyword, "W16", 3))
- {
+ } else if (!strcasecmp(keyword, "sgray_16") ||
+ !strncmp(keyword, "W8-16", 5) ||
+ !strncmp(keyword, "W16", 3)) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel Gray16/%s: \"<</cupsColorSpace 18/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Deep Gray (High Definition Grayscale)")));
+ _cupsLangString(lang, _("Deep Gray (High Definition Grayscale)")));
if (!default_color || !strcmp(default_color, "FastGray"))
default_color = "Gray16";
- }
- else if (!strcasecmp(keyword, "srgb_8") || !strncmp(keyword, "SRGB24", 6) || !strcmp(keyword, "color"))
- {
+ } else if (!strcasecmp(keyword, "srgb_8") ||
+ !strncmp(keyword, "SRGB24", 6) ||
+ !strcmp(keyword, "color")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
- human_readable2 = lookup_choice("color", "print-color-mode", opt_strings_catalog,
+ human_readable2 = lookup_choice("color", "print-color-mode",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*ColorModel RGB/%s: \"<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- (human_readable2 ? human_readable2 :
- _cupsLangString(lang, _("Color"))));
+ (human_readable2 ? human_readable2 :
+ _cupsLangString(lang, _("Color"))));
default_color = "RGB";
- }
- else if ((!strcasecmp(keyword, "srgb_16") || !strncmp(keyword, "SRGB48", 6)) &&
- !ippContainsString(attr, "srgb_8"))
- {
+ } else if ((!strcasecmp(keyword, "srgb_16") ||
+ !strncmp(keyword, "SRGB48", 6)) &&
+ !ippContainsString(attr, "srgb_8")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
- human_readable2 = lookup_choice("color", "print-color-mode", opt_strings_catalog,
+ human_readable2 = lookup_choice("color", "print-color-mode",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*ColorModel RGB/%s: \"<</cupsColorSpace 19/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- (human_readable2 ? human_readable2 :
- _cupsLangString(lang, _("Color"))));
+ (human_readable2 ? human_readable2 :
+ _cupsLangString(lang, _("Color"))));
default_color = "RGB";
- }
- else if (!strcasecmp(keyword, "adobe-rgb_16") || !strncmp(keyword, "ADOBERGB48", 10) ||
- !strncmp(keyword, "ADOBERGB24-48", 13))
- {
+ } else if (!strcasecmp(keyword, "adobe-rgb_16") ||
+ !strncmp(keyword, "ADOBERGB48", 10) ||
+ !strncmp(keyword, "ADOBERGB24-48", 13)) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel AdobeRGB/%s: \"<</cupsColorSpace 20/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Deep Color (Wide Color Gamut, AdobeRGB)")));
+ _cupsLangString(lang, _("Deep Color (Wide Color Gamut, AdobeRGB)")));
if (!default_color)
default_color = "AdobeRGB";
- }
- else if ((!strcasecmp(keyword, "adobe-rgb_8") || !strcmp(keyword, "ADOBERGB24")) &&
- !ippContainsString(attr, "adobe-rgb_16"))
- {
+ } else if ((!strcasecmp(keyword, "adobe-rgb_8") ||
+ !strcmp(keyword, "ADOBERGB24")) &&
+ !ippContainsString(attr, "adobe-rgb_16")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel AdobeRGB/%s: \"<</cupsColorSpace 20/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Deep Color (Wide Color Gamut, AdobeRGB)")));
+ _cupsLangString(lang, _("Deep Color (Wide Color Gamut, AdobeRGB)")));
if (!default_color)
default_color = "AdobeRGB";
- }
- else if ((!strcasecmp(keyword, "black_8") && !ippContainsString(attr, "black_16")) || !strcmp(keyword, "DEVW8"))
- {
+ } else if ((!strcasecmp(keyword, "black_8") &&
+ !ippContainsString(attr, "black_16")) ||
+ !strcmp(keyword, "DEVW8")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel DeviceGray/%s: \"<</cupsColorSpace 0/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Device Gray")));
- }
- else if (!strcasecmp(keyword, "black_16") || !strcmp(keyword, "DEVW16") || !strcmp(keyword, "DEVW8-16"))
- {
+ _cupsLangString(lang, _("Device Gray")));
+ } else if (!strcasecmp(keyword, "black_16") ||
+ !strcmp(keyword, "DEVW16") ||
+ !strcmp(keyword, "DEVW8-16")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel DeviceGray/%s: \"<</cupsColorSpace 0/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Device Gray")));
- }
- else if ((!strcasecmp(keyword, "cmyk_8") && !ippContainsString(attr, "cmyk_16")) || !strcmp(keyword, "DEVCMYK32"))
- {
+ _cupsLangString(lang, _("Device Gray")));
+ } else if ((!strcasecmp(keyword, "cmyk_8") &&
+ !ippContainsString(attr, "cmyk_16")) ||
+ !strcmp(keyword, "DEVCMYK32")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel CMYK/%s: \"<</cupsColorSpace 6/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Device CMYK")));
- }
- else if (!strcasecmp(keyword, "cmyk_16") || !strcmp(keyword, "DEVCMYK32-64") || !strcmp(keyword, "DEVCMYK64"))
- {
+ _cupsLangString(lang, _("Device CMYK")));
+ } else if (!strcasecmp(keyword, "cmyk_16") ||
+ !strcmp(keyword, "DEVCMYK32-64") ||
+ !strcmp(keyword, "DEVCMYK64")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel CMYK/%s: \"<</cupsColorSpace 6/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Device CMYK")));
- }
- else if ((!strcasecmp(keyword, "rgb_8") && !ippContainsString(attr, "rgb_16")) || !strcmp(keyword, "DEVRGB24"))
- {
+ _cupsLangString(lang, _("Device CMYK")));
+ } else if ((!strcasecmp(keyword, "rgb_8") &&
+ !ippContainsString(attr, "rgb_16")) ||
+ !strcmp(keyword, "DEVRGB24")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel DeviceRGB/%s: \"<</cupsColorSpace 1/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Device RGB")));
- }
- else if (!strcasecmp(keyword, "rgb_16") || !strcmp(keyword, "DEVRGB24-48") || !strcmp(keyword, "DEVRGB48"))
- {
+ _cupsLangString(lang, _("Device RGB")));
+ } else if (!strcasecmp(keyword, "rgb_16") ||
+ !strcmp(keyword, "DEVRGB24-48") ||
+ !strcmp(keyword, "DEVRGB48")) {
if (first_choice) {
first_choice = 0;
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *ColorModel\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Color Mode"))));
+ "*OrderDependency: 10 AnySetup *ColorModel\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Color Mode"))));
}
cupsFilePrintf(fp, "*ColorModel DeviceRGB/%s: \"<</cupsColorSpace 1/cupsBitsPerColor 16/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n",
- _cupsLangString(lang, _("Device RGB")));
+ _cupsLangString(lang, _("Device RGB")));
}
}
- if (default_color)
- {
+ if (default_pagesize != NULL) {
+ /* Here we are dealing with a cluster, if the default cluster color
+ is not supplied we set it Gray*/
+ if (default_cluster_color != NULL) {
+ default_color = default_cluster_color;
+ } else
+ default_color = "Gray";
+ }
+
+ if (default_color) {
cupsFilePrintf(fp, "*DefaultColorModel: %s\n", default_color);
cupsFilePuts(fp, "*CloseUI: *ColorModel\n");
}
@@ -2666,36 +2876,36 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if (((attr = ippFindAttribute(response, "sides-supported",
IPP_TAG_KEYWORD)) != NULL &&
ippContainsString(attr, "two-sided-long-edge")) ||
- (attr == NULL && duplex))
- {
+ (attr == NULL && duplex)) {
human_readable = lookup_option("sides", opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *Duplex/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *Duplex\n"
- "*DefaultDuplex: None\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("2-Sided Printing"))));
+ "*OrderDependency: 10 AnySetup *Duplex\n"
+ "*DefaultDuplex: None\n",
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("2-Sided Printing"))));
human_readable = lookup_choice("one-sided", "sides", opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*Duplex None/%s: \"<</Duplex false>>setpagedevice\"\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Off (1-Sided)"))));
- human_readable = lookup_choice("two-sided-long-edge", "sides", opt_strings_catalog,
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Off (1-Sided)"))));
+ human_readable = lookup_choice("two-sided-long-edge", "sides",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*Duplex DuplexNoTumble/%s: \"<</Duplex true/Tumble false>>setpagedevice\"\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Long-Edge (Portrait)"))));
- human_readable = lookup_choice("two-sided-short-edge", "sides", opt_strings_catalog,
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Long-Edge (Portrait)"))));
+ human_readable = lookup_choice("two-sided-short-edge", "sides",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*Duplex DuplexTumble/%s: \"<</Duplex true/Tumble true>>setpagedevice\"\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Short-Edge (Landscape)"))));
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Short-Edge (Landscape)"))));
cupsFilePrintf(fp, "*CloseUI: *Duplex\n");
- if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL)
- {
- keyword = ippGetString(attr, 0, NULL);
- /* Keyword value */
+ if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back",
+ IPP_TAG_KEYWORD)) != NULL) {
+ keyword = ippGetString(attr, 0, NULL); /* Keyword value */
if (!strcmp(keyword, "flipped"))
cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
@@ -2705,31 +2915,21 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePuts(fp, "*cupsBackSide: Normal\n");
else
cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
- }
- else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
- {
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- const char *dm = ippGetString(attr, i, NULL);
- /* DM value */
-
- if (!_cups_strcasecmp(dm, "DM1"))
- {
+ } else if ((attr = ippFindAttribute(response, "urf-supported",
+ IPP_TAG_KEYWORD)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ const char *dm = ippGetString(attr, i, NULL); /* DM value */
+
+ if (!_cups_strcasecmp(dm, "DM1")) {
cupsFilePuts(fp, "*cupsBackSide: Normal\n");
break;
- }
- else if (!_cups_strcasecmp(dm, "DM2"))
- {
+ } else if (!_cups_strcasecmp(dm, "DM2")) {
cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
break;
- }
- else if (!_cups_strcasecmp(dm, "DM3"))
- {
+ } else if (!_cups_strcasecmp(dm, "DM3")) {
cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
break;
- }
- else if (!_cups_strcasecmp(dm, "DM4"))
- {
+ } else if (!_cups_strcasecmp(dm, "DM4")) {
cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
break;
}
@@ -2741,13 +2941,15 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Output bin...
*/
- if ((attr = ippFindAttribute(response, "output-bin-default", IPP_TAG_ZERO)) != NULL)
+ if ((attr = ippFindAttribute(response, "output-bin-default",
+ IPP_TAG_ZERO)) != NULL)
pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
else
strlcpy(ppdname, "Unknown", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
- {
+ if ((attr = ippFindAttribute(response, "output-bin-supported",
+ IPP_TAG_ZERO)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
static const char * const output_bins[][2] =
{ /* "output-bin" strings */
{ "auto", _("Automatic") },
@@ -2798,21 +3000,22 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
human_readable = lookup_option("output-bin", opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *OutputBin/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *OutputBin\n"
- "*DefaultOutputBin: %s\n",
- (human_readable ? human_readable : "Output Bin"),
- ppdname);
+ "*OrderDependency: 10 AnySetup *OutputBin\n"
+ "*DefaultOutputBin: %s\n",
+ (human_readable ? human_readable : "Output Bin"),
+ ppdname);
attr2 = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING);
- for (i = 0; i < count; i ++)
- {
+ for (i = 0; i < count; i ++) {
keyword = ippGetString(attr, i, NULL);
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
- human_readable = lookup_choice((char *)keyword, "output-bin", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword, "output-bin",
+ opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(output_bins) / sizeof(output_bins[0])); j ++)
+ for (j = 0; j < (int)(sizeof(output_bins) / sizeof(output_bins[0]));
+ j ++)
if (!strcmp(output_bins[j][0], keyword)) {
human_readable = (char *)_cupsLangString(lang, output_bins[j][1]);
break;
@@ -2824,43 +3027,33 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
outputorderinfofound = 0;
faceupdown = 1;
firsttolast = 1;
- if (attr2 && i < ippGetCount(attr2))
- {
+ if (attr2 && i < ippGetCount(attr2)) {
outbin_properties_octet = ippGetOctetString(attr2, i, &octet_str_len);
memset(outbin_properties, 0, sizeof(outbin_properties));
memcpy(outbin_properties, outbin_properties_octet,
((size_t)octet_str_len < sizeof(outbin_properties) - 1 ?
(size_t)octet_str_len : sizeof(outbin_properties) - 1));
- if (strcasestr(outbin_properties, "pagedelivery=faceUp"))
- {
+ if (strcasestr(outbin_properties, "pagedelivery=faceUp")) {
outputorderinfofound = 1;
faceupdown = -1;
- }
- else if (strcasestr(outbin_properties, "pagedelivery=faceDown"))
- {
+ } else if (strcasestr(outbin_properties, "pagedelivery=faceDown")) {
outputorderinfofound = 1;
faceupdown = 1;
}
- if (strcasestr(outbin_properties, "stackingorder=lastToFirst"))
- {
+ if (strcasestr(outbin_properties, "stackingorder=lastToFirst")) {
outputorderinfofound = 1;
firsttolast = -1;
- }
- else if (strcasestr(outbin_properties, "stackingorder=firstToLast"))
- {
+ } else if (strcasestr(outbin_properties, "stackingorder=firstToLast")) {
outputorderinfofound = 1;
firsttolast = 1;
}
}
- if (outputorderinfofound == 0)
- {
- if (strcasestr(keyword, "face-up"))
- {
+ if (outputorderinfofound == 0) {
+ if (strcasestr(keyword, "face-up")) {
outputorderinfofound = 1;
faceupdown = -1;
}
- if (strcasestr(keyword, "face-down"))
- {
+ if (strcasestr(keyword, "face-down")) {
outputorderinfofound = 1;
faceupdown = 1;
}
@@ -2882,8 +3075,8 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* punching, etc.)
*/
- if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL)
- {
+ if ((attr = ippFindAttribute(response, "finishings-supported",
+ IPP_TAG_ENUM)) != NULL) {
const char *name; /* String name */
int value; /* Enum value */
cups_array_t *names; /* Names we've added */
@@ -2957,61 +3150,65 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
};
count = ippGetCount(attr);
- names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+ names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
fin_options = cupsArrayNew((cups_array_func_t)strcmp, NULL);
/*
* Staple/Bind/Stitch
*/
- for (i = 0; i < count; i ++)
- {
+ for (i = 0; i < count; i ++) {
value = ippGetInteger(attr, i);
name = ippEnumString("finishings", value);
- if (!strncmp(name, "staple-", 7) || !strncmp(name, "bind-", 5) || !strncmp(name, "edge-stitch-", 12) || !strcmp(name, "saddle-stitch"))
+ if (!strncmp(name, "staple-", 7) || !strncmp(name, "bind-", 5) ||
+ !strncmp(name, "edge-stitch-", 12) || !strcmp(name, "saddle-stitch"))
break;
}
- if (i < count)
- {
+ if (i < count) {
cupsArrayAdd(fin_options, "*StapleLocation");
- human_readable = lookup_choice("staple", "finishing-template", opt_strings_catalog,
+ human_readable = lookup_choice("staple", "finishing-template",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *StapleLocation/%s: PickOne\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Staple"))));
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Staple"))));
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n");
cupsFilePuts(fp, "*DefaultStapleLocation: None\n");
- cupsFilePrintf(fp, "*StapleLocation None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePrintf(fp, "*StapleLocation None/%s: \"\"\n",
+ _cupsLangString(lang, _("None")));
- for (; i < count; i ++)
- {
+ for (; i < count; i ++) {
value = ippGetInteger(attr, i);
name = ippEnumString("finishings", value);
snprintf(buf, sizeof(buf), "%d", value);
- if (strncmp(name, "staple-", 7) && strncmp(name, "bind-", 5) && strncmp(name, "edge-stitch-", 12) && strcmp(name, "saddle-stitch"))
+ if (strncmp(name, "staple-", 7) && strncmp(name, "bind-", 5) &&
+ strncmp(name, "edge-stitch-", 12) && strcmp(name, "saddle-stitch"))
continue;
if (cupsArrayFind(names, (char *)name))
- continue; /* Already did this finishing template */
+ continue; /* Already did this finishing template */
cupsArrayAdd(names, (char *)name);
human_readable = lookup_choice(buf, "finishings", opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0]));
+ j ++)
if (!strcmp(finishings[j][0], name)) {
human_readable = (char *)_cupsLangString(lang, finishings[j][1]);
break;
}
cupsFilePrintf(fp, "*StapleLocation %s%s%s: \"\"\n", name,
- (human_readable ? "/" : ""),
- (human_readable ? human_readable : ""));
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, name, name);
+ (human_readable ? "/" : ""),
+ (human_readable ? human_readable : ""));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n",
+ value, name, name);
}
cupsFilePuts(fp, "*CloseUI: *StapleLocation\n");
@@ -3021,8 +3218,7 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Fold
*/
- for (i = 0; i < count; i ++)
- {
+ for (i = 0; i < count; i ++) {
value = ippGetInteger(attr, i);
name = ippEnumString("finishings", value);
@@ -3030,21 +3226,21 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
break;
}
- if (i < count)
- {
+ if (i < count) {
cupsArrayAdd(fin_options, "*FoldType");
- human_readable = lookup_choice("fold", "finishing-template", opt_strings_catalog,
+ human_readable = lookup_choice("fold", "finishing-template",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *FoldType/%s: PickOne\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Fold"))));
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Fold"))));
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n");
cupsFilePuts(fp, "*DefaultFoldType: None\n");
- cupsFilePrintf(fp, "*FoldType None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePrintf(fp, "*FoldType None/%s: \"\"\n",
+ _cupsLangString(lang, _("None")));
- for (; i < count; i ++)
- {
+ for (; i < count; i ++) {
value = ippGetInteger(attr, i);
name = ippEnumString("finishings", value);
snprintf(buf, sizeof(buf), "%d", value);
@@ -3053,22 +3249,24 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
continue;
if (cupsArrayFind(names, (char *)name))
- continue; /* Already did this finishing template */
+ continue; /* Already did this finishing template */
cupsArrayAdd(names, (char *)name);
human_readable = lookup_choice(buf, "finishings", opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0]));
+ j ++)
if (!strcmp(finishings[j][0], name)) {
human_readable = (char *)_cupsLangString(lang, finishings[j][1]);
break;
}
cupsFilePrintf(fp, "*FoldType %s%s%s: \"\"\n", name,
- (human_readable ? "/" : ""),
- (human_readable ? human_readable : ""));
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, name, name);
+ (human_readable ? "/" : ""),
+ (human_readable ? human_readable : ""));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n",
+ value, name, name);
}
cupsFilePuts(fp, "*CloseUI: *FoldType\n");
@@ -3078,8 +3276,7 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Punch
*/
- for (i = 0; i < count; i ++)
- {
+ for (i = 0; i < count; i ++) {
value = ippGetInteger(attr, i);
name = ippEnumString("finishings", value);
@@ -3087,21 +3284,21 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
break;
}
- if (i < count)
- {
+ if (i < count) {
cupsArrayAdd(fin_options, "*PunchMedia");
- human_readable = lookup_choice("punch", "finishing-template", opt_strings_catalog,
+ human_readable = lookup_choice("punch", "finishing-template",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *PunchMedia/%s: PickOne\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Punch"))));
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Punch"))));
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n");
cupsFilePuts(fp, "*DefaultPunchMedia: None\n");
- cupsFilePrintf(fp, "*PunchMedia None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePrintf(fp, "*PunchMedia None/%s: \"\"\n",
+ _cupsLangString(lang, _("None")));
- for (; i < count; i ++)
- {
+ for (; i < count; i ++) {
value = ippGetInteger(attr, i);
name = ippEnumString("finishings", value);
snprintf(buf, sizeof(buf), "%d", value);
@@ -3110,22 +3307,24 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
continue;
if (cupsArrayFind(names, (char *)name))
- continue; /* Already did this finishing template */
+ continue; /* Already did this finishing template */
cupsArrayAdd(names, (char *)name);
human_readable = lookup_choice(buf, "finishings", opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0]));
+ j ++)
if (!strcmp(finishings[j][0], name)) {
human_readable = (char *)_cupsLangString(lang, finishings[j][1]);
break;
}
cupsFilePrintf(fp, "*PunchMedia %s%s%s: \"\"\n", name,
- (human_readable ? "/" : ""),
- (human_readable ? human_readable : ""));
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, name, name);
+ (human_readable ? "/" : ""),
+ (human_readable ? human_readable : ""));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n",
+ value, name, name);
}
cupsFilePuts(fp, "*CloseUI: *PunchMedia\n");
@@ -3135,64 +3334,72 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Booklet
*/
- if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER))
- {
+ if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER)) {
cupsArrayAdd(fin_options, "*Booklet");
- human_readable = lookup_choice("booklet-maker", "finishing-template", opt_strings_catalog,
+ human_readable = lookup_choice("booklet-maker", "finishing-template",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *Booklet/%s: Boolean\n",
- (human_readable ? human_readable :
- _cupsLangString(lang, _("Booklet"))));
+ (human_readable ? human_readable :
+ _cupsLangString(lang, _("Booklet"))));
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n");
cupsFilePuts(fp, "*DefaultBooklet: False\n");
cupsFilePuts(fp, "*Booklet False: \"\"\n");
cupsFilePuts(fp, "*Booklet True: \"\"\n");
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/booklet-maker: \"*Booklet True\"\n", IPP_FINISHINGS_BOOKLET_MAKER);
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/booklet-maker: \"*Booklet True\"\n",
+ IPP_FINISHINGS_BOOKLET_MAKER);
cupsFilePuts(fp, "*CloseUI: *Booklet\n");
}
cupsArrayDelete(names);
}
- if ((attr = ippFindAttribute(response, "finishings-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
- {
+ if ((attr = ippFindAttribute(response, "finishings-col-database",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
ipp_t *finishing_col; /* Current finishing collection */
ipp_attribute_t *finishing_attr; /* Current finishing member attribute */
cups_array_t *templates; /* Finishing templates */
- cupsFilePrintf(fp, "*OpenUI *cupsFinishingTemplate/%s: PickOne\n", _cupsLangString(lang, _("Finishing Preset")));
+ cupsFilePrintf(fp, "*OpenUI *cupsFinishingTemplate/%s: PickOne\n",
+ _cupsLangString(lang, _("Finishing Preset")));
cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n");
cupsFilePuts(fp, "*DefaultcupsFinishingTemplate: none\n");
- cupsFilePrintf(fp, "*cupsFinishingTemplate none/%s: \"\"\n", _cupsLangString(lang, _("None")));
+ cupsFilePrintf(fp, "*cupsFinishingTemplate none/%s: \"\"\n",
+ _cupsLangString(lang, _("None")));
templates = cupsArrayNew((cups_array_func_t)strcmp, NULL);
count = ippGetCount(attr);
- for (i = 0; i < count; i ++)
- {
+ for (i = 0; i < count; i ++) {
finishing_col = ippGetCollection(attr, i);
- keyword = ippGetString(ippFindAttribute(finishing_col, "finishing-template", IPP_TAG_ZERO), 0, NULL);
+ keyword = ippGetString(ippFindAttribute(finishing_col,
+ "finishing-template",
+ IPP_TAG_ZERO), 0, NULL);
if (!keyword || cupsArrayFind(templates, (void *)keyword))
continue;
- if (strncmp(keyword, "fold-", 5) && (strstr(keyword, "-bottom") || strstr(keyword, "-left") || strstr(keyword, "-right") || strstr(keyword, "-top")))
+ if (strncmp(keyword, "fold-", 5) && (strstr(keyword, "-bottom") ||
+ strstr(keyword, "-left") ||
+ strstr(keyword, "-right") ||
+ strstr(keyword, "-top")))
continue;
cupsArrayAdd(templates, (void *)keyword);
- human_readable = lookup_choice((char *)keyword, "finishing-template", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword, "finishing-template",
+ opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
human_readable = (char *)keyword;
- cupsFilePrintf(fp, "*cupsFinishingTemplate %s/%s: \"\n", keyword, human_readable);
- for (finishing_attr = ippFirstAttribute(finishing_col); finishing_attr; finishing_attr = ippNextAttribute(finishing_col))
- {
- if (ippGetValueTag(finishing_attr) == IPP_TAG_BEGIN_COLLECTION)
- {
- const char *name = ippGetName(finishing_attr);
- /* Member attribute name */
+ cupsFilePrintf(fp, "*cupsFinishingTemplate %s/%s: \"\n", keyword,
+ human_readable);
+ for (finishing_attr = ippFirstAttribute(finishing_col); finishing_attr;
+ finishing_attr = ippNextAttribute(finishing_col)) {
+ if (ippGetValueTag(finishing_attr) == IPP_TAG_BEGIN_COLLECTION) {
+ const char *name = ippGetName(finishing_attr); /* Member attribute
+ name */
if (strcmp(name, "media-size"))
cupsFilePrintf(fp, "%s\n", name);
@@ -3204,17 +3411,18 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePuts(fp, "*CloseUI: *cupsFinishingTemplate\n");
- if (cupsArrayCount(fin_options))
- {
+ if (cupsArrayCount(fin_options)) {
const char *fin_option; /* Current finishing option */
cupsFilePuts(fp, "*cupsUIConstraint finishing-template: \"*cupsFinishingTemplate");
- for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options))
+ for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option;
+ fin_option = (const char *)cupsArrayNext(fin_options))
cupsFilePrintf(fp, " %s", fin_option);
cupsFilePuts(fp, "\"\n");
cupsFilePuts(fp, "*cupsUIResolver finishing-template: \"*cupsFinishingTemplate None");
- for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options))
+ for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option;
+ fin_option = (const char *)cupsArrayNext(fin_options))
cupsFilePrintf(fp, " %s None", fin_option);
cupsFilePuts(fp, "\"\n");
}
@@ -3241,13 +3449,12 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
if ((quality =
ippFindAttribute(response, "print-quality-supported",
- IPP_TAG_ENUM)) != NULL)
- {
+ IPP_TAG_ENUM)) != NULL) {
human_readable = lookup_option("print-quality", opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
- "*DefaultcupsPrintQuality: %d\n",
+ "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
+ "*DefaultcupsPrintQuality: %d\n",
(human_readable ? human_readable :
_cupsLangString(lang, _("Print Quality"))),
IPP_QUALITY_NORMAL);
@@ -3288,12 +3495,15 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Print Optimization ...
*/
- if ((attr = ippFindAttribute(response, "print-content-optimize-default", IPP_TAG_ZERO)) != NULL)
+ if ((attr = ippFindAttribute(response, "print-content-optimize-default",
+ IPP_TAG_ZERO)) != NULL)
strlcpy(ppdname, ippGetString(attr, 0, NULL), sizeof(ppdname));
else
strlcpy(ppdname, "auto", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "print-content-optimize-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) {
+ if ((attr = ippFindAttribute(response, "print-content-optimize-supported",
+ IPP_TAG_ZERO)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
static const char * const content_optimize_types[][2] =
{ /* "print-content-optimize" strings */
{ "auto", _("Automatic") },
@@ -3305,7 +3515,8 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
{ "text-and-graphics", _("Text And Graphics") }
};
- human_readable = lookup_option("print-content-optimize", opt_strings_catalog,
+ human_readable = lookup_option("print-content-optimize",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *print-content-optimize/%s: PickOne\n"
"*OrderDependency: 10 AnySetup *print-content-optimize\n"
@@ -3315,12 +3526,19 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
for (i = 0; i < count; i ++) {
keyword = ippGetString(attr, i, NULL);
- human_readable = lookup_choice((char *)keyword, "print-content-optimize", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword,
+ "print-content-optimize",
+ opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(content_optimize_types) / sizeof(content_optimize_types[0])); j ++)
+ for (j = 0;
+ j < (int)(sizeof(content_optimize_types) /
+ sizeof(content_optimize_types[0]));
+ j ++)
if (!strcmp(content_optimize_types[j][0], keyword)) {
- human_readable = (char *)_cupsLangString(lang, content_optimize_types[j][1]);
+ human_readable =
+ (char *)_cupsLangString(lang,
+ content_optimize_types[j][1]);
break;
}
cupsFilePrintf(fp, "*print-content-optimize %s%s%s: \"\"\n",
@@ -3335,12 +3553,15 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Print Rendering Intent ...
*/
- if ((attr = ippFindAttribute(response, "print-rendering-intent-default", IPP_TAG_ZERO)) != NULL)
+ if ((attr = ippFindAttribute(response, "print-rendering-intent-default",
+ IPP_TAG_ZERO)) != NULL)
strlcpy(ppdname, ippGetString(attr, 0, NULL), sizeof(ppdname));
else
strlcpy(ppdname, "auto", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "print-rendering-intent-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) {
+ if ((attr = ippFindAttribute(response, "print-rendering-intent-supported",
+ IPP_TAG_ZERO)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
static const char * const rendering_intents[][2] =
{ /* "print-rendering-intent" strings */
{ "auto", _("Automatic") },
@@ -3351,22 +3572,31 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
{ "saturation", _("Saturation") }
};
- human_readable = lookup_option("print-rendering-intent", opt_strings_catalog,
+ human_readable = lookup_option("print-rendering-intent",
+ opt_strings_catalog,
printer_opt_strings_catalog);
cupsFilePrintf(fp, "*OpenUI *print-rendering-intent/%s: PickOne\n"
"*OrderDependency: 10 AnySetup *print-rendering-intent\n"
"*Defaultprint-rendering-intent: %s\n",
- (human_readable ? human_readable : "Print Rendering Intent"),
+ (human_readable ? human_readable :
+ "Print Rendering Intent"),
ppdname);
for (i = 0; i < count; i ++) {
keyword = ippGetString(attr, i, NULL);
- human_readable = lookup_choice((char *)keyword, "print-rendering-intent", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword,
+ "print-rendering-intent",
+ opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(rendering_intents) / sizeof(rendering_intents[0])); j ++)
+ for (j = 0;
+ j < (int)(sizeof(rendering_intents) /
+ sizeof(rendering_intents[0]));
+ j ++)
if (!strcmp(rendering_intents[j][0], keyword)) {
- human_readable = (char *)_cupsLangString(lang, rendering_intents[j][1]);
+ human_readable =
+ (char *)_cupsLangString(lang,
+ rendering_intents[j][1]);
break;
}
cupsFilePrintf(fp, "*print-rendering-intent %s%s%s: \"\"\n",
@@ -3376,16 +3606,20 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
}
cupsFilePuts(fp, "*CloseUI: *print-rendering-intent\n");
}
+
/*
* Print Scaling ...
*/
- if ((attr = ippFindAttribute(response, "print-scaling-default", IPP_TAG_ZERO)) != NULL)
+ if ((attr = ippFindAttribute(response, "print-scaling-default",
+ IPP_TAG_ZERO)) != NULL)
strlcpy(ppdname, ippGetString(attr, 0, NULL), sizeof(ppdname));
else
strlcpy(ppdname, "auto", sizeof(ppdname));
- if ((attr = ippFindAttribute(response, "print-scaling-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) {
+ if ((attr = ippFindAttribute(response, "print-scaling-supported",
+ IPP_TAG_ZERO)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
static const char * const scaling_types[][2] =
{ /* "print-scaling" strings */
{ "auto", _("Automatic") },
@@ -3405,12 +3639,17 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
for (i = 0; i < count; i ++) {
keyword = ippGetString(attr, i, NULL);
- human_readable = lookup_choice((char *)keyword, "print-scaling", opt_strings_catalog,
+ human_readable = lookup_choice((char *)keyword, "print-scaling",
+ opt_strings_catalog,
printer_opt_strings_catalog);
if (human_readable == NULL)
- for (j = 0; j < (int)(sizeof(scaling_types) / sizeof(scaling_types[0])); j ++)
+ for (j = 0;
+ j < (int)(sizeof(scaling_types) /
+ sizeof(scaling_types[0]));
+ j ++)
if (!strcmp(scaling_types[j][0], keyword)) {
- human_readable = (char *)_cupsLangString(lang, scaling_types[j][1]);
+ human_readable =
+ (char *)_cupsLangString(lang, scaling_types[j][1]);
break;
}
cupsFilePrintf(fp, "*print-scaling %s%s%s: \"\"\n",
@@ -3426,45 +3665,43 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* Presets...
*/
- if ((attr = ippFindAttribute(response, "job-presets-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL)
- {
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- ipp_t *preset = ippGetCollection(attr, i);
- /* Preset collection */
- const char *preset_name = ippGetString(ippFindAttribute(preset, "preset-name", IPP_TAG_ZERO), 0, NULL),
- /* Preset name */
- *localized_name; /* Localized preset name */
+ if ((attr = ippFindAttribute(response, "job-presets-supported",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ ipp_t *preset = ippGetCollection(attr, i); /* Preset collection */
+ const char *preset_name = /* Preset name */
+ ippGetString(ippFindAttribute(preset,
+ "preset-name", IPP_TAG_ZERO), 0, NULL),
+ *localized_name; /* Localized preset name */
ipp_attribute_t *member; /* Member attribute in preset */
const char *member_name; /* Member attribute name */
- char member_value[256]; /* Member attribute value */
+ char member_value[256]; /* Member attribute value */
if (!preset || !preset_name)
continue;
- if ((localized_name = lookup_option((char *)preset_name, opt_strings_catalog,
+ if ((localized_name = lookup_option((char *)preset_name,
+ opt_strings_catalog,
printer_opt_strings_catalog)) == NULL)
cupsFilePrintf(fp, "*APPrinterPreset %s: \"\n", preset_name);
else
- cupsFilePrintf(fp, "*APPrinterPreset %s/%s: \"\n", preset_name, localized_name);
+ cupsFilePrintf(fp, "*APPrinterPreset %s/%s: \"\n", preset_name,
+ localized_name);
- for (member = ippFirstAttribute(preset); member; member = ippNextAttribute(preset))
- {
+ for (member = ippFirstAttribute(preset); member;
+ member = ippNextAttribute(preset)) {
member_name = ippGetName(member);
if (!member_name || !strcmp(member_name, "preset-name"))
continue;
- if (!strcmp(member_name, "finishings"))
- {
- for (i = 0, count = ippGetCount(member); i < count; i ++)
- {
+ if (!strcmp(member_name, "finishings")) {
+ for (i = 0, count = ippGetCount(member); i < count; i ++) {
const char *option = NULL; /* PPD option name */
keyword = ippEnumString("finishings", ippGetInteger(member, i));
- if (!strcmp(keyword, "booklet-maker"))
- {
+ if (!strcmp(keyword, "booklet-maker")) {
option = "Booklet";
keyword = "True";
}
@@ -3472,60 +3709,68 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
option = "FoldType";
else if (!strncmp(keyword, "punch-", 6))
option = "PunchMedia";
- else if (!strncmp(keyword, "bind-", 5) || !strncmp(keyword, "edge-stitch-", 12) || !strcmp(keyword, "saddle-stitch") || !strncmp(keyword, "staple-", 7))
+ else if (!strncmp(keyword, "bind-", 5) ||
+ !strncmp(keyword, "edge-stitch-", 12) ||
+ !strcmp(keyword, "saddle-stitch") ||
+ !strncmp(keyword, "staple-", 7))
option = "StapleLocation";
if (option && keyword)
cupsFilePrintf(fp, "*%s %s\n", option, keyword);
}
- }
- else if (!strcmp(member_name, "finishings-col"))
- {
+ } else if (!strcmp(member_name, "finishings-col")) {
ipp_t *fin_col; /* finishings-col value */
- for (i = 0, count = ippGetCount(member); i < count; i ++)
- {
+ for (i = 0, count = ippGetCount(member); i < count; i ++) {
fin_col = ippGetCollection(member, i);
- if ((keyword = ippGetString(ippFindAttribute(fin_col, "finishing-template", IPP_TAG_ZERO), 0, NULL)) != NULL)
+ if ((keyword =
+ ippGetString(ippFindAttribute(fin_col,
+ "finishing-template",
+ IPP_TAG_ZERO), 0, NULL)) != NULL)
cupsFilePrintf(fp, "*cupsFinishingTemplate %s\n", keyword);
}
- }
- else if (!strcmp(member_name, "media"))
- {
+ } else if (!strcmp(member_name, "media")) {
/*
* Map media to PageSize...
*/
- if ((pwg = pwgMediaForPWG(ippGetString(member, 0, NULL))) != NULL && pwg->ppd)
+ if ((pwg = pwgMediaForPWG(ippGetString(member, 0, NULL))) != NULL &&
+ pwg->ppd)
cupsFilePrintf(fp, "*PageSize %s\n", pwg->ppd);
- }
- else if (!strcmp(member_name, "media-col"))
- {
+ } else if (!strcmp(member_name, "media-col")) {
media_col = ippGetCollection(member, 0);
- if ((media_size = ippGetCollection(ippFindAttribute(media_col, "media-size", IPP_TAG_BEGIN_COLLECTION), 0)) != NULL)
- {
- x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
- y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
- if ((pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL && pwg->ppd)
+ if ((media_size =
+ ippGetCollection(ippFindAttribute(media_col,
+ "media-size",
+ IPP_TAG_BEGIN_COLLECTION),
+ 0)) != NULL) {
+ x_dim = ippFindAttribute(media_size, "x-dimension",
+ IPP_TAG_INTEGER);
+ y_dim = ippFindAttribute(media_size, "y-dimension",
+ IPP_TAG_INTEGER);
+ if ((pwg = pwgMediaForSize(ippGetInteger(x_dim, 0),
+ ippGetInteger(y_dim, 0))) != NULL &&
+ pwg->ppd)
cupsFilePrintf(fp, "*PageSize %s\n", pwg->ppd);
}
- if ((keyword = ippGetString(ippFindAttribute(media_col, "media-source", IPP_TAG_ZERO), 0, NULL)) != NULL)
- {
+ if ((keyword = ippGetString(ippFindAttribute(media_col,
+ "media-source",
+ IPP_TAG_ZERO), 0,
+ NULL)) != NULL) {
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
cupsFilePrintf(fp, "*InputSlot %s\n", keyword);
}
- if ((keyword = ippGetString(ippFindAttribute(media_col, "media-type", IPP_TAG_ZERO), 0, NULL)) != NULL)
- {
+ if ((keyword = ippGetString(ippFindAttribute(media_col, "media-type",
+ IPP_TAG_ZERO), 0,
+ NULL)) != NULL) {
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
cupsFilePrintf(fp, "*MediaType %s\n", keyword);
}
- }
- else if (!strcmp(member_name, "print-quality"))
- {
+ } else if (!strcmp(member_name, "print-quality")) {
/*
* Map print-quality to cupsPrintQuality...
*/
@@ -3536,15 +3781,13 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
/* cupsPrintQuality values */
if (qval >= IPP_QUALITY_DRAFT && qval <= IPP_QUALITY_HIGH)
- cupsFilePrintf(fp, "*cupsPrintQuality %s\n", qualities[qval - IPP_QUALITY_DRAFT]);
- }
- else if (!strcmp(member_name, "output-bin"))
- {
- pwg_ppdize_name(ippGetString(member, 0, NULL), ppdname, sizeof(ppdname));
+ cupsFilePrintf(fp, "*cupsPrintQuality %s\n",
+ qualities[qval - IPP_QUALITY_DRAFT]);
+ } else if (!strcmp(member_name, "output-bin")) {
+ pwg_ppdize_name(ippGetString(member, 0, NULL), ppdname,
+ sizeof(ppdname));
cupsFilePrintf(fp, "*OutputBin %s\n", ppdname);
- }
- else if (!strcmp(member_name, "sides"))
- {
+ } else if (!strcmp(member_name, "sides")) {
keyword = ippGetString(member, 0, NULL);
if (keyword && !strcmp(keyword, "one-sided"))
cupsFilePuts(fp, "*Duplex None\n");
@@ -3552,9 +3795,7 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
cupsFilePuts(fp, "*Duplex DuplexNoTumble\n");
else if (keyword && !strcmp(keyword, "two-sided-short-edge"))
cupsFilePuts(fp, "*Duplex DuplexTumble\n");
- }
- else
- {
+ } else {
/*
* Add attribute name and value as-is...
*/
@@ -3569,6 +3810,17 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
}
/*
+ * constraints
+ */
+ if(conflicts != NULL) {
+ char* constraint;
+ for (constraint = (char *)cupsArrayFirst(conflicts); constraint;
+ constraint = (char *)cupsArrayNext(conflicts)) {
+ cupsFilePrintf(fp,"%s",constraint);
+ }
+ }
+
+ /*
* Close up and return...
*/
@@ -3594,7 +3846,7 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
* If we get here then there was a problem creating the PPD...
*/
- bad_ppd:
+ bad_ppd:
if (common_res) cupsArrayDelete(common_res);
if (common_def) free(common_def);
@@ -3607,7 +3859,9 @@ ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
unlink(buffer);
*buffer = '\0';
- _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Printer does not support required IPP attributes or document formats."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL,
+ _("Printer does not support required IPP attributes or document formats."),
+ 1);
return (NULL);
}
@@ -3734,8 +3988,7 @@ _pwgPageSizeForMedia(
* Copy or generate a PageSize name...
*/
- if (media->ppd)
- {
+ if (media->ppd) {
/*
* Use a standard Adobe name...
*/
@@ -3745,17 +3998,14 @@ _pwgPageSizeForMedia(
else if (!media->pwg || !strncmp(media->pwg, "custom_", 7) ||
(sizeptr = strchr(media->pwg, '_')) == NULL ||
(dimptr = strchr(sizeptr + 1, '_')) == NULL ||
- (size_t)(dimptr - sizeptr) > namesize)
- {
+ (size_t)(dimptr - sizeptr) > namesize) {
/*
* Use a name of the form "wNNNhNNN"...
*/
snprintf(name, namesize, "w%dh%d", (int)PWG_TO_POINTS(media->width),
(int)PWG_TO_POINTS(media->length));
- }
- else
- {
+ } else {
/*
* Copy the size name from class_sizename_dimensions...
*/
@@ -3783,14 +4033,11 @@ pwg_ppdize_name(const char *ipp, /* I - IPP keyword */
*name = (char)toupper(*ipp++);
- for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;)
- {
- if (*ipp == '-' && _cups_isalpha(ipp[1]))
- {
+ for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;) {
+ if (*ipp == '-' && _cups_isalpha(ipp[1])) {
ipp ++;
*ptr++ = (char)toupper(*ipp++ & 255);
- }
- else
+ } else
*ptr++ = *ipp++;
}
@@ -3814,17 +4061,14 @@ pwg_ppdize_resolution(
{
ipp_res_t units; /* Units for resolution */
-
*xres = ippGetResolution(attr, element, yres, &units);
- if (units == IPP_RES_PER_CM)
- {
+ if (units == IPP_RES_PER_CM) {
*xres = (int)(*xres * 2.54);
*yres = (int)(*yres * 2.54);
}
- if (name && namesize > 4)
- {
+ if (name && namesize > 4) {
if (*xres == *yres)
snprintf(name, namesize, "%ddpi", *xres);
else
@@ -3832,7 +4076,3 @@ pwg_ppdize_resolution(
}
}
#endif /* HAVE_CUPS_1_6 */
-
-/*
- * End
- */
diff --git a/cupsfilters/ppdgenerator.h b/cupsfilters/ppdgenerator.h
index 4bf642e2e..5e03e6d1b 100644
--- a/cupsfilters/ppdgenerator.h
+++ b/cupsfilters/ppdgenerator.h
@@ -55,9 +55,35 @@ extern "C" {
extern char ppdgenerator_msg[1024];
+/* Data structure for resolution (X x Y dpi) */
+typedef struct res_s {
+ int x, y;
+} res_t;
+
char *ppdCreateFromIPP(char *buffer, size_t bufsize,
ipp_t *response, const char *make_model,
const char *pdl, int color, int duplex);
+char *ppdCreateFromIPP2(char *buffer, size_t bufsize,
+ ipp_t *response, const char *make_model,
+ const char *pdl, int color, int duplex,
+ cups_array_t* conflicts,
+ cups_array_t *sizes,char* default_pagesize,
+ const char *default_cluster_color);
+int compare_resolutions(void *resolution_a, void *resolution_b,
+ void *user_data);
+res_t * ippResolutionToRes(ipp_attribute_t *attr, int index);
+cups_array_t * resolutionArrayNew();
+cups_array_t* generate_sizes(ipp_t *response,
+ ipp_attribute_t **defattr,
+ int *min_length,
+ int* min_width,
+ int* max_length,
+ int* max_width,
+ int* bottom,
+ int* left,
+ int* right,
+ int* top,
+ char* ppdname);
#endif /* HAVE_CUPS_1_6 */
# ifdef __cplusplus
@@ -65,8 +91,3 @@ char *ppdCreateFromIPP(char *buffer, size_t bufsize,
# endif /* __cplusplus */
#endif /* !_CUPS_FILTERS_PPDGENERATOR_H_ */
-
-/*
- * End
- */
-
diff --git a/utils/cups-browsed.c b/utils/cups-browsed.c
index 5327e8796..db335aefa 100644
--- a/utils/cups-browsed.c
+++ b/utils/cups-browsed.c
@@ -66,54 +66,54 @@
#ifdef HAVE_LDAP
-LDAP *BrowseLDAPHandle = NULL;
- /* Handle to LDAP server */
-char *BrowseLDAPBindDN = NULL,
- /* LDAP login DN */
- *BrowseLDAPDN = NULL,
- /* LDAP search DN */
- *BrowseLDAPPassword = NULL,
- /* LDAP login password */
- *BrowseLDAPServer = NULL,
- /* LDAP server to use */
- *BrowseLDAPFilter = NULL;
- /* LDAP query filter */
-int BrowseLDAPUpdate = TRUE,
- /* enables LDAP updates */
- BrowseLDAPInitialised = FALSE;
- /* the init stuff has been done */
+LDAP *BrowseLDAPHandle = NULL;
+ /* Handle to LDAP server */
+char *BrowseLDAPBindDN = NULL,
+ /* LDAP login DN */
+ *BrowseLDAPDN = NULL,
+ /* LDAP search DN */
+ *BrowseLDAPPassword = NULL,
+ /* LDAP login password */
+ *BrowseLDAPServer = NULL,
+ /* LDAP server to use */
+ *BrowseLDAPFilter = NULL;
+ /* LDAP query filter */
+int BrowseLDAPUpdate = TRUE,
+ /* enables LDAP updates */
+ BrowseLDAPInitialised = FALSE;
+ /* the init stuff has been done */
# ifdef HAVE_LDAP_SSL
-char *BrowseLDAPCACertFile = NULL;
- /* LDAP CA CERT file to use */
+char *BrowseLDAPCACertFile = NULL;
+ /* LDAP CA CERT file to use */
# endif /* HAVE_LDAP_SSL */
#endif /* HAVE_LDAP */
#ifdef HAVE_LDAP
#define LDAP_BROWSE_FILTER "(objectclass=cupsPrinter)"
-static LDAP *ldap_connect(void);
-static LDAP *ldap_reconnect(void);
-static void ldap_disconnect(LDAP *ld);
-static int ldap_search_rec(LDAP *ld, char *base, int scope,
- char *filter, char *attrs[],
- int attrsonly, LDAPMessage **res);
-static int ldap_getval_firststring(LDAP *ld, LDAPMessage *entry,
- char *attr, char *retval,
- unsigned long maxsize);
-static void ldap_freeres(LDAPMessage *entry);
+static LDAP *ldap_connect(void);
+static LDAP *ldap_reconnect(void);
+static void ldap_disconnect(LDAP *ld);
+static int ldap_search_rec(LDAP *ld, char *base, int scope,
+ char *filter, char *attrs[],
+ int attrsonly, LDAPMessage **res);
+static int ldap_getval_firststring(LDAP *ld, LDAPMessage *entry,
+ char *attr, char *retval,
+ unsigned long maxsize);
+static void ldap_freeres(LDAPMessage *entry);
# ifdef HAVE_LDAP_REBIND_PROC
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
- LDAP_CONST char *refsp,
- ber_tag_t request,
- ber_int_t msgid,
- void *params);
+static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
+ LDAP_CONST char *refsp,
+ ber_tag_t request,
+ ber_int_t msgid,
+ void *params);
# else
-static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
- char **dnp,
- char **passwdp,
- int *authmethodp,
- int freeit,
+static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
+ char **dnp,
+ char **passwdp,
+ int *authmethodp,
+ int freeit,
void *arg);
# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
# endif /* HAVE_LDAP_REBIND_PROC */
@@ -128,6 +128,7 @@ static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
/* Attribute to mark a CUPS queue as created by us */
#define CUPS_BROWSED_MARK "cups-browsed"
+#define AUTO_OPTION "auto"
/* Attribute to tell the implicitclass backend the destination queue for
the current job */
@@ -154,11 +155,11 @@ static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
/* Status of remote printer */
typedef enum printer_status_e {
- STATUS_UNCONFIRMED = 0, /* Generated in a previous session */
- STATUS_CONFIRMED, /* Avahi confirms UNCONFIRMED printer */
- STATUS_TO_BE_CREATED, /* Scheduled for creation */
- STATUS_DISAPPEARED, /* Scheduled for removal */
- STATUS_TO_BE_RELEASED /* Scheduled for release from cups-browsed */
+ STATUS_UNCONFIRMED = 0, /* Generated in a previous session */
+ STATUS_CONFIRMED, /* Avahi confirms UNCONFIRMED printer */
+ STATUS_TO_BE_CREATED, /* Scheduled for creation */
+ STATUS_DISAPPEARED, /* Scheduled for removal */
+ STATUS_TO_BE_RELEASED /* Scheduled for release from cups-browsed */
} printer_status_t;
/* Data structure for remote printers */
@@ -329,6 +330,44 @@ typedef enum autoshutdown_inactivity_type_e {
NO_JOBS
} autoshutdown_inactivity_type_t;
+typedef struct media_size_s{
+ int x;
+ int y;
+}media_size_t;
+
+typedef struct pagesize_range_s{
+ int x_dim_min;
+ int x_dim_max;
+ int y_dim_min;
+ int y_dim_max;
+}pagesize_range_t;
+
+typedef struct media_col_s{
+ int x,y,top_margin,bottom_margin,left_margin,right_margin;
+ char *media_source,*media_type;
+}media_col_t;
+
+typedef struct default_str_attribute_s{
+ char* value;
+ int count;
+}default_str_attribute_t;
+
+typedef struct resolution_count_s{
+ res_t *res;
+ int count;
+}resolution_count_t;
+
+typedef struct mediacol_count_s{
+ media_col_t *data;
+ int count;
+}mediacol_count_t;
+
+typedef struct pagesize_count_s{
+ char* pagesize;
+ int count;
+}pagesize_count_t;
+
+
cups_array_t *remote_printers;
static char *alt_config_file = NULL;
static cups_array_t *command_line_config;
@@ -359,14 +398,14 @@ static int avahi_present = 0;
#endif /* HAVE_AVAHI */
#ifdef HAVE_LDAP
static const char * const ldap_attrs[] =/* CUPS LDAP attributes */
- {
- "printerDescription",
- "printerLocation",
- "printerMakeAndModel",
- "printerType",
- "printerURI",
- NULL
- };
+ {
+ "printerDescription",
+ "printerLocation",
+ "printerMakeAndModel",
+ "printerType",
+ "printerURI",
+ NULL
+ };
#endif /* HAVE_LDAP */
static guint queues_timer_id = 0;
static int browsesocket = -1;
@@ -406,7 +445,7 @@ static cups_array_t *clusters;
static load_balancing_type_t LoadBalancingType = QUEUE_ON_CLIENT;
static char *DefaultOptions = NULL;
static int terminating = 0; /* received SIGTERM, ignore callbacks,
- break loops */
+ break loops */
static int in_shutdown = 0;
static int autoshutdown = 0;
static int autoshutdown_avahi = 0;
@@ -426,6 +465,27 @@ static char remote_default_printer_file[1024];
static char save_options_file[1024];
static char debug_log_file[1024];
+/*Contains ppd keywords which are written by ppdgenerator.c in the ppd file.*/
+static char* ppd_keywords[] =
+ {
+ "PageSize",
+ "PageRegion",
+ "InputSlot",
+ "MediaType",
+ "ColorModel",
+ "Duplex",
+ "OutputBin",
+ "StapleLocation",
+ "FoldType",
+ "PunchMedia",
+ "Booklet",
+ "cupsFinishingTemplate",
+ "cupsPrintQuality",
+ "print-content-optimize",
+ "print-rendering-intent",
+ "print-scaling",
+ };
+
/* Static global variable for indicating we have reached the HTTP timeout */
static int timeout_reached = 0;
@@ -529,7 +589,7 @@ ippGetString(ipp_attribute_t *attr,
return (attr->values[element].string.text);
}
-ipp_attribute_t *
+ipp_attribute_t *
ippFirstAttribute(ipp_t *ipp)
{
if (!ipp)
@@ -596,7 +656,7 @@ start_debug_logging()
lfp = fopen(debug_log_file, "a+");
if (lfp == NULL) {
fprintf(stderr, "cups-browsed: ERROR: Failed creating debug log file %s\n",
- debug_log_file);
+ debug_log_file);
exit(1);
}
}
@@ -634,6 +694,449 @@ debug_printf(const char *format, ...) {
}
}
}
+/*
+ * 'create_media_size()' - Create a media-size value.
+ */
+
+static ipp_t * /* O - media-col collection */
+create_media_size(int width, /* I - x-dimension in 2540ths */
+ int length) /* I - y-dimension in 2540ths */
+{
+ ipp_t *media_size = ippNew(); /* media-size value */
+
+ ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension",
+ width);
+ ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension",
+ length);
+
+ return (media_size);
+}
+
+/*
+ * 'create_media_range()' - Create a pagesize-range value.
+ */
+
+static ipp_t *
+create_media_range(int x_dim_min_width,
+ int x_dim_max_width,
+ int y_dim_min_height,
+ int y_dim_max_height)
+{
+ ipp_t *media_size = ippNew();
+ ippAddRange(media_size, IPP_TAG_PRINTER, "x-dimension",
+ x_dim_min_width, x_dim_max_width);
+ ippAddRange(media_size, IPP_TAG_PRINTER, "y-dimension",
+ y_dim_min_height, y_dim_max_height);
+ return (media_size);
+}
+
+void *
+copy_media_size(void *size, void *user_data)
+{
+ media_size_t *data = (media_size_t *)size;
+ media_size_t *copy;
+
+ copy = (media_size_t *)calloc(1, sizeof(media_size_t));
+ if (copy) {
+ copy->x = data->x;
+ copy->y = data->y;
+ }
+ return copy;
+}
+
+void*
+copy_range_size(void *range, void* user_data)
+{
+ pagesize_range_t *data = (pagesize_range_t *)range;
+ pagesize_range_t *copy;
+
+ copy = (pagesize_range_t *)calloc(1,sizeof(pagesize_range_t));
+ if (copy) {
+ copy->x_dim_min = data->x_dim_min;
+ copy->x_dim_max = data->x_dim_max;
+ copy->y_dim_min = data->y_dim_min;
+ copy->y_dim_max = data->y_dim_max;
+ }
+ return copy;
+}
+
+void *
+copy_media(void *media, void *user_data)
+{
+ media_col_t *data = (media_col_t *)media;
+ media_col_t *copy;
+
+ copy = (media_col_t *)calloc(1, sizeof(media_col_t));
+ if (copy) {
+ copy->x = data->x;
+ copy->y = data->y;
+ copy->left_margin=data->left_margin;
+ copy->right_margin=data->right_margin;
+ copy->top_margin=data->top_margin;
+ copy->bottom_margin=data->bottom_margin;
+ copy->media_source = NULL;
+ copy->media_type = NULL;
+ if (data->media_source != NULL) {
+ copy->media_source = (char *)malloc(sizeof(char)*32);
+ strcpy(copy->media_source,data->media_source);
+ }
+ if (data->media_type != NULL) {
+ copy->media_type = (char *)malloc(sizeof(char)*32);;
+ strcpy(copy->media_type,data->media_type);
+ }
+ }
+ return copy;
+}
+
+void* copy_media_count(void *media, void* user_data)
+{
+ mediacol_count_t *prev = (mediacol_count_t *)media;
+ mediacol_count_t *copy;
+
+ copy = (mediacol_count_t*)calloc(1,sizeof(mediacol_count_t));
+ if (copy) {
+ copy->data = copy_media(prev->data,NULL);
+ copy->count = prev->count;
+ }
+ return copy;
+}
+
+void* copy_pagesize_count(void *pagesize_count, void* user_data)
+{
+ pagesize_count_t *prev = (pagesize_count_t *)pagesize_count;
+ pagesize_count_t *copy;
+
+ copy = (pagesize_count_t*)calloc(1,sizeof(pagesize_count_t));
+ copy->pagesize = malloc(sizeof(char)*32);
+ if (copy) {
+ strcpy(copy->pagesize,prev->pagesize);
+ copy->count = prev->count;
+ }
+ return copy;
+}
+
+int compare_pagesize_count(void* pagesize_a, void* pagesize_b,void* user_data)
+{
+ pagesize_count_t *a = (pagesize_count_t *) pagesize_a;
+ pagesize_count_t *b = (pagesize_count_t *) pagesize_b;
+
+ if (!strcmp(a->pagesize,b->pagesize))
+ return 0;
+ return 1;
+}
+
+/*
+ * 'create_media_col()' - Create a media-col value.
+ */
+
+static ipp_t *
+create_media_col(int width,
+ int length,
+ int left_margin,
+ int right_margin,
+ int top_margin,
+ int bottom_margin,
+ char *media_source,
+ char *media_type)
+{
+ ipp_t *media_col = ippNew(), /* media-col value */
+ *media_size = create_media_size(width, length);
+
+ ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size);
+ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "media-bottom-margin",bottom_margin);
+ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "media-left-margin", left_margin);
+ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "media-right-margin",right_margin);
+ ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "media-top-margin", top_margin);
+ if (media_source != NULL)
+ ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "media-source", NULL,media_source);
+ if (media_type != NULL)
+ ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "media-type", NULL,media_type);
+ ippDelete(media_size);
+
+ return (media_col);
+}
+
+int
+compare_mediasize(void *media_a, void *media_b,
+ void *user_data)
+{
+ media_size_t *a=(media_size_t *)media_a;
+ media_size_t *b=(media_size_t *)media_b;
+
+ if (a->x < b->x)
+ return -1;
+ else if (a->x > b->x)
+ return 1;
+ else{
+ if (a->y == b->y)
+ return 0;
+ else if (a->y < b->y)
+ return -1;
+ return 1;
+ }
+}
+
+int compare_int(int a, int b)
+{
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ return 0;
+}
+
+int compare_rangesize(void *range_a,void *range_b,
+ void *user_data)
+{
+ pagesize_range_t *a = (pagesize_range_t *)range_a;
+ pagesize_range_t *b = (pagesize_range_t *)range_b;
+ int value;
+
+ if ((value = compare_int(a->x_dim_min, b->x_dim_min)) == 0) {
+ if ((value = compare_int(a->x_dim_max, b->x_dim_max)) == 0) {
+ if ((value = compare_int(a->y_dim_min, b->y_dim_min)) == 0) {
+ if ((value = compare_int(a->y_dim_max, b->y_dim_max)) == 0) {
+ return 0;
+ }
+ }
+ }
+ }
+ return value;
+}
+
+int compare_media(void *media_a, void *media_b,
+ void *user_data)
+{
+ media_col_t *a=(media_col_t *)media_a;
+ media_col_t *b=(media_col_t *)media_b;
+ int value;
+
+ if ((value = compare_int(a->x, b->x)) == 0) {
+ if ((value = compare_int(a->y, b->y)) == 0) {
+ if ((value = compare_int(a->top_margin, b->top_margin)) == 0) {
+ if ((value = compare_int(a->bottom_margin, b->bottom_margin)) == 0) {
+ if ((value = compare_int(a->right_margin, b->right_margin)) == 0) {
+ if ((value = compare_int(a->left_margin, b->left_margin)) == 0) {
+ if (a->media_source == NULL && b->media_source == NULL) {
+ if (a->media_type == NULL && b->media_type == NULL)
+ return 0;
+ if (a->media_type == NULL)
+ return -1;
+ if (b->media_type == NULL)
+ return 1;
+ return strcmp(a->media_type, b->media_type);
+ }
+ if (a->media_source == NULL)
+ return -1;
+ if (b->media_source == NULL)
+ return 1;
+ if (!strcmp(a->media_source, b->media_source)) {
+ if (a->media_type==NULL && b->media_type == NULL)
+ return 0;
+ if (a->media_type==NULL)
+ return -1;
+ if (b->media_type==NULL)
+ return 1;
+ return strcmp(a->media_type, b->media_type);
+ }
+ else
+ return strcmp(a->media_source, b->media_source);
+ }
+ }
+ }
+ }
+ }
+ }
+ return value;
+}
+
+int compare_media_count(void* media_a, void* media_b,void* user_data)
+{
+ mediacol_count_t *a = (mediacol_count_t*) media_a;
+ mediacol_count_t *b = (mediacol_count_t*) media_b;
+
+ return (compare_media(a->data, b->data, NULL));
+}
+
+void *
+copy_default_str(void *data, void *user_data)
+{
+ default_str_attribute_t *prev = (default_str_attribute_t *)data;
+ default_str_attribute_t *copy;
+
+ copy = (default_str_attribute_t *)calloc(1, sizeof(default_str_attribute_t));
+ if (copy) {
+ copy->value = (char *)malloc(sizeof(char)*100);
+ copy->value = strdup(prev->value);
+ copy->count = prev->count;
+ }
+ return copy;
+}
+
+
+int
+compare_default_str(void *defstr_a, void *defstr_b,
+ void *user_data)
+{
+ default_str_attribute_t *a=(default_str_attribute_t *)defstr_a;
+ default_str_attribute_t *b=(default_str_attribute_t *)defstr_b;
+
+ return strcmp(a->value, b->value);
+}
+
+void *
+copy_counted_res(void *data, void *user_data)
+{
+ resolution_count_t *prev = (resolution_count_t *)data;
+ resolution_count_t *copy;
+
+ copy = (resolution_count_t *)calloc(1, sizeof(resolution_count_t));
+ if (copy) {
+ copy->res = (res_t *)malloc(sizeof(res_t));
+ copy->res->x = prev->res->x;
+ copy->res->y = prev->res->y;
+ copy->count = prev->count;
+ }
+ return copy;
+}
+
+
+int
+compare_counted_res(void *defres_a, void *defres_b,
+ void *user_data)
+{
+ resolution_count_t *a=(resolution_count_t *)defres_a;
+ resolution_count_t *b=(resolution_count_t *)defres_b;
+
+ return compare_resolutions(a->res, b->res, NULL);
+}
+
+/*
+ * 'pwg_compare_sizes()' - Compare two media sizes...
+ */
+
+static int /* O - Result of comparison */
+pwg_compare_sizes(cups_size_t *a, /* I - First media size */
+ cups_size_t *b) /* I - Second media size */
+{
+ return (strcmp(a->media, b->media));
+}
+
+
+/*
+ * 'pwg_copy_size()' - Copy a media size.
+ */
+
+static cups_size_t * /* O - New media size */
+pwg_copy_size(cups_size_t *size) /* I - Media size to copy */
+{
+ cups_size_t *newsize = (cups_size_t *)calloc(1, sizeof(cups_size_t));
+ /* New media size */
+
+ if (newsize)
+ memcpy(newsize, size, sizeof(cups_size_t));
+
+ return (newsize);
+}
+
+/* Function returns number of jobs queued on printer*/
+int /* O - Number of jobs */
+get_number_of_jobs(http_t *http, /* I - Connection to server */
+ const char *uri, /* I - uri of printer */
+ int myjobs, /* I - 0 = all users, 1 = mine */
+ int whichjobs) /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
+{
+ int n; /* Number of jobs */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ int id; /* job-id */
+ static const char * const attrs[] = /* Requested attributes */
+ {
+ "job-id"
+ };
+
+ httpReconnect2(http, 30000, NULL);
+
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requesting-user-name
+ * which-jobs
+ * my-jobs
+ * requested-attributes
+ */
+
+
+ /* Generating IPP Request */
+ request = ippNewRequest(IPP_OP_GET_JOBS);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ if (myjobs)
+ ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
+ if (whichjobs == CUPS_WHICHJOBS_COMPLETED)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "which-jobs", NULL, "completed");
+ else if (whichjobs == CUPS_WHICHJOBS_ALL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "which-jobs", NULL, "all");
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
+ NULL, attrs);
+
+ /* Do the request and get back a response... */
+ n = 0;
+ if ((response = cupsDoRequest(http, request, "/")) != NULL) {
+ for (attr = ippFirstAttribute(response); attr;
+ attr = ippNextAttribute(response)){
+ /* Skip leading attributes until we hit a job... */
+ while (attr && ippGetGroupTag(attr) != IPP_TAG_JOB)
+ attr = ippNextAttribute(response);
+
+ if (!attr)
+ break;
+ /* Pull the needed attributes from this job */
+ id = 0;
+ while (attr && ippGetGroupTag(attr) == IPP_TAG_JOB) {
+ if (!strcmp(ippGetName(attr), "job-id") &&
+ ippGetValueTag(attr) == IPP_TAG_INTEGER)
+ id = ippGetInteger(attr,0);
+ attr = ippNextAttribute(response);
+ }
+
+ /* See if we have everything needed */
+ if (!id){
+ if (!attr)
+ break;
+ else
+ continue;
+ }
+ /* Incrementing number of jobs*/
+ n ++;
+ if (!attr)
+ break;
+ }
+
+ ippDelete(response);
+ }
+
+ if (n == 0)
+ return (-1);
+ else
+ return (n);
+}
static const char *
password_callback (const char *prompt,
@@ -686,6 +1189,2069 @@ http_close_local (void)
}
}
+int /* O - 1 on match, 0 otherwise */
+_cups_isalpha(int ch) /* I - Character to test */
+{
+ return ((ch >= 'A' && ch <= 'Z') ||
+ (ch >= 'a' && ch <= 'z'));
+}
+
+int /* O - 1 on match, 0 otherwise */
+_cups_islower(int ch) /* I - Character to test */
+{
+ return (ch >= 'a' && ch <= 'z');
+}
+
+int /* O - Converted character */
+_cups_toupper(int ch) /* I - Character to convert */
+{
+ return (_cups_islower(ch) ? ch - 'a' + 'A' : ch);
+}
+
+static void
+pwg_ppdize_name(const char *ipp, /* I - IPP keyword */
+ char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ char *ptr, /* Pointer into name buffer */
+ *end; /* End of name buffer */
+ *name = (char)toupper(*ipp++);
+
+ for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;)
+ {
+ if (*ipp == '-' && _cups_isalpha(ipp[1]))
+ {
+ ipp ++;
+ *ptr++ = (char)toupper(*ipp++ & 255);
+ }
+ else
+ *ptr++ = *ipp++;
+ }
+
+ *ptr = '\0';
+}
+
+void add_mimetype_attributes(char* cluster_name, ipp_t **merged_attributes)
+{
+ int count,i;
+ remote_printer_t *p;
+ const char *str;
+ char *q;
+ cups_array_t *list;
+ ipp_attribute_t *attr;
+ int num_value,attr_no;
+ char* attributes[] = {
+ "document-format-supported"
+ };
+
+ for (attr_no = 0; attr_no < 1; attr_no++) {
+ if ((list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return ;
+
+ num_value=0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no], IPP_TAG_MIMETYPE)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ str = ippGetString(attr, i, NULL);
+ if (!cupsArrayFind(list, (void *)str)){
+ cupsArrayAdd(list, (void *)str);
+ num_value++;
+ }
+ }
+ }
+ }
+ if (num_value != 0){
+ char *values[num_value];
+ for (q = (char *)cupsArrayFirst(list),i=0;
+ q;
+ q = (char *)cupsArrayNext(list),i++) {
+ values[i]=malloc(sizeof(char)*strlen(q)+1);
+ strncpy(values[i],q,strlen(q)+1);
+ }
+ ippAddStrings(*merged_attributes, IPP_TAG_PRINTER,IPP_TAG_MIMETYPE,
+ attributes[attr_no], num_value, NULL,
+ (const char * const *)values);
+ }
+ }
+ cupsArrayDelete(list);
+}
+
+/*add_tagzero_attributes - Adds attribute to the merged_attribute variable for the cluster.
+ This function adds attribute with value tag IPP_TAG_ZERO */
+void add_tagzero_attributes(char* cluster_name,ipp_t **merged_attributes)
+{
+ int count,i;
+ remote_printer_t *p;
+ const char *str;
+ char *q;
+ cups_array_t *list;
+ ipp_attribute_t *attr;
+ int num_value,attr_no;
+ char* attributes[] = {
+ "media-supported",
+ "output-bin-supported",
+ "print-content-optimize-supported",
+ "print-rendering-intent-supported",
+ "print-scaling-supported"
+ };
+
+ for (attr_no = 0; attr_no < 5; attr_no++) {
+ /* Cups Array to store the values for the attribute*/
+ if ((list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return ;
+
+ num_value=0;
+ /* Iterating over all the printers in the cluster*/
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no], IPP_TAG_ZERO)) != NULL) {
+ count = ippGetCount(attr);
+ for(i = 0; i < count; i ++) {
+ /* Pick next format from attribute */
+ str = ippGetString(attr, i, NULL);
+ /* Add format to list, skip duplicates */
+ if (!cupsArrayFind(list, (void *)str)){
+ cupsArrayAdd(list, (void *)str);
+ num_value++;
+ }
+ }
+ }
+ }
+ if (num_value != 0){
+ char *values[num_value];
+ /* Transferring attributes value from cups Array to char* array*/
+ for (q = (char *)cupsArrayFirst(list), i = 0; q;
+ q = (char *)cupsArrayNext(list), i++) {
+ values[i]=malloc(sizeof(char)*strlen(q)+1);
+ strncpy(values[i],q,strlen(q)+1);
+ }
+ ippAddStrings(*merged_attributes, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD),
+ attributes[attr_no], num_value, NULL,
+ (const char * const *)values);
+ }
+ }
+ cupsArrayDelete(list);
+}
+
+/*add_keyword_attributes - Adds attributes to the merged_attribute variable for the cluster.
+ This function adds attributes with value tag IPP_TAG_KEYWORD*/
+void add_keyword_attributes(char* cluster_name,ipp_t **merged_attributes)
+{
+ int count,i;
+ remote_printer_t *p;
+ const char *str;
+ char *q;
+ cups_array_t *list;
+ ipp_attribute_t *attr;
+ int num_value,attr_no;
+ char* attributes[] = {
+ "output-mode-supported",
+ "urf-supported",
+ "pwg-raster-document-type-supported",
+ "media-source-supported",
+ "media-type-supported",
+ "print-color-mode-supported",
+ "sides-supported"
+ };
+
+ for (attr_no = 0; attr_no < 7; attr_no ++) {
+ if ((list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return;
+
+ num_value=0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no], IPP_TAG_KEYWORD)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i++) {
+ str = ippGetString(attr, i, NULL);
+ if (!cupsArrayFind(list, (void *)str)){
+ cupsArrayAdd(list, (void *)str);
+ num_value++;
+ }
+ }
+ }
+ }
+ if (num_value!=0) {
+ char *values[num_value];
+ for (q = (char *)cupsArrayFirst(list), i=0;
+ q;
+ q = (char *)cupsArrayNext(list), i++) {
+ values[i]=malloc(sizeof(char)*strlen(q)+1);
+ strncpy(values[i],q,strlen(q)+1);
+ }
+ ippAddStrings(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ attributes[attr_no], num_value, NULL,
+ (const char * const *)values);
+ }
+ }
+ cupsArrayDelete(list);
+}
+
+/*add_enum_attributes - Adds attributes to the merged_attribute variable for the cluster.
+ This function adds attributes with value tag IPP_TAG_BEGIN_ENUM*/
+void add_enum_attributes(char* cluster_name,ipp_t **merged_attributes)
+{
+ int count,i,value;
+ remote_printer_t *p;
+ char *str;
+ char *q;
+ cups_array_t *list;
+ ipp_attribute_t *attr;
+ int num_value,attr_no;
+ char* attributes[] = {
+ "finishings-supported",
+ "print-quality-supported",
+ "finishing-template",
+ "finishings-col-database"
+ };
+
+ for (attr_no = 0; attr_no < 4; attr_no ++) {
+ if ((list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return ;
+ str = malloc(sizeof(char)*10);
+ num_value=0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no], IPP_TAG_ENUM)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ value = ippGetInteger(attr, i);
+ sprintf(str,"%d",value);
+ if (!cupsArrayFind(list, (void *)str)){
+ cupsArrayAdd(list, (void *)str);
+ num_value++;
+ }
+ }
+ }
+ }
+
+ if (num_value != 0){
+ int values[num_value];
+ for (q = (char *)cupsArrayFirst(list), i = 0;q;
+ q = (char *)cupsArrayNext(list), i++) {
+ values[i] = atoi(q);
+ }
+ ippAddIntegers(*merged_attributes, IPP_TAG_PRINTER,IPP_TAG_ENUM,
+ attributes[attr_no], num_value,values);
+ }
+ }
+ cupsArrayDelete(list);
+}
+
+/*add_margin_attribute - Adds margin attributes to the merged_attribute variable for the cluster.*/
+void add_margin_attributes(char* cluster_name,ipp_t **merged_attributes)
+{
+ int count,i,value;
+ remote_printer_t *p;
+ char *str;
+ char *q;
+ cups_array_t *list;
+ ipp_attribute_t *attr;
+ int num_value,attr_no;
+ char* attributes[] = {
+ "media-bottom-margin-supported",
+ "media-left-margin-supported",
+ "media-top-margin-supported",
+ "media-right-margin-supported"
+ };
+
+ for (attr_no = 0; attr_no < 4; attr_no++) {
+ if ((list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return ;
+ str = malloc(sizeof(char)*10);
+ num_value=0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no], IPP_TAG_INTEGER)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i++) {
+ value = ippGetInteger(attr, i);
+ sprintf(str,"%d",value);
+ if (!cupsArrayFind(list, (void *)str)){
+ cupsArrayAdd(list, (void *)str);
+ num_value++;
+ }
+ }
+ }
+ }
+
+ if (num_value != 0){
+ int values[num_value];
+ for (q = (char *)cupsArrayFirst(list),i=0;q;
+ q = (char *)cupsArrayNext(list),i++) {
+ values[i] = atoi(q);
+ }
+ ippAddIntegers(*merged_attributes, IPP_TAG_PRINTER,IPP_TAG_INTEGER,
+ attributes[attr_no], num_value,values);
+ }
+ }
+ cupsArrayDelete(list);
+}
+
+/*add_resolution_attributes - Adds resolution attributes to the merged_attribute
+ for the cluster*/
+void add_resolution_attributes(char* cluster_name, ipp_t **merged_attributes)
+{
+ int count,i;
+ remote_printer_t *p;
+ ipp_attribute_t *attr;
+ int num_resolution,attr_no;
+ cups_array_t *res_array;
+ res_t *res,*resolution;
+ char* attributes[] = {
+ "printer-resolution-supported",
+ "pwg-raster-document-resolution-supported",
+ "pclm-source-resolution-supported"
+ };
+
+ for (attr_no = 0; attr_no < 3; attr_no++) {
+ res_array = NULL;
+ res_array = resolutionArrayNew();
+ num_resolution = 0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no], IPP_TAG_RESOLUTION)) != NULL){
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ if ((res = ippResolutionToRes(attr, i)) != NULL &&
+ cupsArrayFind(res_array, res) == NULL) {
+ cupsArrayAdd(res_array, res);
+ num_resolution++;
+ }
+ }
+ }
+ }
+ if (num_resolution) {
+ int xres[num_resolution],yres[num_resolution];
+ for (i = 0, resolution=cupsArrayFirst(res_array); resolution;
+ i ++, resolution = cupsArrayNext(res_array)) {
+ xres[i]=resolution->x;
+ yres[i]=resolution->y;
+ }
+ ippAddResolutions(*merged_attributes, IPP_TAG_PRINTER,attributes[attr_no],
+ num_resolution,IPP_RES_PER_INCH,xres,yres);
+ }
+ }
+ cupsArrayDelete(res_array);
+}
+
+/*add_mediasize_attribute - Adds media sizes to the merged_attribute for the printer*/
+void add_mediasize_attributes(char* cluster_name, ipp_t **merged_attributes)
+{
+ int count,i=0;
+ remote_printer_t *p;
+ ipp_attribute_t *attr,*media_size_supported,*x_dim,*y_dim;
+ int num_sizes,attr_no,num_ranges;
+ ipp_t *media_size;
+ cups_array_t *sizes,*size_ranges;
+ media_size_t *temp,*media_s;
+ pagesize_range_t *temp_range;
+ char* attributes[] = {
+ "media-size-supported",
+ };
+
+ sizes = cupsArrayNew3((cups_array_func_t)compare_mediasize, NULL, NULL, 0,
+ (cups_acopy_func_t)copy_media_size,
+ (cups_afree_func_t)free);
+ size_ranges = cupsArrayNew3((cups_array_func_t)compare_rangesize, NULL, NULL,
+ 0,
+ (cups_acopy_func_t)copy_range_size,
+ (cups_afree_func_t)free);
+ temp = (media_size_t *)malloc(sizeof(media_size_t));
+ temp_range = (pagesize_range_t *)malloc(sizeof(pagesize_range_t));
+ for (attr_no = 0; attr_no < 1; attr_no ++) {
+ num_sizes = 0;
+ num_ranges = 0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs, attributes[attr_no],
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ media_size = ippGetCollection(attr, i);
+ x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
+ y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
+ if (ippGetValueTag(x_dim) == IPP_TAG_RANGE ||
+ ippGetValueTag(y_dim) == IPP_TAG_RANGE) {
+ if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
+ temp_range->x_dim_min = ippGetRange(x_dim, 0,
+ &temp_range->x_dim_max);
+ else
+ temp_range->x_dim_min = temp_range->x_dim_max =
+ ippGetInteger(x_dim, 0);
+
+ if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
+ temp_range->y_dim_min = ippGetRange(y_dim, 0,
+ &temp_range->y_dim_max);
+ else
+ temp_range->y_dim_min = temp_range->y_dim_max =
+ ippGetInteger(y_dim, 0);
+ if (!cupsArrayFind(size_ranges,temp_range)) {
+ cupsArrayAdd(size_ranges, temp_range);
+ num_ranges++;
+ }
+ } else {
+ temp->x = ippGetInteger(x_dim,0);
+ temp->y = ippGetInteger(y_dim,0);
+ if (!cupsArrayFind(sizes, temp)){
+ cupsArrayAdd(sizes, temp);
+ num_sizes++;
+ }
+ }
+ }
+ }
+ }
+ media_size_supported =
+ ippAddCollections(*merged_attributes,
+ IPP_TAG_PRINTER,attributes[attr_no],
+ num_sizes+num_ranges, NULL);
+ if (num_sizes){
+ for (i = 0, media_s = cupsArrayFirst(sizes);
+ media_s; i ++, media_s = cupsArrayNext(sizes)) {
+ ipp_t *size = create_media_size(media_s->x,media_s->y);
+ ippSetCollection(*merged_attributes, &media_size_supported, i, size);
+ ippDelete(size);
+ }
+ }
+ if (num_ranges) {
+ for (temp_range = cupsArrayFirst(size_ranges); temp_range;
+ i++, temp_range = cupsArrayNext(size_ranges)) {
+ ipp_t *size_range = create_media_range(temp_range->x_dim_min,
+ temp_range->x_dim_max,
+ temp_range->y_dim_min,
+ temp_range->y_dim_max);
+ ippSetCollection(*merged_attributes, &media_size_supported, i,
+ size_range);
+ ippDelete(size_range);
+ }
+ }
+ }
+ cupsArrayDelete(sizes);
+}
+
+/*add_mediadatabase_attribute - Adds media-col-database attributes for the cluster*/
+void
+add_mediadatabase_attributes(char* cluster_name, ipp_t **merged_attributes)
+{
+ int count, i;
+ remote_printer_t *p;
+ ipp_attribute_t *attr, *media_attr;
+ int num_database, attr_no;
+ cups_array_t *media_database;
+ media_col_t *temp, *media_data;
+ ipp_t *media_col,
+ *media_size, *current_media;
+ ipp_attribute_t *media_col_database;
+ char media_source[32], media_type[32];
+ char* attributes[] = {
+ "media-col-database",
+ };
+ temp = (media_col_t *)malloc(sizeof(media_col_t));
+ media_database = cupsArrayNew3((cups_array_func_t)compare_media,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)copy_media,
+ (cups_afree_func_t)free);
+ for (attr_no = 0; attr_no < 1; attr_no++) {
+ num_database = 0;
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs,attributes[attr_no],
+ IPP_TAG_BEGIN_COLLECTION)) != NULL){
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ media_col = ippGetCollection(attr, i);
+ media_size =
+ ippGetCollection(ippFindAttribute(media_col,
+ "media-size",
+ IPP_TAG_BEGIN_COLLECTION), 0);
+ temp->x = ippGetInteger(ippFindAttribute(media_size, "x-dimension",
+ IPP_TAG_ZERO),0);
+ temp->y = ippGetInteger(ippFindAttribute(media_size, "y-dimension",
+ IPP_TAG_ZERO),0);
+ temp->top_margin =
+ ippGetInteger(ippFindAttribute(media_col,
+ "media-top-margin",
+ IPP_TAG_INTEGER),
+ 0);
+ temp->bottom_margin =
+ ippGetInteger(ippFindAttribute(media_col,
+ "media-bottom-margin",
+ IPP_TAG_INTEGER),
+ 0);
+ temp->left_margin =
+ ippGetInteger(ippFindAttribute(media_col,
+ "media-left-margin",
+ IPP_TAG_INTEGER),
+ 0);
+ temp->right_margin =
+ ippGetInteger(ippFindAttribute(media_col,
+ "media-right-margin",
+ IPP_TAG_INTEGER),
+ 0);
+ media_type[0]='\0';
+ media_source[0]='\0';
+ temp->media_source = NULL;
+ temp->media_type = NULL;
+ if ((media_attr = ippFindAttribute(media_col,
+ "media-type",
+ IPP_TAG_KEYWORD)) != NULL)
+ pwg_ppdize_name(ippGetString(media_attr, 0, NULL), media_type,
+ sizeof(media_type));
+ if (strlen(media_type) > 1) {
+ temp->media_type = (char*)malloc(sizeof(char)*32);
+ strcpy(temp->media_type, media_type);
+ }
+ if ((media_attr = ippFindAttribute(media_col, "media-source",
+ IPP_TAG_KEYWORD)) != NULL) {
+ pwg_ppdize_name(ippGetString(media_attr, 0, NULL), media_source,
+ sizeof(media_source));
+ }
+ if(strlen(media_source) > 1) {
+ temp->media_source = (char*)malloc(sizeof(char)*32);
+ strcpy(temp->media_source, media_source);
+ }
+
+ if (!cupsArrayFind(media_database, temp)) {
+ cupsArrayAdd(media_database, temp);
+ num_database++;
+ }
+ }
+ }
+ }
+
+ if (num_database !=0 ) {
+ media_col_database = ippAddCollections(*merged_attributes,
+ IPP_TAG_PRINTER,
+ attributes[attr_no],
+ num_database, NULL);
+ for (i = 0, media_data = cupsArrayFirst(media_database); media_data;
+ i ++, media_data = cupsArrayNext(media_database)) {
+ current_media = create_media_col(media_data->x, media_data->y,
+ media_data->left_margin,
+ media_data->right_margin,
+ media_data->top_margin,
+ media_data->bottom_margin,
+ media_data->media_source,
+ media_data->media_type);
+ ippSetCollection(*merged_attributes, &media_col_database, i,
+ current_media);
+ ippDelete(current_media);
+ }
+ }
+ }
+ cupsArrayDelete(media_database);
+}
+
+/*add_jobpresets_attribute - Adds presets attributes for the cluster*/
+void add_jobpresets_attribute(char* cluster_name, ipp_t ** merged_attributes)
+{
+ int count,i,num_preset=0,preset_no=0;
+ remote_printer_t *p;
+ cups_array_t *list,*added_presets;
+ ipp_t *preset;
+ ipp_attribute_t *attr;
+ const char *preset_name;
+ ipp_attribute_t *preset_attribute;
+
+ if ((list = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return;
+
+ if ((added_presets = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return;
+
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs, "job-presets-supported",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ preset = ippGetCollection(attr, i);
+ preset_name = ippGetString(ippFindAttribute(preset, "preset-name",
+ IPP_TAG_ZERO), 0, NULL);
+ if (!cupsArrayFind(list, (void *)preset_name)) {
+ cupsArrayAdd(list, (void *)preset_name);
+ num_preset++;
+ }
+ }
+ }
+ }
+
+ if (num_preset == 0)
+ return;
+
+ preset_attribute = ippAddCollections(*merged_attributes, IPP_TAG_PRINTER,
+ "job-presets-supported",num_preset,
+ NULL);
+
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if ((attr = ippFindAttribute(p->prattrs, "job-presets-supported",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ preset = ippGetCollection(attr, i);
+ preset_name = ippGetString(ippFindAttribute(preset, "preset-name",
+ IPP_TAG_ZERO), 0, NULL);
+ if (!cupsArrayFind(added_presets, (void *)preset_name)) {
+ cupsArrayAdd(added_presets, (void *)preset_name);
+ ippSetCollection(*merged_attributes, &preset_attribute, i, preset);
+ preset_no++;
+ } else
+ continue;
+ }
+ }
+ }
+}
+
+/* get_pagesize: Function returns the standard/custom page size using
+ generate_sizes function from ppdgenerator.c*/
+static cups_array_t* get_pagesize(ipp_t *printer_attributes) {
+ cups_array_t *sizes,*page_media;
+ cups_size_t *size;
+ ipp_attribute_t *defattr;
+ char *ppdsizename,*temp;
+ int min_length=INT_MAX, min_width=INT_MAX,
+ max_length=0,max_width=0,
+ bottom,left,right,top;
+ char ppdname[41];
+
+ ppdsizename = (char *)malloc(sizeof(char)*128);
+ sizes = generate_sizes(printer_attributes, &defattr, &min_length, &min_width,
+ &max_length,&max_width,
+ &bottom,&left,&right,&top,ppdname);
+ if ((page_media = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ for (size = (cups_size_t *)cupsArrayFirst(sizes); size;
+ size = (cups_size_t *)cupsArrayNext(sizes)) {
+ strcpy(ppdsizename, size->media);
+ if (( temp = strchr(ppdsizename, ' ')) != NULL)
+ *temp = '\0';
+ cupsArrayAdd(page_media, ppdsizename);
+ }
+ free(ppdsizename);
+ return page_media;
+}
+
+/*get_mediadata - This function extracts the MediaType, InputSlot and OutputBin
+ supported, using IPP Response message of the printer*/
+cups_array_t* get_mediadata(ipp_t *printer_attributes,char* requested_attr){
+ ipp_attribute_t *attr;
+ int count,i;
+ cups_array_t *media_data;
+ const char *keyword; /* Keyword value */
+ char ppdname[41];
+ char requested_option[30];
+
+ if (!strcmp(requested_attr,"MediaType"))
+ strcpy(requested_option,"media-type-supported");
+ else if (!strcmp(requested_attr,"InputSlot"))
+ strcpy(requested_option,"media-source-supported");
+ else if (!strcmp(requested_attr,"OutputBin"))
+ strcpy(requested_option,"output-bin-supported");
+ else
+ return NULL;
+
+ if ((media_data = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, requested_option,
+ IPP_TAG_ZERO)) != NULL
+ && (count = ippGetCount(attr)) > 1) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ keyword = ippGetString(attr, i, NULL);
+ pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
+ cupsArrayAdd(media_data, ppdname);
+ }
+ }
+ return media_data;
+}
+
+/*get_mimetype_attribute - Adds attributes to the merged_attribute variable for
+ the cluster. This function adds attribute with value
+ tag IPP_TAG_MIMETYPE*/
+cups_array_t* get_mimetype_attributes(ipp_t *printer_attributes)
+{
+ int count,i;
+ const char *str;
+ cups_array_t *document_formats;
+ ipp_attribute_t *attr;
+
+ if ((document_formats = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+
+ if ((attr = ippFindAttribute(printer_attributes, "document-format-supported",
+ IPP_TAG_MIMETYPE)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ str = ippGetString(attr, i, NULL);
+ if (!cupsArrayFind(document_formats, (void *)str))
+ cupsArrayAdd(document_formats, (void *)str);
+ }
+ }
+ return document_formats;
+}
+
+/*get_staplelocation: This function returns the supported staple locations of
+ the printer */
+cups_array_t* get_staplelocation(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ int count,value,i;
+ const char *name;
+ cups_array_t *staplelocation;
+
+ if ((staplelocation = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "finishings-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+ if (!strncmp(name, "staple-", 7) || !strncmp(name, "bind-", 5) ||
+ !strncmp(name, "edge-stitch-", 12) || !strcmp(name, "saddle-stitch"))
+ if (!cupsArrayFind(staplelocation,(void*)name))
+ cupsArrayAdd(staplelocation,(void*)name);
+ }
+ }
+ return staplelocation;
+}
+
+/*get_foldtype - Function returns the supported foldtype for the printer*/
+cups_array_t* get_foldtype(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ int count,value,i;
+ const char *name;
+ cups_array_t *foldtype;
+
+ if ((foldtype = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "finishings-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+ if (!strncmp(name, "fold-", 5))
+ if (!cupsArrayFind(foldtype,(void*)name))
+ cupsArrayAdd(foldtype,(void*)name);
+ }
+ }
+ return foldtype;
+}
+
+/*get_finishings - Function returns the supported finishings for the printer*/
+cups_array_t* get_finishings(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ int count,value,i;
+ const char *name;
+ cups_array_t *finishings;
+
+ if ((finishings = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "finishings-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+ if (!cupsArrayFind(finishings,(void*)name))
+ cupsArrayAdd(finishings,(void*)name);
+ }
+ }
+ return finishings;
+}
+
+
+/*get_punchmedia - Returns the puchmedia supported by the printer*/
+cups_array_t* get_punchmedia(ipp_t *printer_attributes){
+ ipp_attribute_t *attr;
+ int count,value,i;
+ const char *name;
+ cups_array_t *punchmedia;
+
+ if ((punchmedia = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "finishings-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+ if (!strncmp(name, "punch-", 6))
+ if (!cupsArrayFind(punchmedia,(void*)name))
+ cupsArrayAdd(punchmedia,(void*)name);
+ }
+ }
+ return punchmedia;
+}
+
+/*get_duplex - Function returns whether the printer support Duplex,
+ DuplexTumble, DuplexNoTumble using attributes returned by the
+ IPP Request*/
+cups_array_t* get_duplex(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ int count,i;
+ cups_array_t *duplex_options;
+ const char *str;
+
+ if ((duplex_options = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "sides-supported",
+ IPP_TAG_KEYWORD)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ str = ippGetString(attr, i, NULL);
+ if (!strcmp(str,"one-sided"))
+ cupsArrayAdd(duplex_options,"None");
+ else if (!strcmp(str,"two-sided-long-edge"))
+ cupsArrayAdd(duplex_options,"DuplexNoTumble");
+ else if (!strcmp(str,"two-sided-short-edge"))
+ cupsArrayAdd(duplex_options,"DuplexTumble");
+ }
+ }
+ return duplex_options;
+}
+
+/* get_colormodel - Returns the colormodel supported by the printer*/
+cups_array_t* get_colormodel(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ int count, i;
+ cups_array_t *colormodel;
+ const char *keyword;
+ int have_bi_level = 0,
+ have_mono = 0;
+
+ if ((colormodel = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "urf-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(printer_attributes,
+ "pwg-raster-document-type-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(printer_attributes,
+ "print-color-mode-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(printer_attributes, "output-mode-supported",
+ IPP_TAG_KEYWORD);
+
+ if (attr && ippGetCount(attr) > 0) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ keyword = ippGetString(attr, i, NULL);
+ if (!have_bi_level && (!strcasecmp(keyword, "black_1") ||
+ !strcmp(keyword, "bi-level") ||
+ !strcmp(keyword, "process-bi-level"))) {
+ cupsArrayAdd(colormodel,"FastGray");
+ have_bi_level = 1;
+ } else if (!have_mono &&(!strcasecmp(keyword, "sgray_8") ||
+ !strncmp(keyword, "W8", 2) ||
+ !strcmp(keyword, "monochrome") ||
+ !strcmp(keyword, "process-monochrome"))) {
+ have_mono = 1;
+ cupsArrayAdd(colormodel,"Gray");
+ } else if (!strcasecmp(keyword, "sgray_16") ||
+ !strncmp(keyword, "W8-16", 5) || !strncmp(keyword, "W16", 3))
+ cupsArrayAdd(colormodel,"Gray16");
+ else if (!strcasecmp(keyword, "srgb_8") ||
+ !strncmp(keyword, "SRGB24", 6) || !strcmp(keyword, "color"))
+ cupsArrayAdd(colormodel,"RGB");
+ else if ((!strcasecmp(keyword, "srgb_16") ||
+ !strncmp(keyword, "SRGB48", 6)) &&
+ !ippContainsString(attr, "srgb_8"))
+ cupsArrayAdd(colormodel,"RGB");
+ else if (!strcasecmp(keyword, "adobe-rgb_16") ||
+ !strncmp(keyword, "ADOBERGB48", 10) ||
+ !strncmp(keyword, "ADOBERGB24-48", 13))
+ cupsArrayAdd(colormodel,"AdobeRGB");
+ else if ((!strcasecmp(keyword, "adobe-rgb_8") ||
+ !strcmp(keyword, "ADOBERGB24")) &&
+ !ippContainsString(attr, "adobe-rgb_16"))
+ cupsArrayAdd(colormodel,"AdobeRGB");
+ else if ((!strcasecmp(keyword, "black_8") &&
+ !ippContainsString(attr, "black_16")) ||
+ !strcmp(keyword, "DEVW8"))
+ cupsArrayAdd(colormodel,"DeviceGray");
+ else if (!strcasecmp(keyword, "black_16") ||
+ !strcmp(keyword, "DEVW16") || !strcmp(keyword, "DEVW8-16"))
+ cupsArrayAdd(colormodel,"DeviceGray");
+ else if ((!strcasecmp(keyword, "cmyk_8") &&
+ !ippContainsString(attr, "cmyk_16")) ||
+ !strcmp(keyword, "DEVCMYK32"))
+ cupsArrayAdd(colormodel,"CMYK");
+ else if (!strcasecmp(keyword, "cmyk_16") ||
+ !strcmp(keyword, "DEVCMYK32-64") ||
+ !strcmp(keyword, "DEVCMYK64"))
+ cupsArrayAdd(colormodel,"CMYK");
+ else if ((!strcasecmp(keyword, "rgb_8") &&
+ !ippContainsString(attr, "rgb_16")) ||
+ !strcmp(keyword, "DEVRGB24"))
+ cupsArrayAdd(colormodel,"DeviceRGB");
+ else if (!strcasecmp(keyword, "rgb_16") ||
+ !strcmp(keyword, "DEVRGB24-48") ||
+ !strcmp(keyword, "DEVRGB48"))
+ cupsArrayAdd(colormodel,"DeviceRGB");
+ }
+ }
+ return colormodel;
+}
+
+/* get_printquality - Returns the print qualities supported by the printer*/
+cups_array_t* get_printquality(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *quality;
+ cups_array_t *print_qualities;
+
+ if ((print_qualities = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((quality=ippFindAttribute(printer_attributes, "print-quality-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
+ cupsArrayAdd(print_qualities,"3");
+ if (ippContainsInteger(quality, IPP_QUALITY_HIGH))
+ cupsArrayAdd(print_qualities,"5");
+ cupsArrayAdd(print_qualities,"4");
+ }
+ return print_qualities;
+}
+
+/* get_job_data - Returns the job_sheets,multiple-document-handling supported
+ by the printer*/
+cups_array_t* get_job_data(ipp_t *printer_attributes,char* requested_attr)
+{
+ ipp_attribute_t *attr;
+ cups_array_t *job_data;
+ int i, count;
+ const char* str;
+
+ if ((job_data = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr=ippFindAttribute(printer_attributes, requested_attr,
+ IPP_TAG_KEYWORD)) != NULL) {
+ for(i = 0, count = ippGetCount(attr); i < count; i ++) {
+ str = ippGetString(attr, i, NULL);
+ if (!cupsArrayFind(job_data, (void *)str))
+ cupsArrayAdd(job_data, (void*)str);
+ }
+ }
+ return job_data;
+}
+
+/* get_finishingtemplate - Returns the Finishing Templates supported by the
+ printer*/
+cups_array_t* get_finishingtemplate(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ cups_array_t *finishing_templates;
+ ipp_t *finishing_col; /* Current finishing collection */
+ int count,i;
+ const char *keyword;
+
+ if ((finishing_templates = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "finishings-col-database",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++) {
+ finishing_col = ippGetCollection(attr, i);
+ keyword = ippGetString(ippFindAttribute(finishing_col,
+ "finishing-template",
+ IPP_TAG_ZERO), 0, NULL);
+ if (!keyword || cupsArrayFind(finishing_templates, (void *)keyword))
+ continue;
+ if (strncmp(keyword, "fold-", 5) && (strstr(keyword, "-bottom") ||
+ strstr(keyword, "-left") ||
+ strstr(keyword, "-right") ||
+ strstr(keyword, "-top")))
+ continue;
+ cupsArrayAdd(finishing_templates, (void*)keyword);
+ }
+ }
+ return finishing_templates;
+}
+
+/* get_printing_data - Returns the print-content-optimize,print-rendering-intent
+ and print-scaling attributes for the printer*/
+cups_array_t* get_printing_data(ipp_t *printer_attributes,char* requested_attr){
+ ipp_attribute_t *attr;
+ int count,i;
+ cups_array_t *printing_support;
+ const char *keyword;
+ char requested_option[40];
+
+ if(!strcmp(requested_attr,"print-content-optimize"))
+ strcpy(requested_option,"print-content-optimize-supported");
+ else if (!strcmp(requested_attr,"print-rendering-intent"))
+ strcpy(requested_option,"print-rendering-intent-supported");
+ else if(!strcmp(requested_attr,"print-scaling"))
+ strcpy(requested_option,"print-scaling-supported");
+ else if (!strcmp(requested_attr,"job-sheets-supported"))
+ strcpy(requested_option,"job-sheets-supported");
+ else
+ return NULL;
+
+ if ((printing_support = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, requested_option,
+ IPP_TAG_ZERO)) != NULL &&
+ (count = ippGetCount(attr)) > 1) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ keyword = ippGetString(attr, i, NULL);
+ cupsArrayAdd(printing_support, (void *)keyword);
+ }
+ }
+ return printing_support;
+}
+
+/*get_presets - Returns a list of presets name supported by the printer*/
+cups_array_t* get_presets(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ int count,i;
+ cups_array_t *presets;
+ ipp_t *preset ;
+ const char *preset_name;
+
+ if ((presets = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "job-presets-supported",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL
+ && (count = ippGetCount(attr)) > 1) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ preset = ippGetCollection(attr, i);
+ preset_name = ippGetString(ippFindAttribute(preset, "preset-name",
+ IPP_TAG_ZERO), 0, NULL);
+ if(!cupsArrayFind(presets,(void*)preset_name))
+ cupsArrayAdd(presets,(void *)preset_name);
+ }
+ }
+ return presets;
+}
+
+/* get_booklet - Returns True if booklet is supported */
+cups_array_t* get_booklet(ipp_t *printer_attributes)
+{
+ ipp_attribute_t *attr;
+ cups_array_t *booklet;
+
+ if ((booklet = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ if ((attr = ippFindAttribute(printer_attributes, "finishings-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER)) {
+ /* Assuming that the printer which supports Booklet also supports
+ printing without Booklet, so for this printer we will return
+ both "True" and "False" */
+ cupsArrayAdd(booklet,"True");
+ }
+ }
+ cupsArrayAdd(booklet,"False");
+ return booklet;
+}
+
+/* get_supported_options - Function returns various attributes supported by the
+ printer, such as PageSize,ColorModel etc.*/
+cups_array_t* get_supported_options(ipp_t *printer_attributes, char* option)
+{
+ if(!strcmp(option,"PageSize") || !strcmp(option,"PageRegion"))
+ return get_pagesize(printer_attributes);
+ else if(!strcmp(option,"MediaType") || !strcmp(option,"InputSlot") ||
+ !strcmp(option,"OutputBin"))
+ return get_mediadata(printer_attributes,option);
+ else if (!strcmp(option,"StapleLocation"))
+ return get_staplelocation(printer_attributes);
+ else if (!strcmp(option,"FoldType"))
+ return get_foldtype(printer_attributes);
+ else if (!strcmp(option,"PunchMedia"))
+ return get_punchmedia(printer_attributes);
+ else if (!strcmp(option,"cupsFinishingTemplate"))
+ return get_finishingtemplate(printer_attributes);
+ else if (!strcmp(option,"cupsPrintQuality"))
+ return get_printquality(printer_attributes);
+ else if (!strcmp(option,"job-sheets-supported") ||
+ !strcmp(option,"print-content-optimize") ||
+ !strcmp(option,"print-rendering-intent") ||
+ !strcmp(option,"print-scaling"))
+ return get_printing_data(printer_attributes,option);
+ else if (!strcmp(option,"APPrinterPreset"))
+ return get_presets(printer_attributes);
+ else if(!strcmp(option,"Booklet"))
+ return get_booklet(printer_attributes);
+ else if(!strcmp(option,"ColorModel"))
+ return get_colormodel(printer_attributes);
+ else if (!strcmp(option,"Duplex"))
+ return get_duplex(printer_attributes);
+ else if (!strcmp(option,"multiple-document-handling-supported") ||
+ !strcmp(option,"cover-back-supported") ||
+ !strcmp(option,"cover-front-supported") ||
+ !strcmp(option,"cover-type-supported") ||
+ !strcmp(option,"media-type-supported"))
+ return get_job_data(printer_attributes,option);
+ else if (!strcmp(option,"finishings-supported"))
+ return get_finishings(printer_attributes);
+ return NULL;
+}
+
+/*check_printer_with_options - Checks whether a printer in an cluster supports
+ option1 for keyword at value idx_option1 in
+ ppd_keywords[] and option2 for keyword at value
+ idx_option2*/
+int check_printer_with_options(char* cluster_name,int idx_option1,char* option1,
+ int idx_option2,char* option2)
+{
+ remote_printer_t *p;
+ cups_array_t *first_attributes_value;
+ cups_array_t *second_attributes_value;
+ char *borderless_pagesize;
+ int option1_is_size=0, option2_is_size=0;
+ char t[] = ".Borderless";
+
+ borderless_pagesize = malloc(sizeof(char)*32);
+ if (!strcmp(ppd_keywords[idx_option1],"PageSize") ||
+ !strcmp(ppd_keywords[idx_option1],"PageRegion")) {
+ /* Check that we are generating .Borderless for the correct size, i.e We
+ are generating 4x5.Borderless for 4x5 and not generating
+ 4x5.Borderless.Borderless for 4x5.Borderless */
+ if (strlen(option1) >= 11 && !strcmp(&option1[strlen(option1)-strlen(t)], t))
+ ;
+ else {
+ strcat(borderless_pagesize,option1);
+ strcat(borderless_pagesize,t);
+ option1_is_size = 1;
+ }
+ }
+ if (!strcmp(ppd_keywords[idx_option2],"PageSize") ||
+ !strcmp(ppd_keywords[idx_option2],"PageRegion")) {
+ if(strlen(option2) >=11 && !strcmp(&option2[strlen(option2)-strlen(t)], t))
+ ;
+ else {
+ strcat(borderless_pagesize,option2);
+ strcat(borderless_pagesize,t);
+ option2_is_size = 1;
+ }
+ }
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if(strcmp(cluster_name, p->queue_name))
+ continue;
+ first_attributes_value = get_supported_options(p->prattrs,
+ ppd_keywords[idx_option1]);
+ if(cupsArrayFind(first_attributes_value, (void*)option1) ||
+ (option1_is_size && cupsArrayFind(first_attributes_value,
+ (void*)borderless_pagesize))) {
+ second_attributes_value =
+ get_supported_options(p->prattrs,
+ ppd_keywords[idx_option2]);
+ if (cupsArrayFind(second_attributes_value,(void*)option2) ||
+ (option2_is_size && cupsArrayFind(second_attributes_value,
+ (void*)borderless_pagesize)))
+ return 1;
+ }
+ }
+ free(borderless_pagesize);
+ return 0;
+}
+
+/* The function returns a array containint the sizes supported by the cluster*/
+cups_array_t* get_cluster_sizes(char* cluster_name)
+{
+ cups_array_t *sizes=NULL;
+ cups_array_t *cluster_sizes=NULL,
+ *sizes_ppdname;
+ cups_size_t *size;
+ pagesize_count_t *temp;
+ remote_printer_t *p;
+ ipp_attribute_t *defattr;
+ char ppdname[41],pagesize[128];
+ char* first_space;
+ int min_length,min_width,max_length,max_width,
+ bottom,left,right,top;
+
+ temp = (pagesize_count_t *)malloc(sizeof(pagesize_count_t));
+ cluster_sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)pwg_copy_size,
+ (cups_afree_func_t)free);
+ sizes_ppdname = cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free);
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (!strcmp(p->queue_name,cluster_name)) {
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ defattr = NULL;
+ min_length = INT_MAX;
+ min_width = INT_MAX;
+ max_length = 0;
+ max_width = 0;
+ bottom = 0;
+ left = 0;
+ right = 0;
+ top = 0;
+ sizes = generate_sizes(p->prattrs, &defattr, &min_length, &min_width,
+ &max_length, &max_width,
+ &bottom, &left, &right, &top, ppdname);
+ temp->pagesize = ppdname;
+ temp->count = 1;
+ for (size = (cups_size_t *)cupsArrayFirst(sizes);
+ size; size = (cups_size_t *)cupsArrayNext(sizes)) {
+ if (!cupsArrayFind(cluster_sizes, size)) {
+ strcpy(pagesize, size->media);
+ if ((first_space = strchr(pagesize, ' ')) != NULL) {
+ *first_space = '\0';
+ }
+ if (!cupsArrayFind(sizes_ppdname,pagesize)) {
+ cupsArrayAdd(cluster_sizes, size);
+ cupsArrayAdd(sizes_ppdname,pagesize);
+ }
+ }
+ }
+ }
+ }
+ return cluster_sizes;
+}
+
+/* generate_cluster_conflicts - Function generates conflicts for the cluster*/
+cups_array_t* generate_cluster_conflicts(char* cluster_name,
+ ipp_t *merged_attributes)
+{
+ remote_printer_t *p;
+ cups_array_t *conflict_pairs=NULL;
+ int i,k,j,no_of_printers=0,no_of_ppd_keywords;
+ cups_array_t *printer_first_options=NULL,*printer_second_options=NULL;
+ char *opt1,*opt2,constraint[100],*ppdsizename,*temp;
+ cups_array_t *sizes = NULL,*pagesizes;
+ cups_size_t *size;
+
+ /* Cups Array to store the conflicts*/
+ ppdsizename = (char *)malloc(sizeof(char)*128);
+ if ((conflict_pairs = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+
+ /* Storing all the values supported by the cluster in cluster_options*/
+ no_of_ppd_keywords = sizeof(ppd_keywords)/sizeof(ppd_keywords[0]);
+ cups_array_t *cluster_options[no_of_ppd_keywords];
+ for(i = 0; i < no_of_ppd_keywords; i ++) {
+ if (strcmp(ppd_keywords[i],"PageSize") &&
+ strcmp(ppd_keywords[i],"PageRegion"))
+ cluster_options[i] =
+ get_supported_options(merged_attributes,ppd_keywords[i]);
+ else {
+ sizes = get_cluster_sizes(cluster_name);
+ if ((pagesizes =
+ cupsArrayNew3((cups_array_func_t)strcasecmp, NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL)
+ return NULL;
+ for (size = (cups_size_t *)cupsArrayFirst(sizes); size;
+ size = (cups_size_t *)cupsArrayNext(sizes)) {
+ strcpy(ppdsizename, size->media);
+ if ((temp = strchr(ppdsizename, ' ')) != NULL)
+ *temp = '\0';
+ cupsArrayAdd(pagesizes, ppdsizename);
+ }
+ cluster_options[i]=pagesizes;
+ }
+ }
+
+ /* Algorithm to find constriants: We iterate over printer, if we
+ find a value for a keyword which is supported by the cluster but
+ not by the printer, that value can be part of the conflict. With
+ this value v and a new value (for an different keyword, at index
+ more than the index of first keyword), we generate a pair (v,u)
+ and then we check whether some printer satisfy this pair, if no
+ such printer exists then the pair is a conflict, we add it to
+ conflict_pairs array */
+
+ no_of_printers = cupsArrayCount(remote_printers);
+ for (j = 0; j < no_of_printers; j ++) {
+ p = (remote_printer_t *)cupsArrayIndex(remote_printers, j);
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ for (i = 0; i < no_of_ppd_keywords; i ++) {
+ printer_first_options =
+ get_supported_options(p->prattrs, ppd_keywords[i]);
+ if (i == 0)
+ for (opt1 = cupsArrayFirst(cluster_options[i]); opt1;
+ opt1 = cupsArrayNext(cluster_options[i])) {
+ if (cupsArrayFind(printer_first_options, opt1))
+ continue;
+ for (k = i + 1; k < no_of_ppd_keywords; k++) {
+ if (!strcmp(ppd_keywords[i],"PageSize") &&
+ !strcmp(ppd_keywords[k],"PageRegion"))
+ continue;
+ printer_second_options = get_supported_options(p->prattrs,
+ ppd_keywords[k]);
+ for(opt2 = cupsArrayFirst(printer_second_options); opt2;
+ opt2 = cupsArrayNext(printer_second_options)) {
+ if (check_printer_with_options(cluster_name, i, opt1, k, opt2))
+ continue;
+ if (!strcasecmp(opt1, AUTO_OPTION) || !strcasecmp(opt2, AUTO_OPTION))
+ continue;
+ if (!strcmp(opt1, "Gray") || !strcmp(opt2,"Gray"))
+ continue;
+ sprintf(constraint, "*UIConstraints: *%s %s *%s %s\n",
+ ppd_keywords[i],
+ opt1,ppd_keywords[k],opt2);
+ if (!cupsArrayFind(conflict_pairs, constraint)) {
+ cupsArrayAdd(conflict_pairs,constraint);
+ }
+ sprintf(constraint, "*UIConstraints: *%s %s *%s %s\n",
+ ppd_keywords[k],
+ opt2,ppd_keywords[i],opt1);
+ if (!cupsArrayFind(conflict_pairs, constraint)) {
+ cupsArrayAdd(conflict_pairs, constraint);
+ }
+ }
+ }
+ }
+ }
+ }
+ free(ppdsizename);
+ return conflict_pairs;
+}
+
+/*get_cluster_attributes - Returns ipp_t* containing the options supplied by
+ all the printers in the cluster, which can be sent
+ to ppdCreateFromIPP2() to generate the ppd file */
+ipp_t* get_cluster_attributes(char* cluster_name)
+{
+ remote_printer_t *p;
+ ipp_t *merged_attributes = NULL;
+ char printer_make_and_model[256];
+ ipp_attribute_t *attr;
+ int color_supported=0,make_model_done = 0,i;
+ char valuebuffer[65536];
+ merged_attributes = ippNew();
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name,p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if (!make_model_done) {
+ strcpy(printer_make_and_model, "Cluster ");
+ strcat(printer_make_and_model, cluster_name);
+ make_model_done = 1;
+ }
+ if (((attr = ippFindAttribute(p->prattrs, "color-supported",
+ IPP_TAG_BOOLEAN)) != NULL &&
+ ippGetBoolean(attr, 0)))
+ color_supported = 1;
+ }
+
+ ippAddString(merged_attributes, IPP_TAG_PRINTER,IPP_TAG_TEXT,
+ "printer-make-and-model",
+ NULL, printer_make_and_model);
+ ippAddBoolean(merged_attributes, IPP_TAG_PRINTER, "color-supported",
+ color_supported);
+
+ add_keyword_attributes(cluster_name, &merged_attributes);
+ add_mimetype_attributes(cluster_name, &merged_attributes);
+ add_tagzero_attributes(cluster_name, &merged_attributes);
+ add_enum_attributes(cluster_name, &merged_attributes);
+ add_resolution_attributes(cluster_name, &merged_attributes);
+ add_margin_attributes(cluster_name, &merged_attributes);
+ add_mediasize_attributes(cluster_name, &merged_attributes);
+ add_mediadatabase_attributes(cluster_name, &merged_attributes);
+ add_jobpresets_attribute(cluster_name, &merged_attributes);
+ attr = ippFirstAttribute(merged_attributes);
+ /* Printing merged attributes*/
+ debug_printf("Merged attributes for the cluster %s : \n", cluster_name);
+ while (attr) {
+ debug_printf(" Attr: %s\n",
+ ippGetName(attr));
+ ippAttributeString(attr, valuebuffer, sizeof(valuebuffer));
+ debug_printf(" Value: %s\n", valuebuffer);
+ const char *kw;
+ for (i = 0; i < ippGetCount(attr); i ++)
+ if ((kw = ippGetString(attr, i, NULL)) != NULL)
+ debug_printf(" Keyword: %s\n", kw);
+ attr = ippNextAttribute(merged_attributes);
+ }
+ return merged_attributes;
+}
+
+int cluster_supports_given_attribute(char* cluster_name,ipp_tag_t tag,
+ const char* attribute)
+{
+ remote_printer_t *p;
+ ipp_attribute_t *attr;
+ int count;
+
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(cluster_name, p->queue_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute(p->prattrs, attribute, tag)) != NULL &&
+ (count = ippGetCount(attr)) > 1)
+ return 1;
+ }
+ return 0;
+}
+
+/* Generating the default values for the cluster*/
+void get_cluster_default_attributes(ipp_t** merged_attributes,
+ char* cluster_name,
+ char* default_pagesize,
+ const char **default_color)
+{
+ int max_pages_per_min = 0,pages_per_min;
+ remote_printer_t *p,*def_printer=NULL;
+ int i,count;
+ ipp_attribute_t *attr,*media_attr,*media_col_default,*defattr;
+ ipp_t *media_col,
+ *media_size,*current_media=NULL;
+ char media_source[32],media_type[32];
+ const char *str;
+ media_col_t *temp;
+ const char *keyword;
+ res_t *res;
+ int xres,yres;
+ int min_length=INT_MAX,min_width=INT_MAX,
+ max_length=0,max_width=0,
+ bottom,left,right,top;
+ char ppdname[41];
+ cups_array_t *sizes;
+
+ /*The printer with the maximum Throughtput(pages_per_min) is selected as
+ the default printer*/
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(p->queue_name, cluster_name))
+ continue;
+ if(p->status == STATUS_DISAPPEARED || p->status == STATUS_UNCONFIRMED ||
+ p->status == STATUS_TO_BE_RELEASED )
+ continue;
+ if ((attr = ippFindAttribute (p->prattrs, "pages-per-minute",
+ IPP_TAG_INTEGER)) != NULL) {
+ pages_per_min = ippGetInteger (attr, 0);
+ if (pages_per_min > max_pages_per_min) {
+ max_pages_per_min = pages_per_min;
+ def_printer = p;
+ }
+ }
+ }
+
+ /* If none of the printer in the cluster has "pages-per-minute" in the ipp
+ response message, then select the first printer in the cluster */
+ if (!def_printer) {
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p; p = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (strcmp(p->queue_name,cluster_name))
+ continue;
+ else {
+ def_printer = p;
+ break;
+ }
+ }
+ }
+
+ debug_printf("Selecting printer (%s) as the default for the cluster %s\n",
+ def_printer->uri, cluster_name);
+ debug_printf("Default Attributes of the cluster %s are : \n",cluster_name);
+
+ /* Generating the default pagesize for the cluster*/
+ sizes = generate_sizes(def_printer->prattrs, &defattr, &min_length,
+ &min_width, &max_length, &max_width,
+ &bottom, &left, &right, &top, ppdname);
+ strcpy(default_pagesize,ppdname);
+ debug_printf("Default PageSize : %s\n", default_pagesize);
+
+ /* Generating the default media-col for the cluster*/
+ if ((attr = ippFindAttribute(def_printer->prattrs, "media-col-default",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL) {
+ media_col = ippGetCollection(attr, 0);
+ media_size = ippGetCollection(ippFindAttribute(media_col, "media-size",
+ IPP_TAG_BEGIN_COLLECTION),
+ 0);
+ temp = (media_col_t *)malloc(sizeof(media_col_t));
+ temp->x = ippGetInteger(ippFindAttribute(media_size, "x-dimension",
+ IPP_TAG_ZERO), 0);
+ temp->y = ippGetInteger(ippFindAttribute(media_size, "y-dimension",
+ IPP_TAG_ZERO), 0);
+ temp->top_margin = ippGetInteger(ippFindAttribute(media_col,
+ "media-top-margin",
+ IPP_TAG_INTEGER), 0);
+ temp->bottom_margin = ippGetInteger(ippFindAttribute(media_col,
+ "media-bottom-margin",
+ IPP_TAG_INTEGER), 0);
+ temp->left_margin = ippGetInteger(ippFindAttribute(media_col,
+ "media-left-margin",
+ IPP_TAG_INTEGER), 0);
+ temp->right_margin = ippGetInteger(ippFindAttribute(media_col,
+ "media-right-margin",
+ IPP_TAG_INTEGER), 0);
+ media_type[0]='\0';
+ media_source[0]='\0';
+ temp->media_source = NULL;
+ temp->media_type = NULL;
+
+ if ((media_attr = ippFindAttribute(media_col, "media-type",
+ IPP_TAG_KEYWORD)) != NULL)
+ pwg_ppdize_name(ippGetString(media_attr, 0, NULL), media_type,
+ sizeof(media_type));
+
+ if (strlen(media_type) > 1) {
+ temp->media_type = (char*)malloc(sizeof(char)*32);
+ strcpy(temp->media_type, media_type);
+ debug_printf("Default MediaType: %s\n", media_type);
+ }
+
+ if ((media_attr = ippFindAttribute(media_col, "media-source",
+ IPP_TAG_KEYWORD)) != NULL) {
+ pwg_ppdize_name(ippGetString(media_attr, 0, NULL), media_source,
+ sizeof(media_source));
+ }
+
+ if (strlen(media_source) > 1) {
+ temp->media_source = (char*)malloc(sizeof(char)*32);
+ strcpy(temp->media_source,media_source);
+ debug_printf("Default MediaSource: %s\n", media_source);
+ }
+
+ if (temp->media_source == NULL) {
+ if (cluster_supports_given_attribute(cluster_name, IPP_TAG_KEYWORD,
+ "media-source-supported")) {
+ strcpy(temp->media_source,AUTO_OPTION);
+ debug_printf("Default MediaSource: %s\n", media_source);
+ }
+ }
+
+ if (temp->media_type == NULL) {
+ if (cluster_supports_given_attribute(cluster_name, IPP_TAG_KEYWORD,
+ "media-type-supported")) {
+ strcpy(temp->media_type, AUTO_OPTION);
+ debug_printf("Default MediaType: %s\n", media_type);
+ }
+ }
+ media_col_default = ippAddCollection(*merged_attributes, IPP_TAG_PRINTER,
+ "media-col-default", NULL);
+ current_media = create_media_col(temp->x, temp->y, temp->left_margin,
+ temp->right_margin, temp->top_margin,
+ temp->bottom_margin,
+ temp->media_source, temp->media_type);
+ ippSetCollection(*merged_attributes, &media_col_default, 0, current_media);
+ }
+
+ /*Finding the default colormodel for the cluster*/
+ if ((attr = ippFindAttribute(def_printer->prattrs, "urf-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(def_printer->prattrs,
+ "pwg-raster-document-type-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(def_printer->prattrs,
+ "print-color-mode-supported",
+ IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(def_printer->prattrs, "output-mode-supported",
+ IPP_TAG_KEYWORD);
+
+ if (attr && ippGetCount(attr) > 0) {
+ *default_color = NULL;
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ keyword = ippGetString(attr, i, NULL);
+ if ((!strcasecmp(keyword, "black_1") ||
+ !strcmp(keyword, "bi-level") ||
+ !strcmp(keyword, "process-bi-level"))) {
+ if (!*default_color)
+ *default_color = "FastGray";
+ } else if ((!strcasecmp(keyword, "sgray_8") ||
+ !strncmp(keyword, "W8", 2) ||
+ !strcmp(keyword, "monochrome") ||
+ !strcmp(keyword, "process-monochrome"))) {
+ if (!*default_color || !strcmp(*default_color, "FastGray"))
+ *default_color = "Gray";
+ } else if (!strcasecmp(keyword, "sgray_16") ||
+ !strncmp(keyword, "W8-16", 5) ||
+ !strncmp(keyword, "W16", 3)) {
+ if (!*default_color || !strcmp(*default_color, "FastGray"))
+ *default_color = "Gray16";
+ } else if (!strcasecmp(keyword, "srgb_8") ||
+ !strncmp(keyword, "SRGB24", 6) ||
+ !strcmp(keyword, "color")) {
+ *default_color = "RGB";
+ } else if ((!strcasecmp(keyword, "srgb_16") ||
+ !strncmp(keyword, "SRGB48", 6)) &&
+ !ippContainsString(attr, "srgb_8")) {
+ *default_color = "RGB";
+ } else if (!strcasecmp(keyword, "adobe-rgb_16") ||
+ !strncmp(keyword, "ADOBERGB48", 10) ||
+ !strncmp(keyword, "ADOBERGB24-48", 13)) {
+ if (!*default_color)
+ *default_color = "AdobeRGB";
+ } else if ((!strcasecmp(keyword, "adobe-rgb_8") ||
+ !strcmp(keyword, "ADOBERGB24")) &&
+ !ippContainsString(attr, "adobe-rgb_16")) {
+ if (!*default_color)
+ *default_color = "AdobeRGB";
+ }
+ }
+ if (*default_color)
+ debug_printf("Default ColorModel : %s\n", *default_color);
+ }
+
+ if ((attr = ippFindAttribute(def_printer->prattrs, "output-bin-default",
+ IPP_TAG_ZERO)) != NULL) {
+ str = ippGetString(attr,0,NULL);
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "output-bin-default", NULL, str);
+ debug_printf("Default OutputBin: %s\n", str);
+ } else {
+ if (cluster_supports_given_attribute(cluster_name,IPP_TAG_ZERO,
+ "output-bin-supported")) {
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "output-bin-default", NULL, AUTO_OPTION);
+ debug_printf("Default OutputBin: %s\n", AUTO_OPTION);
+ }
+ }
+
+ if ((attr = ippFindAttribute(def_printer->prattrs,
+ "print-content-optimize-default",
+ IPP_TAG_ZERO)) != NULL) {
+ str = ippGetString(attr, 0, NULL);
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "print-content-optimize-default", NULL, str);
+ debug_printf("Default print-content-optimize: %s\n", str);
+ } else {
+ if (cluster_supports_given_attribute(cluster_name, IPP_TAG_ZERO,
+ "print-content-optimize-default")) {
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "print-content-optimize-default", NULL, AUTO_OPTION);
+ debug_printf("Default print-content-optimize: %s\n", AUTO_OPTION);
+ }
+ }
+
+ if ((attr = ippFindAttribute(def_printer->prattrs,
+ "print-rendering-intent-default",
+ IPP_TAG_ZERO)) != NULL) {
+ str = ippGetString(attr, 0, NULL);
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "print-rendering-intent-default", NULL, str);
+ debug_printf("Default print-rendering-intent: %s\n", str);
+ } else {
+ if (cluster_supports_given_attribute(cluster_name, IPP_TAG_ZERO,
+ "print-rendering-intent-default")) {
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "print-rendering-intent-default", NULL, AUTO_OPTION);
+ debug_printf("Default print-rendering-intent: %s\n", AUTO_OPTION);
+ }
+ }
+
+ if ((attr = ippFindAttribute(def_printer->prattrs, "print-scaling-default",
+ IPP_TAG_ZERO)) != NULL) {
+ str = ippGetString(attr, 0, NULL);
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "print-scaling-default", NULL, str);
+ debug_printf("Default print-scaling: %s\n",str);
+ } else {
+ if (cluster_supports_given_attribute(cluster_name, IPP_TAG_ZERO,
+ "print-scaling-default")) {
+ ippAddString(*merged_attributes, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "print-scaling-default", NULL, AUTO_OPTION);
+ debug_printf("Default print-scaling: %s\n", AUTO_OPTION);
+ }
+ }
+
+ if ((attr = ippFindAttribute(def_printer->prattrs,
+ "printer-resolution-default",
+ IPP_TAG_ZERO)) != NULL) {
+ if ((res = ippResolutionToRes(attr, 0)) != NULL) {
+ xres = res->x;
+ yres = res->y;
+ ippAddResolution(*merged_attributes, IPP_TAG_PRINTER,
+ "printer-resolution-default",
+ IPP_RES_PER_INCH, xres, yres);
+ debug_printf("Default Resolution : %dx%d\n", xres, yres);
+ }
+ }
+
+ cupsArrayDelete(sizes);
+}
+
+/* Function to see which printer in the cluster supports the
+ requested job attributes*/
+int supports_job_attributes_requested(const gchar* printer, int printer_index,
+ int job_id, int *print_quality)
+{
+ char uri[1024];
+ http_t *http = NULL;
+ ipp_attribute_t *attr,*attr1;
+ ipp_t *request, *response = NULL;
+ const char *str,*side,*resource;
+ cups_array_t *job_sheet_supported,
+ *multiple_doc_supported,*print_qualities,
+ *media_type_supported,*staplelocation_supported,
+ *foldtype_supported,*punchmedia_supported,
+ *color_supported;
+ remote_printer_t *p;
+ int i,count,side_found,orien_req,orien,
+ orien_found;
+ cups_array_t *sizes;
+
+ p = (remote_printer_t *)cupsArrayIndex(remote_printers, printer_index);
+ static const char * const jattrs[] = /* Job attributes we want */
+ {
+ "all"
+ };
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", printer);
+
+ /* Getting the resource */
+ resource = uri + (strlen(uri) - strlen(printer) - 10);
+
+ http = http_connect_local();
+ request = ippNewRequest(IPP_OP_GET_JOB_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",job_id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ (int)(sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs);
+
+ response = cupsDoRequest(http, request,resource);
+ attr = ippFirstAttribute(response);
+
+ /* Document Format */
+/* if ((attr = ippFindAttribute(response, "document-format-detected",
+ IPP_TAG_MIMETYPE)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr,0, NULL);
+ debug_printf("The job-document is of the format %s\n.",str);
+ formats_supported = get_mimetype_attributes(p->prattrs);
+ if(!cupsArrayFind(formats_supported, (void *)str)){
+ debug_printf("Printer %s doesn't support the document format %s\n",
+ printer, str);
+ return 0;
+ }
+ }*/
+
+ /* Job Sheets*/
+ if ((attr = ippFindAttribute(response, "job-sheets",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr, 0, NULL);
+ debug_printf("The job-sheets %s is requested for the job\n", str);
+ job_sheet_supported = get_supported_options(p->prattrs,
+ "job-sheets-supported");
+ if (str) {
+ if (!cupsArrayFind(job_sheet_supported, (void *)str) &&
+ strcasecmp(str,"none")) {
+ debug_printf("Printer %s doesn't support the job-sheet %s\n", printer,
+ str);
+ return 0;
+ }
+ }
+ }
+
+ /*Multiple document handling*/
+ /* Can't get multiple-document-handling data from job templates*/
+ if ((attr = ippFindAttribute(response, "multiple-document-handling",
+ IPP_TAG_ZERO)) != NULL && ippGetCount(attr)>0) {
+ str = ippGetString(attr, 0, NULL);
+ debug_printf("The multiple-document-handling type %s is requested\n", str);
+ if (str) {
+ multiple_doc_supported =
+ get_supported_options(p->prattrs,
+ "multiple-document-handling-supported");
+ if (!cupsArrayFind(multiple_doc_supported, (void *)str)) {
+ debug_printf("Printer %s doesn't support the multiple document handling option %s\n",
+ printer, str);
+ return 0;
+ }
+ }
+ }
+
+ /* Media Type */
+ if ((attr = ippFindAttribute(response, "MediaType",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr,0, NULL);
+ debug_printf("The mediatype %s is requested for the job\n",str);
+ if (str != NULL) {
+ media_type_supported = get_supported_options(p->prattrs,
+ "media-type-supported");
+ if (!cupsArrayFind(media_type_supported, (void *)str) &&
+ strcasecmp(str,AUTO_OPTION)) {
+ debug_printf("Printer %s doesn't support the media-type %s\n",
+ printer, str);
+ return 0;
+ }
+ }
+ }
+
+ /* Staple Location*/
+ if ((attr = ippFindAttribute(response, "StapleLocation",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr, 0, NULL);
+ debug_printf("The staplelocation %s is requested for the job\n", str);
+ if (str != NULL) {
+ staplelocation_supported =
+ get_supported_options(p->prattrs, "StapleLocation");
+ if (!cupsArrayFind(staplelocation_supported, (void *)str) &&
+ strcasecmp(str,"None")) {
+ debug_printf("Printer %s doesn't support the staple location %s\n",
+ printer, str);
+ return 0;
+ }
+ }
+ }
+
+ /*FoldType*/
+ if ((attr = ippFindAttribute(response, "FoldType",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr, 0, NULL);
+ debug_printf("The FoldType %s is requested for the job\n", str);
+ if (str != NULL) {
+ foldtype_supported = get_supported_options(p->prattrs,"FoldType");
+ if (!cupsArrayFind(foldtype_supported, (void *)str) &&
+ strcasecmp(str,"None")) {
+ debug_printf("Printer %s doesn't support the FoldType %s\n",
+ printer, str);
+ return 0;
+ }
+ }
+ }
+
+ /*PunchMedia*/
+ if ((attr = ippFindAttribute(response, "PunchMedia",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr,0, NULL);
+ debug_printf("The PunchMedia %s is requested for the job\n", str);
+ if (str != NULL) {
+ punchmedia_supported = get_supported_options(p->prattrs,"PunchMedia");
+ if (!cupsArrayFind(punchmedia_supported, (void *)str) &&
+ strcasecmp(str,"none")) {
+ debug_printf("Printer %s doesn't support the PunchMedia %s\n",
+ printer, str);
+ return 0;
+ }
+ }
+ }
+
+ /*ColorModel*/
+ if ((attr = ippFindAttribute(response, "ColorModel",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr, 0, NULL);
+ debug_printf("The ColorModel %s is requested for the job\n", str);
+ if (str != NULL) {
+ color_supported = get_supported_options(p->prattrs, "ColorModel");
+ if (!cupsArrayFind(color_supported, (void *)str) &&
+ strcasecmp(str,"Gray")) {
+ debug_printf("Printer %s doesn't support the ColorModel %s\n",
+ printer, str);
+ return 0;
+ }
+ }
+ }
+
+ /* Sides supported*/
+ if ((attr = ippFindAttribute(response, "Duplex",
+ IPP_TAG_ZERO)) != NULL) {
+ side_found = 0;
+ str = ippGetString(attr, 0, NULL);
+ if (str) {
+ if ((attr1 = ippFindAttribute(p->prattrs, "sides-supported",
+ IPP_TAG_KEYWORD)) != NULL) {
+ for (i = 0, count = ippGetCount(attr1); i < count; i++) {
+ side = ippGetString(attr1, i, NULL);
+ debug_printf("The duplex option %s is requested\n", side);
+ if (!strcasecmp(str, "None") && !strcmp(side, "one-sided")) {
+ side_found = 1;
+ break;
+ } else if (!strcmp(str, "DuplexNoTumble") &&
+ !strcmp(side, "two-sided-long-edge")) {
+ side_found = 1;
+ break;
+ } else if (!strcmp(str, "DuplexTumble") &&
+ !strcmp(side, "two-sided-short-edge")) {
+ side_found = 1;
+ break;
+ }
+ }
+ if (!side_found) {
+ debug_printf("Printer %s doesn't support the required duplex options\n",
+ printer);
+ return 0;
+ }
+ }
+ }
+ }
+
+ /* Orientation Requested */
+ if ((attr = ippFindAttribute(response, "orientation-requested",
+ IPP_TAG_ENUM)) != NULL) {
+ orien_found = 0;
+ orien_req = ippGetInteger(attr, 0);
+ if ((attr1 = ippFindAttribute(p->prattrs,
+ "orientation-requested-supported",
+ IPP_TAG_ENUM)) != NULL) {
+ for (i = 0, count = ippGetCount(attr1); i < count; i ++) {
+ orien = ippGetInteger(attr1, i);
+ if (orien == orien_req) {
+ orien_found = 1;
+ break;
+ }
+ }
+ if (!orien_found) {
+ debug_printf("Printer %s doesn't support the requested orientation\n",
+ printer);
+ return 0;
+ }
+ }
+ }
+
+ /*Page Size*/
+ if ((attr = ippFindAttribute(response, "PageSize",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ str = ippGetString(attr, 0, NULL);
+ if (str) {
+ sizes = get_pagesize(p->prattrs);
+ if (!cupsArrayFind(sizes, (void*)str)) {
+ debug_printf("Printer %s doesn't support %s PageSize\n", p->uri, str);
+ return 0;
+ }
+ }
+ }
+
+ /*Print Quality*/
+ *print_quality = 4;
+ if ((attr = ippFindAttribute(response, "cupsPrintQuality",
+ IPP_TAG_ZERO)) != NULL &&
+ ippGetCount(attr) > 0) {
+ print_qualities = get_supported_options(p->prattrs, "cupsPrintQuality");
+ str = ippGetString(attr, 0, NULL);
+ debug_printf("%s\n", str);
+ if (str && !cupsArrayFind(print_qualities, (void*)str)) {
+ debug_printf("In\n");
+ if(!strcmp(str, "5"))
+ *print_quality = 5;
+ else if (!strcmp(str, "3"))
+ *print_quality = 3;
+ debug_printf("Printer doesn't support %s print quality\n",
+ !strcmp(str, "5") ? "HIGH": "DRAFT");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/*
* Remove all illegal characters and replace each group of such characters
@@ -807,17 +3373,17 @@ local_printer_has_uri (gpointer key,
gpointer user_data)
{
local_printer_t *printer = value;
- char *device_uri = user_data;
- char lhost[HTTP_MAX_URI], /* Local printer: Hostname */
- lresource[HTTP_MAX_URI],/* Local printer: Resource path */
- lscheme[32], /* Local printer: URI's scheme */
- lusername[64], /* Local printer: URI's username */
- dhost[HTTP_MAX_URI], /* Discovered printer: Hostname */
- dresource[HTTP_MAX_URI],/* Discovered printer: Resource path */
- dscheme[32], /* Discovered printer: URI's scheme */
- dusername[64]; /* Discovered printer: URI's username */
- int lport = 0, /* Local printer: URI's port number */
- dport = 0; /* Discovered printer: URI's port number */
+ char *device_uri = user_data;
+ char lhost[HTTP_MAX_URI], /* Local printer: Hostname */
+ lresource[HTTP_MAX_URI], /* Local printer: Resource path */
+ lscheme[32], /* Local printer: URI's scheme */
+ lusername[64], /* Local printer: URI's username */
+ dhost[HTTP_MAX_URI], /* Discovered printer: Hostname */
+ dresource[HTTP_MAX_URI], /* Discovered printer: Resource path */
+ dscheme[32], /* Discovered printer: URI's scheme */
+ dusername[64]; /* Discovered printer: URI's username */
+ int lport = 0, /* Local printer: URI's port number */
+ dport = 0; /* Discovered printer: URI's port number */
debug_printf("local_printer_has_uri() in THREAD %ld\n", pthread_self());
/* Separate the two URIs to be compared into their components */
@@ -1094,7 +3660,7 @@ prepare_browse_data (void)
break;
}
} else if (!strcasecmp(attrname, "printer-state") &&
- value_tag == IPP_TAG_ENUM)
+ value_tag == IPP_TAG_ENUM)
state = ippGetInteger(attr, 0);
else if (!strcasecmp(attrname, "printer-uri-supported") &&
value_tag == IPP_TAG_URI)
@@ -1315,7 +3881,7 @@ color_space_score(const char *color_space)
} else if (!strncasecmp(p, "rgb", 3)) {
p += 3;
score += 5000;
- }
+ }
if (!strncasecmp(p, "-", 1) || !strncasecmp(p, "_", 1)) {
p += 1;
}
@@ -1331,20 +3897,17 @@ color_space_score(const char *color_space)
* 'ldap_rebind_proc()' - Callback function for LDAP rebind
*/
-static int /* O - Result code */
-ldap_rebind_proc(
- LDAP *RebindLDAPHandle, /* I - LDAP handle */
- LDAP_CONST char *refsp, /* I - ??? */
- ber_tag_t request, /* I - ??? */
- ber_int_t msgid, /* I - ??? */
- void *params) /* I - ??? */
+static int /* O - Result code */
+ldap_rebind_proc(LDAP *RebindLDAPHandle, /* I - LDAP handle */
+ LDAP_CONST char *refsp, /* I - ??? */
+ ber_tag_t request, /* I - ??? */
+ ber_int_t msgid, /* I - ??? */
+ void *params) /* I - ??? */
{
- int rc; /* Result code */
+ int rc; /* Result code */
# if LDAP_API_VERSION > 3000
- struct berval bval; /* Bind value */
+ struct berval bval; /* Bind value */
# endif /* LDAP_API_VERSION > 3000 */
-
-
(void)request;
(void)msgid;
(void)params;
@@ -1375,50 +3938,48 @@ ldap_rebind_proc(
* 'ldap_rebind_proc()' - Callback function for LDAP rebind
*/
-static int /* O - Result code */
-ldap_rebind_proc(
- LDAP *RebindLDAPHandle, /* I - LDAP handle */
- char **dnp, /* I - ??? */
- char **passwdp, /* I - ??? */
- int *authmethodp, /* I - ??? */
- int freeit, /* I - ??? */
- void *arg) /* I - ??? */
+static int /* O - Result code */
+ldap_rebind_proc(LDAP *RebindLDAPHandle, /* I - LDAP handle */
+ char **dnp, /* I - ??? */
+ char **passwdp, /* I - ??? */
+ int *authmethodp, /* I - ??? */
+ int freeit, /* I - ??? */
+ void *arg) /* I - ??? */
{
- switch (freeit)
- {
- case 1:
- /*
- * Free current values...
- */
+ switch (freeit) {
+ case 1:
+ /*
+ * Free current values...
+ */
- debug_printf("ldap_rebind_proc: Free values...\n");
+ debug_printf("ldap_rebind_proc: Free values...\n");
- if (dnp && *dnp)
- free(*dnp);
+ if (dnp && *dnp)
+ free(*dnp);
- if (passwdp && *passwdp)
- free(*passwdp);
- break;
+ if (passwdp && *passwdp)
+ free(*passwdp);
+ break;
- case 0:
- /*
- * Return credentials for LDAP referal...
- */
+ case 0:
+ /*
+ * Return credentials for LDAP referal...
+ */
- debug_printf("ldap_rebind_proc: Return necessary values...\n");
+ debug_printf("ldap_rebind_proc: Return necessary values...\n");
- *dnp = strdup(BrowseLDAPBindDN);
- *passwdp = strdup(BrowseLDAPPassword);
- *authmethodp = LDAP_AUTH_SIMPLE;
- break;
+ *dnp = strdup(BrowseLDAPBindDN);
+ *passwdp = strdup(BrowseLDAPPassword);
+ *authmethodp = LDAP_AUTH_SIMPLE;
+ break;
- default:
- /*
- * Should never happen...
- */
+ default:
+ /*
+ * Should never happen...
+ */
- debug_printf("LDAP rebind has been called with wrong freeit value!\n");
- break;
+ debug_printf("LDAP rebind has been called with wrong freeit value!\n");
+ break;
}
return (LDAP_SUCCESS);
@@ -1432,17 +3993,17 @@ ldap_rebind_proc(
* 'ldap_connect()' - Start new LDAP connection
*/
-static LDAP * /* O - LDAP handle */
+static LDAP * /* O - LDAP handle */
ldap_connect(void)
{
- int rc; /* LDAP API status */
- int version = 3; /* LDAP version */
- struct berval bv = {0, ""}; /* SASL bind value */
- LDAP *TempBrowseLDAPHandle=NULL;
- /* Temporary LDAP Handle */
+ int rc; /* LDAP API status */
+ int version = 3; /* LDAP version */
+ struct berval bv = {0, ""}; /* SASL bind value */
+ LDAP *TempBrowseLDAPHandle=NULL;
+ /* Temporary LDAP Handle */
# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
- int ldap_ssl = 0; /* LDAP SSL indicator */
- int ssl_err = 0; /* LDAP SSL error value */
+ int ldap_ssl = 0; /* LDAP SSL indicator */
+ int ssl_err = 0; /* LDAP SSL error value */
# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
@@ -1452,13 +4013,12 @@ ldap_connect(void)
* Set the certificate file to use for encrypted LDAP sessions...
*/
- if (BrowseLDAPCACertFile)
- {
+ if (BrowseLDAPCACertFile) {
debug_printf("ldap_connect: Setting CA certificate file \"%s\"\n",
- BrowseLDAPCACertFile);
+ BrowseLDAPCACertFile);
if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
- (void *)BrowseLDAPCACertFile)) != LDAP_SUCCESS)
+ (void *)BrowseLDAPCACertFile)) != LDAP_SUCCESS)
debug_printf("Unable to set CA certificate file for LDAP "
"connections: %d - %s\n", rc, ldap_err2string(rc));
}
@@ -1476,16 +4036,15 @@ ldap_connect(void)
# else /* HAVE_OPENLDAP */
- int ldap_port = 0; /* LDAP port */
- char ldap_protocol[11], /* LDAP protocol */
- ldap_host[255]; /* LDAP host */
+ int ldap_port = 0; /* LDAP port */
+ char ldap_protocol[11], /* LDAP protocol */
+ ldap_host[255]; /* LDAP host */
/*
* Split LDAP URI into its components...
*/
- if (!BrowseLDAPServer)
- {
+ if (!BrowseLDAPServer) {
debug_printf("BrowseLDAPServer not configured!\n");
debug_printf("Disabling LDAP browsing!\n");
/*BrowseLocalProtocols &= ~BROWSE_LDAP;*/
@@ -1500,8 +4059,7 @@ ldap_connect(void)
ldap_ssl = 0;
else if (!strcmp(ldap_protocol, "ldaps"))
ldap_ssl = 1;
- else
- {
+ else {
debug_printf("Unrecognized LDAP protocol (%s)!\n",
ldap_protocol);
debug_printf("Disabling LDAP browsing!\n");
@@ -1510,8 +4068,7 @@ ldap_connect(void)
return (NULL);
}
- if (ldap_port == 0)
- {
+ if (ldap_port == 0) {
if (ldap_ssl)
ldap_port = LDAPS_PORT;
else
@@ -1519,46 +4076,37 @@ ldap_connect(void)
}
debug_printf("ldap_connect: PROT:%s HOST:%s PORT:%d\n",
- ldap_protocol, ldap_host, ldap_port);
+ ldap_protocol, ldap_host, ldap_port);
/*
* Initialize LDAP connection...
*/
- if (!ldap_ssl)
- {
+ if (!ldap_ssl) {
if ((TempBrowseLDAPHandle = ldap_init(ldap_host, ldap_port)) == NULL)
rc = LDAP_OPERATIONS_ERROR;
else
rc = LDAP_SUCCESS;
# ifdef HAVE_LDAP_SSL
- }
- else
- {
+ } else {
/*
* Initialize SSL LDAP connection...
*/
- if (BrowseLDAPCACertFile)
- {
+ if (BrowseLDAPCACertFile) {
rc = ldapssl_client_init(BrowseLDAPCACertFile, (void *)NULL);
- if (rc != LDAP_SUCCESS)
- {
+ if (rc != LDAP_SUCCESS) {
debug_printf("Failed to initialize LDAP SSL client!\n");
rc = LDAP_OPERATIONS_ERROR;
- }
- else
- {
+ } else {
if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port,
1)) == NULL)
rc = LDAP_OPERATIONS_ERROR;
else
rc = LDAP_SUCCESS;
}
- }
- else
- {
+ } else {
debug_printf("LDAP SSL certificate file/database not configured!\n");
rc = LDAP_OPERATIONS_ERROR;
}
@@ -1580,14 +4128,12 @@ ldap_connect(void)
* Check return code from LDAP initialize...
*/
- if (rc != LDAP_SUCCESS)
- {
+ if (rc != LDAP_SUCCESS) {
debug_printf("Unable to initialize LDAP!\n");
if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
debug_printf("Temporarily disabling LDAP browsing...\n");
- else
- {
+ else {
debug_printf("Disabling LDAP browsing!\n");
/*BrowseLocalProtocols &= ~BROWSE_LDAP;*/
@@ -1604,8 +4150,7 @@ ldap_connect(void)
*/
if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
- (const void *)&version) != LDAP_SUCCESS)
- {
+ (const void *)&version) != LDAP_SUCCESS) {
debug_printf("Unable to set LDAP protocol version %d!\n",
version);
debug_printf("Disabling LDAP browsing!\n");
@@ -1650,21 +4195,20 @@ ldap_connect(void)
rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
NULL, NULL);
else
- rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
+ rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
+ LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
# else
- rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
- BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
+ rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
+ BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
# endif /* LDAP_API_VERSION > 3000 */
- if (rc != LDAP_SUCCESS)
- {
+ if (rc != LDAP_SUCCESS) {
debug_printf("LDAP bind failed with error %d: %s\n",
rc, ldap_err2string(rc));
# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
- if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR))
- {
+ if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)) {
ssl_err = PORT_GetError();
if (ssl_err != 0)
debug_printf("LDAP SSL error %d: %s\n", ssl_err,
@@ -1687,11 +4231,10 @@ ldap_connect(void)
* 'ldap_reconnect()' - Reconnect to LDAP Server
*/
-static LDAP * /* O - New LDAP handle */
+static LDAP * /* O - New LDAP handle */
ldap_reconnect(void)
{
- LDAP *TempBrowseLDAPHandle = NULL; /* Temp Handle to LDAP server */
-
+ LDAP *TempBrowseLDAPHandle = NULL; /* Temp Handle to LDAP server */
/*
* Get a new LDAP Handle and replace the global Handle
@@ -1702,8 +4245,7 @@ ldap_reconnect(void)
TempBrowseLDAPHandle = ldap_connect();
- if (TempBrowseLDAPHandle != NULL)
- {
+ if (TempBrowseLDAPHandle != NULL) {
if (BrowseLDAPHandle != NULL)
ldap_disconnect(BrowseLDAPHandle);
@@ -1719,10 +4261,9 @@ ldap_reconnect(void)
*/
static void
-ldap_disconnect(LDAP *ld) /* I - LDAP handle */
+ldap_disconnect(LDAP *ld) /* I - LDAP handle */
{
- int rc; /* Return code */
-
+ int rc; /* Return code */
/*
* Close LDAP handle...
@@ -1746,24 +4287,24 @@ ldap_disconnect(LDAP *ld) /* I - LDAP handle */
void
cupsdUpdateLDAPBrowse(void)
{
- char uri[HTTP_MAX_URI], /* Printer URI */
- host[HTTP_MAX_URI], /* Hostname */
- resource[HTTP_MAX_URI], /* Resource path */
- local_resource[HTTP_MAX_URI], /* Resource path */
- service_name[2048],
- location[1024], /* Printer location */
- info[1024], /* Printer information */
- make_model[1024], /* Printer make and model */
- type_num[30], /* Printer type number */
- scheme[32], /* URI's scheme */
- username[64]; /* URI's username */
- int port; /* URI's port number */
- char *c;
- int hl;
- int rc; /* LDAP status */
- int limit; /* Size limit */
- LDAPMessage *res, /* LDAP search results */
- *e; /* Current entry from search */
+ char uri[HTTP_MAX_URI], /* Printer URI */
+ host[HTTP_MAX_URI], /* Hostname */
+ resource[HTTP_MAX_URI], /* Resource path */
+ local_resource[HTTP_MAX_URI], /* Resource path */
+ service_name[2048],
+ location[1024], /* Printer location */
+ info[1024], /* Printer information */
+ make_model[1024], /* Printer make and model */
+ type_num[30], /* Printer type number */
+ scheme[32], /* URI's scheme */
+ username[64]; /* URI's username */
+ int port; /* URI's port number */
+ char *c;
+ int hl;
+ int rc; /* LDAP status */
+ int limit; /* Size limit */
+ LDAPMessage *res, /* LDAP search results */
+ *e; /* Current entry from search */
debug_printf("UpdateLDAPBrowse\n");
@@ -1771,8 +4312,7 @@ cupsdUpdateLDAPBrowse(void)
* Reconnect if LDAP Handle is invalid...
*/
- if (! BrowseLDAPHandle)
- {
+ if (! BrowseLDAPHandle) {
ldap_reconnect();
return;
}
@@ -1789,10 +4329,9 @@ cupsdUpdateLDAPBrowse(void)
* and temporary disable LDAP updates...
*/
- if (rc != LDAP_SUCCESS)
- {
- if (BrowseLDAPUpdate && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR)))
- {
+ if (rc != LDAP_SUCCESS) {
+ if (BrowseLDAPUpdate && ((rc == LDAP_SERVER_DOWN) ||
+ (rc == LDAP_CONNECT_ERROR))) {
BrowseLDAPUpdate = FALSE;
debug_printf("LDAP update temporary disabled\n");
}
@@ -1803,8 +4342,7 @@ cupsdUpdateLDAPBrowse(void)
* If LDAP updates were disabled, we will reenable them...
*/
- if (! BrowseLDAPUpdate)
- {
+ if (!BrowseLDAPUpdate) {
BrowseLDAPUpdate = TRUE;
debug_printf("LDAP update enabled\n");
}
@@ -1815,8 +4353,7 @@ cupsdUpdateLDAPBrowse(void)
limit = ldap_count_entries(BrowseLDAPHandle, res);
debug_printf("LDAP search returned %d entries\n", limit);
- if (limit < 1)
- {
+ if (limit < 1) {
ldap_freeres(res);
return;
}
@@ -1827,8 +4364,7 @@ cupsdUpdateLDAPBrowse(void)
for (e = ldap_first_entry(BrowseLDAPHandle, res);
e;
- e = ldap_next_entry(BrowseLDAPHandle, e))
- {
+ e = ldap_next_entry(BrowseLDAPHandle, e)) {
/*
* Get the required values from this entry...
*/
@@ -1838,15 +4374,18 @@ cupsdUpdateLDAPBrowse(void)
continue;
if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerLocation", location, sizeof(location)) == -1)
+ "printerLocation", location,
+ sizeof(location)) == -1)
continue;
if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerMakeAndModel", make_model, sizeof(make_model)) == -1)
+ "printerMakeAndModel", make_model,
+ sizeof(make_model)) == -1)
continue;
if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerType", type_num, sizeof(type_num)) == -1)
+ "printerType", type_num,
+ sizeof(type_num)) == -1)
continue;
if (ldap_getval_firststring(BrowseLDAPHandle, e,
@@ -1911,17 +4450,17 @@ cupsdUpdateLDAPBrowse(void)
* 'ldap_search_rec()' - LDAP Search with reconnect
*/
-static int /* O - Return code */
-ldap_search_rec(LDAP *ld, /* I - LDAP handler */
- char *base, /* I - Base dn */
- int scope, /* I - LDAP search scope */
- char *filter, /* I - Filter string */
- char *attrs[], /* I - Requested attributes */
- int attrsonly, /* I - Return only attributes? */
- LDAPMessage **res) /* I - LDAP handler */
+static int /* O - Return code */
+ldap_search_rec(LDAP *ld, /* I - LDAP handler */
+ char *base, /* I - Base dn */
+ int scope, /* I - LDAP search scope */
+ char *filter, /* I - Filter string */
+ char *attrs[], /* I - Requested attributes */
+ int attrsonly, /* I - Return only attributes? */
+ LDAPMessage **res) /* I - LDAP handler */
{
- int rc; /* Return code */
- LDAP *ldr; /* LDAP handler after reconnect */
+ int rc; /* Return code */
+ LDAP *ldr; /* LDAP handler after reconnect */
# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
@@ -1935,8 +4474,7 @@ ldap_search_rec(LDAP *ld, /* I - LDAP handler */
* If we have a connection problem try again...
*/
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- {
+ if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
debug_printf("LDAP search failed with status %d: %s\n",
rc, ldap_err2string(rc));
debug_printf("We try the LDAP search once again after reconnecting to "
@@ -1970,10 +4508,9 @@ ldap_search_rec(LDAP *ld, /* I - LDAP handler */
*/
static void
-ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */
+ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */
{
- int rc; /* Return value */
-
+ int rc; /* Return value */
rc = ldap_msgfree(entry);
if (rc == -1)
@@ -1987,76 +4524,68 @@ ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */
* 'ldap_getval_char()' - Get first LDAP value and convert to string
*/
-static int /* O - Return code */
-ldap_getval_firststring(
- LDAP *ld, /* I - LDAP handler */
- LDAPMessage *entry, /* I - LDAP message or search result */
- char *attr, /* I - the wanted attribute */
- char *retval, /* O - String to return */
- unsigned long maxsize) /* I - Max string size */
+static int /* O - Return code */
+ldap_getval_firststring(LDAP *ld, /* I - LDAP handler */
+ LDAPMessage *entry, /* I - LDAP message or search
+ result */
+ char *attr, /* I - the wanted attribute */
+ char *retval, /* O - String to return */
+ unsigned long maxsize) /* I - Max string size */
{
- char *dn; /* LDAP DN */
- int rc = 0; /* Return code */
+ char *dn; /* LDAP DN */
+ int rc = 0; /* Return code */
# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- struct berval **bval; /* LDAP value array */
- unsigned long size; /* String size */
+ struct berval **bval; /* LDAP value array */
+ unsigned long size; /* String size */
/*
* Get value from LDAPMessage...
*/
- if ((bval = ldap_get_values_len(ld, entry, attr)) == NULL)
- {
+ if ((bval = ldap_get_values_len(ld, entry, attr)) == NULL) {
rc = -1;
dn = ldap_get_dn(ld, entry);
debug_printf("Failed to get LDAP value %s for %s!\n",
attr, dn);
ldap_memfree(dn);
- }
- else
- {
+ } else {
/*
* Check size and copy value into our string...
*/
size = maxsize;
- if (size < (bval[0]->bv_len + 1))
- {
+ if (size < (bval[0]->bv_len + 1)) {
rc = -1;
dn = ldap_get_dn(ld, entry);
debug_printf("Attribute %s is too big! (dn: %s)\n",
attr, dn);
ldap_memfree(dn);
- }
- else
+ } else
size = bval[0]->bv_len + 1;
strncpy(retval, bval[0]->bv_val, size);
if (size > 0)
- retval[size - 1] = '\0';
+ retval[size - 1] = '\0';
ldap_value_free_len(bval);
}
# else
- char **value; /* LDAP value */
+ char **value; /* LDAP value */
/*
* Get value from LDAPMessage...
*/
- if ((value = (char **)ldap_get_values(ld, entry, attr)) == NULL)
- {
+ if ((value = (char **)ldap_get_values(ld, entry, attr)) == NULL) {
rc = -1;
dn = ldap_get_dn(ld, entry);
debug_printf("Failed to get LDAP value %s for %s!\n",
attr, dn);
ldap_memfree(dn);
- }
- else
- {
+ } else {
strncpy(retval, *value, maxsize);
if (maxsize > 0)
- retval[maxsize - 1] = '\0';
+ retval[maxsize - 1] = '\0';
ldap_value_free(value);
}
# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
@@ -2227,11 +4756,11 @@ log_cluster(remote_printer_t *p) {
int i;
if (p == NULL || (!debug_stderr && !debug_logfile))
return;
- if (p->netprinter) {
- debug_printf("Printer %s is not a remote CUPS printer, load-balanced clustering not supported.\n",
- p->queue_name);
- return;
- }
+ /* if (p->netprinter) {
+ debug_printf("Printer %s is not a remote CUPS printer, load-balanced clustering not supported.\n",
+ p->queue_name);
+ return;
+ }*/
if (p->slave_of)
q = p->slave_of;
else
@@ -2255,13 +4784,15 @@ log_all_printers() {
debug_printf("=== Remote printer overview ===\n");
for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
- debug_printf("Printer %s (%s, %s): Local queue %s, %s, Slave of %s%s\n", p->uri,
+ debug_printf("Printer %s (%s, %s): Local queue %s, %s, Slave of %s%s\n",
+ p->uri,
p->host, (p->ip ? p->ip : "IP not determined"), p->queue_name,
(p->netprinter ? "IPP Printer" : "Remote CUPS Printer"),
((q = p->slave_of) != NULL ? q->uri : "None"),
(p->status == STATUS_UNCONFIRMED ? " (Unconfirmed)" :
(p->status == STATUS_DISAPPEARED ? " (Disappeared)" :
- (p->status == STATUS_TO_BE_RELEASED ? " (To be released from cups-browsed)" :
+ (p->status == STATUS_TO_BE_RELEASED ?
+ " (To be released from cups-browsed)" :
(p->status == STATUS_TO_BE_CREATED ?
" (To be created/updated)" : "")))));
debug_printf("===============================\n");
@@ -2354,8 +4885,8 @@ is_disabled(const char *printer, const char *reason) {
return pstatemsg;
else {
if (pstatemsg != NULL) {
- free(pstatemsg);
- pstatemsg = NULL;
+ free(pstatemsg);
+ pstatemsg = NULL;
}
return NULL;
}
@@ -2442,7 +4973,7 @@ disable_printer (const char *printer, const char *reason) {
int
set_cups_default_printer(const char *printer) {
- ipp_t *request;
+ ipp_t *request;
char uri[HTTP_MAX_URI];
http_t *conn = NULL;
@@ -2511,7 +5042,7 @@ get_cups_default_printer() {
}
}
if (default_printer_name)
- break;
+ break;
}
}
@@ -2624,30 +5155,30 @@ record_printer_options(const char *printer) {
int i;
/* List of IPP attributes to get recorded */
static const char *attrs_to_record[] =
- {
- "*-default",
- "auth-info-required",
- /*"device-uri",*/
- "job-quota-period",
- "job-k-limit",
- "job-page-limit",
- /*"port-monitor",*/
- "printer-error-policy",
- "printer-info",
- "printer-is-accepting-jobs",
- "printer-is-shared",
- "printer-geo-location",
- "printer-location",
- "printer-op-policy",
- "printer-organization",
- "printer-organizational-unit",
- /*"printer-state",
- "printer-state-message",
- "printer-state-reasons",*/
- "requesting-user-name-allowed",
- "requesting-user-name-denied",
- NULL
- };
+ {
+ "*-default",
+ "auth-info-required",
+ /*"device-uri",*/
+ "job-quota-period",
+ "job-k-limit",
+ "job-page-limit",
+ /*"port-monitor",*/
+ "printer-error-policy",
+ "printer-info",
+ "printer-is-accepting-jobs",
+ "printer-is-shared",
+ "printer-geo-location",
+ "printer-location",
+ "printer-op-policy",
+ "printer-organization",
+ "printer-organizational-unit",
+ /*"printer-state",
+ "printer-state-message",
+ "printer-state-reasons",*/
+ "requesting-user-name-allowed",
+ "requesting-user-name-denied",
+ NULL
+ };
const char **ptr;
http_t *conn = NULL;
@@ -2857,7 +5388,7 @@ queue_removal_handle_default(const char *printer) {
return 0;
/* Record the fact that this printer was default */
if (record_default_printer(default_printer, 0) < 0) {
- /* Delete record file if recording failed */
+ /* Delete record file if recording failed */
debug_printf("ERROR: Failed recording remote default printer (%s). Removing the file with possible old recording.\n",
printer);
invalidate_default_printer(0);
@@ -2888,7 +5419,7 @@ get_local_queue_name(const char *service_name,
int *is_cups_queue,
const char *exclude) {
char *queue_name = NULL, *backup_queue_name = NULL,
- *local_queue_name = NULL, *local_queue_name_lower = NULL;
+ *local_queue_name = NULL, *local_queue_name_lower = NULL;
local_printer_t *local_printer = NULL;
cluster_t *cluster = NULL;
char *member = NULL, *str = NULL;
@@ -2995,67 +5526,66 @@ get_local_queue_name(const char *service_name,
return NULL;
}
- if (*is_cups_queue) {
- /* Check whether our new printer matches one of the user-defined
- printer clusters */
+ /* Check whether our new printer matches one of the user-defined
+ printer clusters */
+ for (cluster = cupsArrayFirst(clusters);
+ cluster;
+ cluster = cupsArrayNext(clusters)) {
+ if (exclude && !strcasecmp(cluster->local_queue_name, exclude))
+ continue;
+ local_queue_name_lower = g_ascii_strdown(cluster->local_queue_name, -1);
+ local_printer = g_hash_table_lookup (local_printers,
+ local_queue_name_lower);
+ free(local_queue_name_lower);
+ if (local_printer && !local_printer->cups_browsed_controlled)
+ continue;
+ for (member = cupsArrayFirst(cluster->members);
+ member;
+ member = cupsArrayNext(cluster->members)) {
+ /* Match remote CUPS queue name */
+ if ((str = strrchr(resource, '/')) != NULL && strlen(str) > 1) {
+ str = remove_bad_chars(str + 1, 2);
+ if (strcasecmp(member, str) == 0) /* Match */
+ break;
+ free(str);
+ }
+ /* Match make and model */
+ if (make_model) {
+ str = remove_bad_chars(make_model, 2);
+ if (strcasecmp(member, str) == 0) /* Match */
+ break;
+ free(str);
+ }
+ /* Match DNS-SD service name */
+ if (service_name) {
+ str = remove_bad_chars(service_name, 2);
+ if (strcasecmp(member, str) == 0) /* Match */
+ break;
+ free(str);
+ }
+ }
+ if (member)
+ break;
+ }
+ if (cluster) {
+ local_queue_name = strdup(cluster->local_queue_name);
+ *is_cups_queue = 2;
+ free(str);
+ } else if (AutoClustering) {
+ /* If we do automatic clustering by matching queue names, do not
+ add a queue to a manually defined cluster because it matches
+ the cluster's local queue name. Manually defined clusters can
+ only be joined by printers which match one of the cluster's
+ member names */
for (cluster = cupsArrayFirst(clusters);
cluster;
cluster = cupsArrayNext(clusters)) {
- if (exclude && !strcasecmp(cluster->local_queue_name, exclude))
- continue;
- local_queue_name_lower = g_ascii_strdown(cluster->local_queue_name, -1);
- local_printer = g_hash_table_lookup (local_printers,
- local_queue_name_lower);
- free(local_queue_name_lower);
- if (local_printer && !local_printer->cups_browsed_controlled)
- continue;
- for (member = cupsArrayFirst(cluster->members);
- member;
- member = cupsArrayNext(cluster->members)) {
- /* Match remote CUPS queue name */
- if ((str = strrchr(resource, '/')) != NULL && strlen(str) > 1) {
- str = remove_bad_chars(str + 1, 2);
- if (strcasecmp(member, str) == 0) /* Match */
- break;
- free(str);
- }
- /* Match make and model */
- if (make_model) {
- str = remove_bad_chars(make_model, 2);
- if (strcasecmp(member, str) == 0) /* Match */
- break;
- free(str);
- }
- /* Match DNS-SD service name */
- if (service_name) {
- str = remove_bad_chars(service_name, 2);
- if (strcasecmp(member, str) == 0) /* Match */
- break;
- free(str);
- }
- }
- if (member)
- break;
- }
- if (cluster) {
- local_queue_name = strdup(cluster->local_queue_name);
- *is_cups_queue = 2;
- free(str);
- } else if (AutoClustering) {
- /* If we do automatic clustering by matching queue names, do not
- add a queue to a manually defined cluster because it matches
- the cluster's local queue name. Manually defined clusters can
- only be joined by printers which match one of the cluster's
- member names */
- for (cluster = cupsArrayFirst(clusters);
- cluster;
- cluster = cupsArrayNext(clusters)) {
- if (strcasecmp(local_queue_name, cluster->local_queue_name) == 0) {
- debug_printf("We have already a manually defined printer cluster with the name %s. Automatic clustering does not add this printer to this cluster as it does not match any of the cluster's member names. Skipping this printer.\n", local_queue_name);
- debug_printf("In cups-browsed.conf try \"LocalQueueNamingRemoteCUPS DNS-SD\" or give another name to your manually defined cluster (\"Cluster\" directive) to avoid name clashes.\n");
- free(local_queue_name);
- return NULL;
- }
+ if (strcasecmp(local_queue_name, cluster->local_queue_name) == 0) {
+ debug_printf("We have already a manually defined printer cluster with the name %s. Automatic clustering does not add this printer to this cluster as it does not match any of the cluster's member names. Skipping this printer.\n",
+ local_queue_name);
+ debug_printf("In cups-browsed.conf try \"LocalQueueNamingRemoteCUPS DNS-SD\" or give another name to your manually defined cluster (\"Cluster\" directive) to avoid name clashes.\n");
+ free(local_queue_name);
+ return NULL;
}
}
}
@@ -3080,16 +5610,12 @@ join_cluster_if_needed(remote_printer_t *p,
!q->slave_of) /* Find the master of the queues with this name,
to avoid "daisy chaining" */
break;
- if (q && AutoClustering == 0 && is_cups_queue == 1) {
+ if (q && AutoClustering == 0 && (is_cups_queue == 1 ||is_cups_queue == 0) ) {
debug_printf("We have already created a queue with the name %s for another remote CUPS printer but automatic clustering of equally named printers is turned off nor did we find a manually defined cluster this printer belongs to. Skipping this printer.\n", p->queue_name);
debug_printf("In cups-browsed.conf try setting \"AutoClustering On\" to cluster equally-named remote CUPS printers, \"LocalQueueNamingRemoteCUPS DNS-SD\" to avoid queue name clashes, or define clusters with the \"Cluster\" directive.\n");
return -1;
}
- if (q && q->netprinter == 1) {
- debug_printf("We have already created a queue with the name %s for another printer which is not a remote CUPS printer. Skipping this printer.\n", p->queue_name);
- debug_printf("Try setting \"LocalQueueNamingRemoteCUPS DNS-SD\" or \"LocalQueueNamingRemoteCUPS RemoteName\" in cups-browsed.conf.\n");
- return -1;
- }
+
p->slave_of = (q && q->status != STATUS_DISAPPEARED &&
q->status != STATUS_UNCONFIRMED &&
q->status != STATUS_TO_BE_RELEASED) ? q : NULL;
@@ -3138,7 +5664,8 @@ on_printer_state_changed (CupsNotifier *object,
/* If auto shutdown is active for triggering on no jobs being left, we
schedule the shutdown in autoshutdown_timeout seconds */
if (!autoshutdown_exec_id) {
- debug_printf ("No jobs there any more on printers made available by us, shutting down in %d sec...\n", autoshutdown_timeout);
+ debug_printf ("No jobs there any more on printers made available by us, shutting down in %d sec...\n",
+ autoshutdown_timeout);
autoshutdown_exec_id =
g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
NULL);
@@ -3216,33 +5743,40 @@ on_job_state (CupsNotifier *object,
guint job_impressions_completed,
gpointer user_data)
{
- int i;
+ int i, count;
char buf[2048];
- remote_printer_t *p, *q;
+ remote_printer_t *p, *q, *r, *s=NULL;
http_t *http = NULL;
- ipp_t *request, *response;
+ ipp_t *request, *response, *printer_attributes = NULL;
ipp_attribute_t *attr;
const char *pname = NULL;
char *remote_cups_queue;
ipp_pstate_t pstate = IPP_PRINTER_IDLE;
int paccept = 0;
int num_jobs, min_jobs = 99999999;
- cups_job_t *jobs = NULL;
+ char destination_uri[1024];
const char *dest_host = NULL;
int dest_port = 0;
char dest_name[1024];
int dest_index = 0;
int valid_dest_found = 0;
char uri[HTTP_MAX_URI];
- /*int job_id = 0;*/
int num_options;
cups_option_t *options;
+ int num_of_printers;
+ char* document_format;
+ int print_quality;
+ const char *pdl=NULL;
+ cups_array_t *pdl_list;
+ char resolution[32];
+ res_t *max_res=NULL,*min_res=NULL,*res;
+ int xres,yres;
static const char *pattrs[] =
- {
- "printer-name",
- "printer-state",
- "printer-is-accepting-jobs"
- };
+ {
+ "printer-name",
+ "printer-state",
+ "printer-is-accepting-jobs"
+ };
http_t *conn = NULL;
debug_printf("on_job_state() in THREAD %ld\n", pthread_self());
@@ -3276,7 +5810,7 @@ on_job_state (CupsNotifier *object,
} else {
/* If auto shutdown is active for triggering on no jobs being left, we
cancel a shutdown in autoshutdown_timeout seconds as there are jobs
- again. */
+ again. */
if (autoshutdown_exec_id) {
debug_printf ("New jobs there on the printers made available by us, killing auto shutdown timer.\n");
g_source_remove(autoshutdown_exec_id);
@@ -3339,15 +5873,17 @@ on_job_state (CupsNotifier *object,
/* If we hit a slave and not the master, switch to the master */
if (q && q->slave_of)
q = q->slave_of;
- if (q && q->netprinter == 0) {
+ if (q) {
/* We have remote CUPS queue(s) and so are using the implicitclass
backend */
debug_printf("[CUPS Notification] %s is using the \"implicitclass\" CUPS backend, so let us search for a destination for this job.\n", printer);
+
/* We keep track of the printer which we used last time and start
checking with the next printer this time, to get a "round robin"
type of printer usage instead of having most jobs going to the first
printer in the list. Method taken from the cupsdFindAvailablePrinter()
function of the scheduler/classes.c file of CUPS. */
+
if (q->last_printer < 0 ||
q->last_printer >= cupsArrayCount(remote_printers))
q->last_printer = 0;
@@ -3359,7 +5895,32 @@ on_job_state (CupsNotifier *object,
if (!strcasecmp(p->queue_name, printer) &&
p->status == STATUS_CONFIRMED) {
remote_cups_queue = strrchr(p->uri, '/') + 1;
- debug_printf("Checking state of remote printer %s on host %s, IP %s, port %d.\n", remote_cups_queue, p->host, p->ip, p->port);
+ num_of_printers = 0;
+ for (r = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ r; r = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if(!strcmp(r->queue_name, q->queue_name)){
+ if(r->status == STATUS_DISAPPEARED || r->status == STATUS_UNCONFIRMED ||
+ r->status == STATUS_TO_BE_RELEASED )
+ continue;
+ num_of_printers++;
+ }
+ }
+
+ /* If we are in a cluster, see whether the printer supports the
+ requested job attributes*/
+ if (num_of_printers > 1) {
+ if (!supports_job_attributes_requested(printer, i, job_id,
+ &print_quality)) {
+ debug_printf("Printer with uri %s in cluster %s doesn't support the requested job attributes\n",
+ p->uri, p->queue_name);
+ if (i == q->last_printer)
+ break;
+ else
+ continue;
+ }
+ }
+ debug_printf("Checking state of remote printer %s on host %s, IP %s, port %d.\n",
+ remote_cups_queue, p->host, p->ip, p->port);
http = httpConnectEncryptShortTimeout (p->ip ? p->ip : p->host,
p->port,
HTTP_ENCRYPT_IF_REQUESTED);
@@ -3368,7 +5929,9 @@ on_job_state (CupsNotifier *object,
if (http) {
/* Check whether the printer is idle, processing, or disabled */
httpSetTimeout(http, HttpRemoteTimeout, http_timeout_cb, NULL);
- request = ippNewRequest(CUPS_GET_PRINTERS);
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL,p->uri);
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes",
sizeof(pattrs) / sizeof(pattrs[0]),
@@ -3412,53 +5975,61 @@ on_job_state (CupsNotifier *object,
else
continue;
}
- if (!strcasecmp(pname, remote_cups_queue)) {
- if (paccept) {
- debug_printf("Printer %s on host %s, port %d is accepting jobs.\n", remote_cups_queue, p->host, p->port);
- switch (pstate) {
- case IPP_PRINTER_IDLE:
- valid_dest_found = 1;
- dest_host = p->ip ? p->ip : p->host;
- dest_port = p->port;
- strncpy(dest_name, remote_cups_queue, sizeof(dest_name));
- if (strlen(remote_cups_queue) > 1023)
- dest_name[1023] = '\0';
- dest_index = i;
- debug_printf("Printer %s on host %s, port %d is idle, take this as destination and stop searching.\n",
- remote_cups_queue, p->host, p->port);
- break;
- case IPP_PRINTER_PROCESSING:
- valid_dest_found = 1;
- if (LoadBalancingType == QUEUE_ON_SERVERS) {
- num_jobs = 0;
- jobs = NULL;
- num_jobs =
- cupsGetJobs2(http, &jobs, remote_cups_queue, 0,
- CUPS_WHICHJOBS_ACTIVE);
- if (num_jobs >= 0 && num_jobs < min_jobs) {
- min_jobs = num_jobs;
- dest_host = p->ip ? p->ip : p->host;
- dest_port = p->port;
- strncpy(dest_name, remote_cups_queue, sizeof(dest_name));
- if (strlen(remote_cups_queue) > 1023)
- dest_name[1023] = '\0';
- dest_index = i;
- }
- debug_printf("Printer %s on host %s, port %d is printing and it has %d jobs.\n",
- remote_cups_queue, p->host, p->port,
- num_jobs);
- } else
- debug_printf("Printer %s on host %s, port %d is printing.\n", remote_cups_queue, p->host, p->port);
- break;
- case IPP_PRINTER_STOPPED:
- debug_printf("Printer %s on host %s, port %d is disabled, skip it.\n", remote_cups_queue, p->host, p->port);
- break;
- }
- } else {
- debug_printf("Printer %s on host %s, port %d is not accepting jobs, skip it.\n", remote_cups_queue, p->host, p->port);
+ if (paccept) {
+ debug_printf("Printer %s on host %s, port %d is accepting jobs.\n",
+ remote_cups_queue, p->host, p->port);
+ switch (pstate) {
+ case IPP_PRINTER_IDLE:
+ valid_dest_found = 1;
+ dest_host = p->ip ? p->ip : p->host;
+ dest_port = p->port;
+ strncpy(destination_uri,p->uri,sizeof(destination_uri));
+ printer_attributes = p->prattrs;
+ pdl = p->pdl;
+ s = p;
+ strncpy(dest_name, remote_cups_queue, sizeof(dest_name));
+ if (strlen(remote_cups_queue) > 1023)
+ dest_name[1023] = '\0';
+ dest_index = i;
+ debug_printf("Printer %s on host %s, port %d is idle, take this as destination and stop searching.\n",
+ remote_cups_queue, p->host, p->port);
+ break;
+ case IPP_PRINTER_PROCESSING:
+ valid_dest_found = 1;
+ if (LoadBalancingType == QUEUE_ON_SERVERS) {
+ num_jobs = 0;
+ num_jobs = get_number_of_jobs(http, p->uri, 0,
+ CUPS_WHICHJOBS_ACTIVE);
+ if (num_jobs >= 0 && num_jobs < min_jobs) {
+ min_jobs = num_jobs;
+ dest_host = p->ip ? p->ip : p->host;
+ dest_port = p->port;
+ strncpy(destination_uri,p->uri,sizeof(destination_uri));
+ printer_attributes = p->prattrs;
+ pdl = p->pdl;
+ s = p;
+ strncpy(dest_name, remote_cups_queue,
+ sizeof(dest_name));
+ if (strlen(remote_cups_queue) > 1023)
+ dest_name[1023] = '\0';
+ dest_index = i;
+ }
+ debug_printf("Printer %s on host %s, port %d is printing and it has %d jobs.\n",
+ remote_cups_queue, p->host, p->port,
+ num_jobs);
+ } else
+ debug_printf("Printer %s on host %s, port %d is printing.\n", remote_cups_queue, p->host, p->port);
+ break;
+ case IPP_PRINTER_STOPPED:
+ debug_printf("Printer %s on host %s, port %d is disabled, skip it.\n",
+ remote_cups_queue, p->host, p->port);
+ break;
}
- break;
+ } else {
+ debug_printf("Printer %s on host %s, port %d is not accepting jobs, skip it.\n",
+ remote_cups_queue, p->host, p->port);
}
+ break;
}
if (pstate == IPP_PRINTER_IDLE && paccept) {
q->last_printer = i;
@@ -3478,6 +6049,127 @@ on_job_state (CupsNotifier *object,
/* Write the selected destination host into an option of our implicit
class queue (cups-browsed-dest-printer="<dest>") so that the
implicitclass backend will pick it up */
+
+ if ((pdl_list = cupsArrayNew3((cups_array_func_t)strcasecmp,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free)) == NULL){
+ debug_printf("Could Not allocate memory for cups Array \n");
+ return;
+ }
+
+ /* Finding the best pdl supported by the printer, we need to send the
+ document format to the implictclass backend */
+ if (((attr = ippFindAttribute(printer_attributes,
+ "document-format-supported",
+ IPP_TAG_MIMETYPE)) != NULL) ||
+ (pdl && pdl[0] != '\0')) {
+ const char *format = pdl;
+ i = 0;
+ count = ippGetCount(attr);
+ while ((attr && i < count) || /* Go through formats in attribute */
+ (!attr && pdl && pdl[0] != '\0' && format[0] != '\0')) {
+ /* Go through formats in pdl string (from DNS-SD record) */
+ /* Pick next format from attribute */
+ if (attr) format = ippGetString(attr, i, NULL);
+ /* Add format to list of supported PDLs, skip duplicates */
+ if (!cupsArrayFind(pdl_list, (void *)format))
+ cupsArrayAdd(pdl_list, (void *)format);
+ if (attr)
+ /* Next format in attribute */
+ i ++;
+ else {
+ /* Find the next format in the string pdl, if there is none left,
+ go to the terminating zero */
+ while (!isspace(*format) && *format != ',' && *format != '\0')
+ format ++;
+ while ((isspace(*format) || *format == ',') && *format != '\0')
+ format++;
+ }
+ }
+ }
+
+ document_format = (char *)malloc(sizeof(char) * 32);
+ if (cupsArrayFind(pdl_list, "application/vnd.cups-pdf") ||
+ cupsArrayFind(pdl_list, "application/pdf"))
+ strcpy(document_format,"pdf");
+ else if(cupsArrayFind(pdl_list, "image/pwg-raster"))
+ strcpy(document_format,"raster");
+ else {
+#ifdef CUPS_RASTER_HAVE_APPLERASTER
+ if (cupsArrayFind(pdl_list, "image/urf"))
+ strcpy(document_format,"apple-raster");
+#else
+#ifdef QPDF_HAVE_PCLM
+ if (cupsArrayFind(pdl_list, "application/PCLm"))
+ strcpy(document_format,"pclm");
+#else
+ if(cupsArrayFind(pdl_list, "application/vnd.hp-pclxl"))
+ stcpy(document_format,"pclxl");
+ else(cupsArrayFind(pdl_list, "application/vnd.hp-pcl")||cupsArrayFind(pdl_list, "application/pcl")||
+ cupsArrayFind(pdl_list, "application/x-pcl"))
+ strcpy(document_format,"pcl");
+#endif
+#endif
+ }
+
+ /* Deciding the resolution to be sent with the job */
+ /* Finding the minimum and maximum resolution supported by the printer */
+ if (s &&
+ ((attr = ippFindAttribute(s->prattrs, "printer-resolution-supported",
+ IPP_TAG_RESOLUTION)) != NULL)) {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++) {
+ if ((res = ippResolutionToRes(attr, i)) != NULL) {
+ debug_printf("%d %d\n",res->x,res->y);
+ if (i == 0) {
+ max_res = res;
+ min_res = res;
+ } else {
+ if(compare_resolutions((void *)res,(void *)max_res,NULL) > 0)
+ max_res = res;
+ if(compare_resolutions((void *)res,(void *)min_res,NULL) < 0)
+ min_res = res;
+ }
+ }
+ }
+ }
+
+ /* If we are requesting normal print quality then send default
+ resolution, for draft send minimum resolution and for high,
+ send the maximum resolution */
+ /* If none of the below dpi is selected then default dpi will be
+ sent as 600 */
+ snprintf(resolution,sizeof(resolution), "600dpi");
+ if (s && print_quality == 3) {
+ if (min_res != NULL){
+ if (min_res->x == min_res->y)
+ snprintf(resolution,sizeof(resolution), "%ddpi", min_res->x);
+ else
+ snprintf(resolution,sizeof(resolution), "%dx%ddpi", min_res->x,
+ min_res->y);
+ }
+ } else if (s && print_quality == 5) {
+ if (max_res != NULL) {
+ if (max_res->x == max_res->y)
+ snprintf(resolution, sizeof(resolution), "%ddpi", max_res->x);
+ else
+ snprintf(resolution, sizeof(resolution), "%dx%ddpi", max_res->x,
+ max_res->y);
+ }
+ } else if (s) {
+ if ((attr = ippFindAttribute(s->prattrs, "printer-resolution-default",
+ IPP_TAG_ZERO)) != NULL) {
+ if ((res = ippResolutionToRes(attr, 0)) != NULL) {
+ xres = res->x;
+ yres = res->y;
+ if(xres == yres)
+ snprintf(resolution, sizeof(resolution), "%ddpi", xres);
+ else
+ snprintf(resolution, sizeof(resolution), "%dx%ddpi", xres, yres);
+ }
+ }
+ }
+
request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", ippPort(), "/printers/%s", printer);
@@ -3487,8 +6179,8 @@ on_job_state (CupsNotifier *object,
"requesting-user-name", NULL, cupsUser());
if (dest_host) {
q->last_printer = dest_index;
- snprintf(buf, sizeof(buf), "\"%d %s:%d/%s\"", job_id, dest_host,
- dest_port, dest_name);
+ snprintf(buf, sizeof(buf), "\"%d %s %s %s\"", job_id, destination_uri,
+ document_format, resolution);
debug_printf("Destination for job %d to %s: %s:%d, queue %s\n",
job_id, printer, dest_host, dest_port, dest_name);
} else if (valid_dest_found == 1) {
@@ -3671,16 +6363,16 @@ queue_overwritten (remote_printer_t *p)
device = uri;
if (device != NULL &&
(p->uri == NULL ||
- (p->netprinter != 0 && strcasecmp(device, p->uri)) ||
- (p->netprinter == 0 &&
- (strlen(device) < 16 || strncmp(device, "implicitclass://", 16))))) {
+ (strlen(device) < 16 || strncmp(device, "implicitclass://", 16)))) {
/* The printer's device URI is different to what we have
assigned, so we got notified because the queue was
externally modified and so we will release this printer
from the control of cups-browsed */
debug_printf("Printer %s got modified externally, discovered by a change of its device URI from %s to %s.\n",
p->queue_name,
- (p->uri ? (p->netprinter ? p->uri : "implicitclass://...") : "(not yet determined)"),
+ (p->uri ? (p->netprinter ? p->uri :
+ "implicitclass://...") :
+ "(not yet determined)"),
device);
overwritten = 1;
}
@@ -3722,7 +6414,8 @@ queue_overwritten (remote_printer_t *p)
cups-browsed */
debug_printf("Printer %s got modified externally, discovered by the NickName of its PPD file having changed from \"%s\" to \"%s\".\n",
p->queue_name, (p->nickname ? p->nickname : "(no PPD)"),
- (ppd->nickname ? ppd->nickname : "(NickName not readable)"));
+ (ppd->nickname ? ppd->nickname :
+ "(NickName not readable)"));
overwritten = 1;
}
}
@@ -3839,11 +6532,11 @@ on_printer_modified (CupsNotifier *object,
} else {
free(p->queue_name);
p->queue_name = new_queue_name;
- /* Check whether the queue under its new name will be stand-alone or part of
- a cluster */
+ /* Check whether the queue under its new name will be stand-alone or
+ part of a cluster */
if (join_cluster_if_needed(p, is_cups_queue) < 0) {
- /* There are other cups-browsed-generated queues with the new name, not able to
- cluster this queue with them */
+ /* There are other cups-browsed-generated queues with the new
+ name, not able to cluster this queue with them */
debug_printf("Not able to cluster this queue with equally-named ones.\n");
re_create = 0;
}
@@ -3890,7 +6583,8 @@ on_printer_modified (CupsNotifier *object,
#ifdef HAVE_CUPS_1_6
static ipp_t *
-get_printer_attributes(const char* uri) {
+get_printer_attributes(const char* uri)
+{
int uri_status, host_port, i;
http_t *http_printer = NULL;
char scheme[10], userpass[1024], host_name[1024], resource[1024];
@@ -3898,10 +6592,11 @@ get_printer_attributes(const char* uri) {
ipp_attribute_t *attr;
char valuebuffer[65536];
static const char * const pattrs[] =
- {
- "all",
- "media-col-database"
- };
+ {
+ "all",
+ "media-col-database"
+ };
+
/* Request printer properties via IPP to generate a PPD file for the
printer (mainly driverless-capable printers)
If we work with Systen V interface scripts use this info to set
@@ -4033,10 +6728,10 @@ create_remote_printer_entry (const char *queue_name,
p->slave_of = NULL;
p->last_printer = -1;
-
+
p->num_options = 0;
p->options = NULL;
-
+
p->host = strdup (host);
if (!p->host)
goto fail;
@@ -4095,13 +6790,13 @@ create_remote_printer_entry (const char *queue_name,
remote CUPS server gets used. So we will not generate a PPD file
or interface script at this point. */
p->netprinter = 0;
- p->prattrs = NULL;
+ p->prattrs = get_printer_attributes(p->uri);
p->nickname = NULL;
-
- /* Check whether we have an equally named queue already from another
- server and join a cluster if needed */
- if (join_cluster_if_needed(p, is_cups_queue) < 0)
+ if (p->prattrs == NULL) {
+ debug_printf("get-printer-attributes IPP call failed on printer %s (%s).\n",
+ p->queue_name, p->uri);
goto fail;
+ }
} else {
#ifndef HAVE_CUPS_1_6
/* The following code uses a lot of CUPS >= 1.6 specific stuff.
@@ -4197,7 +6892,8 @@ create_remote_printer_entry (const char *queue_name,
IPP_TAG_KEYWORD)) != NULL) {
debug_printf(" Attr: %s\n", ippGetName(attr));
for (i = 0; i < ippGetCount(attr); i ++) {
- strncpy(valuebuffer, ippGetString(attr, i, NULL), sizeof(valuebuffer));
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
if (strlen(ippGetString(attr, i, NULL)) > 65535)
valuebuffer[65535] = '\0';
debug_printf(" Keyword: %s\n", valuebuffer);
@@ -4230,7 +6926,8 @@ create_remote_printer_entry (const char *queue_name,
debug_printf(" Value: %s\n", valuebuffer);
if (valuebuffer[0] == '\0') {
for (i = 0; i < ippGetCount(attr); i ++) {
- strncpy(valuebuffer, ippGetString(attr, i, NULL), sizeof(valuebuffer));
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
if (strlen(ippGetString(attr, i, NULL)) > 65535)
valuebuffer[65535] = '\0';
debug_printf(" Keyword: %s\n", valuebuffer);
@@ -4262,7 +6959,8 @@ create_remote_printer_entry (const char *queue_name,
debug_printf(" Value: %s\n", valuebuffer);
if (valuebuffer[0] == '\0') {
for (i = 0; i < ippGetCount(attr); i ++) {
- strncpy(valuebuffer, ippGetString(attr, i, NULL), sizeof(valuebuffer));
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
if (strlen(ippGetString(attr, i, NULL)) > 65535)
valuebuffer[65535] = '\0';
debug_printf(" Keyword: %s\n", valuebuffer);
@@ -4297,7 +6995,8 @@ create_remote_printer_entry (const char *queue_name,
debug_printf(" Value: %s\n", p->queue_name, valuebuffer);
if (valuebuffer[0] == '\0') {
for (i = 0; i < ippGetCount(attr); i ++) {
- strncpy(valuebuffer, ippGetString(attr, i, NULL), sizeof(valuebuffer));
+ strncpy(valuebuffer, ippGetString(attr, i, NULL),
+ sizeof(valuebuffer));
if (strlen(ippGetString(attr, i, NULL)) > 65535)
valuebuffer[65535] = '\0';
debug_printf(" Keyword: %s\n", valuebuffer);
@@ -4319,8 +7018,8 @@ create_remote_printer_entry (const char *queue_name,
"application/pdf" under its PDLs. */
if (CreateIPPPrinterQueues == IPP_PRINTERS_PDF ||
CreateIPPPrinterQueues == IPP_PRINTERS_DRIVERLESS) {
- debug_printf("Checking whether printer %s understands PDF: PDLs: %s\n",
- p->queue_name, pdl);
+ debug_printf("Checking whether printer %s understands PDF: PDLs: %s\n",
+ p->queue_name, pdl);
if(strcasestr(pdl, "application/pdf"))
is_pdf = 1;
debug_printf(" --> Printer %s PDF.\n",
@@ -4383,7 +7082,10 @@ create_remote_printer_entry (const char *queue_name,
#endif /* HAVE_CUPS_1_6 */
}
-
+ /* Check whether we have an equally named queue already from another
+ server and join a cluster if needed */
+ if (join_cluster_if_needed(p, is_cups_queue) < 0)
+ goto fail;
/* Add the new remote printer entry */
log_all_printers();
cupsArrayAdd(remote_printers, p);
@@ -4470,7 +7172,7 @@ remove_printer_entry(remote_printer_t *p) {
} else
debug_printf("Printer %s (Host: %s, Port: %d, URI: %s) disappeared and no slave available (or it is a slave of another printer), removing entry.\n",
p->queue_name, p->host, p->port, p->uri);
-
+
/* Schedule entry and its CUPS queue for removal */
if (p->status != STATUS_TO_BE_RELEASED)
p->status = STATUS_DISAPPEARED;
@@ -4478,42 +7180,50 @@ remove_printer_entry(remote_printer_t *p) {
}
gboolean update_cups_queues(gpointer unused) {
- remote_printer_t *p, *q, *r;
- http_t *http, *remote_http;
- char uri[HTTP_MAX_URI], device_uri[HTTP_MAX_URI], buf[1024], line[1024];
- char *remote_cups_queue;
- int num_options;
+ remote_printer_t *p, *q, *r, *s, *master;
+ http_t *http;
+ char uri[HTTP_MAX_URI], device_uri[HTTP_MAX_URI], buf[1024],
+ line[1024];
+ int num_options;
cups_option_t *options;
- int num_jobs;
- cups_job_t *jobs;
- ipp_t *request;
- time_t current_time;
- int i, new_cupsfilter_line_inserted, ap_remote_queue_id_line_inserted,
- cont_line_read, want_raw;
- char *disabled_str, *ptr, *prefix;
- char *ppdfile, *ifscript;
- int fd = 0; /* Script file descriptor */
- char tempfile[1024]; /* Temporary file */
- char buffer[8192]; /* Buffer for creating script */
+ int num_jobs;
+ cups_job_t *jobs;
+ ipp_t *request;
+ time_t current_time;
+ int i, ap_remote_queue_id_line_inserted,
+ want_raw, num_cluster_printers = 0;
+ char *disabled_str, *ptr;
+ char *ppdfile, *ifscript;
+ int fd = 0; /* Script file descriptor */
+ char tempfile[1024]; /* Temporary file */
+ char buffer[8192]; /* Buffer for creating script */
int bytes;
- const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
+ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */
#ifdef HAVE_CUPS_1_6
ipp_attribute_t *attr;
- int count, left, right, bottom, top;
- const char *default_page_size = NULL, *best_color_space = NULL, *color_space;
+ int count, left, right, bottom, top;
+ const char *default_page_size = NULL, *best_color_space = NULL,
+ *color_space;
#endif
- const char *loadedppd = NULL;
- int pass_through_ppd;
- ppd_file_t *ppd;
- ppd_choice_t *choice;
- cups_file_t *in, *out;
- char keyword[1024], *keyptr;
- const char *customval;
- const char *val = NULL;
- cups_dest_t *dest = NULL;
- int is_shared;
-
- debug_printf("update_cups_queues() in THREAD %ld\n", pthread_self());
+ const char *loadedppd = NULL;
+ ppd_file_t *ppd;
+ ppd_choice_t *choice;
+ cups_file_t *in, *out;
+ char keyword[1024], *keyptr;
+ const char *customval;
+ const char *val = NULL;
+ cups_dest_t *dest = NULL;
+ int is_shared;
+ cups_array_t *conflicts = NULL;
+ ipp_t *printer_attributes = NULL;
+ cups_array_t *sizes=NULL;
+ ipp_t *printer_ipp_response;
+ char *make_model;
+ const char *pdl=NULL;
+ int color;
+ int duplex;
+ char *default_pagesize;
+ const char *default_color = NULL;
/* Create dummy entry to point slaves at when their master is about to
get removed now (if we point them to NULL, we would try to remove
@@ -4531,7 +7241,8 @@ gboolean update_cups_queues(gpointer unused) {
to this dummy entry */
for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
p; p = (remote_printer_t *)cupsArrayNext(remote_printers))
- if ((p->status == STATUS_DISAPPEARED || p->status == STATUS_TO_BE_RELEASED) &&
+ if ((p->status == STATUS_DISAPPEARED ||
+ p->status == STATUS_TO_BE_RELEASED) &&
(q = p->slave_of) != NULL &&
(q->status == STATUS_DISAPPEARED || q->status == STATUS_TO_BE_RELEASED))
p->slave_of = r;
@@ -4578,10 +7289,12 @@ gboolean update_cups_queues(gpointer unused) {
if (p->timeout > current_time)
break;
- cannot_create:
+ cannot_create:
debug_printf("Removing entry %s (%s)%s.\n", p->queue_name, p->uri,
- (p->slave_of || p->status == STATUS_TO_BE_RELEASED ? "" : " and its CUPS queue"));
+ (p->slave_of ||
+ p->status == STATUS_TO_BE_RELEASED ? "" :
+ " and its CUPS queue"));
/* Slaves do not have a CUPS queue */
if ((q = p->slave_of) == NULL) {
@@ -4610,7 +7323,8 @@ gboolean update_cups_queues(gpointer unused) {
then */
num_jobs = 0;
jobs = NULL;
- num_jobs = cupsGetJobs2(http, &jobs, p->queue_name, 0, CUPS_WHICHJOBS_ACTIVE);
+ num_jobs = cupsGetJobs2(http, &jobs, p->queue_name, 0,
+ CUPS_WHICHJOBS_ACTIVE);
if (num_jobs != 0) { /* error or jobs */
debug_printf("Queue has still jobs or CUPS error!\n");
cupsFreeJobs(num_jobs, jobs);
@@ -4662,7 +7376,8 @@ gboolean update_cups_queues(gpointer unused) {
request = ippNewRequest(CUPS_DELETE_PRINTER);
/* Printer URI: ipp://localhost:631/printers/<queue name> */
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", ippPort(), "/printers/%s", p->queue_name);
+ "localhost", ippPort(), "/printers/%s",
+ p->queue_name);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
/* Default user */
@@ -4712,7 +7427,7 @@ gboolean update_cups_queues(gpointer unused) {
p = NULL;
/* If auto shutdown is active and all printers we have set up got removed
- again, schedule the shutdown in autoshutdown_timeout seconds
+ again, schedule the shutdown in autoshutdown_timeout seconds
Note that in this case we also do not have jobs any more so if we
auto shutdown on running out of jobs, trigger it here, too. */
if (in_shutdown == 0 && autoshutdown && !autoshutdown_exec_id &&
@@ -4721,7 +7436,7 @@ gboolean update_cups_queues(gpointer unused) {
debug_printf ("No printers there any more to make available or no jobs, shutting down in %d sec...\n", autoshutdown_timeout);
autoshutdown_exec_id =
g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
- NULL);
+ NULL);
}
break;
@@ -4729,12 +7444,15 @@ gboolean update_cups_queues(gpointer unused) {
/* DNS-SD has reported a new remote printer, create a CUPS queue for it,
or upgrade an existing queue, or update a queue to use a backup host
when it has disappeared on the currently used host */
- /* (...or, we've just received a CUPS Browsing packet for this queue) */
+ /* (...or, we've just received a CUPS Browsing packet for this queue) */
case STATUS_TO_BE_CREATED:
/* Do not create a queue for slaves */
if (p->slave_of) {
p->status = STATUS_CONFIRMED;
+ master = p->slave_of;
+ master->status = STATUS_TO_BE_CREATED;
+ master->timeout = time(NULL) + TIMEOUT_IMMEDIATELY;
if (p->is_legacy) {
p->timeout = time(NULL) + BrowseTimeout;
debug_printf("starting BrowseTimeout timer for %s (%ds)\n",
@@ -4788,9 +7506,11 @@ gboolean update_cups_queues(gpointer unused) {
Either CUPS generates a temporary queue here or we have already
made this queue permanent. In any case, load the PPD from this
queue to conserve the PPD which CUPS has originally generated. */
- if (p->netprinter == 1 && IPPPrinterQueueType == PPD_YES && UseCUPSGeneratedPPDs) {
+ if (p->netprinter == 1 && IPPPrinterQueueType == PPD_YES &&
+ UseCUPSGeneratedPPDs) {
if (LocalQueueNamingIPPPrinter != LOCAL_QUEUE_NAMING_DNSSD) {
- debug_printf("Local queue %s: We can replace temporary CUPS queues and keep their PPD file only when we name our queues like them, to avoid duplicate queues to the same printer.\n", p->queue_name);
+ debug_printf("Local queue %s: We can replace temporary CUPS queues and keep their PPD file only when we name our queues like them, to avoid duplicate queues to the same printer.\n",
+ p->queue_name);
debug_printf("Not loading PPD from temporary CUPS queue for this printer.\n");
debug_printf("Try setting \"LocalQueueNamingIPPPrinter DNS-SD\" in cups-browsed.conf.\n");
} else {
@@ -4835,7 +7555,7 @@ gboolean update_cups_queues(gpointer unused) {
we cannot modify its printer-is-shared option as CUPS prevents
this. In this case we remove the temporary queue so that we
create a fresh one which will always be permanent.
- If the temporary queue has still jobs we will not remove it to
+ If the temporary queue has still jobs we will not remove it to
not loose the jobs and wait with creating our new queue until
the jobs are done. */
val = cupsGetOption ("printer-is-shared",
@@ -4865,7 +7585,8 @@ gboolean update_cups_queues(gpointer unused) {
num_options = cupsAddOption("printer-is-shared",
(i == 0 ? "true" : "false"),
num_options, &options);
- cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
+ cupsEncodeOptions2(request, num_options, options,
+ IPP_TAG_OPERATION);
cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
ippDelete(cupsDoRequest(http, request, "/admin/"));
cupsFreeOptions(num_options, options);
@@ -4876,8 +7597,8 @@ gboolean update_cups_queues(gpointer unused) {
break;
}
}
- /* Error on modifying printer-is-shared bit, removing possibly temporary
- queue */
+ /* Error on modifying printer-is-shared bit, removing possibly
+ temporary queue */
if (i <= 1) {
debug_printf("Removing the possibly temporary CUPS queue.\n");
/* Check whether there are still jobs and do not remove the queue
@@ -4936,18 +7657,77 @@ gboolean update_cups_queues(gpointer unused) {
goto cannot_create;
}
if (IPPPrinterQueueType == PPD_YES) {
+ num_cluster_printers = 0;
+ for (s = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ s; s = (remote_printer_t *)cupsArrayNext(remote_printers)){
+ if(!strcmp(s->queue_name,p->queue_name)) {
+ if(s->status == STATUS_DISAPPEARED || s->status == STATUS_UNCONFIRMED ||
+ s->status == STATUS_TO_BE_RELEASED )
+ continue;
+ num_cluster_printers++;
+ }
+ }
+
+ if (num_cluster_printers == 1) {
+ printer_attributes = p->prattrs;
+ conflicts = NULL;
+ default_pagesize = NULL;
+ default_color = NULL;
+ make_model = p->make_model;
+ pdl = p->pdl;
+ color = p->color;
+ duplex = p->duplex;
+ sizes = NULL;
+ } else {
+ make_model = (char*)malloc(sizeof(char) * 256);
+ if ((attr = ippFindAttribute(printer_attributes,
+ "printer-make-and-model",
+ IPP_TAG_TEXT)) != NULL)
+ strncpy(make_model, ippGetString(attr, 0, NULL), 256);
+ color = 0;
+ duplex = 0;
+ for (r = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ r; r = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if (!strcmp(p->queue_name, r->queue_name)) {
+ if (r->color == 1)
+ color = 1;
+ if (r->duplex == 1)
+ duplex = 1;
+ }
+ }
+ default_pagesize = (char *)malloc(sizeof(char)*32);
+ printer_attributes = get_cluster_attributes(p->queue_name);
+ debug_printf("Generated Merged Attributes for local queue %s\n",
+ p->queue_name);
+ conflicts = generate_cluster_conflicts(p->queue_name,
+ printer_attributes);
+ debug_printf("Generated Constraints for queue %s\n",
+ p->queue_name);
+ sizes = get_cluster_sizes(p->queue_name);
+ get_cluster_default_attributes(&printer_attributes,
+ p->queue_name, default_pagesize,
+ &default_color);
+ debug_printf("Generated Default Attributes for local queue %s\n",
+ p->queue_name);
+ }
p->nickname = NULL;
if (ppdfile == NULL) {
/* If we do not want CUPS-generated PPDs or we cannot obtain a
CUPS-generated PPD, for example if CUPS does not create a
temporary queue for this printer, we generate a PPD by
ourselves */
- if (!ppdCreateFromIPP(buffer, sizeof(buffer), p->prattrs, p->make_model,
- p->pdl, p->color, p->duplex)) {
+ printer_ipp_response = (num_cluster_printers == 1) ? p->prattrs :
+ printer_attributes;
+ if (!ppdCreateFromIPP2(buffer, sizeof(buffer), printer_ipp_response,
+ make_model,
+ pdl, color, duplex, conflicts, sizes,
+ default_pagesize, default_color)) {
if (errno != 0)
- debug_printf("Unable to create PPD file: %s\n", strerror(errno));
+ debug_printf("Unable to create PPD file: %s\n",
+ strerror(errno));
else
- debug_printf("Unable to create PPD file: %s\n", ppdgenerator_msg);
+ debug_printf("Unable to create PPD file: %s\n",
+ ppdgenerator_msg);
p->status = STATUS_DISAPPEARED;
current_time = time(NULL);
p->timeout = current_time + TIMEOUT_IMMEDIATELY;
@@ -4983,13 +7763,18 @@ gboolean update_cups_queues(gpointer unused) {
p->num_options = cupsAddOption("media-default",
strdup(default_page_size),
p->num_options, &(p->options));
- } else
+ } else
debug_printf("No default page size found!\n");
}
/* Find maximum unprintable margins of the printer */
- if ((attr = ippFindAttribute(p->prattrs, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL) {
- for (i = 1, bottom = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if ((attr = ippFindAttribute(p->prattrs,
+ "media-bottom-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, bottom = ippGetInteger(attr, 0),
+ count = ippGetCount(attr);
+ i < count;
+ i ++)
if (ippGetInteger(attr, i) > bottom)
bottom = ippGetInteger(attr, i);
} else
@@ -4999,8 +7784,13 @@ gboolean update_cups_queues(gpointer unused) {
strdup(buffer),
p->num_options, &(p->options));
- if ((attr = ippFindAttribute(p->prattrs, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL) {
- for (i = 1, left = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if ((attr = ippFindAttribute(p->prattrs,
+ "media-left-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, left = ippGetInteger(attr, 0),
+ count = ippGetCount(attr);
+ i < count;
+ i ++)
if (ippGetInteger(attr, i) > left)
left = ippGetInteger(attr, i);
} else
@@ -5010,8 +7800,13 @@ gboolean update_cups_queues(gpointer unused) {
strdup(buffer),
p->num_options, &(p->options));
- if ((attr = ippFindAttribute(p->prattrs, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL) {
- for (i = 1, right = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if ((attr = ippFindAttribute(p->prattrs,
+ "media-right-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, right = ippGetInteger(attr, 0),
+ count = ippGetCount(attr);
+ i < count;
+ i ++)
if (ippGetInteger(attr, i) > right)
right = ippGetInteger(attr, i);
} else
@@ -5021,8 +7816,13 @@ gboolean update_cups_queues(gpointer unused) {
strdup(buffer),
p->num_options, &(p->options));
- if ((attr = ippFindAttribute(p->prattrs, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL) {
- for (i = 1, top = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
+ if ((attr = ippFindAttribute(p->prattrs,
+ "media-top-margin-supported",
+ IPP_TAG_INTEGER)) != NULL) {
+ for (i = 1, top = ippGetInteger(attr, 0),
+ count = ippGetCount(attr);
+ i < count;
+ i ++)
if (ippGetInteger(attr, i) > top)
top = ippGetInteger(attr, i);
} else
@@ -5060,10 +7860,12 @@ gboolean update_cups_queues(gpointer unused) {
}
if (p->duplex)
- p->num_options = cupsAddOption("sides-default", "two-sided-long-edge",
+ p->num_options = cupsAddOption("sides-default",
+ "two-sided-long-edge",
p->num_options, &(p->options));
- p->num_options = cupsAddOption("output-format-default", strdup(p->pdl),
+ p->num_options = cupsAddOption("output-format-default",
+ strdup(p->pdl),
p->num_options, &(p->options));
p->num_options = cupsAddOption("make-and-model-default",
remove_bad_chars(p->make_model, 0),
@@ -5112,8 +7914,6 @@ gboolean update_cups_queues(gpointer unused) {
ifscript = strdup(tempfile);
}
- ippDelete(p->prattrs);
- p->prattrs = NULL;
}
#endif /* HAVE_CUPS_1_6 */
@@ -5129,18 +7929,12 @@ gboolean update_cups_queues(gpointer unused) {
p->num_options = load_printer_options(p->queue_name, p->num_options,
&p->options);
- /* If we create a queue to a remote CUPS printer we need the queue
- name on the remote server */
- if (p->netprinter == 0)
- remote_cups_queue = strrchr(p->uri, '/') + 1;
-
/* Determine whether we have an IPP network printer. If not we
have remote CUPS queue(s) and so we use an implicit class for
load balancing. In this case we will assign an
implicitclass://... device URI, which makes cups-browsed find
the best destination for each job. */
loadedppd = NULL;
- pass_through_ppd = 0;
if (cups_notifier != NULL && p->netprinter == 0) {
/* We are not an IPP network printer, so we use the device URI
implicitclass://<queue name>/
@@ -5170,45 +7964,98 @@ gboolean update_cups_queues(gpointer unused) {
the PPD's NickName, so that automatic PPD updating by the
distribution's package installation/update infrastructure
is suppressed. */
- /* Load the PPD file from one of the servers */
- if ((remote_http =
- httpConnectEncryptShortTimeout(p->ip ? p->ip : p->host,
- p->port ? p->port :
- ippPort(),
- cupsEncryption()))
- == NULL) {
- debug_printf("Could not connect to the server %s:%d for %s!\n",
- p->host, p->port, p->queue_name);
- current_time = time(NULL);
- p->timeout = current_time + TIMEOUT_RETRY;
- p->no_autosave = 0;
- break;
+ /* Generating the ppd file for the remote cups queue */
+ if (p->prattrs == NULL)
+ p->prattrs = get_printer_attributes(p->uri);
+ if (p->prattrs == NULL) {
+ debug_printf("get-printer-attributes IPP call failed on printer %s (%s).\n",
+ p->queue_name, p->uri);
+ goto cannot_create;
}
- httpSetTimeout(remote_http, HttpRemoteTimeout, http_timeout_cb, NULL);
- if ((loadedppd = cupsGetPPD2(remote_http, remote_cups_queue))
- == NULL &&
- CreateRemoteRawPrinterQueues == 0) {
- debug_printf("Unable to load PPD file for %s from the server %s:%d!\n",
- p->queue_name, p->host, p->port);
- current_time = time(NULL);
- p->timeout = current_time + TIMEOUT_RETRY;
- p->no_autosave = 0;
- httpClose(remote_http);
- break;
- } else if (loadedppd) {
- debug_printf("Loaded PPD file %s for printer %s from server %s:%d!\n",
- loadedppd, p->queue_name, p->host, p->port);
- /* Modify PPD to not filter the job */
- pass_through_ppd = 1;
+ p->nickname = NULL;
+ num_cluster_printers = 0;
+ for (s = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ s; s = (remote_printer_t *)cupsArrayNext(remote_printers)) {
+ if(!strcmp(s->queue_name,p->queue_name)) {
+ if(s->status == STATUS_DISAPPEARED || s->status == STATUS_UNCONFIRMED ||
+ s->status == STATUS_TO_BE_RELEASED )
+ continue;
+ num_cluster_printers++;
+ }
+ }
+ if (num_cluster_printers == 1) {
+ printer_attributes = p->prattrs;
+ conflicts = NULL;
+ default_pagesize = NULL;
+ default_color = NULL;
+ make_model = p->make_model;
+ pdl = p->pdl;
+ color = p->color;
+ duplex = p->duplex;
+ sizes = NULL;
+ } else {
+ make_model = (char*)malloc(sizeof(char)*256);
+ if((attr = ippFindAttribute(printer_attributes,
+ "printer-make-and-model",
+ IPP_TAG_TEXT)) != NULL)
+ strncpy(make_model, ippGetString(attr, 0, NULL), 256);
+ color = 0;
+ duplex = 0;
+ for(r = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ r; r = (remote_printer_t *)cupsArrayNext(remote_printers)){
+ if(!strcmp(p->queue_name,r->queue_name)){
+ if(r->color==1)
+ color = 1;
+ if(r->duplex==1)
+ duplex = 1;
+ }
+ }
+ default_pagesize = (char *)malloc(sizeof(char)*32);
+ printer_attributes = get_cluster_attributes(p->queue_name);
+ debug_printf("Generated Merged Attributes for local queue %s\n",
+ p->queue_name);
+ conflicts = generate_cluster_conflicts(p->queue_name,
+ printer_attributes);
+ debug_printf("Generated Constraints for queue %s\n",p->queue_name);
+ sizes = get_cluster_sizes(p->queue_name);
+ get_cluster_default_attributes(&printer_attributes, p->queue_name,
+ default_pagesize,&default_color);
+ debug_printf("Generated Default Attributes for local queue %s\n",
+ p->queue_name);
+ }
+ if (ppdfile == NULL) {
+ /* If we do not want CUPS-generated PPDs or we cannot obtain a
+ CUPS-generated PPD, for example if CUPS does not create a
+ temporary queue for this printer, we generate a PPD by
+ ourselves */
+ printer_ipp_response = (num_cluster_printers == 1) ? p->prattrs :
+ printer_attributes;
+ if (!ppdCreateFromIPP2(buffer, sizeof(buffer), printer_ipp_response,
+ make_model,
+ pdl, color, duplex, conflicts, sizes,
+ default_pagesize, default_color)) {
+ if (errno != 0)
+ debug_printf("Unable to create PPD file: %s\n", strerror(errno));
+ else
+ debug_printf("Unable to create PPD file: %s\n", ppdgenerator_msg);
+ p->status = STATUS_DISAPPEARED;
+ current_time = time(NULL);
+ p->timeout = current_time + TIMEOUT_IMMEDIATELY;
+ goto cannot_create;
+ } else {
+ debug_printf("PPD generation successful: %s\n", ppdgenerator_msg);
+ debug_printf("Created temporary PPD file: %s\n", buffer);
+ ppdfile = strdup(buffer);
+ }
}
- httpClose(remote_http);
}
} else {
- /* Device URI: ipp(s)://<remote host>:631/printers/<remote queue> */
- strncpy(device_uri, p->uri, sizeof(device_uri));
+ /* Device URI: using implicitclass backend for IPP network printer */
+ httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri),
+ "implicitclass", NULL, p->queue_name, 0, NULL);
if (strlen(p->uri) > HTTP_MAX_URI-1)
device_uri[HTTP_MAX_URI-1] = '\0';
- debug_printf("Print queue %s is for an IPP network printer, or we do not get notifications from CUPS, using direct device URI %s\n",
+ debug_printf("Print queue %s is for an IPP network printer, using implicitclass backend for the printer. %s\n",
p->queue_name, device_uri);
}
@@ -5253,66 +8100,11 @@ gboolean update_cups_queues(gpointer unused) {
}
debug_printf("Editing PPD file %s for printer %s, setting the option defaults of the previous cups-browsed session%s, saving the resulting PPD in %s.\n",
loadedppd, p->queue_name,
- (pass_through_ppd == 1 ?
- " and inhibiting client-side filtering of the job" : ""),
+ " and doing client-side filtering of the job" ,
buf);
- new_cupsfilter_line_inserted = 0;
ap_remote_queue_id_line_inserted = 0;
- cont_line_read = 0;
while (cupsFileGets(in, line, sizeof(line))) {
- if (pass_through_ppd == 1 &&
- (!strncmp(line, "*cupsFilter:", 12) ||
- !strncmp(line, "*cupsFilter2:", 13))) {
- cont_line_read = 0;
- /* "*cupfFilter(2): ..." line: Remove it and replace the
- first one by a line which passes through the data
- unfiltered */
- if (new_cupsfilter_line_inserted == 0) {
- cupsFilePrintf(out, "*cupsFilter: \"*/* 0 -\"\n");
- new_cupsfilter_line_inserted = 1;
- }
- /* Find the end of the "*cupsFilter(2): ..." entry in the
- case it spans more than one line */
- do {
- if (strlen(line) != 0) {
- ptr = line + strlen(line) - 1;
- while(isspace(*ptr) && ptr > line)
- ptr --;
- if (*ptr == '"')
- break;
- }
- cont_line_read = 1;
- } while (cupsFileGets(in, line, sizeof(line)));
- } else if (pass_through_ppd == 1 &&
- !strncmp(line, "*NickName:", 10)) {
- cont_line_read = 0;
- /* Prefix the "NickName" of the printer so that automatic
- PPD updaters skip this PPD */
- ptr = strchr(line, '"');
- if (ptr) {
- ptr ++;
- prefix = "Remote printer: ";
- line[sizeof(line) - strlen(prefix) - 1] = '\0';
- memmove(ptr + strlen(prefix), ptr, strlen(ptr) + 1);
- memmove(ptr, prefix, strlen(prefix));
- ptr = line + strlen(line) - 1;
- while(isspace(*ptr) && ptr > line) {
- *ptr = '\0';
- ptr --;
- }
- if (*ptr != '"') {
- if (ptr < line + sizeof(line) - 2) {
- *(ptr + 1) = '"';
- *(ptr + 2) = '\0';
- } else {
- line[sizeof(line) - 2] = '"';
- line[sizeof(line) - 1] = '\0';
- }
- }
- }
- cupsFilePrintf(out, "%s\n", line);
- } else if (!strncmp(line, "*Default", 8)) {
- cont_line_read = 0;
+ if (!strncmp(line, "*Default", 8)) {
strncpy(keyword, line + 8, sizeof(keyword));
if ((strlen(line) + 8) > 1023)
keyword[1023] = '\0';
@@ -5341,8 +8133,7 @@ gboolean update_cups_queues(gpointer unused) {
cupsFilePrintf(out, "%s\n", line);
} else
cupsFilePrintf(out, "%s\n", line);
- } else if (cont_line_read == 0 || strncmp(line, "*End", 4)) {
- cont_line_read = 0;
+ } else if (strncmp(line, "*End", 4)) {
/* Write an "APRemoteQueueID" line to make this queue marked
as remote printer by CUPS */
if (p->netprinter == 0 &&
@@ -5368,8 +8159,8 @@ gboolean update_cups_queues(gpointer unused) {
}
}
}
- if (pass_through_ppd == 1 && new_cupsfilter_line_inserted == 0)
- cupsFilePrintf(out, "*cupsFilter: \"*/* 0 -\"\n");
+ cupsFilePrintf(out,"*cupsFilter2: \"application/vnd.cups-pdf application/pdf 0 -\"\n");
+
cupsFileClose(in);
cupsFileClose(out);
ppdClose(ppd);
@@ -5383,7 +8174,7 @@ gboolean update_cups_queues(gpointer unused) {
/* Create a new CUPS queue or modify the existing queue */
request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
+ "printer-uri", NULL, uri);
/* Default user */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());
@@ -5439,7 +8230,7 @@ gboolean update_cups_queues(gpointer unused) {
} else {
debug_printf("Queue %s keeping its current PPD file/interface script\n", p->queue_name);
want_raw = 0;
- }
+ }
ippDelete(cupsDoRequest(http, request, "/admin/"));
}
cupsFreeOptions(num_options, options);
@@ -5473,7 +8264,7 @@ gboolean update_cups_queues(gpointer unused) {
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, cupsUser());
+ "requesting-user-name", NULL, cupsUser());
num_options = 0;
options = NULL;
if (p->netprinter == 1 &&
@@ -5542,7 +8333,10 @@ gboolean update_cups_queues(gpointer unused) {
if ((disabled_str = is_disabled(p->queue_name, "cups-browsed")) != NULL) {
enable_printer(p->queue_name);
free(disabled_str);
- } else if ((disabled_str = is_disabled(p->queue_name, "Printer stopped due to backend errors")) != NULL) {
+ } else if ((disabled_str =
+ is_disabled(p->queue_name,
+ "Printer stopped due to backend errors")) !=
+ NULL) {
enable_printer(p->queue_name);
free(disabled_str);
}
@@ -5557,8 +8351,8 @@ gboolean update_cups_queues(gpointer unused) {
/* Check if an HTTP timeout happened during the print queue creation
If it does - increment p->timeouted and set status to TO_BE_CREATED
- because the creation can fall through the process, have state changed to
- STATUS_CONFIRMED and experience the timeout */
+ because the creation can fall through the process, have state changed
+ to STATUS_CONFIRMED and experience the timeout */
/* If no timeout has happened, clear p->timeouted */
if (timeout_reached == 1) {
fprintf(stderr, "Timeout happened during creation of the queue %s, turn on DebugLogging for more info.\n", p->queue_name);
@@ -5690,17 +8484,17 @@ matched_filters (const char *queue_name,
avahi_free(value);
goto filter_failed;
}
- }
+ }
} else {
/* match boolean value */
if (filter->sense == FILTER_MATCH) {
- if (!value || strcasecmp(value, "T")) {
+ if (!value || strcasecmp(value, "T")) {
avahi_free(key);
avahi_free(value);
goto filter_failed;
}
} else {
- if (value && !strcasecmp(value, "T")) {
+ if (value && !strcasecmp(value, "T")) {
avahi_free(key);
avahi_free(value);
goto filter_failed;
@@ -5793,7 +8587,7 @@ examine_discovered_printer_record(const char *host,
char uri[HTTP_MAX_URI];
char *remote_host = NULL, *pdl = NULL,
- *make_model = NULL;
+ *make_model = NULL;
int color = 1, duplex = 1;
#ifdef HAVE_AVAHI
char *fields[] = { "product", "usb_MDL", "ty", NULL }, **f;
@@ -5812,7 +8606,6 @@ examine_discovered_printer_record(const char *host,
return NULL;
}
-
is_cups_queue = 0;
memset(uri, 0, sizeof(uri));
@@ -5821,9 +8614,8 @@ examine_discovered_printer_record(const char *host,
(strcasestr(type, "_ipps") ? "ipps" : "ipp"), NULL,
(ip != NULL ? ip : host), port, "/%s", resource);
/* Find the remote host name.
- * Used in constructing backup queue name, so need to sanitize.
- * strdup() is called inside remove_bad_chars() and result is free()-able.
- */
+ Used in constructing backup queue name, so need to sanitize.
+ strdup() is called inside remove_bad_chars() and result is free()-able. */
remote_host = remove_bad_chars(host, 1);
/* If we only want to create queues for printers for which CUPS does
@@ -5833,8 +8625,8 @@ examine_discovered_printer_record(const char *host,
if (g_hash_table_find (cups_supported_remote_printers,
local_printer_service_name_matches,
(gpointer *)service_name)) {
- /* Found a DNS-SD-discovered CUPS-supported printer whose service name matches
- our discovered printer */
+ /* Found a DNS-SD-discovered CUPS-supported printer whose service name
+ matches our discovered printer */
debug_printf("Printer with DNS-SD service name \"%s\" and URI \"%s\" does not need to be covered by us as it is already supported by CUPS, skipping.\n",
service_name, uri);
goto fail;
@@ -5862,11 +8654,13 @@ examine_discovered_printer_record(const char *host,
avahi_free(value);
}
}
- /* Check by the printer-type TXT field whether the discovered printer is a CUPS queue */
+ /* Check by the printer-type TXT field whether the discovered printer is a
+ CUPS queue */
entry = avahi_string_list_find((AvahiStringList *)txt, "printer-type");
if (entry) {
avahi_string_list_get_pair(entry, &key, &value, NULL);
- if (key && value && strlen(value) > 1 && !strcasecmp(key, "printer-type") && value[0] == '0' &&
+ if (key && value && strlen(value) > 1 &&
+ !strcasecmp(key, "printer-type") && value[0] == '0' &&
value[1] == 'x') {
is_cups_queue = 1;
}
@@ -5960,7 +8754,8 @@ examine_discovered_printer_record(const char *host,
if (entry) {
avahi_string_list_get_pair(entry, &key, &note_value, NULL);
if (key && note_value && !strcasecmp(key, "note")) {
- debug_printf("examine_discovered_printer_record: TXT.note: |%s|\n", note_value); /* !! */
+ debug_printf("examine_discovered_printer_record: TXT.note: |%s|\n",
+ note_value); /* !! */
location = note_value;
}
avahi_free(key);
@@ -5970,7 +8765,8 @@ examine_discovered_printer_record(const char *host,
if (!location)
location = "";
}
- /* A NULL location is only passed in from resolve_callback(), which is HAVE_AVAHI */
+ /* A NULL location is only passed in from resolve_callback(), which is
+ HAVE_AVAHI */
#endif /* HAVE_AVAHI */
/* Determine the queue name */
@@ -5979,8 +8775,8 @@ examine_discovered_printer_record(const char *host,
if (local_queue_name == NULL)
goto fail;
- if (!matched_filters (local_queue_name, remote_host, port, service_name, domain,
- txt)) {
+ if (!matched_filters (local_queue_name, remote_host, port, service_name,
+ domain, txt)) {
debug_printf("Printer %s does not match BrowseFilter lines in cups-browsed.conf, printer ignored.\n",
local_queue_name);
goto fail;
@@ -6335,7 +9131,7 @@ update_netifs (gpointer data)
addr_size = 0;
if (addr_size)
for (i = 0; i <= 1; i ++)
- if (getnameinfo (ifa->ifa_addr, addr_size,
+ if (getnameinfo (ifa->ifa_addr, addr_size,
buf, HTTP_MAX_HOST, NULL, 0,
i == 0 ? NI_NUMERICHOST : NI_NAMEREQD) == 0)
if (buf[0]) {
@@ -6382,13 +9178,14 @@ update_netifs (gpointer data)
memcpy (&iface->broadcast, ifa->ifa_broadaddr,
sizeof (struct sockaddr_in));
iface->broadcast.ipv4.sin_port = htons (BrowsePort);
- /* discard if we already have an interface sharing the broadcast address */
+ /* discard if we already have an interface sharing the broadcast
+ address */
dupe = 0;
for (iface2 = (netif_t *)cupsArrayFirst (netifs);
iface2 != NULL;
iface2 = (netif_t *)cupsArrayNext (netifs)) {
if (memcmp(&iface2->broadcast, &iface->broadcast,
- sizeof(struct sockaddr_in)) == 0) {
+ sizeof(struct sockaddr_in)) == 0) {
dupe = 1;
break;
}
@@ -6414,7 +9211,7 @@ update_netifs (gpointer data)
iface2 != NULL;
iface2 = (netif_t *)cupsArrayNext (netifs)) {
if (memcmp(&iface2->broadcast, ifa->ifa_broadaddr,
- sizeof(struct sockaddr_in6)) == 0) {
+ sizeof(struct sockaddr_in6)) == 0) {
dupe = 1;
break;
}
@@ -6442,20 +9239,19 @@ update_netifs (gpointer data)
}
#ifdef HAVE_AVAHI
-static void resolve_callback(
- AvahiServiceResolver *r,
- AvahiIfIndex interface,
- AvahiProtocol protocol,
- AvahiResolverEvent event,
- const char *name,
- const char *type,
- const char *domain,
- const char *host_name,
- const AvahiAddress *address,
- uint16_t port,
- AvahiStringList *txt,
- AvahiLookupResultFlags flags,
- AVAHI_GCC_UNUSED void* userdata) {
+static void resolve_callback(AvahiServiceResolver *r,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ const char *host_name,
+ const AvahiAddress *address,
+ uint16_t port,
+ AvahiStringList *txt,
+ AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata) {
char ifname[IF_NAMESIZE];
debug_printf("resolve_callback() in THREAD %ld\n", pthread_self());
@@ -6695,16 +9491,15 @@ static void resolve_callback(
recheck_timer ();
}
-static void browse_callback(
- AvahiServiceBrowser *b,
- AvahiIfIndex interface,
- AvahiProtocol protocol,
- AvahiBrowserEvent event,
- const char *name,
- const char *type,
- const char *domain,
- AvahiLookupResultFlags flags,
- void* userdata) {
+static void browse_callback(AvahiServiceBrowser *b,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ AvahiLookupResultFlags flags,
+ void* userdata) {
AvahiClient *c = userdata;
char ifname[IF_NAMESIZE];
@@ -7126,7 +9921,7 @@ process_browse_data (GIOChannel *source,
end = packet + sizeof(packet);
c = strchr (packet, '\"');
if (c >= end)
- return TRUE;
+ return TRUE;
if (c) {
/* Extract location field */
@@ -7144,7 +9939,7 @@ process_browse_data (GIOChannel *source,
;
if (c >= end)
- return TRUE;
+ return TRUE;
if (*c == '\"') {
for (c++; c < end && isspace(*c); c++)
@@ -7340,7 +10135,6 @@ browse_poll_get_printers (browsepoll_t *context, http_t *conn)
info = NULL;
location = NULL;
while (attr && ippGetGroupTag(attr) == IPP_TAG_PRINTER) {
-
if (!strcasecmp (ippGetName(attr), "printer-uri-supported") &&
ippGetValueTag(attr) == IPP_TAG_URI)
uri = ippGetString(attr, 0, NULL);
@@ -7350,7 +10144,6 @@ browse_poll_get_printers (browsepoll_t *context, http_t *conn)
else if (!strcasecmp (ippGetName(attr), "printer-info") &&
ippGetValueTag(attr) == IPP_TAG_TEXT)
info = ippGetString(attr, 0, NULL);
-
attr = ippNextAttribute(response);
}
@@ -7576,7 +10369,8 @@ browsepoll_printer_keepalive (gpointer data, gpointer user_data)
{
browsepoll_printer_t *printer = data;
const char *server = user_data;
- debug_printf("browsepoll_printer_keepalive() in THREAD %ld\n", pthread_self());
+ debug_printf("browsepoll_printer_keepalive() in THREAD %ld\n",
+ pthread_self());
found_cups_printer (server, printer->uri_supported, printer->location,
printer->info);
}
@@ -7654,44 +10448,38 @@ browse_ldap_poll (gpointer data)
debug_printf("browse_ldap_poll() in THREAD %ld\n", pthread_self());
/* do real stuff here */
- if (!BrowseLDAPDN)
- {
+ if (!BrowseLDAPDN) {
debug_printf("Need to set BrowseLDAPDN to use LDAP browsing!\n");
BrowseLocalProtocols &= ~BROWSE_LDAP;
BrowseRemoteProtocols &= ~BROWSE_LDAP;
return FALSE;
- }
- else
- {
- if (!BrowseLDAPInitialised)
- {
+ } else {
+ if (!BrowseLDAPInitialised) {
BrowseLDAPInitialised = TRUE;
/*
* Query filter string
*/
if (BrowseLDAPFilter)
- filterLen = snprintf(NULL, 0, "(&%s%s)", LDAP_BROWSE_FILTER, BrowseLDAPFilter);
+ filterLen = snprintf(NULL, 0, "(&%s%s)", LDAP_BROWSE_FILTER,
+ BrowseLDAPFilter);
else
filterLen = strlen(LDAP_BROWSE_FILTER);
tmpFilter = (char *)malloc(filterLen + 1);
- if (!tmpFilter)
- {
- debug_printf("Could not allocate memory for LDAP browse query filter!\n");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
-
- return FALSE;
- }
+ if (!tmpFilter) {
+ debug_printf("Could not allocate memory for LDAP browse query filter!\n");
+ BrowseLocalProtocols &= ~BROWSE_LDAP;
+ BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ return FALSE;
+ }
- if (BrowseLDAPFilter)
- {
- snprintf(tmpFilter, filterLen + 1, "(&%s%s)", LDAP_BROWSE_FILTER, BrowseLDAPFilter);
- free(BrowseLDAPFilter);
- BrowseLDAPFilter = NULL;
- }
- else
+ if (BrowseLDAPFilter) {
+ snprintf(tmpFilter, filterLen + 1, "(&%s%s)", LDAP_BROWSE_FILTER,
+ BrowseLDAPFilter);
+ free(BrowseLDAPFilter);
+ BrowseLDAPFilter = NULL;
+ } else
strcpy(tmpFilter, LDAP_BROWSE_FILTER);
BrowseLDAPFilter = tmpFilter;
@@ -7761,7 +10549,7 @@ sigusr2_handler(int sig) {
debug_printf ("We entered auto shutdown mode and no printers are there to make available or no jobs on them, shutting down in %d sec...\n", autoshutdown_timeout);
autoshutdown_exec_id =
g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute,
- NULL);
+ NULL);
}
}
@@ -7869,7 +10657,9 @@ read_configuration (const char *filename)
in the configuration file is used. */
while ((i < cupsArrayCount(command_line_config) &&
(value = cupsArrayIndex(command_line_config, i++)) &&
- strncpy(line, value, sizeof(line)) && ((strlen(value) > HTTP_MAX_BUFFER-1)? line[HTTP_MAX_BUFFER-1] = '\0': 1)) ||
+ strncpy(line, value, sizeof(line)) &&
+ ((strlen(value) > HTTP_MAX_BUFFER-1) ?
+ line[HTTP_MAX_BUFFER-1] = '\0': 1)) ||
cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) {
if (linenum < 0) {
/* We are still reading options from the command line ("-o ..."),
@@ -7910,8 +10700,8 @@ read_configuration (const char *filename)
if (value[0] != '\0')
strncpy(logdir, value, sizeof(logdir) - 1);
} else if ((!strcasecmp(line, "BrowseProtocols") ||
- !strcasecmp(line, "BrowseLocalProtocols") ||
- !strcasecmp(line, "BrowseRemoteProtocols")) && value) {
+ !strcasecmp(line, "BrowseLocalProtocols") ||
+ !strcasecmp(line, "BrowseRemoteProtocols")) && value) {
int protocols = 0;
char *p, *saveptr;
p = strtok_r (value, delim, &saveptr);
@@ -8170,28 +10960,28 @@ read_configuration (const char *filename)
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
OnlyUnsupportedByCUPS = 1;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
OnlyUnsupportedByCUPS = 0;
} else if (!strcasecmp(line, "UseCUPSGeneratedPPDs") && value) {
if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
UseCUPSGeneratedPPDs = 1;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
UseCUPSGeneratedPPDs = 0;
} else if (!strcasecmp(line, "CreateRemoteRawPrinterQueues") && value) {
if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
CreateRemoteRawPrinterQueues = 1;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
CreateRemoteRawPrinterQueues = 0;
} else if (!strcasecmp(line, "CreateRemoteCUPSPrinterQueues") && value) {
if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
CreateRemoteCUPSPrinterQueues = 1;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
CreateRemoteCUPSPrinterQueues = 0;
} else if (!strcasecmp(line, "CreateIPPPrinterQueues") && value) {
if (!strcasecmp(value, "all") ||
@@ -8199,7 +10989,7 @@ read_configuration (const char *filename)
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
CreateIPPPrinterQueues = IPP_PRINTERS_ALL;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
CreateIPPPrinterQueues = IPP_PRINTERS_NO;
else if (strcasestr(value, "local") || strcasestr(value, "usb"))
CreateIPPPrinterQueues = IPP_PRINTERS_LOCAL_ONLY;
@@ -8227,14 +11017,14 @@ read_configuration (const char *filename)
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
NewIPPPrinterQueuesShared = 1;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
NewIPPPrinterQueuesShared = 0;
} else if (!strcasecmp(line, "AutoClustering") && value) {
if (!strcasecmp(value, "yes") || !strcasecmp(value, "true") ||
!strcasecmp(value, "on") || !strcasecmp(value, "1"))
AutoClustering = 1;
else if (!strcasecmp(value, "no") || !strcasecmp(value, "false") ||
- !strcasecmp(value, "off") || !strcasecmp(value, "0"))
+ !strcasecmp(value, "off") || !strcasecmp(value, "0"))
AutoClustering = 0;
} else if (!strcasecmp(line, "Cluster") && value) {
ptr = value;
@@ -8336,7 +11126,7 @@ read_configuration (const char *filename)
autoshutdown = 1;
debug_printf("Turning on auto shutdown mode.\n");
} else if (!strcasecmp(p, "Off") || !strcasecmp(p, "No") ||
- !strcasecmp(p, "False") || !strcasecmp(p, "0")) {
+ !strcasecmp(p, "False") || !strcasecmp(p, "0")) {
autoshutdown = 0;
debug_printf("Turning off auto shutdown mode (permanent mode).\n");
} else if (!strcasecmp(p, "avahi")) {
@@ -8547,7 +11337,7 @@ int main(int argc, char*argv[]) {
fprintf(stderr,
"Reading command line option -c, no alternative configuration file name supplied.\n\n");
goto help;
- }
+ }
} else if (!strncasecmp(argv[i], "-o", 2)) {
/* Configuration option via command line */
val = argv[i] + 2;
@@ -8561,12 +11351,12 @@ int main(int argc, char*argv[]) {
if (val) {
cupsArrayAdd (command_line_config, strdup(val));
debug_printf("Reading command line option -o %s, applying extra configuration option.\n",
- val);
+ val);
} else {
fprintf(stderr,
"Reading command line option -o, no extra configuration option supplied.\n\n");
goto help;
- }
+ }
} else if (!strncasecmp(argv[i], "--autoshutdown-timeout", 22)) {
debug_printf("Reading command line: %s\n", argv[i]);
if (argv[i][22] == '=' && argv[i][23])
@@ -8634,7 +11424,7 @@ int main(int argc, char*argv[]) {
autoshutdown = 1;
debug_printf("Turning on auto shutdown mode.\n");
} else if (!strcasecmp(val, "Off") || !strcasecmp(val, "No") ||
- !strcasecmp(val, "False") || !strcasecmp(val, "0")) {
+ !strcasecmp(val, "False") || !strcasecmp(val, "0")) {
autoshutdown = 0;
debug_printf("Turning off auto shutdown mode (permanent mode).\n");
} else if (!strcasecmp(val, "avahi")) {
@@ -8906,16 +11696,16 @@ int main(int argc, char*argv[]) {
}
if (BrowseLocalProtocols & BROWSE_CUPS) {
- debug_printf ("will send browse data every %ds\n",
- BrowseInterval);
- g_idle_add (send_browse_data, NULL);
+ debug_printf ("will send browse data every %ds\n",
+ BrowseInterval);
+ g_idle_add (send_browse_data, NULL);
}
#ifdef HAVE_LDAP
if (BrowseRemoteProtocols & BROWSE_LDAP) {
- debug_printf ("will browse poll LDAP every %ds\n",
- BrowseInterval);
- g_idle_add (browse_ldap_poll, NULL);
+ debug_printf ("will browse poll LDAP every %ds\n",
+ BrowseInterval);
+ g_idle_add (browse_ldap_poll, NULL);
}
#endif /* HAVE_LDAP */
@@ -8962,7 +11752,8 @@ int main(int argc, char*argv[]) {
schedule the shutdown in autoshutdown_timeout seconds */
if (autoshutdown && !autoshutdown_exec_id &&
cupsArrayCount(remote_printers) == 0) {
- debug_printf ("No printers found to make available, shutting down in %d sec...\n", autoshutdown_timeout);
+ debug_printf ("No printers found to make available, shutting down in %d sec...\n",
+ autoshutdown_timeout);
autoshutdown_exec_id =
g_timeout_add_seconds (autoshutdown_timeout, autoshutdown_execute, NULL);
}
@@ -9029,8 +11820,7 @@ fail:
#ifdef HAVE_LDAP
if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) &&
- BrowseLDAPHandle)
- {
+ BrowseLDAPHandle) {
ldap_disconnect(BrowseLDAPHandle);
BrowseLDAPHandle = NULL;
}
@@ -9092,4 +11882,3 @@ fail:
return 1;
}
-