diff --git a/.cups.metadata b/.cups.metadata
new file mode 100644
index 0000000..d16ffa2
--- /dev/null
+++ b/.cups.metadata
@@ -0,0 +1,2 @@
+04940471e4f99bcb45dd8a93477676ba1f213fc6 SOURCES/cups-1.6.3-source.tar.bz2
+79ee155bed4c18088be472a6e364f37ad6e410a6 SOURCES/cupsprinter.png
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..030435d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+SOURCES/cups-1.6.3-source.tar.bz2
+SOURCES/cupsprinter.png
diff --git a/README.md b/README.md
deleted file mode 100644
index 0e7897f..0000000
--- a/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-The master branch has no content
-
-Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6
-
-If you find this file in a distro specific branch, it means that no content has been checked in yet
diff --git a/SOURCES/cups-0755.patch b/SOURCES/cups-0755.patch
new file mode 100644
index 0000000..b0df3a0
--- /dev/null
+++ b/SOURCES/cups-0755.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.6b1/Makedefs.in.0755 cups-1.6b1/Makedefs.in
+--- cups-1.6b1/Makedefs.in.0755 2012-05-23 01:58:31.000000000 +0200
++++ cups-1.6b1/Makedefs.in 2012-05-25 16:09:40.545463214 +0200
+@@ -40,14 +40,14 @@ SHELL = /bin/sh
+ # Installation programs...
+ #
+
+-INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@
++INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 755 @INSTALL_STRIP@
+ INSTALL_COMPDATA = $(INSTALL) -c -m 444 @INSTALL_GZIP@
+ INSTALL_CONFIG = $(INSTALL) -c -m @CUPS_CONFIG_FILE_PERM@
+ INSTALL_DATA = $(INSTALL) -c -m 444
+ INSTALL_DIR = $(INSTALL) -d
+-INSTALL_LIB = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@
++INSTALL_LIB = $(LIBTOOL) $(INSTALL) -c -m 755 @INSTALL_STRIP@
+ INSTALL_MAN = $(INSTALL) -c -m 444
+-INSTALL_SCRIPT = $(INSTALL) -c -m 555
++INSTALL_SCRIPT = $(INSTALL) -c -m 755
+
+ #
+ # Default user, group, and system groups for the scheduler...
diff --git a/SOURCES/cups-1.6.3-legacy-iso88591.patch b/SOURCES/cups-1.6.3-legacy-iso88591.patch
new file mode 100644
index 0000000..7be2a04
--- /dev/null
+++ b/SOURCES/cups-1.6.3-legacy-iso88591.patch
@@ -0,0 +1,135 @@
+diff -up cups-1.6.3/scheduler/cups-lpd.c.legacy-iso88591 cups-1.6.3/scheduler/cups-lpd.c
+--- cups-1.6.3/scheduler/cups-lpd.c.legacy-iso88591 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/scheduler/cups-lpd.c 2017-09-21 15:16:28.104331875 +0200
+@@ -82,7 +82,7 @@ static int remove_jobs(const char *name,
+ static int send_state(const char *name, const char *list,
+ int longstatus);
+ static char *smart_gets(char *s, int len, FILE *fp);
+-
++static void smart_strlcpy(char *dst, const char *src, size_t dstsize);
+
+ /*
+ * 'main()' - Process an incoming LPD request...
+@@ -1053,15 +1053,15 @@ recv_print_job(
+ switch (line[0])
+ {
+ case 'J' : /* Job name */
+- strlcpy(title, line + 1, sizeof(title));
++ smart_strlcpy(title, line + 1, sizeof(title));
+ break;
+
+ case 'N' : /* Document name */
+- strlcpy(docname, line + 1, sizeof(docname));
++ smart_strlcpy(docname, line + 1, sizeof(docname));
+ break;
+
+ case 'P' : /* User identification */
+- strlcpy(user, line + 1, sizeof(user));
++ smart_strlcpy(user, line + 1, sizeof(user));
+ break;
+
+ case 'L' : /* Print banner page */
+@@ -1146,7 +1146,7 @@ recv_print_job(
+ switch (line[0])
+ {
+ case 'N' : /* Document name */
+- strlcpy(docname, line + 1, sizeof(docname));
++ smart_strlcpy(docname, line + 1, sizeof(docname));
+ break;
+
+ case 'c' : /* Plot CIF file */
+@@ -1622,5 +1622,94 @@ smart_gets(char *s, /* I - Pointer to
+
+
+ /*
++ * 'smart_strlcpy()' - Copy a string and convert from ISO-8859-1 to UTF-8 as needed.
++ */
++
++static void
++smart_strlcpy(char *dst, /* I - Output buffer */
++ const char *src, /* I - Input string */
++ size_t dstsize) /* I - Size of output buffer */
++{
++ const unsigned char *srcptr; /* Pointer into input string */
++ unsigned char *dstptr, /* Pointer into output buffer */
++ *dstend; /* End of output buffer */
++ int saw_8859 = 0; /* Saw an extended character that was not UTF-8? */
++
++
++ for (srcptr = (unsigned char *)src, dstptr = (unsigned char *)dst, dstend = dstptr + dstsize - 1; *srcptr;)
++ {
++ if (*srcptr < 0x80)
++ *dstptr++ = *srcptr++; /* ASCII */
++ else if (saw_8859)
++ {
++ /*
++ * Map ISO-8859-1 (most likely character set for legacy LPD clients) to
++ * UTF-8...
++ */
++
++ if (dstptr > (dstend - 2))
++ break;
++
++ *dstptr++ = 0xc0 | (*srcptr >> 6);
++ *dstptr++ = 0x80 | (*srcptr++ & 0x3f);
++ }
++ else if ((*srcptr & 0xe0) == 0xc0 && (srcptr[1] & 0xc0) == 0x80)
++ {
++ /*
++ * 2-byte UTF-8 sequence...
++ */
++
++ if (dstptr > (dstend - 2))
++ break;
++
++ *dstptr++ = *srcptr++;
++ *dstptr++ = *srcptr++;
++ }
++ else if ((*srcptr & 0xf0) == 0xe0 && (srcptr[1] & 0xc0) == 0x80 && (srcptr[2] & 0xc0) == 0x80)
++ {
++ /*
++ * 3-byte UTF-8 sequence...
++ */
++
++ if (dstptr > (dstend - 3))
++ break;
++
++ *dstptr++ = *srcptr++;
++ *dstptr++ = *srcptr++;
++ *dstptr++ = *srcptr++;
++ }
++ else if ((*srcptr & 0xf8) == 0xf0 && (srcptr[1] & 0xc0) == 0x80 && (srcptr[2] & 0xc0) == 0x80 && (srcptr[3] & 0xc0) == 0x80)
++ {
++ /*
++ * 4-byte UTF-8 sequence...
++ */
++
++ if (dstptr > (dstend - 4))
++ break;
++
++ *dstptr++ = *srcptr++;
++ *dstptr++ = *srcptr++;
++ *dstptr++ = *srcptr++;
++ *dstptr++ = *srcptr++;
++ }
++ else
++ {
++ /*
++ * Bad UTF-8 sequence, this must be an ISO-8859-1 string...
++ */
++
++ saw_8859 = 1;
++
++ if (dstptr > (dstend - 2))
++ break;
++
++ *dstptr++ = 0xc0 | (*srcptr >> 6);
++ *dstptr++ = 0x80 | (*srcptr++ & 0x3f);
++ }
++ }
++
++ *dstptr = '\0';
++}
++/*
+ * End of "$Id: cups-lpd.c 7899 2008-09-03 12:57:17Z mike $".
+ */
diff --git a/SOURCES/cups-1.6.3-overriden-h.patch b/SOURCES/cups-1.6.3-overriden-h.patch
new file mode 100644
index 0000000..6bcff5f
--- /dev/null
+++ b/SOURCES/cups-1.6.3-overriden-h.patch
@@ -0,0 +1,32 @@
+diff -up cups-1.6.3/cups/usersys.c.overriden-h cups-1.6.3/cups/usersys.c
+--- cups-1.6.3/cups/usersys.c.overriden-h 2017-09-22 13:33:48.389439818 +0200
++++ cups-1.6.3/cups/usersys.c 2017-09-22 13:41:08.580033663 +0200
+@@ -380,6 +380,20 @@ cupsSetServer(const char *server) /* I -
+ cg->ipp_port = atoi(port);
+ }
+
++ if (!cg->ipp_port)
++ {
++ const char *ipp_port; /* IPP_PORT environment variable */
++
++ if ((ipp_port = getenv("IPP_PORT")) != NULL)
++ {
++ if ((cg->ipp_port = atoi(ipp_port)) <= 0)
++ cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
++ }
++ else
++ cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
++ }
++
++
+ if (cg->server[0] == '/')
+ strcpy(cg->servername, "localhost");
+ else
+@@ -390,6 +404,7 @@ cupsSetServer(const char *server) /* I -
+ cg->server[0] = '\0';
+ cg->servername[0] = '\0';
+ cg->server_version = 20;
++ cg->ipp_port = 0;
+ }
+
+ if (cg->http)
diff --git a/SOURCES/cups-1.6.3-page-count.patch b/SOURCES/cups-1.6.3-page-count.patch
new file mode 100644
index 0000000..f0a5147
--- /dev/null
+++ b/SOURCES/cups-1.6.3-page-count.patch
@@ -0,0 +1,56 @@
+--- cups-1.6.3.rsac.old/backend/snmp-supplies.c 2013-06-06 18:12:52.000000000 -0700
++++ cups-1.6.3.rsac.new/backend/snmp-supplies.c 2017-02-20 15:57:28.420977310 -0800
+@@ -90,6 +90,8 @@ static backend_supplies_t supplies[CUPS_
+ /* Supply information */
+ static int supply_state = -1;
+ /* Supply state info */
++static int use_snmp_pages = 1;
++ /* Report pages used or not */
+
+ static const int hrDeviceDescr[] =
+ { CUPS_OID_hrDeviceDescr, 1, -1 };
+@@ -410,16 +412,21 @@ backendSNMPSupplies(
+
+ if (page_count)
+ {
+- if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
+- _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
+- prtMarkerLifeCount))
+- return (-1);
+-
+- if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
+- packet.object_type != CUPS_ASN1_COUNTER)
+- return (-1);
+-
+- *page_count = packet.object_value.counter;
++ if (use_snmp_pages)
++ {
++ if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
++ _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
++ prtMarkerLifeCount))
++ return (-1);
++
++ if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
++ packet.object_type != CUPS_ASN1_COUNTER)
++ return (-1);
++
++ *page_count = packet.object_value.counter;
++ }
++ else
++ *page_count = 0;
+ }
+
+ return (0);
+@@ -521,6 +528,12 @@ backend_init_supplies(
+ quirks |= CUPS_SNMP_CAPACITY;
+ }
+
++ if ((ppdattr = ppdFindAttr(ppd, "cupsSNMPPages", NULL)) != NULL )
++ {
++ if (_cups_strcasecmp(ppdattr->value, "true"))
++ use_snmp_pages = 0;
++ }
++
+ ppdClose(ppd);
+
+ /*
diff --git a/SOURCES/cups-1.6.3-resolv_reload.patch b/SOURCES/cups-1.6.3-resolv_reload.patch
new file mode 100644
index 0000000..10971c2
--- /dev/null
+++ b/SOURCES/cups-1.6.3-resolv_reload.patch
@@ -0,0 +1,323 @@
+diff -up cups-1.6.3/cups/auth.c.resolv_reload cups-1.6.3/cups/auth.c
+--- cups-1.6.3/cups/auth.c.resolv_reload 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/cups/auth.c 2017-04-07 13:34:55.224510840 +0200
+@@ -527,6 +527,18 @@ cups_gss_getname(
+ DEBUG_printf(("7cups_gss_getname(http=%p, service_name=\"%s\")", http,
+ service_name));
+
++#ifdef HAVE_RES_INIT
++ /*
++ * Check if /etc/resolv.conf is modified.
++ * If so, reload resolver.
++ */
++
++ dns_resolver_reload_rv retval;
++
++ retval = dnsReloadResolver();
++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR)
++ DEBUG_printf(("1cups_gss_getname: dnsReloadResolver() failed - %s.", strerror(retval.errnum)));
++#endif /* HAVE_RES_INIT */
+
+ /*
+ * Get the hostname...
+diff -up cups-1.6.3/cups/http-addr.c.resolv_reload cups-1.6.3/cups/http-addr.c
+--- cups-1.6.3/cups/http-addr.c.resolv_reload 2017-04-07 13:34:55.112511816 +0200
++++ cups-1.6.3/cups/http-addr.c 2017-04-07 13:34:55.224510840 +0200
+@@ -220,6 +220,20 @@ httpAddrLookup(
+
+ #ifdef HAVE_RES_INIT
+ /*
++ * Check if /etc/resolv.conf is modified.
++ * If so, reload resolver and set need_res_init to 0.
++ */
++
++ dns_resolver_reload_rv retval;
++
++ retval = dnsReloadResolver();
++
++ if (retval.status == DNS_RESOLVER_RELOAD_RELOADED && cg->need_res_init == 1)
++ cg->need_res_init = 0;
++
++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR)
++ DEBUG_printf(("1httpAddrLookup: dnsReloadResolver() failed - %s.", strerror(retval.errnum)));
++ /*
+ * STR #2920: Initialize resolver after failure in cups-polld
+ *
+ * If the previous lookup failed, re-initialize the resolver to prevent
+diff -up cups-1.6.3/cups/http-addrlist.c.resolv_reload cups-1.6.3/cups/http-addrlist.c
+--- cups-1.6.3/cups/http-addrlist.c.resolv_reload 2017-04-07 13:34:55.112511816 +0200
++++ cups-1.6.3/cups/http-addrlist.c 2017-04-07 13:34:55.224510840 +0200
+@@ -389,6 +389,20 @@ httpAddrGetList(const char *hostname, /*
+
+ #ifdef HAVE_RES_INIT
+ /*
++ * Check if /etc/resolv.conf is modified.
++ * If so, reload resolver and set cg->need_res_init to 0
++ */
++
++ dns_resolver_reload_rv retval;
++
++ retval = dnsReloadResolver();
++
++ if (retval.status == DNS_RESOLVER_RELOAD_RELOADED && cg->need_res_init == 1)
++ cg->need_res_init = 0;
++
++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR)
++ DEBUG_printf(("1httpAddrGetList: dnsReloadResolver() failed - %s.", strerror(retval.errnum)));
++ /*
+ * STR #2920: Initialize resolver after failure in cups-polld
+ *
+ * If the previous lookup failed, re-initialize the resolver to prevent
+diff -up cups-1.6.3/cups/http.c.resolv_reload cups-1.6.3/cups/http.c
+--- cups-1.6.3/cups/http.c.resolv_reload 2017-04-07 13:34:55.207510988 +0200
++++ cups-1.6.3/cups/http.c 2017-04-10 21:21:41.528795395 +0200
+@@ -4795,6 +4795,108 @@ _httpTLSSetOptions(int options)
+ tls_options = options;
+ }
+
++#ifdef HAVE_RES_INIT
++/*
++ * Function to check modification time of resolv.conf.
++ * If time is changed, it reloads resolver.
++ * If /etc/resolv.conf doesn't exist, it tries to reload resolver with local nameserver, if it wasn't reloaded before
++ * If even reloading resolver with local nameserver doesn't work, it ends with error.
++ * Global variable resolv_conf_modtime is set to -1 before the first call of this function - this is for prevention of resolver's reloading when cupsd is just started and resolv.conf exists - cupsd has current configuration in that case.
++ */
++
++dns_resolver_reload_rv
++dnsReloadResolver()
++{
++ dns_resolver_reload_rv retval, lstat_retval, stat_retval, res_init_retval;
++ struct stat resolv_conf_stat, resolv_conf_lstat, resolv_conf_status;
++ retval.status = DNS_RESOLVER_RELOAD_OK;
++ retval.errnum = 0;
++ stat_retval.errnum = 0;
++ lstat_retval.errnum = 0;
++ res_init_retval.errnum = 0;
++
++ /* Variable to store /etc/resolv.conf modification time - initialized by actual time*/
++ static time_t resolv_conf_modtime = -1;
++
++ /* This part of code is to ensure we get modification time of symlink and original file - we will decide which is newer later */
++ stat_retval.status = stat(DNS_RESOLV_CONF_PATH, &resolv_conf_stat);
++ stat_retval.errnum = errno;
++ lstat_retval.status = lstat(DNS_RESOLV_CONF_PATH, &resolv_conf_lstat);
++ lstat_retval.errnum = errno;
++
++ /* symlink /etc/resolv.conf or original file couldn't be stated because it doesn't exist, try resolver on localhost
++ * Covers cases:
++ * - resolv.conf and original file existed and it doesn't now - resolv_conf_modtime has different value than 0 - reload resolver with local nameserver
++ * - resolv.conf and original file didn't exist and still doesn't exist - resolv_conf_modtime is set to 0 - do nothing
++ */
++ if (stat_retval.status == -1 && lstat_retval.status == -1 && stat_retval.errnum == ENOENT && lstat_retval.errnum == ENOENT)
++ {
++ /* if resolv_conf_modtime is set to 0, it means previous reload was for resolver with local nameserver - no need to reload again */
++ if (resolv_conf_modtime != 0)
++ {
++ res_init_retval.status = res_init();
++ res_init_retval.errnum = errno;
++ if (res_init_retval.status == 0)
++ {
++ resolv_conf_modtime = 0;
++ retval.status = DNS_RESOLVER_RELOAD_RELOADED;
++ }
++ else
++ retval.status = res_init_retval.status;
++
++ retval.errnum = res_init_retval.errnum;
++ }
++ else
++ {
++ retval.status = DNS_RESOLVER_RELOAD_OK;
++ retval.errnum = ENOENT;
++ }
++
++ return (retval);
++ }
++
++ /* If stat ends with different errno, return status - it should return both statuses and errnos, but for simplification it returns only stat */
++ if (stat_retval.status == -1 && lstat_retval.status == -1)
++ {
++ retval.errnum = stat_retval.errnum;
++ retval.status = stat_retval.status;
++ return (retval);
++ }
++
++ /* Here we compare modification times from lstat and stat to decide which is newer - if they are equal, lstat modification time is used. We are checking only stat() errno, because case with errors in both lstat() and stat() functions is checked before */
++ if (stat_retval.errnum == 0)
++ if (resolv_conf_stat.st_mtime > resolv_conf_lstat.st_mtime)
++ resolv_conf_status = resolv_conf_stat;
++ else
++ resolv_conf_status = resolv_conf_lstat;
++ else
++ resolv_conf_status = resolv_conf_lstat;
++
++ /* If /etc/resolv.conf exists and modification times are different, reload resolver.
++ * Covers cases:
++ * - resolv.conf or original file exists and it was modified - resolv_conf_modtime has different value than resolv_conf_status.st_mtime - reload resolver with nameserver from /etc/resolv.conf
++ * - resolv.conf or original file didn't exist and it does now - resolv_conf_modtime is set to 0 and resolv_conf_status.st_mtime has value - reload resolver with nameserver form /etc/resolv.conf
++ * - resolv.conf or original file exists and it wasn't modified - resolv_conf_modtime is equal to resolv_conf_status.st_mtime - do nothing
++ */
++ if (resolv_conf_status.st_mtime != resolv_conf_modtime)
++ {
++ res_init_retval.status = res_init();
++ res_init_retval.errnum = errno;
++ if (res_init_retval.status == 0)
++ {
++ retval.status = DNS_RESOLVER_RELOAD_RELOADED;
++ }
++ else
++ retval.status = res_init_retval.status;
++
++ retval.errnum = res_init_retval.errnum;
++ }
++
++ resolv_conf_modtime = resolv_conf_status.st_mtime;
++
++ return (retval);
++}
++#endif /* HAVE_RES_INIT */
+
+ /*
+ * End of "$Id: http.c 7850 2008-08-20 00:07:25Z mike $".
+diff -up cups-1.6.3/cups/http.h.resolv_reload cups-1.6.3/cups/http.h
+--- cups-1.6.3/cups/http.h.resolv_reload 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/cups/http.h 2017-04-07 13:34:55.225510832 +0200
+@@ -60,6 +60,12 @@ typedef off_t ssize_t; /* @private@ */
+ # define SO_PEERCRED LOCAL_PEERCRED
+ # endif /* LOCAL_PEERCRED && !SO_PEERCRED */
+ # endif /* WIN32 */
++# ifdef HAVE_RES_INIT
++# include
++# include
++# include
++# include
++# endif /* HAVE_RES_INIT */
+
+
+ /*
+@@ -102,6 +108,13 @@ extern "C" {
+ #endif /* AF_INET6 && !s6_addr32 */
+
+
++#ifdef HAVE_RES_INIT
++/*
++ * Global variable for storing old modification time of resolv.conf
++ */
++ extern time_t resolv_conf_modtime;
++#endif /* HAVE_RES_INIT */
++
+ /*
+ * Limits...
+ */
+@@ -110,6 +123,9 @@ extern "C" {
+ # define HTTP_MAX_HOST 256 /* Max length of hostname string */
+ # define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */
+ # define HTTP_MAX_VALUE 256 /* Max header field value length */
++# ifdef HAVE_RES_INIT
++# define DNS_RESOLV_CONF_PATH "/etc/resolv.conf" /* Path to resolv.conf */
++# endif /* HAVE_RES_INIT */
+
+
+ /*
+@@ -290,6 +306,15 @@ typedef enum http_version_e /**** HTTP
+ HTTP_1_1 = 101 /* HTTP/1.1 */
+ } http_version_t;
+
++#ifdef HAVE_RES_INIT
++typedef enum dns_resolver_reload_e
++{
++ DNS_RESOLVER_RELOAD_ERROR = -1,
++ DNS_RESOLVER_RELOAD_OK = 0,
++ DNS_RESOLVER_RELOAD_RELOADED = 1
++} dns_resolver_reload_t;
++#endif /* HAVE_RES_INIT */
++
+ typedef union _http_addr_u /**** Socket address union, which
+ **** makes using IPv6 and other
+ **** address types easier and
+@@ -328,6 +353,13 @@ typedef struct http_credential_s /**** H
+ typedef int (*http_timeout_cb_t)(http_t *http, void *user_data);
+ /**** HTTP timeout callback @since CUPS 1.5/OS X 10.7@ ****/
+
++#ifdef HAVE_RES_INIT
++typedef struct dns_resolver_reload_retval
++{
++ dns_resolver_reload_t status;
++ int errnum;
++} dns_resolver_reload_rv;
++#endif /* HAVE_RES_INIT */
+
+
+ /*
+@@ -472,6 +504,11 @@ extern http_version_t httpGetVersion(htt
+ extern int httpReconnect2(http_t *http, int msec, int *cancel)
+ _CUPS_API_1_6;
+
++/**** Prototype of function to check modification time of /etc/resolv.conf ****/
++#ifdef HAVE_RES_INIT
++extern dns_resolver_reload_rv dnsReloadResolver();
++#endif /* HAVE_RES_INIT */
++
+
+ /*
+ * C++ magic...
+diff -up cups-1.6.3/cups/http-support.c.resolv_reload cups-1.6.3/cups/http-support.c
+--- cups-1.6.3/cups/http-support.c.resolv_reload 2017-04-07 13:34:55.130511659 +0200
++++ cups-1.6.3/cups/http-support.c 2017-04-07 13:34:55.225510832 +0200
+@@ -2095,6 +2095,18 @@ http_resolve_cb(
+ http_addrlist_t *addrlist, /* List of addresses */
+ *addr; /* Current address */
+
++#ifdef HAVE_RES_INIT
++ /*
++ * Check if resolv.conf is modified, if so, reload resolver
++ */
++
++ dns_resolver_reload_rv retval;
++
++ retval = dnsReloadResolver();
++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR)
++ DEBUG_printf(("1http_resolve_cb: dnsReloadResolver() failed - %s.", strerror(retval.errnum)));
++#endif /* HAVE_RES_INIT */
++
+ DEBUG_printf(("8http_resolve_cb: Looking up \"%s\".", hostTarget));
+
+ snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port));
+diff -up cups-1.6.3/scheduler/conf.c.resolv_reload cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.resolv_reload 2017-04-07 13:34:55.213510936 +0200
++++ cups-1.6.3/scheduler/conf.c 2017-04-07 13:34:55.226510823 +0200
+@@ -859,6 +859,15 @@ cupsdReadConfiguration(void)
+ if (!RemotePort)
+ BrowseLocalProtocols = 0; /* Disable sharing - no remote access */
+
++#ifdef HAVE_RES_INIT
++ dns_resolver_reload_rv retval; /* Return status of dnsReloadResolver() */
++
++ retval = dnsReloadResolver();
++
++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR)
++ syslog(LOG_LPR, "1cupsdReadConfiguration: dnsReloadResolver() failed - %s.", strerror(retval.errnum));
++#endif /* HAVE_RES_INIT */
++
+ /*
+ * See if the ServerName is an IP address...
+ */
+diff -up cups-1.6.3/scheduler/main.c.resolv_reload cups-1.6.3/scheduler/main.c
+--- cups-1.6.3/scheduler/main.c.resolv_reload 2017-04-07 13:34:55.149511494 +0200
++++ cups-1.6.3/scheduler/main.c 2017-04-07 13:34:55.226510823 +0200
+@@ -164,6 +164,14 @@ main(int argc, /* I - Number of comm
+ long tmo_delay; /* Time before it must be called */
+ #endif /* HAVE_AVAHI */
+
++#ifdef HAVE_RES_INIT
++ dns_resolver_reload_rv retval; /* Return status from dnsReloadResolver() */
++
++ retval = dnsReloadResolver();
++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR)
++ fprintf(stderr, "cupsd: Cannot reload a resolver - %s , using old configuration now.\n", strerror(retval.errnum));
++#endif /* HAVE_RES_INIT */
++
+
+ #ifdef HAVE_GETEUID
+ /*
diff --git a/SOURCES/cups-1.6.3-tlsv12.patch b/SOURCES/cups-1.6.3-tlsv12.patch
new file mode 100644
index 0000000..a845d43
--- /dev/null
+++ b/SOURCES/cups-1.6.3-tlsv12.patch
@@ -0,0 +1,178 @@
+diff -up cups-1.6.3/cups/http.c.tlsv12 cups-1.6.3/cups/http.c
+--- cups-1.6.3/cups/http.c.tlsv12 2017-12-12 14:40:02.672393885 +0100
++++ cups-1.6.3/cups/http.c 2017-12-12 16:45:11.417535244 +0100
+@@ -3726,6 +3726,8 @@ http_send(http_t *http, /* I - Con
+ httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
+ if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.1,TLS/1.0,SSL/3.0");
++ else if (tls_options & _HTTP_TLS_MIN_TLS12)
++ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2+");
+ else
+ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.1,TLS/1.0");
+ }
+@@ -3968,6 +3970,8 @@ http_setup_ssl(http_t *http) /* I - Con
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* Don't use SSLv3 */
+ if (!(tls_options & _HTTP_TLS_ALLOW_RC4))
+ SSL_CTX_set_cipher_list(context, "DEFAULT:-RC4");
++ if (tls_options & _HTTP_TLS_MIN_TLS12)
++ SSL_CTX_set_cipher_list(context, "DEFAULT:!SSLv3:!TLSv1");
+
+ bio = BIO_new(_httpBIOMethods());
+ BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
+@@ -4453,6 +4457,8 @@ http_upgrade(http_t *http) /* I - Conne
+ httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
+ if (tls_options & _HTTP_TLS_ALLOW_SSL3)
+ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2, TLS/1.1, TLS/1.0, SSL/3.0");
++ else if (tls_options & _HTTP_TLS_MIN_TLS12)
++ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2+");
+ else
+ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2, TLS/1.1, TLS/1.0");
+
+diff -up cups-1.6.3/cups/http-private.h.tlsv12 cups-1.6.3/cups/http-private.h
+--- cups-1.6.3/cups/http-private.h.tlsv12 2017-12-12 14:40:02.642394135 +0100
++++ cups-1.6.3/cups/http-private.h 2017-12-12 14:40:02.689393744 +0100
+@@ -143,6 +143,7 @@ extern "C" {
+ /* care - these should be the same values as the CUPSD_SSL_* equivalents */
+ #define _HTTP_TLS_ALLOW_RC4 2
+ #define _HTTP_TLS_ALLOW_SSL3 4
++#define _HTTP_TLS_MIN_TLS12 8
+
+
+ /*
+diff -up cups-1.6.3/cups/usersys.c.tlsv12 cups-1.6.3/cups/usersys.c
+--- cups-1.6.3/cups/usersys.c.tlsv12 2017-12-12 14:40:02.676393852 +0100
++++ cups-1.6.3/cups/usersys.c 2017-12-12 14:40:02.689393744 +0100
+@@ -992,7 +992,7 @@ cups_read_client_conf(
+ else if (ssl_options && !_cups_strcasecmp(line, "SSLOptions") && value)
+ {
+ /*
+- * SSLOptions [AllowRC4] [AllowSSL3] [None]
++ * SSLOptions [AllowRC4] [AllowSSL3] [MinTLS1.2] [None]
+ */
+
+ int options = 0; /* SSL/TLS options */
+@@ -1020,6 +1020,8 @@ cups_read_client_conf(
+ options |= _HTTP_TLS_ALLOW_RC4;
+ else if (!_cups_strcasecmp(start, "AllowSSL3"))
+ options |= _HTTP_TLS_ALLOW_SSL3;
++ else if (!_cups_strcasecmp(start, "MinTLS1.2"))
++ options |= _HTTP_TLS_MIN_TLS12;
+ else if (!_cups_strcasecmp(start, "None"))
+ options = 0;
+ }
+diff -up cups-1.6.3/man/client.conf.man.in.tlsv12 cups-1.6.3/man/client.conf.man.in
+--- cups-1.6.3/man/client.conf.man.in.tlsv12 2017-12-12 14:40:02.643394126 +0100
++++ cups-1.6.3/man/client.conf.man.in 2017-12-14 12:51:09.366872384 +0100
+@@ -53,14 +53,15 @@ Specifies the address and optionally the
+ server running CUPS 1.3.12 and earlier. \fBNote: Not supported on OS X 10.7 or
+ later.\fR
+ .TP 5
+-SSLOptions \fR[\fIAllowRC4\fR] [\fIAllow SSL3\fR]
++SSLOptions \fR[\fIAllowRC4\fR] [\fIAllow SSL3\fR] [\fIMinTLS1.2\fR]
+ .br
+ Sets SSL/TLS protocol options for encrypted connections. By default,
+ CUPS only supports encryption using TLS v1.0 or higher using known
+ secure cipher suites. The \fIAllowRC4\fR option enables the 128-bit
+ RC4 cipher suites, which are required for some older clients that do
+ not implement newer ones. The \fIAllowSSL3\fR option enables SSL v3.0,
+-which is required for some older clients that do not support TLS v1.0.
++which is required for some older clients that do not support TLS v1.0.
++The \fIMinTLS1.2\fR option enforces CUPS to use TLS v1.2 and higher.
+ .TP 5
+ User name
+ .br
+diff -up cups-1.6.3/man/cupsd.conf.man.in.tlsv12 cups-1.6.3/man/cupsd.conf.man.in
+--- cups-1.6.3/man/cupsd.conf.man.in.tlsv12 2017-12-14 12:42:34.233473538 +0100
++++ cups-1.6.3/man/cupsd.conf.man.in 2017-12-14 12:51:09.327872724 +0100
+@@ -480,7 +480,7 @@ Listens on the specified address and por
+ .TP 5
+ SSLOptions None
+ .TP 5
+-SSLOptions \fR[\fINoEmptyFragments\fR] [\fIAllowRC4\fR] [\fIAllow SSL3\fR]
++SSLOptions \fR[\fINoEmptyFragments\fR] [\fIAllowRC4\fR] [\fIAllow SSL3\fR] [\fIMinTLS1.2\fR]
+ .br
+ Sets SSL/TLS protocol options for encrypted connections. By default,
+ CUPS only supports encryption using TLS v1.0 or higher using known
+@@ -490,6 +490,7 @@ enabled. The \fIAllowRC4\fR option enabl
+ suites, which are required for some older clients that do not
+ implement newer ones. The \fIAllowSSL3\fR option enables SSL v3.0,
+ which is required for some older clients that do not support TLS v1.0.
++The \fIMinTLS1.2\fR option enforces CUPS to use TLS v1.2 and higher.
+ .TP 5
+ SSLPort
+ .br
+diff -up cups-1.6.3/scheduler/client.c.tlsv12 cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.tlsv12 2017-12-12 15:18:01.683589773 +0100
++++ cups-1.6.3/scheduler/client.c 2017-12-12 16:44:38.721796794 +0100
+@@ -1189,7 +1189,11 @@ cupsdReadClient(cupsd_client_t *con) /*
+ }
+
+ httpPrintf(HTTP(con), "Connection: Upgrade\r\n");
+- httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
++ if ((SSLOptions & CUPSD_SSL_MIN_TLS12) ||
++ !_cups_strcasecmp(con->http.fields[HTTP_FIELD_UPGRADE], "TLS/1.2+"))
++ httpPrintf(HTTP(con), "Upgrade: TLS/1.2+,HTTP/1.1\r\n");
++ else
++ httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
+ httpPrintf(HTTP(con), "Content-Length: 0\r\n");
+ httpPrintf(HTTP(con), "\r\n");
+
+@@ -1263,7 +1268,11 @@ cupsdReadClient(cupsd_client_t *con) /*
+ }
+
+ httpPrintf(HTTP(con), "Connection: Upgrade\r\n");
+- httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
++ if ((SSLOptions & CUPSD_SSL_MIN_TLS12) ||
++ !_cups_strcasecmp(con->http.fields[HTTP_FIELD_UPGRADE], "TLS/1.2+"))
++ httpPrintf(HTTP(con), "Upgrade: TLS/1.2+,HTTP/1.1\r\n");
++ else
++ httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
+ httpPrintf(HTTP(con), "Content-Length: 0\r\n");
+ httpPrintf(HTTP(con), "\r\n");
+
+diff -up cups-1.6.3/scheduler/conf.c.tlsv12 cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.tlsv12 2017-12-12 14:40:02.681393811 +0100
++++ cups-1.6.3/scheduler/conf.c 2017-12-12 14:40:02.689393744 +0100
+@@ -3383,7 +3383,7 @@ read_cupsd_conf(cups_file_t *fp) /* I -
+ else if (!_cups_strcasecmp(line, "SSLOptions"))
+ {
+ /*
+- * SSLOptions [AllowRC4] [AllowSSL3] [NoEmptyFragments] [None]
++ * SSLOptions [AllowRC4] [AllowSSL3] [MinTLS1.2] [NoEmptyFragments] [None]
+ */
+
+ int options = 0; /* SSL/TLS options */
+@@ -3420,6 +3420,8 @@ read_cupsd_conf(cups_file_t *fp) /* I -
+ options |= CUPSD_SSL_ALLOW_RC4;
+ else if (!_cups_strcasecmp(start, "AllowSSL3"))
+ options |= CUPSD_SSL_ALLOW_SSL3;
++ else if (!_cups_strcasecmp(start, "MinTLS1.2"))
++ options |= CUPSD_SSL_MIN_TLS12;
+ else if (!_cups_strcasecmp(start, "None"))
+ options = 0;
+ else
+diff -up cups-1.6.3/scheduler/conf.h.tlsv12 cups-1.6.3/scheduler/conf.h
+--- cups-1.6.3/scheduler/conf.h.tlsv12 2017-12-12 14:40:02.681393811 +0100
++++ cups-1.6.3/scheduler/conf.h 2017-12-12 14:40:02.690393736 +0100
+@@ -80,7 +80,7 @@ typedef enum
+ #define CUPSD_SSL_NOEMPTY 1 /* Do not insert empty fragments */
+ #define CUPSD_SSL_ALLOW_RC4 2 /* Allow RC4 cipher suites */
+ #define CUPSD_SSL_ALLOW_SSL3 4 /* Allow SSL 3.0 */
+-
++#define CUPSD_SSL_MIN_TLS12 8 /* Deny TLS 1.1 */
+
+ /*
+ * ServerAlias data...
+diff -up cups-1.6.3/scheduler/tls-openssl.c.tlsv12 cups-1.6.3/scheduler/tls-openssl.c
+--- cups-1.6.3/scheduler/tls-openssl.c.tlsv12 2017-12-12 14:40:02.645394110 +0100
++++ cups-1.6.3/scheduler/tls-openssl.c 2017-12-12 16:49:10.357623844 +0100
+@@ -111,6 +111,9 @@ cupsdStartTLS(cupsd_client_t *con) /* I
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* Don't use SSLv3 */
+ if (!(SSLOptions & CUPSD_SSL_ALLOW_RC4))
+ SSL_CTX_set_cipher_list(context, "DEFAULT:-RC4");
++ if ((SSLOptions & CUPSD_SSL_MIN_TLS12) ||
++ !_cups_strcasecmp(con->http.fields[HTTP_FIELD_UPGRADE], "TLS/1.2+"))
++ SSL_CTX_set_cipher_list(context, "DEFAULT:!SSLv3:!TLSv1");
+ SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
+ SSL_CTX_use_certificate_chain_file(context, ServerCertificate);
+
diff --git a/SOURCES/cups-1.6.3-ypbind.patch b/SOURCES/cups-1.6.3-ypbind.patch
new file mode 100644
index 0000000..6cc5fab
--- /dev/null
+++ b/SOURCES/cups-1.6.3-ypbind.patch
@@ -0,0 +1,11 @@
+diff -up cups-1.6.3/data/cups.service.in.ypbind cups-1.6.3/data/cups.service.in
+--- cups-1.6.3/data/cups.service.in.ypbind 2017-09-15 15:40:12.193292843 +0200
++++ cups-1.6.3/data/cups.service.in 2017-09-15 15:40:46.441010187 +0200
+@@ -1,6 +1,6 @@
+ [Unit]
+ Description=CUPS Printing Service
+-After=network.target
++After=network.target ypbind.service
+
+ [Service]
+ ExecStart=@sbindir@/cupsd -f
diff --git a/SOURCES/cups-163-enotif.patch b/SOURCES/cups-163-enotif.patch
new file mode 100644
index 0000000..5798135
--- /dev/null
+++ b/SOURCES/cups-163-enotif.patch
@@ -0,0 +1,14 @@
+diff -up cups-1.6.3/scheduler/subscriptions.c.enotif cups-1.6.3/scheduler/subscriptions.c
+--- cups-1.6.3/scheduler/subscriptions.c.enotif 2016-04-20 08:23:22.000000000 +0200
++++ cups-1.6.3/scheduler/subscriptions.c 2016-04-22 10:35:07.363139391 +0200
+@@ -126,9 +126,7 @@ cupsdAddEvent(
+ * Check if this subscription requires this event...
+ */
+
+- if ((sub->mask & event) != 0 &&
+- (sub->dest == dest || !sub->dest) &&
+- (sub->job == job || !sub->job))
++ if ((sub->mask & event) != 0 && (sub->dest == dest || !sub->dest || sub->job == job))
+ {
+ /*
+ * Need this event, so create a new event record...
diff --git a/SOURCES/cups-163-fdleak.patch b/SOURCES/cups-163-fdleak.patch
new file mode 100644
index 0000000..47d3d91
--- /dev/null
+++ b/SOURCES/cups-163-fdleak.patch
@@ -0,0 +1,10 @@
+--- cups-1.6.3/cups/usersys.c
++++ cups-1.6.3/cups/usersys.c
+@@ -846,6 +846,7 @@ _cupsSetDefaults(void)
+ #endif /* HAVE_GSSAPI */
+ cups_anyroot, cups_expiredroot,
+ cups_expiredcerts, 1);
++ cupsFileClose(fp);
+
+ /*
+ * Then user defaults, if it is safe to do so...
diff --git a/SOURCES/cups-CVE-2014-2856.patch b/SOURCES/cups-CVE-2014-2856.patch
new file mode 100644
index 0000000..d72556d
--- /dev/null
+++ b/SOURCES/cups-CVE-2014-2856.patch
@@ -0,0 +1,18 @@
+diff -up cups-1.6.3/scheduler/client.c.CVE-2014-2856 cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.CVE-2014-2856 2014-07-25 12:11:48.054960093 +0100
++++ cups-1.6.3/scheduler/client.c 2014-07-25 12:11:27.764854789 +0100
+@@ -3686,6 +3686,14 @@ is_path_absolute(const char *path) /* I
+ return (0);
+
+ /*
++ * Check for "<" or quotes in the path and reject since this is probably
++ * someone trying to inject HTML...
++ */
++
++ if (strchr(path, '<') != NULL || strchr(path, '\"') != NULL || strchr(path, '\'') != NULL)
++ return (0);
++
++ /*
+ * Check for "/.." in the path...
+ */
+
diff --git a/SOURCES/cups-CVE-2014-3537.patch b/SOURCES/cups-CVE-2014-3537.patch
new file mode 100644
index 0000000..32bba8f
--- /dev/null
+++ b/SOURCES/cups-CVE-2014-3537.patch
@@ -0,0 +1,48 @@
+diff -up cups-1.6.3/scheduler/client.c.CVE-2014-3537 cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.CVE-2014-3537 2014-09-02 11:30:50.021384781 +0100
++++ cups-1.6.3/scheduler/client.c 2014-09-02 11:31:00.606440125 +0100
+@@ -3197,7 +3197,7 @@ get_file(cupsd_client_t *con, /* I - C
+ if ((ptr = strchr(filename, '?')) != NULL)
+ *ptr = '\0';
+
+- if ((status = stat(filename, filestats)) != 0)
++ if ((status = lstat(filename, filestats)) != 0)
+ {
+ /*
+ * Drop the language prefix and try the root directory...
+@@ -3209,12 +3209,33 @@ get_file(cupsd_client_t *con, /* I - C
+ if ((ptr = strchr(filename, '?')) != NULL)
+ *ptr = '\0';
+
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+ }
+ }
+
++ /*
++ * If we've found a symlink, 404 the sucker to avoid disclosing information.
++ */
++
++ if (!status && S_ISLNK(filestats->st_mode))
++ {
++ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Symlinks such as \"%s\" are not allowed.", con->http.fd, filename);
++ return (NULL);
++ }
++
++ /*
++ * Similarly, if the file/directory does not have world read permissions, do
++ * not allow access...
++ */
++
++ if (!status && !(filestats->st_mode & S_IROTH))
++ {
++ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename);
++ return (NULL);
++ }
++
+ /*
+- * If we're found a directory, get the index.html file instead...
++ * If we've found a directory, get the index.html file instead...
+ */
+
+ if (!status && S_ISDIR(filestats->st_mode))
diff --git a/SOURCES/cups-CVE-2014-5029-5030-5031.patch b/SOURCES/cups-CVE-2014-5029-5030-5031.patch
new file mode 100644
index 0000000..cd595e7
--- /dev/null
+++ b/SOURCES/cups-CVE-2014-5029-5030-5031.patch
@@ -0,0 +1,88 @@
+diff -up cups-1.6.3/scheduler/client.c.CVE-2014-5029-5030-5031 cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.CVE-2014-5029-5030-5031 2014-09-02 11:42:02.465900694 +0100
++++ cups-1.6.3/scheduler/client.c 2014-09-02 11:42:44.383119863 +0100
+@@ -3180,7 +3180,7 @@ get_file(cupsd_client_t *con, /* I - C
+ * then fallback to the default one...
+ */
+
+- if ((status = stat(filename, filestats)) != 0 && language[0] &&
++ if ((status = lstat(filename, filestats)) != 0 && language[0] &&
+ strncmp(con->uri, "/icons/", 7) &&
+ strncmp(con->uri, "/ppd/", 5) &&
+ strncmp(con->uri, "/rss/", 5) &&
+@@ -3278,13 +3278,13 @@ get_file(cupsd_client_t *con, /* I - C
+ plen = len - (ptr - filename);
+
+ strlcpy(ptr, "index.html", plen);
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+
+ #ifdef HAVE_JAVA
+ if (status)
+ {
+ strlcpy(ptr, "index.class", plen);
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+ }
+ #endif /* HAVE_JAVA */
+
+@@ -3292,7 +3292,7 @@ get_file(cupsd_client_t *con, /* I - C
+ if (status)
+ {
+ strlcpy(ptr, "index.pl", plen);
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+ }
+ #endif /* HAVE_PERL */
+
+@@ -3300,7 +3300,7 @@ get_file(cupsd_client_t *con, /* I - C
+ if (status)
+ {
+ strlcpy(ptr, "index.php", plen);
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+ }
+ #endif /* HAVE_PHP */
+
+@@ -3308,18 +3308,39 @@ get_file(cupsd_client_t *con, /* I - C
+ if (status)
+ {
+ strlcpy(ptr, "index.pyc", plen);
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+ }
+
+ if (status)
+ {
+ strlcpy(ptr, "index.py", plen);
+- status = stat(filename, filestats);
++ status = lstat(filename, filestats);
+ }
+ #endif /* HAVE_PYTHON */
+
+ }
+ while (status && language[0]);
++
++ /*
++ * If we've found a symlink, 404 the sucker to avoid disclosing information.
++ */
++
++ if (!status && S_ISLNK(filestats->st_mode))
++ {
++ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Symlinks such as \"%s\" are not allowed.", con->http.fd, filename);
++ return (NULL);
++ }
++
++ /*
++ * Similarly, if the file/directory does not have world read permissions, do
++ * not allow access...
++ */
++
++ if (!status && !(filestats->st_mode & S_IROTH))
++ {
++ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename);
++ return (NULL);
++ }
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
diff --git a/SOURCES/cups-avahi-address.patch b/SOURCES/cups-avahi-address.patch
new file mode 100644
index 0000000..308ee89
--- /dev/null
+++ b/SOURCES/cups-avahi-address.patch
@@ -0,0 +1,95 @@
+diff -up cups-1.6.2/cups/http-support.c.avahi-address cups-1.6.2/cups/http-support.c
+--- cups-1.6.2/cups/http-support.c.avahi-address 2013-03-11 18:44:36.000000000 +0000
++++ cups-1.6.2/cups/http-support.c 2013-06-28 13:42:15.834715511 +0100
+@@ -2121,7 +2121,7 @@ http_resolve_cb(
+ const char *type, /* I - Registration type */
+ const char *domain, /* I - Domain (unused) */
+ const char *hostTarget, /* I - Hostname */
+- const AvahiAddress *address, /* I - Address (unused) */
++ const AvahiAddress *address, /* I - Address */
+ uint16_t port, /* I - Port number */
+ AvahiStringList *txt, /* I - TXT record */
+ AvahiLookupResultFlags flags, /* I - Lookup flags (unused) */
+@@ -2248,41 +2248,59 @@ http_resolve_cb(
+ * getting the IP address of the .local name and then do reverse-lookups...
+ */
+
+- http_addrlist_t *addrlist, /* List of addresses */
+- *addr; /* Current address */
++ http_addr_t addr;
++ size_t addrlen;
++ int error;
+
+ DEBUG_printf(("8http_resolve_cb: Looking up \"%s\".", hostTarget));
+
+- snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port));
+- if ((addrlist = httpAddrGetList(hostTarget, AF_UNSPEC, fqdn)) != NULL)
++ switch (address->proto)
+ {
+- for (addr = addrlist; addr; addr = addr->next)
++ case AVAHI_PROTO_INET:
++ addr.ipv4.sin_family = AF_INET;
++ addrlen = sizeof (addr.ipv4.sin_addr);
++ memcpy (&addr.ipv4.sin_addr, &address->data, addrlen);
++ break;
++ case AVAHI_PROTO_INET6:
++ addr.ipv6.sin6_family = AF_INET6;
++ addrlen = sizeof (addr.ipv6.sin6_addr);
++ memcpy (&addr.ipv6.sin6_addr, &address->data, addrlen);
++ break;
++ default:
++ DEBUG_printf(("8http_resolve_cb: unknown address family %d",
++ address->proto));
++ addrlen = 0;
++ }
++
++ if (addrlen > 0) {
++ error = getnameinfo(&addr.addr, httpAddrLength (&addr),
++ fqdn, sizeof(fqdn), NULL, 0, NI_NAMEREQD);
++
++ if (!error)
+ {
+- int error = getnameinfo(&(addr->addr.addr),
+- httpAddrLength(&(addr->addr)),
+- fqdn, sizeof(fqdn), NULL, 0, NI_NAMEREQD);
++ DEBUG_printf(("8http_resolve_cb: Found \"%s\".", fqdn));
+
+- if (!error)
++ if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn ||
++ _cups_strcasecmp(hostptr, ".local"))
+ {
+- DEBUG_printf(("8http_resolve_cb: Found \"%s\".", fqdn));
+-
+- if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn ||
+- _cups_strcasecmp(hostptr, ".local"))
+- {
+- hostTarget = fqdn;
+- break;
+- }
++ hostTarget = fqdn;
+ }
++ } else {
++ avahi_address_snprint (fqdn, sizeof (fqdn), address);
++ hostTarget = fqdn;
+ #ifdef DEBUG
+- else
+- DEBUG_printf(("8http_resolve_cb: \"%s\" did not resolve: %d",
+- httpAddrString(&(addr->addr), fqdn, sizeof(fqdn)),
+- error));
++ DEBUG_printf(("8http_resolve_cb: \"%s\" did not resolve: %d",
++ fqdn, error));
+ #endif /* DEBUG */
+ }
+-
+- httpAddrFreeList(addrlist);
+ }
++ } else {
++ /*
++ * Use the IP address that responded...
++ */
++
++ avahi_address_snprint (fqdn, sizeof (fqdn), address);
++ hostTarget = fqdn;
+ }
+
+ /*
diff --git a/SOURCES/cups-avahi-no-threaded.patch b/SOURCES/cups-avahi-no-threaded.patch
new file mode 100644
index 0000000..d97c58a
--- /dev/null
+++ b/SOURCES/cups-avahi-no-threaded.patch
@@ -0,0 +1,999 @@
+diff -up cups-1.6.3/scheduler/avahi.c.avahi-no-threaded cups-1.6.3/scheduler/avahi.c
+--- cups-1.6.3/scheduler/avahi.c.avahi-no-threaded 2013-07-12 11:42:14.650430828 +0200
++++ cups-1.6.3/scheduler/avahi.c 2013-07-12 11:42:14.650430828 +0200
+@@ -0,0 +1,441 @@
++/*
++ * "$Id$"
++ *
++ * Avahi poll implementation for the CUPS scheduler.
++ *
++ * Copyright (C) 2010, 2011 Red Hat, Inc.
++ * Authors:
++ * Tim Waugh
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Contents:
++ *
++ * watch_read_cb - Read callback for file descriptor
++ * watch_write_cb - Write callback for file descriptor
++ * watched_fd_add_select() - Call cupsdAddSelect() as needed
++ * watch_new() - Create a new file descriptor watch
++ * watch_free() - Free a file descriptor watch
++ * watch_update() - Update watched events for a file descriptor
++ * watch_get_events() - Get events that happened for a file descriptor
++ * timeout_cb() - Run a timed Avahi callback
++ * timeout_new() - Set a wakeup time
++ * timeout_update() - Update the expiration time for a timeout
++ * timeout_free() - Free a timeout
++ * compare_watched_fds() - Compare watched file descriptors for array sorting
++ * avahi_cups_poll_new() - Create a new Avahi main loop object for CUPS
++ * avahi_cups_poll_free() - Free an Avahi main loop object for CUPS
++ * avahi_cups_poll_get() - Get the abstract poll API structure
++ */
++
++#include
++
++#ifdef HAVE_AVAHI /* Applies to entire file... */
++
++/*
++ * Include necessary headers...
++ */
++
++#include "cupsd.h"
++
++#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
++# include
++#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
++
++#ifdef HAVE_AVAHI
++# include
++#endif /* HAVE_AVAHI */
++
++
++typedef struct
++{
++ AvahiCupsPoll *cups_poll;
++
++ int fd;
++ AvahiWatchEvent occurred;
++ cups_array_t *watches;
++} cupsd_watched_fd_t;
++
++struct AvahiWatch
++{
++ cupsd_watched_fd_t *watched_fd;
++
++ AvahiWatchEvent events;
++ AvahiWatchCallback callback;
++ void *userdata;
++};
++
++struct AvahiTimeout
++{
++ AvahiCupsPoll *cups_poll;
++ AvahiTimeoutCallback callback;
++ void *userdata;
++ cupsd_timeout_t *cupsd_timeout;
++};
++
++/*
++ * Local functions...
++ */
++
++static AvahiWatch * watch_new(const AvahiPoll *api,
++ int fd,
++ AvahiWatchEvent events,
++ AvahiWatchCallback callback,
++ void *userdata);
++static void watch_free(AvahiWatch *watch);
++static void watch_update(AvahiWatch *watch,
++ AvahiWatchEvent events);
++static AvahiWatchEvent watch_get_events(AvahiWatch *watch);
++
++
++/*
++ * 'watch_read_cb' - Read callback for file descriptor
++ */
++
++static void
++watch_read_cb (void *userdata)
++{
++ AvahiWatch *watch;
++ cupsd_watched_fd_t *watched_fd = userdata;
++ watched_fd->occurred |= AVAHI_WATCH_IN;
++ for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
++ watch;
++ watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
++ {
++ if (watch->events & watched_fd->occurred)
++ {
++ (watch->callback) (watch, watched_fd->fd,
++ AVAHI_WATCH_IN, watch->userdata);
++ watched_fd->occurred &= ~AVAHI_WATCH_IN;
++ break;
++ }
++ }
++}
++
++
++/*
++ * 'watch_write_cb' - Write callback for file descriptor
++ */
++
++static void
++watch_write_cb (void *userdata)
++{
++ AvahiWatch *watch;
++ cupsd_watched_fd_t *watched_fd = userdata;
++ watched_fd->occurred |= AVAHI_WATCH_OUT;
++ for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
++ watch;
++ watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
++ {
++ if (watch->events & watched_fd->occurred)
++ {
++ (watch->callback) (watch, watched_fd->fd,
++ AVAHI_WATCH_OUT, watch->userdata);
++ watched_fd->occurred &= ~AVAHI_WATCH_OUT;
++ break;
++ }
++ }
++}
++
++
++/*
++ * 'watched_fd_add_select' - Call cupsdAddSelect() as needed
++ */
++
++static int /* O - Watches? */
++watched_fd_add_select (cupsd_watched_fd_t *watched_fd)
++{
++ AvahiWatch *watch;
++ cupsd_selfunc_t read_cb = NULL, write_cb = NULL;
++ int any_watches = 0;
++
++ for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
++ watch;
++ watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
++ {
++ any_watches = 1;
++ if (watch->events & (AVAHI_WATCH_IN |
++ AVAHI_WATCH_ERR |
++ AVAHI_WATCH_HUP))
++ {
++ read_cb = (cupsd_selfunc_t)watch_read_cb;
++ if (write_cb != NULL)
++ break;
++ }
++
++ if (watch->events & AVAHI_WATCH_OUT)
++ {
++ write_cb = (cupsd_selfunc_t)watch_write_cb;
++ if (read_cb != NULL)
++ break;
++ }
++ }
++
++ if (read_cb || write_cb)
++ cupsdAddSelect (watched_fd->fd, read_cb, write_cb, watched_fd);
++ else
++ cupsdRemoveSelect (watched_fd->fd);
++
++ return (any_watches);
++}
++
++/*
++ * 'watch_new' - Create a new file descriptor watch
++ */
++
++static AvahiWatch *
++watch_new (const AvahiPoll *api,
++ int fd,
++ AvahiWatchEvent events,
++ AvahiWatchCallback callback,
++ void *userdata)
++{
++ cupsd_watched_fd_t key, *watched_fd;
++ AvahiCupsPoll *cups_poll = api->userdata;
++ AvahiWatch *watch = malloc(sizeof(AvahiWatch));
++ if (watch == NULL)
++ return (NULL);
++
++ watch->events = events;
++ watch->callback = callback;
++ watch->userdata = userdata;
++
++ key.fd = fd;
++ watched_fd = cupsArrayFind (cups_poll->watched_fds, &key);
++ if (watched_fd == NULL)
++ {
++ watched_fd = malloc(sizeof(cupsd_watched_fd_t));
++ if (watched_fd == NULL)
++ {
++ free (watch);
++ return (NULL);
++ }
++
++ watched_fd->fd = fd;
++ watched_fd->occurred = 0;
++ watched_fd->cups_poll = cups_poll;
++ watched_fd->watches = cupsArrayNew (NULL, NULL);
++ cupsArrayAdd (cups_poll->watched_fds, watched_fd);
++ }
++
++ watch->watched_fd = watched_fd;
++ cupsArrayAdd(watched_fd->watches, watch);
++ watched_fd_add_select (watched_fd);
++ return (watch);
++}
++
++
++/*
++ * 'watch_free' - Free a file descriptor watch
++ */
++
++static void
++watch_free (AvahiWatch *watch)
++{
++ cupsd_watched_fd_t *watched_fd = watch->watched_fd;
++ AvahiCupsPoll *cups_poll = watched_fd->cups_poll;
++
++ cupsArrayRemove (watched_fd->watches, watch);
++ free (watch);
++
++ if (!watched_fd_add_select (watched_fd))
++ {
++ /* No more watches */
++ cupsArrayRemove (cups_poll->watched_fds, watched_fd);
++ free (watched_fd);
++ }
++}
++
++
++/*
++ * 'watch_update' - Update watched events for a file descriptor
++ */
++
++static void
++watch_update (AvahiWatch *watch,
++ AvahiWatchEvent events)
++{
++ watch->events = events;
++ watched_fd_add_select (watch->watched_fd);
++}
++
++
++/*
++ * 'watch_get_events' - Get events that happened for a file descriptor
++ */
++
++static AvahiWatchEvent
++watch_get_events (AvahiWatch *watch)
++{
++ return (watch->watched_fd->occurred);
++}
++
++
++/*
++ * 'timeout_cb()' - Run a timed Avahi callback
++ */
++
++static void
++timeout_cb (cupsd_timeout_t *cupsd_timeout, void *userdata)
++{
++ AvahiTimeout *timeout = userdata;
++ (timeout->callback) (timeout, timeout->userdata);
++}
++
++
++/*
++ * 'timeout_new' - Set a wakeup time
++ */
++
++static AvahiTimeout *
++timeout_new (const AvahiPoll *api,
++ const struct timeval *tv,
++ AvahiTimeoutCallback callback,
++ void *userdata)
++{
++ AvahiTimeout *timeout;
++ AvahiCupsPoll *cups_poll = api->userdata;
++
++ timeout = malloc(sizeof(AvahiTimeout));
++ if (timeout == NULL)
++ return (NULL);
++
++ timeout->cups_poll = cups_poll;
++ timeout->callback = callback;
++ timeout->userdata = userdata;
++ timeout->cupsd_timeout = cupsdAddTimeout (tv,
++ (cupsd_timeoutfunc_t)timeout_cb,
++ timeout);
++ cupsArrayAdd (cups_poll->timeouts, timeout);
++ return (timeout);
++}
++
++
++/*
++ * 'timeout_update' - Update the expiration time for a timeout
++ */
++
++static void
++timeout_update (AvahiTimeout *timeout,
++ const struct timeval *tv)
++{
++ cupsdUpdateTimeout (timeout->cupsd_timeout, tv);
++}
++
++
++/*
++ * ' timeout_free' - Free a timeout
++ */
++
++static void
++timeout_free (AvahiTimeout *timeout)
++{
++ cupsArrayRemove (timeout->cups_poll->timeouts, timeout);
++ cupsdRemoveTimeout (timeout->cupsd_timeout);
++ free (timeout);
++}
++
++
++/*
++ * 'compare_watched_fds' - Compare watched file descriptors for array sorting
++ */
++static int
++compare_watched_fds(cupsd_watched_fd_t *p0,
++ cupsd_watched_fd_t *p1)
++{
++ /*
++ * Compare by fd (no two elements have the same fd)
++ */
++
++ if (p0->fd == p1->fd)
++ return 0;
++
++ return (p0->fd < p1->fd ? -1 : 1);
++}
++
++
++/*
++ * 'avahi_cups_poll_new' - Create a new Avahi main loop object for CUPS
++ */
++
++AvahiCupsPoll *
++avahi_cups_poll_new (void)
++{
++ AvahiCupsPoll *cups_poll = malloc(sizeof(AvahiCupsPoll));
++ if (cups_poll == NULL)
++ return (NULL);
++
++ cups_poll->watched_fds = cupsArrayNew ((cups_array_func_t)compare_watched_fds,
++ NULL);
++ cups_poll->timeouts = cupsArrayNew (NULL, NULL);
++
++ cups_poll->api.userdata = cups_poll;
++ cups_poll->api.watch_new = watch_new;
++ cups_poll->api.watch_free = watch_free;
++ cups_poll->api.watch_update = watch_update;
++ cups_poll->api.watch_get_events = watch_get_events;
++
++ cups_poll->api.timeout_new = timeout_new;
++ cups_poll->api.timeout_update = timeout_update;
++ cups_poll->api.timeout_free = timeout_free;
++
++ return (cups_poll);
++}
++
++
++/*
++ * 'avahi_cups_poll_free' - Free an Avahi main loop object for CUPS
++ */
++void
++avahi_cups_poll_free (AvahiCupsPoll *cups_poll)
++{
++ cupsd_watched_fd_t *watched_fd;
++
++ for (watched_fd = (cupsd_watched_fd_t*)cupsArrayFirst(cups_poll->watched_fds);
++ watched_fd;
++ watched_fd = (cupsd_watched_fd_t*)cupsArrayNext(cups_poll->watched_fds))
++ cupsArrayClear (watched_fd->watches);
++
++ cupsArrayClear (cups_poll->watched_fds);
++ cupsArrayClear (cups_poll->timeouts);
++}
++
++
++/*
++ * 'avahi_cups_poll_get' - Get the abstract poll API structure
++ */
++
++const AvahiPoll *
++avahi_cups_poll_get (AvahiCupsPoll *cups_poll)
++{
++ return (&cups_poll->api);
++}
++
++
++#endif /* HAVE_AVAHI ... from top of file */
++
++/*
++ * End of "$Id$".
++ */
+diff -up cups-1.6.3/scheduler/avahi.h.avahi-no-threaded cups-1.6.3/scheduler/avahi.h
+--- cups-1.6.3/scheduler/avahi.h.avahi-no-threaded 2013-07-12 11:42:14.651430814 +0200
++++ cups-1.6.3/scheduler/avahi.h 2013-07-12 11:42:14.651430814 +0200
+@@ -0,0 +1,69 @@
++/*
++ * "$Id$"
++ *
++ * Avahi poll implementation for the CUPS scheduler.
++ *
++ * Copyright (C) 2010, 2011 Red Hat, Inc.
++ * Authors:
++ * Tim Waugh
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include
++
++#ifdef HAVE_AVAHI
++# include
++# include
++#endif /* HAVE_AVAHI */
++
++#ifdef HAVE_AUTHORIZATION_H
++# include
++#endif /* HAVE_AUTHORIZATION_H */
++
++
++#ifdef HAVE_AVAHI
++typedef struct
++{
++ AvahiPoll api;
++ cups_array_t *watched_fds;
++ cups_array_t *timeouts;
++} AvahiCupsPoll;
++#endif /* HAVE_AVAHI */
++
++/*
++ * Prototypes...
++ */
++
++#ifdef HAVE_AVAHI
++extern AvahiCupsPoll * avahi_cups_poll_new(void);
++extern void avahi_cups_poll_free(AvahiCupsPoll *cups_poll);
++extern const AvahiPoll *avahi_cups_poll_get(AvahiCupsPoll *cups_poll);
++#endif /* HAVE_AVAHI */
++
++
++/*
++ * End of "$Id$".
++ */
+diff -up cups-1.6.3/scheduler/cupsd.h.avahi-no-threaded cups-1.6.3/scheduler/cupsd.h
+--- cups-1.6.3/scheduler/cupsd.h.avahi-no-threaded 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/scheduler/cupsd.h 2013-07-12 11:52:42.947705883 +0200
+@@ -119,6 +119,7 @@ extern const char *cups_hstrerror(int);
+ #include "colorman.h"
+ #include "conf.h"
+ #include "banners.h"
++#include "avahi.h"
+ #include "dirsvc.h"
+ #include "network.h"
+ #include "subscriptions.h"
+@@ -139,6 +140,15 @@ extern const char *cups_hstrerror(int);
+
+ typedef void (*cupsd_selfunc_t)(void *data);
+
++#ifdef HAVE_AVAHI
++/*
++ * Timeout callback function type...
++ */
++
++typedef struct _cupsd_timeout_s cupsd_timeout_t;
++typedef void (*cupsd_timeoutfunc_t)(cupsd_timeout_t *timeout, void *data);
++#endif /* HAVE_AVAHI */
++
+
+ /*
+ * Globals...
+@@ -165,6 +175,11 @@ VAR int Launchd VALUE(0);
+ /* Running from launchd */
+ #endif /* HAVE_LAUNCH_H */
+
++#ifdef HAVE_AVAHI
++VAR cups_array_t *Timeouts; /* Timed callbacks for main loop */
++#endif /* HAVE_AVAHI */
++
++
+
+ /*
+ * Prototypes...
+@@ -228,6 +243,17 @@ extern void cupsdStopSelect(void);
+ extern void cupsdStartServer(void);
+ extern void cupsdStopServer(void);
+
++#ifdef HAVE_AVAHI
++extern void cupsdInitTimeouts(void);
++extern cupsd_timeout_t *cupsdAddTimeout (const struct timeval *tv,
++ cupsd_timeoutfunc_t cb,
++ void *data);
++extern cupsd_timeout_t *cupsdNextTimeout (long *delay);
++extern void cupsdRunTimeout (cupsd_timeout_t *timeout);
++extern void cupsdUpdateTimeout (cupsd_timeout_t *timeout,
++ const struct timeval *tv);
++extern void cupsdRemoveTimeout (cupsd_timeout_t *timeout);
++#endif /* HAVE_AVAHI */
+
+ /*
+ * End of "$Id: cupsd.h 7928 2008-09-10 22:14:22Z mike $".
+diff -up cups-1.6.3/scheduler/dirsvc.c.avahi-no-threaded cups-1.6.3/scheduler/dirsvc.c
+--- cups-1.6.3/scheduler/dirsvc.c.avahi-no-threaded 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/scheduler/dirsvc.c 2013-07-12 11:42:14.652430800 +0200
+@@ -212,7 +212,7 @@ cupsdStartBrowsing(void)
+ }
+
+ # else /* HAVE_AVAHI */
+- if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
++ if ((DNSSDMaster = avahi_cups_poll_new()) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");
+
+@@ -223,7 +223,7 @@ cupsdStartBrowsing(void)
+ {
+ int error; /* Error code, if any */
+
+- DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), 0,
++ DNSSDClient = avahi_client_new(avahi_cups_poll_get(DNSSDMaster), 0,
+ NULL, NULL, &error);
+
+ if (DNSSDClient == NULL)
+@@ -235,11 +235,9 @@ cupsdStartBrowsing(void)
+ if (FatalErrors & CUPSD_FATAL_BROWSE)
+ cupsdEndProcess(getpid(), 0);
+
+- avahi_threaded_poll_free(DNSSDMaster);
++ avahi_cups_poll_free(DNSSDMaster);
+ DNSSDMaster = NULL;
+ }
+- else
+- avahi_threaded_poll_start(DNSSDMaster);
+ }
+ # endif /* HAVE_DNSSD */
+
+@@ -746,9 +744,7 @@ dnssdDeregisterInstance(
+ DNSServiceRefDeallocate(*srv);
+
+ # else /* HAVE_AVAHI */
+- avahi_threaded_poll_lock(DNSSDMaster);
+ avahi_entry_group_free(*srv);
+- avahi_threaded_poll_unlock(DNSSDMaster);
+ # endif /* HAVE_DNSSD */
+
+ *srv = NULL;
+@@ -1043,14 +1039,10 @@ dnssdRegisterInstance(
+ (void)commit;
+
+ # else /* HAVE_AVAHI */
+- avahi_threaded_poll_lock(DNSSDMaster);
+-
+ if (!*srv)
+ *srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL);
+ if (!*srv)
+ {
+- avahi_threaded_poll_unlock(DNSSDMaster);
+-
+ cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
+ name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
+ return (0);
+@@ -1165,8 +1157,6 @@ dnssdRegisterInstance(
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
+ name);
+ }
+-
+- avahi_threaded_poll_unlock(DNSSDMaster);
+ # endif /* HAVE_DNSSD */
+
+ if (error)
+@@ -1336,7 +1326,7 @@ dnssdStop(void)
+ avahi_client_free(DNSSDClient);
+ DNSSDClient = NULL;
+
+- avahi_threaded_poll_free(DNSSDMaster);
++ avahi_cups_poll_free(DNSSDMaster);
+ DNSSDMaster = NULL;
+ # endif /* HAVE_DNSSD */
+
+diff -up cups-1.6.3/scheduler/dirsvc.h.avahi-no-threaded cups-1.6.3/scheduler/dirsvc.h
+--- cups-1.6.3/scheduler/dirsvc.h.avahi-no-threaded 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/scheduler/dirsvc.h 2013-07-12 11:42:14.652430800 +0200
+@@ -51,7 +51,7 @@ VAR cups_array_t *DNSSDPrinters VALUE(NU
+ VAR DNSServiceRef DNSSDMaster VALUE(NULL);
+ /* Master DNS-SD service reference */
+ # else /* HAVE_AVAHI */
+-VAR AvahiThreadedPoll *DNSSDMaster VALUE(NULL);
++VAR AvahiCupsPoll *DNSSDMaster VALUE(NULL);
+ /* Master polling interface for Avahi */
+ VAR AvahiClient *DNSSDClient VALUE(NULL);
+ /* Client information */
+diff -up cups-1.6.3/scheduler/main.c.avahi-no-threaded cups-1.6.3/scheduler/main.c
+--- cups-1.6.3/scheduler/main.c.avahi-no-threaded 2013-07-12 11:42:14.624431189 +0200
++++ cups-1.6.3/scheduler/main.c 2013-07-12 11:42:14.653430786 +0200
+@@ -159,6 +159,10 @@ main(int argc, /* I - Number of comm
+ int launchd_idle_exit;
+ /* Idle exit on select timeout? */
+ #endif /* HAVE_LAUNCHD */
++#ifdef HAVE_AVAHI
++ cupsd_timeout_t *tmo; /* Next scheduled timed callback */
++ long tmo_delay; /* Time before it must be called */
++#endif /* HAVE_AVAHI */
+
+
+ #ifdef HAVE_GETEUID
+@@ -603,6 +607,14 @@ main(int argc, /* I - Number of comm
+
+ httpInitialize();
+
++#ifdef HAVE_AVAHI
++ /*
++ * Initialize timed callback structures.
++ */
++
++ cupsdInitTimeouts();
++#endif /* HAVE_AVAHI */
++
+ cupsdStartServer();
+
+ /*
+@@ -946,6 +958,16 @@ main(int argc, /* I - Number of comm
+ }
+ #endif /* __APPLE__ */
+
++#ifdef HAVE_AVAHI
++ /*
++ * If a timed callback is due, run it.
++ */
++
++ tmo = cupsdNextTimeout (&tmo_delay);
++ if (tmo && tmo_delay == 0)
++ cupsdRunTimeout (tmo);
++#endif /* HAVE_AVAHI */
++
+ #ifndef __APPLE__
+ /*
+ * Update the network interfaces once a minute...
+@@ -1938,6 +1960,10 @@ select_timeout(int fds) /* I - Number
+ cupsd_job_t *job; /* Job information */
+ cupsd_subscription_t *sub; /* Subscription information */
+ const char *why; /* Debugging aid */
++#ifdef HAVE_AVAHI
++ cupsd_timeout_t *tmo; /* Timed callback */
++ long tmo_delay; /* Seconds before calling it */
++#endif /* HAVE_AVAHI */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: JobHistoryUpdate=%ld",
+@@ -1983,6 +2009,19 @@ select_timeout(int fds) /* I - Number
+ }
+ #endif /* __APPLE__ */
+
++#ifdef HAVE_AVAHI
++ /*
++ * See if there are any scheduled timed callbacks to run.
++ */
++
++ if ((tmo = cupsdNextTimeout(&tmo_delay)) != NULL &&
++ (now + tmo_delay) < timeout)
++ {
++ timeout = tmo_delay;
++ why = "run a timed callback";
++ }
++#endif /* HAVE_AVAHI */
++
+ /*
+ * Check whether we are accepting new connections...
+ */
+diff -up cups-1.6.3/scheduler/Makefile.avahi-no-threaded cups-1.6.3/scheduler/Makefile
+--- cups-1.6.3/scheduler/Makefile.avahi-no-threaded 2013-07-12 11:42:14.625431175 +0200
++++ cups-1.6.3/scheduler/Makefile 2013-07-12 11:42:14.653430786 +0200
+@@ -17,6 +17,7 @@ include ../Makedefs
+
+ CUPSDOBJS = \
+ auth.o \
++ avahi.o \
+ banners.o \
+ cert.o \
+ classes.o \
+@@ -41,6 +42,7 @@ CUPSDOBJS = \
+ statbuf.o \
+ subscriptions.o \
+ sysman.o \
++ timeout.o \
+ tls.o
+ LIBOBJS = \
+ filter.o \
+diff -up cups-1.6.3/scheduler/timeout.c.avahi-no-threaded cups-1.6.3/scheduler/timeout.c
+--- cups-1.6.3/scheduler/timeout.c.avahi-no-threaded 2013-07-12 11:42:14.654430772 +0200
++++ cups-1.6.3/scheduler/timeout.c 2013-07-12 11:42:14.654430772 +0200
+@@ -0,0 +1,235 @@
++/*
++ * "$Id$"
++ *
++ * Timeout functions for the Common UNIX Printing System (CUPS).
++ *
++ * Copyright (C) 2010, 2011 Red Hat, Inc.
++ * Authors:
++ * Tim Waugh
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Contents:
++ *
++ * cupsdInitTimeouts() - Initialise timeout structure.
++ * cupsdAddTimeout() - Add a timed callback.
++ * cupsdNextTimeout() - Find the next enabled timed callback.
++ * cupsdUpdateTimeout() - Adjust the time of a timed callback or disable it.
++ * cupsdRemoveTimeout() - Discard a timed callback.
++ * compare_timeouts() - Compare timed callbacks for array sorting.
++ */
++
++#include
++
++#ifdef HAVE_AVAHI /* Applies to entire file... */
++
++/*
++ * Include necessary headers...
++ */
++
++#include "cupsd.h"
++
++#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
++# include
++#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
++
++#ifdef HAVE_AVAHI
++# include
++#endif /* HAVE_AVAHI */
++
++
++struct _cupsd_timeout_s
++{
++ struct timeval when;
++ int enabled;
++ cupsd_timeoutfunc_t callback;
++ void *data;
++};
++
++/*
++ * Local functions...
++ */
++
++/*
++ * 'compare_timeouts()' - Compare timed callbacks for array sorting.
++ */
++
++static int
++compare_addrs (void *p0, void *p1)
++{
++ if (p0 == p1)
++ return (0);
++ if (p0 < p1)
++ return (-1);
++ return (1);
++}
++
++static int
++compare_timeouts (cupsd_timeout_t *p0, cupsd_timeout_t *p1)
++{
++ int addrsdiff = compare_addrs (p0, p1);
++ int tvdiff;
++
++ if (addrsdiff == 0)
++ return (0);
++
++ if (!p0->enabled || !p1->enabled)
++ {
++ if (!p0->enabled && !p1->enabled)
++ return (addrsdiff);
++
++ return (p0->enabled ? -1 : 1);
++ }
++
++ tvdiff = avahi_timeval_compare (&p0->when, &p1->when);
++ if (tvdiff != 0)
++ return (tvdiff);
++
++ return (addrsdiff);
++}
++
++
++/*
++ * 'cupsdInitTimeouts()' - Initialise timeout structures.
++ */
++
++void
++cupsdInitTimeouts(void)
++{
++ Timeouts = cupsArrayNew ((cups_array_func_t)compare_timeouts, NULL);
++}
++
++
++/*
++ * 'cupsdAddTimeout()' - Add a timed callback.
++ */
++
++cupsd_timeout_t * /* O - Timeout handle */
++cupsdAddTimeout(const struct timeval *tv, /* I - Absolute time */
++ cupsd_timeoutfunc_t cb, /* I - Callback function */
++ void *data) /* I - User data */
++{
++ cupsd_timeout_t *timeout;
++
++ timeout = malloc (sizeof(cupsd_timeout_t));
++ if (timeout != NULL)
++ {
++ timeout->enabled = (tv != NULL);
++ if (tv)
++ {
++ timeout->when.tv_sec = tv->tv_sec;
++ timeout->when.tv_usec = tv->tv_usec;
++ }
++
++ timeout->callback = cb;
++ timeout->data = data;
++ cupsArrayAdd (Timeouts, timeout);
++ }
++
++ return timeout;
++}
++
++
++/*
++ * 'cupsdNextTimeout()' - Find the next enabled timed callback.
++ */
++
++cupsd_timeout_t * /* O - Next enabled timeout or NULL */
++cupsdNextTimeout(long *delay) /* O - Seconds before scheduled */
++{
++ cupsd_timeout_t *first = cupsArrayFirst (Timeouts);
++ struct timeval curtime;
++
++ if (first && !first->enabled)
++ first = NULL;
++
++ if (first && delay)
++ {
++ gettimeofday (&curtime, NULL);
++ if (avahi_timeval_compare (&curtime, &first->when) > 0)
++ {
++ *delay = 0;
++ } else {
++ *delay = 1 + first->when.tv_sec - curtime.tv_sec;
++ if (first->when.tv_usec < curtime.tv_usec)
++ (*delay)--;
++ }
++ }
++
++ return (first);
++}
++
++
++/*
++ * 'cupsdRunTimeout()' - Run a timed callback.
++ */
++
++void
++cupsdRunTimeout(cupsd_timeout_t *timeout) /* I - Timeout */
++{
++ if (!timeout)
++ return;
++ timeout->enabled = 0;
++ if (!timeout->callback)
++ return;
++ timeout->callback (timeout, timeout->data);
++}
++
++/*
++ * 'cupsdUpdateTimeout()' - Adjust the time of a timed callback or disable it.
++ */
++
++void
++cupsdUpdateTimeout(cupsd_timeout_t *timeout, /* I - Timeout */
++ const struct timeval *tv) /* I - Absolute time or NULL */
++{
++ cupsArrayRemove (Timeouts, timeout);
++ timeout->enabled = (tv != NULL);
++ if (tv)
++ {
++ timeout->when.tv_sec = tv->tv_sec;
++ timeout->when.tv_usec = tv->tv_usec;
++ }
++ cupsArrayAdd (Timeouts, timeout);
++}
++
++
++/*
++ * 'cupsdRemoveTimeout()' - Discard a timed callback.
++ */
++
++void
++cupsdRemoveTimeout(cupsd_timeout_t *timeout) /* I - Timeout */
++{
++ cupsArrayRemove (Timeouts, timeout);
++ free (timeout);
++}
++
++
++#endif /* HAVE_AVAHI ... from top of file */
++
++/*
++ * End of "$Id$".
++ */
diff --git a/SOURCES/cups-banners.patch b/SOURCES/cups-banners.patch
new file mode 100644
index 0000000..aa19282
--- /dev/null
+++ b/SOURCES/cups-banners.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.5b1/scheduler/banners.c.banners cups-1.5b1/scheduler/banners.c
+--- cups-1.5b1/scheduler/banners.c.banners 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/banners.c 2011-05-23 17:35:30.000000000 +0200
+@@ -110,6 +110,8 @@ cupsdLoadBanners(const char *d) /* I -
+ if ((ext = strrchr(dent->filename, '.')) != NULL)
+ if (!strcmp(ext, ".bck") ||
+ !strcmp(ext, ".bak") ||
++ !strcmp(ext, ".rpmnew") ||
++ !strcmp(ext, ".rpmsave") ||
+ !strcmp(ext, ".sav"))
+ continue;
+
diff --git a/SOURCES/cups-colord-interface.patch b/SOURCES/cups-colord-interface.patch
new file mode 100644
index 0000000..49057eb
--- /dev/null
+++ b/SOURCES/cups-colord-interface.patch
@@ -0,0 +1,23 @@
+diff -up cups-1.6.3/scheduler/colorman.c.colord-interface cups-1.6.3/scheduler/colorman.c
+--- cups-1.6.3/scheduler/colorman.c.colord-interface 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/scheduler/colorman.c 2014-09-02 10:47:19.457169176 +0100
+@@ -107,6 +107,10 @@ extern CFUUIDRef ColorSyncCreateUUIDFrom
+ "org.freedesktop.ColorManager", (p),\
+ "org.freedesktop.ColorManager", (m))
+ /* Macro to make new colord messages */
++# define COLORD_DEVICE_DBUS_MSG(p,m) dbus_message_new_method_call( \
++ "org.freedesktop.ColorManager", (p),\
++ "org.freedesktop.ColorManager.Device", (m))
++ /* Macro to make new colord messages */
+ # define COLORD_DBUS_PATH "/org/freedesktop/ColorManager"
+ /* Path for color management system */
+ # define COLORD_DBUS_TIMEOUT 5000 /* Timeout for connecting to colord in ms */
+@@ -1196,7 +1200,7 @@ colord_device_add_profile(
+ DBusError error; /* D-Bus error */
+
+
+- message = COLORD_DBUS_MSG(device_path, "AddProfile");
++ message = COLORD_DEVICE_DBUS_MSG(device_path, "AddProfile");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &relation);
diff --git a/SOURCES/cups-dbus-notifier.patch b/SOURCES/cups-dbus-notifier.patch
new file mode 100644
index 0000000..371f63e
--- /dev/null
+++ b/SOURCES/cups-dbus-notifier.patch
@@ -0,0 +1,104 @@
+diff -up cups-1.6.3/notifier/dbus.c.dbus-notifier cups-1.6.3/notifier/dbus.c
+--- cups-1.6.3/notifier/dbus.c.dbus-notifier 2013-11-19 12:23:56.860249407 +0000
++++ cups-1.6.3/notifier/dbus.c 2013-11-19 12:24:46.919476920 +0000
+@@ -4,7 +4,7 @@
+ * D-Bus notifier for CUPS.
+ *
+ * Copyright 2008-2011 by Apple Inc.
+- * Copyright (C) 2011 Red Hat, Inc.
++ * Copyright (C) 2011, 2013 Red Hat, Inc.
+ * Copyright (C) 2007 Tim Waugh
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+@@ -157,9 +157,16 @@ enum
+
+
+ /*
++ * Global variables...
++ */
++
++static char lock_filename[1024]; /* Lock filename */
++
++/*
+ * Local functions...
+ */
+
++static void release_lock(void);
+ static int acquire_lock(int *fd, char *lockfile, size_t locksize);
+ static const char *validate_utf8(const char *str);
+
+@@ -251,8 +258,6 @@ main(int argc, /* I - Number of comm
+ DBusMessage *message; /* Message to send */
+ DBusMessageIter iter; /* Iterator for message data */
+ int lock_fd = -1; /* Lock file descriptor */
+- char lock_filename[1024];
+- /* Lock filename */
+
+
+ /*
+@@ -651,7 +656,7 @@ main(int argc, /* I - Number of comm
+ if (lock_fd >= 0)
+ {
+ close(lock_fd);
+- unlink(lock_filename);
++ release_lock();
+ }
+
+ return (0);
+@@ -659,6 +664,27 @@ main(int argc, /* I - Number of comm
+
+
+ /*
++ * 'release_lock()' - Release the singleton lock.
++ */
++
++static void
++release_lock(void)
++{
++ unlink(lock_filename);
++}
++
++
++/*
++ * 'handle_sigterm()' - Handle SIGTERM signal.
++ */
++static void
++handle_sigterm(int signum)
++{
++ release_lock();
++ _exit (0);
++}
++
++/*
+ * 'acquire_lock()' - Acquire a lock so we only have a single notifier running.
+ */
+
+@@ -667,7 +692,8 @@ acquire_lock(int *fd, /* O - Lock fi
+ char *lockfile, /* I - Lock filename buffer */
+ size_t locksize) /* I - Size of filename buffer */
+ {
+- const char *tmpdir; /* Temporary directory */
++ const char *tmpdir; /* Temporary directory */
++ struct sigaction action; /* POSIX sigaction data */
+
+
+ /*
+@@ -685,8 +711,16 @@ acquire_lock(int *fd, /* O - Lock fi
+
+ if ((*fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
+ return (-1);
+- else
+- return (0);
++
++ /*
++ * Set a SIGTERM handler to make sure we release the lock if the
++ * scheduler decides to stop us.
++ */
++ memset(&action, 0, sizeof(action));
++ action.sa_handler = handle_sigterm;
++ sigaction(SIGTERM, &action, NULL);
++
++ return (0);
+ }
+ #else /* !HAVE_DBUS */
+ int
diff --git a/SOURCES/cups-dbus-utf8.patch b/SOURCES/cups-dbus-utf8.patch
new file mode 100644
index 0000000..0bcd4a1
--- /dev/null
+++ b/SOURCES/cups-dbus-utf8.patch
@@ -0,0 +1,106 @@
+diff -up cups-1.6.1/notifier/dbus.c.dbus-utf8 cups-1.6.1/notifier/dbus.c
+--- cups-1.6.1/notifier/dbus.c.dbus-utf8 2012-01-20 19:00:32.000000000 +0000
++++ cups-1.6.1/notifier/dbus.c 2012-10-31 11:04:47.686973616 +0000
+@@ -31,6 +31,9 @@
+ #include
+ #include
+ #include
++#include
++#include
++#include
+
+ #ifdef HAVE_DBUS
+ # include
+@@ -157,10 +160,82 @@ enum
+ * Local functions...
+ */
+
+-static int acquire_lock(int *fd, char *lockfile, size_t locksize);
++static int acquire_lock(int *fd, char *lockfile, size_t locksize);
++static const char *validate_utf8(const char *str);
+
+
+ /*
++ * 'validate_utf8()' - Convert to valid UTF-8
++ */
++
++static const char *
++validate_utf8 (const char *str)
++{
++ static char *buffer = NULL;
++ static size_t buflen = 0;
++ char *p;
++ size_t str_len;
++ unsigned int i;
++ mbstate_t instate, outstate;
++
++ if (str == NULL)
++ {
++ free (buffer);
++ return (NULL);
++ }
++
++ /* Is it already valid? */
++ if (mbstowcs (NULL, str, 0) != (size_t) -1)
++ return str;
++
++ /* Make sure our buffer is at least as large as the input string */
++ str_len = strlen (str);
++ if (str_len > buflen)
++ {
++ if (buffer == NULL)
++ /* Set encoding type to UTF-8 the first time we need to */
++ setlocale (LC_CTYPE, "en_US.UTF-8");
++
++ buflen = str_len + 1;
++ buffer = realloc (buffer, buflen);
++ }
++
++ memset (&instate, '\0', sizeof (mbstate_t));
++ memset (&outstate, '\0', sizeof (mbstate_t));
++ p = buffer;
++ i = 0;
++ while (i < str_len)
++ {
++ wchar_t wc;
++ size_t used, written;
++ mbstate_t orig_instate = instate;
++ used = mbrtowc (&wc, str + i, str_len - i, &instate);
++ switch (used)
++ {
++ case (size_t) -2:
++ case (size_t) -1:
++ wc = L'?'; /* so replacement is never longer than original char */
++ instate = orig_instate;
++ /* fallthru */
++ case 0:
++ used = 1;
++ }
++
++ written = wcrtomb (p, wc, &outstate);
++ if (written != -1)
++ {
++ p += written;
++ assert (p - buffer < buflen);
++ }
++
++ i += used;
++ }
++
++ *p = '\0';
++ return buffer;
++}
++
++/*
+ * 'main()' - Read events and send DBUS notifications.
+ */
+
+@@ -366,7 +441,7 @@ main(int argc, /* I - Number of comm
+ attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT);
+ if (attr)
+ {
+- const char *val = ippGetString(attr, 0, NULL);
++ const char *val = validate_utf8 (ippGetString(attr, 0, NULL));
+ if (!dbus_message_iter_append_string(&iter, &val))
+ goto bail;
+ }
diff --git a/SOURCES/cups-direct-usb.patch b/SOURCES/cups-direct-usb.patch
new file mode 100644
index 0000000..4e25ce7
--- /dev/null
+++ b/SOURCES/cups-direct-usb.patch
@@ -0,0 +1,27 @@
+diff -up cups-1.5b1/backend/usb-unix.c.direct-usb cups-1.5b1/backend/usb-unix.c
+--- cups-1.5b1/backend/usb-unix.c.direct-usb 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/backend/usb-unix.c 2011-05-23 17:52:14.000000000 +0200
+@@ -102,6 +102,9 @@ print_device(const char *uri, /* I - De
+ _cups_strncasecmp(hostname, "Minolta", 7);
+ #endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */
+
++ if (use_bc && !strncmp(uri, "usb:/dev/", 9))
++ use_bc = 0;
++
+ if ((device_fd = open_device(uri, &use_bc)) == -1)
+ {
+ if (getenv("CLASS") != NULL)
+@@ -331,12 +334,7 @@ open_device(const char *uri, /* I - Dev
+ if (!strncmp(uri, "usb:/dev/", 9))
+ #ifdef __linux
+ {
+- /*
+- * Do not allow direct devices anymore...
+- */
+-
+- errno = ENODEV;
+- return (-1);
++ return (open(uri + 4, O_RDWR | O_EXCL));
+ }
+ else if (!strncmp(uri, "usb://", 6))
+ {
diff --git a/SOURCES/cups-dnssd-deviceid.patch b/SOURCES/cups-dnssd-deviceid.patch
new file mode 100644
index 0000000..b3c2b8e
--- /dev/null
+++ b/SOURCES/cups-dnssd-deviceid.patch
@@ -0,0 +1,38 @@
+diff -up cups-1.6b1/backend/dnssd.c.dnssd-deviceid cups-1.6b1/backend/dnssd.c
+--- cups-1.6b1/backend/dnssd.c.dnssd-deviceid 2012-05-21 18:05:58.000000000 +0200
++++ cups-1.6b1/backend/dnssd.c 2012-05-25 16:27:49.226874427 +0200
+@@ -1181,15 +1181,22 @@ query_callback(
+ if (device->device_id)
+ free(device->device_id);
+
++ if (device_id[0])
++ {
++ /* Mark this as the real device ID. */
++ ptr = device_id + strlen(device_id);
++ snprintf(ptr, sizeof(device_id) - (ptr - device_id), "FZY:0;");
++ }
++
+ if (!device_id[0] && strcmp(model, "Unknown"))
+ {
+ if (make_and_model[0])
+- snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;",
++ snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;FZY:1;",
+ make_and_model, model);
+ else if (!_cups_strncasecmp(model, "designjet ", 10))
+- snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s", model + 10);
++ snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s;FZY:1;", model + 10);
+ else if (!_cups_strncasecmp(model, "stylus ", 7))
+- snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s", model + 7);
++ snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s;FZY:1;", model + 7);
+ else if ((ptr = strchr(model, ' ')) != NULL)
+ {
+ /*
+@@ -1199,7 +1206,7 @@ query_callback(
+ memcpy(make_and_model, model, ptr - model);
+ make_and_model[ptr - model] = '\0';
+
+- snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s",
++ snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;FZY:1;",
+ make_and_model, ptr + 1);
+ }
+ }
diff --git a/SOURCES/cups-driverd-timeout.patch b/SOURCES/cups-driverd-timeout.patch
new file mode 100644
index 0000000..cb9e5cf
--- /dev/null
+++ b/SOURCES/cups-driverd-timeout.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.5.0/scheduler/ipp.c.driverd-timeout cups-1.5.0/scheduler/ipp.c
+--- cups-1.5.0/scheduler/ipp.c.driverd-timeout 2011-10-10 17:03:41.801690962 +0100
++++ cups-1.5.0/scheduler/ipp.c 2011-10-10 17:03:41.861689834 +0100
+@@ -5723,7 +5723,7 @@ copy_model(cupsd_client_t *con, /* I -
+ close(temppipe[1]);
+
+ /*
+- * Wait up to 30 seconds for the PPD file to be copied...
++ * Wait up to 70 seconds for the PPD file to be copied...
+ */
+
+ total = 0;
+@@ -5743,7 +5743,7 @@ copy_model(cupsd_client_t *con, /* I -
+ FD_SET(temppipe[0], &input);
+ FD_SET(CGIPipes[0], &input);
+
+- timeout.tv_sec = 30;
++ timeout.tv_sec = 70;
+ timeout.tv_usec = 0;
+
+ if ((i = select(maxfd, &input, NULL, NULL, &timeout)) < 0)
diff --git a/SOURCES/cups-dymo-deviceid.patch b/SOURCES/cups-dymo-deviceid.patch
new file mode 100644
index 0000000..cc2995d
--- /dev/null
+++ b/SOURCES/cups-dymo-deviceid.patch
@@ -0,0 +1,11 @@
+diff -up cups-1.6.2/ppdc/sample.drv.dymo-deviceid cups-1.6.2/ppdc/sample.drv
+--- cups-1.6.2/ppdc/sample.drv.dymo-deviceid 2013-06-18 16:57:02.110662953 +0100
++++ cups-1.6.2/ppdc/sample.drv 2013-06-18 16:58:56.513989117 +0100
+@@ -125,6 +125,7 @@ Version "1.5"
+ {
+ Manufacturer "Dymo"
+ ModelName "Label Printer"
++ Attribute "1284DeviceID" "" "MFG:DYMO;MDL:LabelWriter 400;"
+ Attribute NickName "" "Dymo Label Printer"
+ PCFileName "dymo.ppd"
+ DriverType label
diff --git a/SOURCES/cups-eggcups.patch b/SOURCES/cups-eggcups.patch
new file mode 100644
index 0000000..981d920
--- /dev/null
+++ b/SOURCES/cups-eggcups.patch
@@ -0,0 +1,130 @@
+diff -up cups-1.5.3/backend/ipp.c.eggcups cups-1.5.3/backend/ipp.c
+--- cups-1.5.3/backend/ipp.c.eggcups 2012-05-05 01:00:01.000000000 +0200
++++ cups-1.5.3/backend/ipp.c 2012-05-15 16:50:41.142868986 +0200
+@@ -138,6 +138,70 @@ static cups_array_t *state_reasons; /* A
+ static char tmpfilename[1024] = "";
+ /* Temporary spool file name */
+
++#if HAVE_DBUS
++#include
++
++static DBusConnection *dbus_connection = NULL;
++
++static int
++init_dbus (void)
++{
++ DBusConnection *connection;
++ DBusError error;
++
++ if (dbus_connection &&
++ !dbus_connection_get_is_connected (dbus_connection)) {
++ dbus_connection_unref (dbus_connection);
++ dbus_connection = NULL;
++ }
++
++ dbus_error_init (&error);
++ connection = dbus_bus_get (getuid () ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error);
++ if (connection == NULL) {
++ dbus_error_free (&error);
++ return -1;
++ }
++
++ dbus_connection = connection;
++ return 0;
++}
++
++int
++dbus_broadcast_queued_remote (const char *printer_uri,
++ ipp_status_t status,
++ unsigned int local_job_id,
++ unsigned int remote_job_id,
++ const char *username,
++ const char *printer_name)
++{
++ DBusMessage *message;
++ DBusMessageIter iter;
++ const char *errstr;
++
++ if (!dbus_connection || !dbus_connection_get_is_connected (dbus_connection)) {
++ if (init_dbus () || !dbus_connection)
++ return -1;
++ }
++
++ errstr = ippErrorString (status);
++ message = dbus_message_new_signal ("/com/redhat/PrinterSpooler",
++ "com.redhat.PrinterSpooler",
++ "JobQueuedRemote");
++ dbus_message_iter_init_append (message, &iter);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &printer_uri);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &errstr);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &local_job_id);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &remote_job_id);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &username);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &printer_name);
++
++ dbus_connection_send (dbus_connection, message, NULL);
++ dbus_connection_flush (dbus_connection);
++ dbus_message_unref (message);
++
++ return 0;
++}
++#endif /* HAVE_DBUS */
+
+ /*
+ * Local functions...
+@@ -1520,6 +1584,15 @@ main(int argc, /* I - Number of comm
+ _("Print file accepted - job ID %d."), job_id);
+ }
+
++#if HAVE_DBUS
++ dbus_broadcast_queued_remote (argv[0],
++ ipp_status,
++ atoi (argv[1]),
++ job_id,
++ argv[2],
++ getenv ("PRINTER"));
++#endif /* HAVE_DBUS */
++
+ fprintf(stderr, "DEBUG: job-id=%d\n", job_id);
+ ippDelete(response);
+
+diff -up cups-1.5.3/backend/Makefile.eggcups cups-1.5.3/backend/Makefile
+--- cups-1.5.3/backend/Makefile.eggcups 2012-04-23 19:42:12.000000000 +0200
++++ cups-1.5.3/backend/Makefile 2012-05-15 16:48:17.253871982 +0200
+@@ -212,7 +212,7 @@ dnssd: dnssd.o ../cups/$(LIBCUPS) libbac
+
+ ipp: ipp.o ../cups/$(LIBCUPS) libbackend.a
+ echo Linking $@...
+- $(CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS)
++ $(CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS) $(SERVERLIBS)
+ $(RM) http
+ $(LN) ipp http
+
+diff -up cups-1.5.3/scheduler/subscriptions.c.eggcups cups-1.5.3/scheduler/subscriptions.c
+--- cups-1.5.3/scheduler/subscriptions.c.eggcups 2012-02-12 06:48:09.000000000 +0100
++++ cups-1.5.3/scheduler/subscriptions.c 2012-05-15 16:48:17.253871982 +0200
+@@ -1314,13 +1314,13 @@ cupsd_send_dbus(cupsd_eventmask_t event,
+ what = "PrinterAdded";
+ else if (event & CUPSD_EVENT_PRINTER_DELETED)
+ what = "PrinterRemoved";
+- else if (event & CUPSD_EVENT_PRINTER_CHANGED)
+- what = "QueueChanged";
+ else if (event & CUPSD_EVENT_JOB_CREATED)
+ what = "JobQueuedLocal";
+ else if ((event & CUPSD_EVENT_JOB_STATE) && job &&
+ job->state_value == IPP_JOB_PROCESSING)
+ what = "JobStartedLocal";
++ else if (event & (CUPSD_EVENT_PRINTER_CHANGED|CUPSD_EVENT_JOB_STATE_CHANGED|CUPSD_EVENT_PRINTER_STATE_CHANGED))
++ what = "QueueChanged";
+ else
+ return;
+
+@@ -1356,7 +1356,7 @@ cupsd_send_dbus(cupsd_eventmask_t event,
+ dbus_message_append_iter_init(message, &iter);
+ if (dest)
+ dbus_message_iter_append_string(&iter, dest->name);
+- if (job)
++ if (job && strcmp (what, "QueueChanged") != 0)
+ {
+ dbus_message_iter_append_uint32(&iter, job->id);
+ dbus_message_iter_append_string(&iter, job->username);
diff --git a/SOURCES/cups-enum-all.patch b/SOURCES/cups-enum-all.patch
new file mode 100644
index 0000000..0ac3983
--- /dev/null
+++ b/SOURCES/cups-enum-all.patch
@@ -0,0 +1,17 @@
+diff -up cups-1.6.2/cups/dest.c.enum-all cups-1.6.2/cups/dest.c
+--- cups-1.6.2/cups/dest.c.enum-all 2013-06-04 10:58:36.169786250 +0100
++++ cups-1.6.2/cups/dest.c 2013-06-04 10:59:02.147900811 +0100
+@@ -2724,9 +2724,12 @@ cups_dnssd_browse_cb(
+ break;
+
+ case AVAHI_BROWSER_REMOVE:
+- case AVAHI_BROWSER_ALL_FOR_NOW:
+ case AVAHI_BROWSER_CACHE_EXHAUSTED:
+ break;
++
++ case AVAHI_BROWSER_ALL_FOR_NOW:
++ avahi_simple_poll_quit(data->simple_poll);
++ break;
+ }
+ }
+
diff --git a/SOURCES/cups-error-policy-manpage.patch b/SOURCES/cups-error-policy-manpage.patch
new file mode 100644
index 0000000..c7528cf
--- /dev/null
+++ b/SOURCES/cups-error-policy-manpage.patch
@@ -0,0 +1,31 @@
+diff -up cups-1.6.3/man/cupsd.conf.man.in.error-policy-manpage cups-1.6.3/man/cupsd.conf.man.in
+--- cups-1.6.3/man/cupsd.conf.man.in.error-policy-manpage 2014-09-02 11:23:05.798957567 +0100
++++ cups-1.6.3/man/cupsd.conf.man.in 2014-09-02 11:24:35.813428214 +0100
+@@ -3,7 +3,7 @@
+ .\"
+ .\" cupsd.conf man page for CUPS.
+ .\"
+-.\" Copyright 2007-2013 by Apple Inc.
++.\" Copyright 2007-2014 by Apple Inc.
+ .\" Copyright 1997-2006 by Easy Software Products.
+ .\"
+ .\" These coded instructions, statements, and computer programs are the
+@@ -180,6 +180,18 @@ Encryption Required
+ Specifies the level of encryption that is required for a particular
+ location.
+ .TP 5
++ErrorPolicy abort-job
++Specifies that a failed print job should be aborted (discarded) unless otherwise specified for the printer.
++.TP 5
++ErrorPolicy retry-job
++Specifies that a failed print job should be retried at a later time unless otherwise specified for the printer.
++.TP 5
++ErrorPolicy retry-this-job
++Specifies that a failed print job should be retried immediately unless otherwise specified for the printer.
++.TP 5
++ErrorPolicy stop-printer
++Specifies that a failed print job should stop the printer unless otherwise specified for the printer. The 'stop-printer' error policy is the default.
++.TP 5
+ FilterLimit limit
+ .br
+ Specifies the maximum cost of filters that are run concurrently.
diff --git a/SOURCES/cups-failover-backend.patch b/SOURCES/cups-failover-backend.patch
new file mode 100644
index 0000000..acaf4b0
--- /dev/null
+++ b/SOURCES/cups-failover-backend.patch
@@ -0,0 +1,874 @@
+diff -up cups-1.6.3/backend/failover.c.failover-backend cups-1.6.3/backend/failover.c
+--- cups-1.6.3/backend/failover.c.failover-backend 2017-10-25 13:57:43.032337219 +0200
++++ cups-1.6.3/backend/failover.c 2017-10-25 16:15:31.746984025 +0200
+@@ -0,0 +1,837 @@
++/*
++ * Failover Backend for the Common UNIX Printing System (CUPS).
++ *
++ * Copyright (c) 2014, Red Hat, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * * Neither the name of Red Hat, Inc. nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT,
++ * INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ *
++ * Original version by Clark Hale, Red Hat, Inc.
++ *
++ * This backend presents a fake printer that will choose the first
++ * available printer from a list of IPP URIs.
++ *
++ * Option failover contains a comma separated list of IPP URIs. The
++ * URIs are attempted in-order.
++ *
++ * Option failover-retries contains an integer that indicates how many
++ * times to iterate through the failover list before completely
++ * failing.
++ *
++ * Contents:
++ * main() - Checks each printer in a failover list, and
++ * sends job data to the first available printer
++ * move_job() - Sends and IPP Move-Job request
++ * check_printer() - Checks a printer's attributes to see
++ * if it's enabled and accepting jobs
++ * read_config() - Read the backends configuration from
++ * options
++ * get_printer_attributes() - Sends an IPP Get-Attributes request to
++ * a URI
++ * sigterm_handler() - Handle SIGTERM that cancels the job
++ * password_cb() - Password call back used to disable password
++ * prompt
++ */
++#include
++#include
++#include
++#include
++#include
++#include
++#include "backend-private.h"
++
++/*
++ * Return Values
++ */
++typedef enum fo_state_e
++{
++ FO_PRINTER_GOOD = 0,
++ FO_PRINTER_BAD,
++ FO_PRINTER_BUSY,
++ FO_AUTH_REQUIRED
++} fo_state_t;
++
++/*
++ * Constants
++ */
++#define FAILOVER_DEFAULT_RETRIES (3)
++#define FAILOVER_PASSWORD_RETRIES_MAX (3)
++
++/*
++ * Local Functions
++ */
++static int check_printer(const char *device_uri);
++static int read_config(cups_array_t *printer_array, int *retries,
++ const char *options);
++static int get_printer_attributes(const char *device_uri,
++ ipp_t **attributes);
++static int move_job(int jobid, const char *dest);
++static void sigterm_handler(int sig);
++static const char *password_cb(const char *);
++
++/*
++ * Global Variables
++ */
++static int job_canceled = 0; /* Job canceled */
++static char *password = NULL; /* password for device */
++static int password_retries = 0;
++static const char *auth_info_required = "none";
++
++/*
++ * 'main()' - Checks each printer in a failover list, and
++ * sends job data to the first available printer
++ * Usage:
++ * printer-uri job-id user title copies options [file]
++ *
++ * The printer-uri option is not used, but it still required to fit
++ * to the backend(7) standards.
++ */
++int
++main(int argc, char *argv[])
++{
++ const char *selected_uri = NULL; /* URI of selected printer */
++ const char *tmp_device_uri; /* Device URI to check */
++ cups_array_t *printer_array; /* Array of available printers */
++ int printer_count = 0; /* current printer array index */
++ int retry_max = 1; /* maximum retries before exit */
++ int retry_count = 0; /* current retry number */
++ int auth_failed_count = 0; /* auth failures per loop */
++ int rc = CUPS_BACKEND_OK;
++#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
++ struct sigaction action; /* Actions for POSIX signals */
++#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
++
++ /*
++ * Check args
++ */
++ if (argc == 1)
++ {
++ /*
++ * print out discovery data
++ */
++ char *backendName;
++
++ if ((backendName = strrchr(argv[0], '/')) != NULL)
++ backendName++;
++ else
++ backendName = argv[0];
++
++ _cupsLangPrintf(stderr,"network %s \"Unknown\" \"%s (%s)\"\n",
++ backendName,
++ _cupsLangString(cupsLangDefault(), _("Failover Printer")),
++ backendName);
++
++ return (CUPS_BACKEND_OK);
++ }
++ else if (argc < 6)
++ {
++ _cupsLangPrintf(stderr,
++ _("Usage: %s job-id user title copies options [file]"),
++ argv[0]);
++ return (CUPS_BACKEND_STOP);
++ }
++
++ fprintf(stderr, "DEBUG: Failover backend starting up.\n");
++
++ /*
++ * Don't buffer status messages
++ */
++ setbuf(stderr, NULL);
++
++ /*
++ * Ignore SIGPIPE and catch SIGTERM signals...
++ */
++#ifdef HAVE_SIGSET
++ sigset(SIGPIPE, SIG_IGN);
++ sigset(SIGTERM, sigterm_handler);
++#elif defined(HAVE_SIGACTION)
++ memset(&action, 0, sizeof(action));
++ action.sa_handler = SIG_IGN;
++ sigaction(SIGPIPE, &action, NULL);
++
++ sigemptyset(&action.sa_mask);
++ sigaddset(&action.sa_mask, SIGTERM);
++ action.sa_handler = sigterm_handler;
++ sigaction(SIGTERM, &action, NULL);
++#else
++ signal(SIGPIPE, SIG_IGN);
++ signal(SIGTERM, sigterm_handler);
++#endif /* HAVE_SIGSET */
++
++ printer_array = cupsArrayNew(NULL, NULL);
++
++ /*
++ * Read Configuration
++ */
++ if ((rc = read_config(printer_array, &retry_max,
++ argv[5])) != CUPS_BACKEND_OK)
++ {
++ fprintf(stderr, "ERROR: Failed to read configuration options!\n");
++ goto cleanup;
++ }
++
++ /*
++ * Main Retry Loop
++ */
++ for (retry_count = 0; retry_count < retry_max; retry_count++)
++ {
++ fprintf(stderr, "DEBUG: Retry loop #%d\n", retry_count + 1);
++
++ /*
++ * Reset Counters
++ */
++ printer_count = 0;
++ auth_failed_count = 0;
++
++ tmp_device_uri = (char *)cupsArrayFirst(printer_array);
++
++ do
++ {
++ if (job_canceled)
++ {
++ fprintf(stderr, "DEBUG: Job Canceled\n");
++ goto cleanup;
++ }
++
++ fprintf(stderr,"DEBUG: Checking printer #%d: %s\n",
++ printer_count+1, tmp_device_uri);
++
++ rc = check_printer(tmp_device_uri);
++
++ // Printer is available and not busy.
++ if ( rc == FO_PRINTER_GOOD )
++ {
++ selected_uri = tmp_device_uri;
++ break;
++ }
++ // Printer is busy
++ else if ( rc == FO_PRINTER_BUSY )
++ {
++ fprintf(stderr, "DEBUG: Waiting for job to complete.\n");
++ sleep(2);
++ continue;
++ }
++ // Authorization is required to access the printer.
++ else if (rc == FO_AUTH_REQUIRED)
++ {
++ auth_failed_count++;
++ fprintf(stderr, "DEBUG: auth_failed_count = %d\n", auth_failed_count);
++ }
++ // Printer is stopped or not accepting jobs
++ else
++ {
++ if (!printer_count)
++ fprintf(stderr, "INFO: Primary Printer, %s, not available. "
++ "Attempting Failovers...\n",
++ tmp_device_uri);
++ else
++ fprintf(stderr, "INFO: Failover Printer, %s, not available. "
++ "Attempting Failovers..\n",
++ tmp_device_uri);
++ printer_count++;
++ tmp_device_uri = (char *)cupsArrayNext(printer_array);
++ }
++ } while (tmp_device_uri != NULL);
++
++ if (selected_uri && !printer_count)
++ fprintf(stderr, "STATE: -primary-printer-failed\n");
++ else
++ fprintf(stderr, "STATE: +primary-printer-failed\n");
++
++ if (job_canceled)
++ {
++ fprintf(stderr, "DEBUG: Job Canceled\n");
++ goto cleanup;
++ }
++
++ if (!selected_uri && auth_failed_count == printer_count)
++ {
++ fprintf(stderr, "ERROR: All failover printers failed with "
++ "authorization issues.\n");
++ rc = CUPS_BACKEND_AUTH_REQUIRED;
++ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required);
++ goto cleanup;
++ }
++ else if (!selected_uri && retry_count + 1 < retry_max)
++ {
++ fprintf(stderr, "INFO: No suitable printer found...retrying...\n");
++ sleep(2);
++ continue;
++ }
++ else if (selected_uri)
++ {
++ fprintf(stderr, "DEBUG: Using printer, %s.\n", selected_uri);
++ break;
++ }
++ }
++
++ if (!selected_uri)
++ {
++ fprintf(stderr, "ERROR: No suitable printer found. Aborting print\n");
++ rc = CUPS_BACKEND_FAILED;
++ goto cleanup;
++ }
++
++ rc = move_job(atoi(argv[1]), selected_uri);
++
++ if (job_canceled)
++ rc = CUPS_BACKEND_OK;
++
++cleanup :
++ if (job_canceled)
++ rc = CUPS_BACKEND_OK;
++
++ tmp_device_uri = (char *)cupsArrayFirst(printer_array);
++ do
++ {
++ free((void *)tmp_device_uri);
++ } while ((tmp_device_uri = (char *)cupsArrayNext(printer_array)) != NULL);
++
++ cupsArrayDelete(printer_array);
++ sleep(2);
++ return (rc);
++}
++
++/*
++ * 'check_printer()' - Checks the status of a remote printer and returns
++ * back a good/bad/busy status.
++ */
++int
++check_printer(const char *device_uri)
++{
++ ipp_t *attributes = NULL; /* attributes for device_uri */
++ ipp_attribute_t *tmp_attribute; /* for examining attribs */
++ int rc = FO_PRINTER_GOOD; /* return code */
++ char *reason; /* printer state reason */
++ int i;
++
++ fprintf(stderr, "DEBUG: Checking printer %s\n",device_uri);
++
++ rc = get_printer_attributes(device_uri, &attributes);
++ if ( rc != CUPS_BACKEND_OK )
++ {
++ fprintf(stderr, "DEBUG: Failed to get attributes from printer: %s\n",
++ device_uri);
++ if ( rc == CUPS_BACKEND_AUTH_REQUIRED )
++ return (FO_AUTH_REQUIRED);
++ else
++ return (FO_PRINTER_BAD);
++ }
++
++ /*
++ * Check if printer is accepting jobs
++ */
++ if ((tmp_attribute = ippFindAttribute(attributes,
++ "printer-is-accepting-jobs",
++ IPP_TAG_BOOLEAN)) != NULL &&
++ !tmp_attribute->values[0].boolean)
++ {
++ fprintf(stderr,
++ "DEBUG: Printer, %s, is not accepting jobs.\n",
++ device_uri);
++
++ rc = FO_PRINTER_BAD;
++ }
++
++ /*
++ * Check if printer is stopped or busy processing
++ */
++ if ((tmp_attribute = ippFindAttribute(attributes,
++ "printer-state",
++ IPP_TAG_ENUM)) != NULL)
++ {
++ // Printer Stopped
++ if ( tmp_attribute->values[0].integer == IPP_PRINTER_STOPPED )
++ {
++ fprintf(stderr, "DEBUG: Printer, %s, stopped.\n", device_uri);
++ rc = FO_PRINTER_BAD;
++ }
++ // Printer Busy
++ else if ( tmp_attribute->values[0].integer == IPP_PRINTER_PROCESSING )
++ {
++ fprintf(stderr, "DEBUG: Printer %s is busy.\n", device_uri);
++ rc = FO_PRINTER_BUSY;
++ }
++ }
++
++ /*
++ * Parse through the printer-state-reasons
++ */
++ if ((tmp_attribute = ippFindAttribute(attributes, "printer-state-reasons",
++ IPP_TAG_KEYWORD)) != NULL)
++ {
++ for (i = 0; i < tmp_attribute->num_values; i++)
++ {
++ reason = tmp_attribute->values[i].string.text;
++ int len = strlen(reason);
++
++ if (len > 8 && !strcmp(reason + len - 8, "-warning"))
++ {
++ fprintf(stderr, "DEBUG: Printer Supply Warning, %s\n", reason);
++ rc = FO_PRINTER_BAD;
++ }
++ else if (len > 6 && !strcmp(reason + len - 6, "-error"))
++ {
++ fprintf(stderr, "DEBUG: Printer Supply Error, %s\n", reason);
++ rc = FO_PRINTER_BAD;
++ }
++ }
++ }
++
++ return (rc);
++}
++
++/*
++ * 'read_config()' - Parses the failover and failover-retries options
++ *
++ */
++static int
++read_config(cups_array_t *printer_array, int *retries, const char *options)
++{
++
++ const char *tmp; /* temporary ptr */
++ char *tok_tmp; /* temporary ptr for option parsing */
++ int jobopts_count = 0; /* number of options */
++ cups_option_t *jobopts = NULL; /* job options */
++
++
++ fprintf(stderr, "DEBUG: Reading Configuration.\n");
++ jobopts_count = cupsParseOptions(options, 0, &jobopts);
++
++ if (!jobopts_count)
++ {
++ fprintf(stderr,
++ "ERROR: No job options! Cannot find failover options!\n");
++ return (CUPS_BACKEND_STOP);
++ }
++
++ /*
++ * Get attributes from the primary printer
++ */
++ fprintf(stderr, "DEBUG: Searching for failover option.\n");
++
++ if ((tmp = cupsGetOption("failover", jobopts_count, jobopts)) != NULL)
++ {
++ fprintf(stderr, "DEBUG: Failover option contents: %s.\n", tmp);
++
++ tok_tmp = strdup(tmp);
++
++ tmp = strtok(tok_tmp, ",");
++ do
++ {
++ cupsArrayAdd(printer_array, strdup(tmp));
++ } while ((tmp = strtok(NULL,",")) != NULL);
++
++ free(tok_tmp);
++ }
++ else
++ {
++ /*
++ * The queue is misconfigured, so return back CUPS_BACKEND_STOP
++ */
++ fprintf(stderr, "ERROR: failover option not specified!\n");
++ return (CUPS_BACKEND_STOP);
++ }
++
++ /*
++ * Get the failover-retries value, if it exists.
++ */
++ fprintf(stderr, "DEBUG: Searching for failover-retries option.\n");
++
++ if ((tmp = cupsGetOption("failover-retries",
++ jobopts_count, jobopts)) != NULL)
++ {
++ fprintf(stderr, "DEBUG: failover-retries option contents: %s.\n", tmp);
++ *retries = atoi(tmp);
++ }
++ else
++ {
++ *retries = FAILOVER_DEFAULT_RETRIES;
++ fprintf(stderr, "DEBUG: Failed to get failover-retries option\n");
++ fprintf(stderr, "DEBUG: Defaulted to %d retries\n", *retries);
++ }
++
++ return (CUPS_BACKEND_OK);
++}
++
++/*
++ * 'get_printer_attributes()' - Sends an IPP Get-Attributes request to
++ * a URI
++ */
++int
++get_printer_attributes(const char *device_uri, ipp_t **attributes)
++{
++ char uri[HTTP_MAX_URI]; /* Updated URI without login */
++ int version; /* IPP version */
++ char scheme[256]; /* Scheme in URI */
++ ipp_status_t ipp_status; /* Status of IPP request */
++ char hostname[1024]; /* Hostname */
++ char resource[1024]; /* Resource infoo */
++ char addrname[256]; /* Address name */
++ int port; /* IPP Port number */
++ char portname[255]; /* Port as string */
++ http_t *http; /* HTTP connection */
++ ipp_t *request; /* IPP request */
++ int rc = CUPS_BACKEND_OK; /* Return Code */
++ char username[256]; /* Username for device URI */
++ char *option_ptr; /* for parsing resource opts */
++ const char * const pattrs[] = /* Printer attributes wanted */
++ {
++ "printer-is-accepting-jobs",
++ "printer-state",
++ "printer-state-reasons"
++ };
++
++ if (job_canceled)
++ return (CUPS_BACKEND_OK);
++
++ fprintf(stderr, "DEBUG: Getting Printer Attributes.\n");
++ fprintf(stderr, "DEBUG: Device URL %s.\n", device_uri);
++
++ /*
++ * Parse device_uri
++ */
++ if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme),
++ username, sizeof(username), hostname, sizeof(hostname),
++ &port, resource, sizeof(resource)) != HTTP_URI_OK)
++ {
++ fprintf(stderr, "ERROR: Problem parsing device_uri, %s\n", device_uri);
++ return (CUPS_BACKEND_STOP);
++ }
++
++ if (!port)
++ port = IPP_PORT;
++
++ sprintf(portname, "%d", port);
++
++ fprintf(stderr, "DEBUG: Getting Printer Attributes.\n");
++
++ /*
++ * Configure password
++ */
++ cupsSetPasswordCB(password_cb);
++
++ /*
++ * reset, in case a previous attempt for
++ * another printer left residue
++ */
++ cupsSetUser(NULL);
++ password = NULL;
++ password_retries = 0;
++
++ if (*username)
++ {
++ if ((password = strchr(username, ':')) != NULL)
++ {
++ *password = '\0';
++ password++;
++ }
++
++ cupsSetUser(username);
++ }
++ else if (!getuid())
++ {
++ const char *username_env;
++
++ if ((username_env = getenv("AUTH_USERNAME")) != NULL)
++ {
++ cupsSetUser(username_env);
++ password = getenv("AUTH_PASSWORD");
++ }
++ }
++
++ /*
++ * Try connecting to the remote server...
++ */
++ fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port);
++ _cupsLangPuts(stderr, _("INFO: Connecting to printer...\n"));
++
++ http = httpConnectEncrypt(hostname, port, cupsEncryption());
++
++ /*
++ * Deal the socket not being open.
++ */
++ if (!http)
++ {
++ int error = errno; /* Connection error */
++
++ switch (error)
++ {
++ case EHOSTDOWN :
++ _cupsLangPuts(stderr, _("WARNING: "
++ "The printer may not exist or "
++ "is unavailable at this time.\n"));
++ break;
++ case EHOSTUNREACH :
++ _cupsLangPuts(stderr, _("WARNING: "
++ "The printer is unreachable at this "
++ "time.\n"));
++ break;
++ case ECONNREFUSED :
++ _cupsLangPuts(stderr, _("WARNING: "
++ "Connection Refused.\n"));
++ break;
++ default :
++ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
++ break;
++ }
++
++ rc = CUPS_BACKEND_FAILED;
++ sleep(5);
++ goto prt_available_cleanup;
++ }
++
++
++#ifdef AF_INET6
++ if (http->hostaddr->addr.sa_family == AF_INET6)
++ fprintf(stderr, "DEBUG: Connected to [%s]:%d (IPv6)...\n",
++ httpAddrString(http->hostaddr, addrname, sizeof(addrname)),
++ ntohs(http->hostaddr->ipv6.sin6_port));
++ else
++#endif /* AF_INET6 */
++ if (http->hostaddr->addr.sa_family == AF_INET)
++ fprintf(stderr, "DEBUG: Connected to %s:%d (IPv4)...\n",
++ httpAddrString(http->hostaddr, addrname, sizeof(addrname)),
++ ntohs(http->hostaddr->ipv4.sin_port));
++
++ /*
++ * Search the resource string for options.
++ * We only care about version, for the moment.
++ */
++ version = 11;
++
++ if ((option_ptr = strchr(resource, '?')) != NULL)
++ {
++ *option_ptr++ = '\0';
++
++ if ((option_ptr = strstr(option_ptr, "version="))!=NULL)
++ {
++ int minor; /* minor version from URI */
++ int major; /* major version from URI */
++ char *version_str; /* ipp version */
++
++ option_ptr += 8;
++ version_str = option_ptr;
++
++ while (*option_ptr && *option_ptr != '&' && *option_ptr != '+')
++ option_ptr++;
++
++ if (*option_ptr)
++ *option_ptr = '\0';
++
++ sscanf(version_str, "%d.%d", &major, &minor);
++
++ version = (major * 10) + minor;
++
++ switch(version)
++ {
++ case 10 :
++ case 11 :
++ case 20 :
++ case 21 :
++ fprintf(stderr,
++ "DEBUG: Set version to %d from URI\n",
++ version);
++ break;
++ default :
++ _cupsLangPrintf(stderr,
++ _("DEBUG: Invalid version, %d, from URI. "
++ "Using default of 1.1 \n"),
++ version);
++ version = 11;
++ }
++ }
++ }
++
++
++ /*
++ * Build a URI for the printer. We can't use the URI in argv[0]
++ * because it might contain username:password information...
++ */
++ if (httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, NULL,
++ hostname, port, resource) != HTTP_URI_OK)
++ {
++ fprintf(stderr, "ERROR: Problem assembling printer URI from host %s, "
++ "port %d, resource %s\n", hostname, port, resource);
++ return (CUPS_BACKEND_STOP);
++ }
++
++ /*
++ * Build the IPP request...
++ */
++ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
++ request->request.op.version[0] = version / 10;
++ request->request.op.version[1] = version % 10;
++
++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
++ NULL, uri);
++
++ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
++ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
++ NULL, pattrs);
++
++ /*
++ * Do the request...
++ */
++ fputs("DEBUG: Getting supported attributes...\n", stderr);
++
++ fprintf(stderr, "DEBUG: IPP Request Structure Built.\n");
++
++ *attributes = cupsDoRequest(http, request, resource);
++ ipp_status = cupsLastError();
++
++ fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n",
++ ippErrorString(ipp_status), cupsLastErrorString());
++
++ if (ipp_status > IPP_OK_CONFLICT)
++ {
++ fprintf(stderr, "DEBUG: Get-Printer-Attributes returned %s.\n",
++ ippErrorString(ipp_status));
++ switch(ipp_status)
++ {
++ case IPP_FORBIDDEN :
++ case IPP_NOT_AUTHORIZED :
++ _cupsLangPuts(stderr, _("ERROR: Not Authorized.\n"));
++ rc = CUPS_BACKEND_AUTH_REQUIRED;
++ break;
++ case IPP_PRINTER_BUSY :
++ case IPP_SERVICE_UNAVAILABLE :
++ _cupsLangPuts(stderr, _("ERROR: "
++ "The printer is not responding.\n"));
++ rc = CUPS_BACKEND_FAILED;
++ break;
++ case IPP_BAD_REQUEST :
++ case IPP_VERSION_NOT_SUPPORTED :
++ fprintf(stderr, "ERROR: Destination does not support IPP version %d\n",
++ version);
++ case IPP_NOT_FOUND :
++ _cupsLangPuts(stderr, _("ERROR: "
++ "The printer configuration is incorrect or the "
++ "printer no longer exists.\n"));
++ rc = CUPS_BACKEND_STOP;
++ break;
++ default :
++ rc = CUPS_BACKEND_FAILED;
++ }
++ goto prt_available_cleanup;
++ }
++
++prt_available_cleanup :
++ httpClose(http);
++ return (rc);
++}
++
++static int
++move_job(int jobid, /* Job ID */
++ const char *dest) /* Destination ipp address */
++{
++ ipp_t *request; /* IPP Request */
++ char job_uri[HTTP_MAX_URI]; /* job-uri */
++
++ http_t* http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
++
++ if (!http)
++ {
++ _cupsLangPrintf(stderr,
++ _("failover: Unable to connect to server: %s\n"),
++ strerror(errno));
++ return (CUPS_BACKEND_FAILED);
++ }
++
++ /*
++ * Build a CUPS_MOVE_JOB request, which requires the following
++ * attributes:
++ *
++ * job-uri/printer-uri
++ * job-printer-uri
++ * requesting-user-name
++ */
++
++ request = ippNewRequest(CUPS_MOVE_JOB);
++
++ snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid);
++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
++ job_uri);
++
++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
++ "requesting-user-name",
++ NULL, cupsUser());
++
++ ippAddString(request, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri",
++ NULL, dest);
++
++ /*
++ * Do the request and get back a response...
++ */
++
++ ippDelete(cupsDoRequest(http, request, "/jobs"));
++
++ httpClose(http);
++
++ if (cupsLastError() > IPP_OK_CONFLICT)
++ {
++ _cupsLangPrintf(stderr, "failover: %s\n", cupsLastErrorString());
++ return (CUPS_BACKEND_FAILED);
++ }
++ else
++ return (CUPS_BACKEND_OK);
++}
++
++/*
++ * 'sigterm_handler()' - handles a sigterm, i.e. job canceled
++ */
++static void
++sigterm_handler(int sig)
++{
++ if (!job_canceled)
++ {
++ write(2, "DEBUG: Got SIGTERM.\n", 20);
++ job_canceled = 1;
++ }
++ else
++ {
++ /*
++ * Job has already been canceled, so just exit
++ */
++ exit(1);
++ }
++}
++
++/*
++ * 'password_cb()' - Disable the password prompt for cupsDoFileRequest().
++ */
++static const char * /* O - Password */
++password_cb(const char *prompt) /* I - Prompt (not used) */
++{
++ auth_info_required = "username,password";
++ password_retries++;
++
++ if(password_retries < FAILOVER_PASSWORD_RETRIES_MAX)
++ return (password);
++ else
++ return (NULL);
++}
+diff -up cups-1.6.3/backend/Makefile.failover-backend cups-1.6.3/backend/Makefile
+--- cups-1.6.3/backend/Makefile.failover-backend 2017-10-25 13:57:42.940337847 +0200
++++ cups-1.6.3/backend/Makefile 2017-10-25 13:57:43.032337219 +0200
+@@ -30,6 +30,7 @@ include ../Makedefs
+ RBACKENDS = \
+ ipp \
+ lpd \
++ failover \
+ $(DNSSD_BACKEND)
+ UBACKENDS = \
+ snmp \
+@@ -51,6 +52,7 @@ LIBOBJS = \
+ OBJS = \
+ ipp.o \
+ lpd.o \
++ failover.o \
+ dnssd.o \
+ snmp.o \
+ socket.o \
+@@ -257,6 +259,13 @@ lpd: lpd.o ../cups/$(LIBCUPS) libbackend
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpd lpd.o libbackend.a $(LIBS)
+
++#
++# failover
++#
++
++failover: failover.o ../cups/$(LIBCUPS) libbackend.a
++ echo Linking $@...
++ $(CC) $(LDFLAGS) -o failover failover.o libbackend.a $(LIBS) $(CUPSDLIBS)
+
+ #
+ # snmp
diff --git a/SOURCES/cups-filter-debug.patch b/SOURCES/cups-filter-debug.patch
new file mode 100644
index 0000000..96c82da
--- /dev/null
+++ b/SOURCES/cups-filter-debug.patch
@@ -0,0 +1,32 @@
+diff -up cups-1.6b1/scheduler/job.c.filter-debug cups-1.6b1/scheduler/job.c
+--- cups-1.6b1/scheduler/job.c.filter-debug 2012-05-25 16:06:01.000000000 +0200
++++ cups-1.6b1/scheduler/job.c 2012-05-25 16:07:46.309259511 +0200
+@@ -625,10 +625,28 @@ cupsdContinueJob(cupsd_job_t *job) /* I
+
+ if (!filters)
+ {
++ mime_filter_t *current;
++
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Unable to convert file %d to printable format.",
+ job->current_file);
+
++ cupsdLogJob(job, CUPSD_LOG_ERROR,
++ "Required: %s/%s -> %s/%s",
++ job->filetypes[job->current_file]->super,
++ job->filetypes[job->current_file]->type,
++ job->printer->filetype->super,
++ job->printer->filetype->type);
++
++ for (current = (mime_filter_t *)cupsArrayFirst(MimeDatabase->srcs);
++ current;
++ current = (mime_filter_t *)cupsArrayNext(MimeDatabase->srcs))
++ cupsdLogJob(job, CUPSD_LOG_ERROR,
++ "Available: %s/%s -> %s/%s (%s)",
++ current->src->super, current->src->type,
++ current->dst->super, current->dst->type,
++ current->filter);
++
+ abort_message = "Aborting job because it cannot be printed.";
+ abort_state = IPP_JOB_ABORTED;
+
diff --git a/SOURCES/cups-full-relro.patch b/SOURCES/cups-full-relro.patch
new file mode 100644
index 0000000..5216973
--- /dev/null
+++ b/SOURCES/cups-full-relro.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.6.3/config-scripts/cups-compiler.m4.full-relro cups-1.6.3/config-scripts/cups-compiler.m4
+--- cups-1.6.3/config-scripts/cups-compiler.m4.full-relro 2013-08-15 12:40:51.965747766 +0100
++++ cups-1.6.3/config-scripts/cups-compiler.m4 2013-08-15 12:42:15.083630332 +0100
+@@ -171,7 +171,7 @@ if test -n "$GCC"; then
+ # The -z relro option is provided by the Linux linker command to
+ # make relocatable data read-only.
+ if test x$enable_relro = xyes; then
+- RELROFLAGS="-Wl,-z,relro"
++ RELROFLAGS="-Wl,-z,relro,-z,now"
+ fi
+ ;;
+ esac
diff --git a/SOURCES/cups-gz-crc.patch b/SOURCES/cups-gz-crc.patch
new file mode 100644
index 0000000..699e5e4
--- /dev/null
+++ b/SOURCES/cups-gz-crc.patch
@@ -0,0 +1,14 @@
+diff -up cups-1.6.2/cups/file.c.gz-crc cups-1.6.2/cups/file.c
+--- cups-1.6.2/cups/file.c.gz-crc 2013-07-11 12:06:49.920878639 +0100
++++ cups-1.6.2/cups/file.c 2013-07-11 12:13:41.169628104 +0100
+@@ -2429,8 +2429,8 @@ cups_fill(cups_file_t *fp) /* I - CUPS
+ }
+ else
+ {
+- tcrc = (((((trailer[3] << 8) | trailer[2]) << 8) | trailer[1]) << 8) |
+- trailer[0];
++ tcrc = (((uLong) ((trailer[3] << 8) | trailer[2])) << 16) |
++ (uLong) ((trailer[1] << 8) | trailer[0]);
+
+ if (tcrc != fp->crc)
+ {
diff --git a/SOURCES/cups-hp-deviceid-oid.patch b/SOURCES/cups-hp-deviceid-oid.patch
new file mode 100644
index 0000000..da5136a
--- /dev/null
+++ b/SOURCES/cups-hp-deviceid-oid.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.5b1/backend/snmp.c.hp-deviceid-oid cups-1.5b1/backend/snmp.c
+--- cups-1.5b1/backend/snmp.c.hp-deviceid-oid 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/backend/snmp.c 2011-05-24 17:24:48.000000000 +0200
+@@ -187,6 +187,7 @@ static const int UriOID[] = { CUPS_OID_p
+ static const int LexmarkProductOID[] = { 1,3,6,1,4,1,641,2,1,2,1,2,1,-1 };
+ static const int LexmarkProductOID2[] = { 1,3,6,1,4,1,674,10898,100,2,1,2,1,2,1,-1 };
+ static const int LexmarkDeviceIdOID[] = { 1,3,6,1,4,1,641,2,1,2,1,3,1,-1 };
++static const int HPDeviceIdOID[] = { 1,3,6,1,4,1,11,2,3,9,1,1,7,0,-1 };
+ static const int XeroxProductOID[] = { 1,3,6,1,4,1,128,2,1,3,1,2,0,-1 };
+ static cups_array_t *DeviceURIs = NULL;
+ static int HostNameLookups = 0;
+@@ -1006,6 +1007,9 @@ read_snmp_response(int fd) /* I - SNMP
+ _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+ packet.community, CUPS_ASN1_GET_REQUEST,
+ DEVICE_PRODUCT, XeroxProductOID);
++ _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
++ packet.community, CUPS_ASN1_GET_REQUEST,
++ DEVICE_ID, HPDeviceIdOID);
+ break;
+
+ case DEVICE_DESCRIPTION :
diff --git a/SOURCES/cups-ipp-multifile.patch b/SOURCES/cups-ipp-multifile.patch
new file mode 100644
index 0000000..087a556
--- /dev/null
+++ b/SOURCES/cups-ipp-multifile.patch
@@ -0,0 +1,20 @@
+diff -up cups-1.6.3/backend/ipp.c.ipp-multifile cups-1.6.3/backend/ipp.c
+--- cups-1.6.3/backend/ipp.c.ipp-multifile 2013-08-06 17:17:19.359471503 +0100
++++ cups-1.6.3/backend/ipp.c 2013-08-06 17:19:03.346990727 +0100
+@@ -1682,10 +1682,13 @@ main(int argc, /* I - Number of comm
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, argv[2]);
+
+- if ((i + 1) >= num_files)
+- ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
++ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document",
++ (i + 1) >= num_files);
+
+- if (document_format)
++ if (num_files > 1)
++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
++ "document-format", NULL, "application/octet-stream");
++ else if (document_format)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
+ "document-format", NULL, document_format);
+
diff --git a/SOURCES/cups-logrotate.patch b/SOURCES/cups-logrotate.patch
new file mode 100644
index 0000000..a6485a9
--- /dev/null
+++ b/SOURCES/cups-logrotate.patch
@@ -0,0 +1,63 @@
+diff -up cups-1.5b1/scheduler/log.c.logrotate cups-1.5b1/scheduler/log.c
+--- cups-1.5b1/scheduler/log.c.logrotate 2011-05-14 01:04:16.000000000 +0200
++++ cups-1.5b1/scheduler/log.c 2011-05-24 15:47:20.000000000 +0200
+@@ -32,6 +32,9 @@
+ #include "cupsd.h"
+ #include
+ #include
++#include
++#include
++#include
+
+
+ /*
+@@ -71,12 +74,10 @@ cupsdCheckLogFile(cups_file_t **lf, /* I
+ return (1);
+
+ /*
+- * Format the filename as needed...
++ * Format the filename...
+ */
+
+- if (!*lf ||
+- (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize &&
+- MaxLogSize > 0))
++ if (strncmp(logname, "/dev/", 5))
+ {
+ /*
+ * Handle format strings...
+@@ -186,6 +187,34 @@ cupsdCheckLogFile(cups_file_t **lf, /* I
+ }
+
+ /*
++ * Has someone else (i.e. logrotate) already rotated the log for us?
++ */
++ else if (strncmp(filename, "/dev/", 5))
++ {
++ struct stat st;
++ if (stat(filename, &st) || st.st_size == 0)
++ {
++ /* File is either missing or has zero size. */
++
++ cupsFileClose(*lf);
++ if ((*lf = cupsFileOpen(filename, "a")) == NULL)
++ {
++ syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
++ strerror(errno));
++
++ return (0);
++ }
++
++ /*
++ * Change ownership and permissions of non-device logs...
++ */
++
++ fchown(cupsFileNumber(*lf), RunUser, Group);
++ fchmod(cupsFileNumber(*lf), LogFilePerm);
++ }
++ }
++
++ /*
+ * Do we need to rotate the log?
+ */
+
diff --git a/SOURCES/cups-lpd-manpage.patch b/SOURCES/cups-lpd-manpage.patch
new file mode 100644
index 0000000..9a71cc3
--- /dev/null
+++ b/SOURCES/cups-lpd-manpage.patch
@@ -0,0 +1,77 @@
+diff -up cups-1.6.3/man/cups-lpd.man.in.lpd-manpage cups-1.6.3/man/cups-lpd.man.in
+--- cups-1.6.3/man/cups-lpd.man.in.lpd-manpage 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/man/cups-lpd.man.in 2015-10-29 13:37:20.650824688 +0100
+@@ -26,39 +26,8 @@ cups-lpd \- receive print jobs and repor
+ \fIcups-lpd\fR is the CUPS Line Printer Daemon ("LPD")
+ mini-server that supports legacy client systems that use the LPD
+ protocol. \fIcups-lpd\fR does not act as a standalone network
+-daemon but instead operates using the Internet "super-server"
+-\fIinetd(8)\fR or \fIxinetd(8)\fR. If you are using \fIinetd\fR,
+-add the following line to the \fIinetd.conf\fR file to enable the
+-\fIcups-lpd\fR mini-server:
+-.br
+-.nf
+-
+- printer stream tcp nowait lp @CUPS_SERVERBIN@/daemon/cups-lpd cups-lpd \\
+- -o document-format=application/octet-stream
+-.fi
+-.LP
+-.LP
+-\fBNote:\fR If you are using Solaris 10 or higher, you must run
+-the \fIinetdconv(1m)\fR program to register the changes to the
+-inetd.conf file.
+-.LP
+-If you are using the newer \fIxinetd(8)\fR daemon, create a file
+-named \fI/etc/xinetd.d/cups\fR containing the following lines:
+-.br
+-.nf
+-
+- service printer
+- {
+- socket_type = stream
+- protocol = tcp
+- wait = no
+- user = lp
+- group = sys
+- passenv =
+- server = @CUPS_SERVERBIN@/daemon/cups-lpd
+- server_args = -o document-format=application/octet-stream
+- }
+-.fi
++daemon but instead operates as a socket-activatable \fIsystemd(1)\fR
++service.
+ .SH OPTIONS
+ .TP 5
+ -h hostname[:port]
+@@ -93,8 +62,7 @@ wrappers. Therefore, running \fIcups-lpd
+ allow any computer on your network (and perhaps the entire
+ Internet) to print to your server.
+ .LP
+-While \fIxinetd\fR has built-in access control support, you
+-should use the TCP wrappers package with \fIinetd\fR to limit
++You should use configure the firewall to limit TCP port 515
+ access to only those computers that should be able to print
+ through your server.
+ .LP
+@@ -112,10 +80,18 @@ The output of the status requests follow
+ between LPD and IPP Protocols. Since many LPD implementations
+ stray from this definition, remote status reporting to LPD
+ clients may be unreliable.
++.SH EXAMPLE
++CUPS includes configuration files for
++.BR systemd (8).
++Simply enable the
++.B cups-lpd
++socket using the corresponding control program.
++.nf
++ systemctl enable cups-lpd.socket
++ systemctl start cups-lpd.socket
++.fi
+ .SH SEE ALSO
+-\fIcups(1)\fR, \fIcupsd(8)\fR, \fIinetconv(1m)\fR,
+-\fIinetd(8)\fR, \fIxinetd(8)\fR,
+-.br
++\fIcups(1)\fR, \fIcupsd(8)\fR, \fIsystemd(1)\fR,
+ http://localhost:631/help
+ .SH COPYRIGHT
+ Copyright 2007-2013 by Apple Inc.
diff --git a/SOURCES/cups-lpd.socket b/SOURCES/cups-lpd.socket
new file mode 100644
index 0000000..b098052
--- /dev/null
+++ b/SOURCES/cups-lpd.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=CUPS-LPD Server Socket
+
+[Socket]
+ListenStream=515
+Accept=yes
+
+[Install]
+WantedBy=sockets.target
diff --git a/SOURCES/cups-lpd@.service b/SOURCES/cups-lpd@.service
new file mode 100644
index 0000000..23b59c1
--- /dev/null
+++ b/SOURCES/cups-lpd@.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Allow legacy LPD clients to communicate with CUPS
+Documentation=man:cups-lpd(8)
+
+[Service]
+ExecStart=-/usr/lib/cups/daemon/cups-lpd
+StandardInput=socket
+User=lp
diff --git a/SOURCES/cups-lpr-help.patch b/SOURCES/cups-lpr-help.patch
new file mode 100644
index 0000000..c42434d
--- /dev/null
+++ b/SOURCES/cups-lpr-help.patch
@@ -0,0 +1,48 @@
+diff -up cups-1.5b1/berkeley/lpr.c.lpr-help cups-1.5b1/berkeley/lpr.c
+--- cups-1.5b1/berkeley/lpr.c.lpr-help 2011-03-21 23:02:00.000000000 +0100
++++ cups-1.5b1/berkeley/lpr.c 2011-05-23 17:58:06.000000000 +0200
+@@ -24,6 +24,31 @@
+ #include
+
+
++static void
++usage (const char *name)
++{
++ _cupsLangPrintf(stdout,
++"Usage: %s [OPTION] [ file(s) ]\n"
++"Print files.\n\n"
++" -E force encryption\n"
++" -H server[:port] specify alternate server\n"
++" -C title, -J title, -T title\n"
++" set the job name\n\n"
++" -P destination/instance print to named printer\n"
++" -U username specify alternate username\n"
++" -# num-copies set number of copies\n"
++" -h disable banner printing\n"
++" -l print without filtering\n"
++" -m send email on completion\n"
++" -o option[=value] set a job option\n"
++" -p format text file with header\n"
++" -q hold job for printing\n"
++" -r delete files after printing\n"
++"\nWith no file given, read standard input.\n"
++, name);
++}
++
++
+ /*
+ * 'main()' - Parse options and send files for printing.
+ */
+@@ -270,6 +294,12 @@ main(int argc, /* I - Number of comm
+ break;
+
+ default :
++ if (!strcmp (argv[i], "--help"))
++ {
++ usage (argv[0]);
++ return (0);
++ }
++
+ _cupsLangPrintf(stderr,
+ _("%s: Error - unknown option \"%c\"."), argv[0],
+ argv[i][1]);
diff --git a/SOURCES/cups-lspp.patch b/SOURCES/cups-lspp.patch
new file mode 100644
index 0000000..d30b965
--- /dev/null
+++ b/SOURCES/cups-lspp.patch
@@ -0,0 +1,2810 @@
+diff -up cups-1.6.3/config.h.in.lspp cups-1.6.3/config.h.in
+--- cups-1.6.3/config.h.in.lspp 2015-06-10 11:45:38.074441762 +0200
++++ cups-1.6.3/config.h.in 2015-06-10 11:45:38.158441533 +0200
+@@ -747,6 +747,13 @@ static __inline int _cups_abs(int i) { r
+ # endif /* __GNUC__ || __STDC_VERSION__ */
+ #endif /* !HAVE_ABS && !abs */
+
++/*
++ * Are we trying to meet LSPP requirements?
++ */
++
++#undef WITH_LSPP
++
++
+ #endif /* !_CUPS_CONFIG_H_ */
+
+ /*
+diff -up cups-1.6.3/config-scripts/cups-lspp.m4.lspp cups-1.6.3/config-scripts/cups-lspp.m4
+--- cups-1.6.3/config-scripts/cups-lspp.m4.lspp 2015-06-10 11:45:38.157441536 +0200
++++ cups-1.6.3/config-scripts/cups-lspp.m4 2015-06-10 11:45:38.157441536 +0200
+@@ -0,0 +1,36 @@
++dnl
++dnl LSPP code for the Common UNIX Printing System (CUPS).
++dnl
++dnl Copyright 2005-2006 by Hewlett-Packard Development Company, L.P.
++dnl
++dnl This program is free software; you can redistribute it and/or modify
++dnl it under the terms of the GNU General Public License as published by
++dnl the Free Software Foundation; version 2.
++dnl
++dnl This program is distributed in the hope that it will be useful, but
++dnl WITHOUT ANY WARRANTY; without even the implied warranty of
++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++dnl General Public License for more details.
++dnl
++dnl You should have received a copy of the GNU General Public License
++dnl along with this program; if not, write to the Free Software Foundation,
++dnl Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA
++dnl
++
++dnl Are we trying to meet LSPP requirements
++AC_ARG_ENABLE(lspp, [ --enable-lspp turn on auditing and label support, default=no])
++
++if test x"$enable_lspp" != xno; then
++ case "$uname" in
++ Linux)
++ AC_CHECK_LIB(audit,audit_log_user_message, [LIBAUDIT="-laudit" AC_SUBST(LIBAUDIT)])
++ AC_CHECK_HEADER(libaudit.h)
++ AC_CHECK_LIB(selinux,getpeercon, [LIBSELINUX="-lselinux" AC_SUBST(LIBSELINUX)])
++ AC_CHECK_HEADER(selinux/selinux.h)
++ AC_DEFINE(WITH_LSPP)
++ ;;
++ *)
++ # All others
++ ;;
++ esac
++fi
+diff -up cups-1.6.3/configure.in.lspp cups-1.6.3/configure.in
+--- cups-1.6.3/configure.in.lspp 2015-06-10 11:45:38.075441759 +0200
++++ cups-1.6.3/configure.in 2015-06-10 11:45:38.158441533 +0200
+@@ -37,6 +37,8 @@ sinclude(config-scripts/cups-systemd.m4)
+ sinclude(config-scripts/cups-defaults.m4)
+ sinclude(config-scripts/cups-scripting.m4)
+
++sinclude(config-scripts/cups-lspp.m4)
++
+ INSTALL_LANGUAGES=""
+ UNINSTALL_LANGUAGES=""
+ LANGFILES=""
+diff -up cups-1.6.3/data/Makefile.lspp cups-1.6.3/data/Makefile
+--- cups-1.6.3/data/Makefile.lspp 2015-06-10 11:45:38.075441759 +0200
++++ cups-1.6.3/data/Makefile 2015-06-10 11:45:38.158441533 +0200
+@@ -25,7 +25,11 @@ BANNERS = \
+ secret \
+ standard \
+ topsecret \
+- unclassified
++ unclassified \
++ selinux \
++ mls \
++ te
++
+
+ DATAFILES = \
+ testprint
+diff -up cups-1.6.3/data/mls.lspp cups-1.6.3/data/mls
+--- cups-1.6.3/data/mls.lspp 2015-06-10 11:45:38.158441533 +0200
++++ cups-1.6.3/data/mls 2015-06-10 11:45:38.158441533 +0200
+@@ -0,0 +1,261 @@
++%!PS-Adobe-3.0
++%%BoundingBox: 0 0 612 792
++%%Pages: 1
++%%LanguageLevel: 1
++%%DocumentData: Clean7Bit
++%%DocumentSuppliedResources: procset bannerprint/1.0
++%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
++%%Creator: Michael Sweet, Easy Software Products
++%%CreationDate: May 10, 2000
++%%Title: Test Page
++%%EndComments
++%%BeginProlog
++%%BeginResource procset bannerprint 1.1 0
++%
++% PostScript banner page for the Common UNIX Printing System ("CUPS").
++%
++% Copyright 1993-2005 by Easy Software Products
++%
++% These coded instructions, statements, and computer programs are the
++% property of Easy Software Products and are protected by Federal
++% copyright law. Distribution and use rights are outlined in the file
++% "LICENSE.txt" which should have been included with this file. If this
++% file is missing or damaged please contact Easy Software Products
++% at:
++%
++% Attn: CUPS Licensing Information
++% Easy Software Products
++% 44141 Airport View Drive, Suite 204
++% Hollywood, Maryland 20636 USA
++%
++% Voice: (301) 373-9600
++% EMail: cups-info@cups.org
++% WWW: http://www.cups.org
++%
++/CENTER { % Draw centered text
++ % (name) CENTER -
++ dup stringwidth pop % Get the width of the string
++ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
++ show % Show the string
++} bind def
++/RIGHT { % Draw right-justified text
++ % (name) RIGHT -
++ dup stringwidth pop % Get the width of the string
++ neg 0 rmoveto % Shift left the entire distance
++ show % Show the string
++} bind def
++/NUMBER { % Draw a number
++ % power n NUMBER -
++ 1 index 1 eq { % power == 1?
++ round cvi exch pop % Convert "n" to integer
++ } {
++ 1 index mul round exch div % Truncate extra decimal places
++ } ifelse
++ 100 string cvs show % Convert to a string and show it...
++} bind def
++/CUPSLOGO { % Draw the CUPS logo
++ % height CUPSLOGO
++ % Start with a big C...
++ /Helvetica findfont 1 index scalefont setfont
++ 0 setgray
++ 0 0 moveto
++ (C) show
++
++ % Then "UNIX Printing System" much smaller...
++ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
++ 0.25 mul
++ dup dup 2.0 mul moveto
++ (UNIX) show
++ dup dup 1.6 mul moveto
++ (Printing) show
++ dup 1.2 mul moveto
++ (System) show
++} bind def
++/ESPLOGO { % Draw the ESP logo
++ % height ESPLOGO
++ % Compute the size of the logo...
++ 0 0
++ 2 index 1.5 mul 3 index
++
++ % Do the "metallic" fill from 10% black to 40% black...
++ 1 -0.001 0 {
++ dup % loopval
++ -0.15 mul % loopval * -0.15
++ 0.9 add % 0.9 - loopval * 0.15
++ setgray % set gray shade
++
++ 0 % x
++ 1 index neg % loopval
++ 1 add % 1 - loopval
++ 3 index % height
++ mul % height * (1 - loopval)
++ moveto % starting point
++
++ dup % loopval
++ 3 index % width
++ mul % loopval * width
++ 2 index % height
++ lineto % Next point
++
++ 0 % x
++ 2 index % height
++ lineto % Next point
++
++ closepath
++ fill
++
++ dup % loopval
++ 0.15 mul % loopval * 0.15
++ 0.6 add % 0.6 + loopval * 0.15
++ setgray
++
++ dup % loopval
++ neg 1 add % 1 - loopval
++ 3 index % width
++ mul % (1 - loopval) * width
++ 0 % y
++ moveto % Starting point
++
++ 2 index % width
++ exch % loopval
++ 2 index % height
++ mul % loopval * height
++ lineto % Next point
++
++ 1 index % width
++ 0 % y
++ lineto % Next point
++
++ closepath
++ fill
++ } for
++
++ 0 setgray rectstroke
++
++ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
++ dup 40 div
++
++ dup 4 mul 1 index 25 mul moveto (E) show
++ dup 10 mul 1 index 15 mul moveto (S) show
++ dup 16 mul 1 index 5 mul moveto (P) show
++
++ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
++ dup 14 mul 1 index 29 mul moveto (asy) show
++ dup 20 mul 1 index 19 mul moveto (oftware) show
++ dup 26 mul 1 index 9 mul moveto (roducts) show
++
++ pop
++} bind def
++%%EndResource
++%%EndProlog
++%%Page: 1 1
++gsave
++
++ % Determine the imageable area and device resolution...
++ initclip newpath clippath pathbbox % Get bounding rectangle
++ 72 div /pageTop exch def % Get top margin in inches
++ 72 div /pageRight exch def % Get right margin in inches
++ 72 div /pageBottom exch def % Get bottom margin in inches
++ 72 div /pageLeft exch def % Get left margin in inches
++
++ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
++ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
++
++ /boxWidth % width of text box
++ pageWidth pageHeight lt
++ { pageWidth 54 mul }
++ { pageHeight 42 mul }
++ ifelse def
++
++ newpath % Clear bounding path
++
++ % Create fonts...
++ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
++ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
++
++ /mediumFont /Helvetica findfont % mediumFont = Helvetica
++ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
++
++ % Offset page to account for lower-left margin...
++ pageLeft 72 mul
++ pageBottom 72 mul
++ translate
++
++ % Job information box...
++ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
++ boxWidth 0.5 mul sub % x-= 1/2 box width
++ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
++ boxWidth % w = box width
++ pageHeight 14 mul % h = pageHeight * 1/2 * 72
++ 0.5 setgray rectfill % Draw a shadow
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ boxWidth 0.5 mul sub % x-= 1/2 box width
++ pageHeight 30 mul % y = pageHeight * 1/4 * 72
++ boxWidth % w = box width
++ pageHeight 14 mul % h = pageHeight * 1/2 * 72
++
++ 4 copy 1 setgray rectfill % Clear the box to white
++ 0 setgray rectstroke % Draw a black box around it...
++
++ % Job information text...
++ mediumFont setfont % Medium sized font
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight 5 mul add % y += 2 lines
++ 2 copy % Copy X & Y
++ moveto
++ (Job ID: ) RIGHT
++ moveto
++ ({printer-name}-{job-id}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight 2 mul add % y += 1 line
++ 2 copy % Copy X & Y
++ moveto
++ (Title: ) RIGHT
++ moveto
++ ({job-name}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight -1 mul add % y -= 1 line
++ 2 copy % Copy X & Y
++ moveto
++ (Requesting User: ) RIGHT
++ moveto
++ ({job-originating-user-name}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight -4 mul add % y -= 2 lines
++ 2 copy % Copy X & Y
++ moveto
++ (Billing Info: ) RIGHT
++ moveto
++ ({?job-billing}) show
++
++ % Then the CUPS logo....
++ gsave
++ pageWidth 4 mul
++ pageWidth 6 mul
++ translate
++ pageWidth 9 mul CUPSLOGO
++ grestore
++
++ % And the ESP logo....
++ gsave
++ pageWidth 59 mul
++ pageWidth 6 mul
++ translate
++ pageWidth 6 mul ESPLOGO
++ grestore
++% Show the page...
++grestore
++showpage
++%
++% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $".
++%
++%%EOF
+diff -up cups-1.6.3/data/selinux.lspp cups-1.6.3/data/selinux
+--- cups-1.6.3/data/selinux.lspp 2015-06-10 11:45:38.158441533 +0200
++++ cups-1.6.3/data/selinux 2015-06-10 11:45:38.158441533 +0200
+@@ -0,0 +1,261 @@
++%!PS-Adobe-3.0
++%%BoundingBox: 0 0 612 792
++%%Pages: 1
++%%LanguageLevel: 1
++%%DocumentData: Clean7Bit
++%%DocumentSuppliedResources: procset bannerprint/1.0
++%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
++%%Creator: Michael Sweet, Easy Software Products
++%%CreationDate: May 10, 2000
++%%Title: Test Page
++%%EndComments
++%%BeginProlog
++%%BeginResource procset bannerprint 1.1 0
++%
++% PostScript banner page for the Common UNIX Printing System ("CUPS").
++%
++% Copyright 1993-2005 by Easy Software Products
++%
++% These coded instructions, statements, and computer programs are the
++% property of Easy Software Products and are protected by Federal
++% copyright law. Distribution and use rights are outlined in the file
++% "LICENSE.txt" which should have been included with this file. If this
++% file is missing or damaged please contact Easy Software Products
++% at:
++%
++% Attn: CUPS Licensing Information
++% Easy Software Products
++% 44141 Airport View Drive, Suite 204
++% Hollywood, Maryland 20636 USA
++%
++% Voice: (301) 373-9600
++% EMail: cups-info@cups.org
++% WWW: http://www.cups.org
++%
++/CENTER { % Draw centered text
++ % (name) CENTER -
++ dup stringwidth pop % Get the width of the string
++ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
++ show % Show the string
++} bind def
++/RIGHT { % Draw right-justified text
++ % (name) RIGHT -
++ dup stringwidth pop % Get the width of the string
++ neg 0 rmoveto % Shift left the entire distance
++ show % Show the string
++} bind def
++/NUMBER { % Draw a number
++ % power n NUMBER -
++ 1 index 1 eq { % power == 1?
++ round cvi exch pop % Convert "n" to integer
++ } {
++ 1 index mul round exch div % Truncate extra decimal places
++ } ifelse
++ 100 string cvs show % Convert to a string and show it...
++} bind def
++/CUPSLOGO { % Draw the CUPS logo
++ % height CUPSLOGO
++ % Start with a big C...
++ /Helvetica findfont 1 index scalefont setfont
++ 0 setgray
++ 0 0 moveto
++ (C) show
++
++ % Then "UNIX Printing System" much smaller...
++ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
++ 0.25 mul
++ dup dup 2.0 mul moveto
++ (UNIX) show
++ dup dup 1.6 mul moveto
++ (Printing) show
++ dup 1.2 mul moveto
++ (System) show
++} bind def
++/ESPLOGO { % Draw the ESP logo
++ % height ESPLOGO
++ % Compute the size of the logo...
++ 0 0
++ 2 index 1.5 mul 3 index
++
++ % Do the "metallic" fill from 10% black to 40% black...
++ 1 -0.001 0 {
++ dup % loopval
++ -0.15 mul % loopval * -0.15
++ 0.9 add % 0.9 - loopval * 0.15
++ setgray % set gray shade
++
++ 0 % x
++ 1 index neg % loopval
++ 1 add % 1 - loopval
++ 3 index % height
++ mul % height * (1 - loopval)
++ moveto % starting point
++
++ dup % loopval
++ 3 index % width
++ mul % loopval * width
++ 2 index % height
++ lineto % Next point
++
++ 0 % x
++ 2 index % height
++ lineto % Next point
++
++ closepath
++ fill
++
++ dup % loopval
++ 0.15 mul % loopval * 0.15
++ 0.6 add % 0.6 + loopval * 0.15
++ setgray
++
++ dup % loopval
++ neg 1 add % 1 - loopval
++ 3 index % width
++ mul % (1 - loopval) * width
++ 0 % y
++ moveto % Starting point
++
++ 2 index % width
++ exch % loopval
++ 2 index % height
++ mul % loopval * height
++ lineto % Next point
++
++ 1 index % width
++ 0 % y
++ lineto % Next point
++
++ closepath
++ fill
++ } for
++
++ 0 setgray rectstroke
++
++ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
++ dup 40 div
++
++ dup 4 mul 1 index 25 mul moveto (E) show
++ dup 10 mul 1 index 15 mul moveto (S) show
++ dup 16 mul 1 index 5 mul moveto (P) show
++
++ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
++ dup 14 mul 1 index 29 mul moveto (asy) show
++ dup 20 mul 1 index 19 mul moveto (oftware) show
++ dup 26 mul 1 index 9 mul moveto (roducts) show
++
++ pop
++} bind def
++%%EndResource
++%%EndProlog
++%%Page: 1 1
++gsave
++
++ % Determine the imageable area and device resolution...
++ initclip newpath clippath pathbbox % Get bounding rectangle
++ 72 div /pageTop exch def % Get top margin in inches
++ 72 div /pageRight exch def % Get right margin in inches
++ 72 div /pageBottom exch def % Get bottom margin in inches
++ 72 div /pageLeft exch def % Get left margin in inches
++
++ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
++ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
++
++ /boxWidth % width of text box
++ pageWidth pageHeight lt
++ { pageWidth 54 mul }
++ { pageHeight 42 mul }
++ ifelse def
++
++ newpath % Clear bounding path
++
++ % Create fonts...
++ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
++ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
++
++ /mediumFont /Helvetica findfont % mediumFont = Helvetica
++ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
++
++ % Offset page to account for lower-left margin...
++ pageLeft 72 mul
++ pageBottom 72 mul
++ translate
++
++ % Job information box...
++ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
++ boxWidth 0.5 mul sub % x-= 1/2 box width
++ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
++ boxWidth % w = box width
++ pageHeight 14 mul % h = pageHeight * 1/2 * 72
++ 0.5 setgray rectfill % Draw a shadow
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ boxWidth 0.5 mul sub % x-= 1/2 box width
++ pageHeight 30 mul % y = pageHeight * 1/4 * 72
++ boxWidth % w = box width
++ pageHeight 14 mul % h = pageHeight * 1/2 * 72
++
++ 4 copy 1 setgray rectfill % Clear the box to white
++ 0 setgray rectstroke % Draw a black box around it...
++
++ % Job information text...
++ mediumFont setfont % Medium sized font
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight 5 mul add % y += 2 lines
++ 2 copy % Copy X & Y
++ moveto
++ (Job ID: ) RIGHT
++ moveto
++ ({printer-name}-{job-id}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight 2 mul add % y += 1 line
++ 2 copy % Copy X & Y
++ moveto
++ (Title: ) RIGHT
++ moveto
++ ({job-name}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight -1 mul add % y -= 1 line
++ 2 copy % Copy X & Y
++ moveto
++ (Requesting User: ) RIGHT
++ moveto
++ ({job-originating-user-name}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight -4 mul add % y -= 2 lines
++ 2 copy % Copy X & Y
++ moveto
++ (Billing Info: ) RIGHT
++ moveto
++ ({?job-billing}) show
++
++ % Then the CUPS logo....
++ gsave
++ pageWidth 4 mul
++ pageWidth 6 mul
++ translate
++ pageWidth 9 mul CUPSLOGO
++ grestore
++
++ % And the ESP logo....
++ gsave
++ pageWidth 59 mul
++ pageWidth 6 mul
++ translate
++ pageWidth 6 mul ESPLOGO
++ grestore
++% Show the page...
++grestore
++showpage
++%
++% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $".
++%
++%%EOF
+diff -up cups-1.6.3/data/te.lspp cups-1.6.3/data/te
+--- cups-1.6.3/data/te.lspp 2015-06-10 11:45:38.159441530 +0200
++++ cups-1.6.3/data/te 2015-06-10 11:45:38.159441530 +0200
+@@ -0,0 +1,261 @@
++%!PS-Adobe-3.0
++%%BoundingBox: 0 0 612 792
++%%Pages: 1
++%%LanguageLevel: 1
++%%DocumentData: Clean7Bit
++%%DocumentSuppliedResources: procset bannerprint/1.0
++%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
++%%Creator: Michael Sweet, Easy Software Products
++%%CreationDate: May 10, 2000
++%%Title: Test Page
++%%EndComments
++%%BeginProlog
++%%BeginResource procset bannerprint 1.1 0
++%
++% PostScript banner page for the Common UNIX Printing System ("CUPS").
++%
++% Copyright 1993-2005 by Easy Software Products
++%
++% These coded instructions, statements, and computer programs are the
++% property of Easy Software Products and are protected by Federal
++% copyright law. Distribution and use rights are outlined in the file
++% "LICENSE.txt" which should have been included with this file. If this
++% file is missing or damaged please contact Easy Software Products
++% at:
++%
++% Attn: CUPS Licensing Information
++% Easy Software Products
++% 44141 Airport View Drive, Suite 204
++% Hollywood, Maryland 20636 USA
++%
++% Voice: (301) 373-9600
++% EMail: cups-info@cups.org
++% WWW: http://www.cups.org
++%
++/CENTER { % Draw centered text
++ % (name) CENTER -
++ dup stringwidth pop % Get the width of the string
++ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
++ show % Show the string
++} bind def
++/RIGHT { % Draw right-justified text
++ % (name) RIGHT -
++ dup stringwidth pop % Get the width of the string
++ neg 0 rmoveto % Shift left the entire distance
++ show % Show the string
++} bind def
++/NUMBER { % Draw a number
++ % power n NUMBER -
++ 1 index 1 eq { % power == 1?
++ round cvi exch pop % Convert "n" to integer
++ } {
++ 1 index mul round exch div % Truncate extra decimal places
++ } ifelse
++ 100 string cvs show % Convert to a string and show it...
++} bind def
++/CUPSLOGO { % Draw the CUPS logo
++ % height CUPSLOGO
++ % Start with a big C...
++ /Helvetica findfont 1 index scalefont setfont
++ 0 setgray
++ 0 0 moveto
++ (C) show
++
++ % Then "UNIX Printing System" much smaller...
++ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
++ 0.25 mul
++ dup dup 2.0 mul moveto
++ (UNIX) show
++ dup dup 1.6 mul moveto
++ (Printing) show
++ dup 1.2 mul moveto
++ (System) show
++} bind def
++/ESPLOGO { % Draw the ESP logo
++ % height ESPLOGO
++ % Compute the size of the logo...
++ 0 0
++ 2 index 1.5 mul 3 index
++
++ % Do the "metallic" fill from 10% black to 40% black...
++ 1 -0.001 0 {
++ dup % loopval
++ -0.15 mul % loopval * -0.15
++ 0.9 add % 0.9 - loopval * 0.15
++ setgray % set gray shade
++
++ 0 % x
++ 1 index neg % loopval
++ 1 add % 1 - loopval
++ 3 index % height
++ mul % height * (1 - loopval)
++ moveto % starting point
++
++ dup % loopval
++ 3 index % width
++ mul % loopval * width
++ 2 index % height
++ lineto % Next point
++
++ 0 % x
++ 2 index % height
++ lineto % Next point
++
++ closepath
++ fill
++
++ dup % loopval
++ 0.15 mul % loopval * 0.15
++ 0.6 add % 0.6 + loopval * 0.15
++ setgray
++
++ dup % loopval
++ neg 1 add % 1 - loopval
++ 3 index % width
++ mul % (1 - loopval) * width
++ 0 % y
++ moveto % Starting point
++
++ 2 index % width
++ exch % loopval
++ 2 index % height
++ mul % loopval * height
++ lineto % Next point
++
++ 1 index % width
++ 0 % y
++ lineto % Next point
++
++ closepath
++ fill
++ } for
++
++ 0 setgray rectstroke
++
++ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
++ dup 40 div
++
++ dup 4 mul 1 index 25 mul moveto (E) show
++ dup 10 mul 1 index 15 mul moveto (S) show
++ dup 16 mul 1 index 5 mul moveto (P) show
++
++ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
++ dup 14 mul 1 index 29 mul moveto (asy) show
++ dup 20 mul 1 index 19 mul moveto (oftware) show
++ dup 26 mul 1 index 9 mul moveto (roducts) show
++
++ pop
++} bind def
++%%EndResource
++%%EndProlog
++%%Page: 1 1
++gsave
++
++ % Determine the imageable area and device resolution...
++ initclip newpath clippath pathbbox % Get bounding rectangle
++ 72 div /pageTop exch def % Get top margin in inches
++ 72 div /pageRight exch def % Get right margin in inches
++ 72 div /pageBottom exch def % Get bottom margin in inches
++ 72 div /pageLeft exch def % Get left margin in inches
++
++ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
++ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
++
++ /boxWidth % width of text box
++ pageWidth pageHeight lt
++ { pageWidth 54 mul }
++ { pageHeight 42 mul }
++ ifelse def
++
++ newpath % Clear bounding path
++
++ % Create fonts...
++ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
++ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
++
++ /mediumFont /Helvetica findfont % mediumFont = Helvetica
++ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
++
++ % Offset page to account for lower-left margin...
++ pageLeft 72 mul
++ pageBottom 72 mul
++ translate
++
++ % Job information box...
++ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
++ boxWidth 0.5 mul sub % x-= 1/2 box width
++ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
++ boxWidth % w = box width
++ pageHeight 14 mul % h = pageHeight * 1/2 * 72
++ 0.5 setgray rectfill % Draw a shadow
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ boxWidth 0.5 mul sub % x-= 1/2 box width
++ pageHeight 30 mul % y = pageHeight * 1/4 * 72
++ boxWidth % w = box width
++ pageHeight 14 mul % h = pageHeight * 1/2 * 72
++
++ 4 copy 1 setgray rectfill % Clear the box to white
++ 0 setgray rectstroke % Draw a black box around it...
++
++ % Job information text...
++ mediumFont setfont % Medium sized font
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight 5 mul add % y += 2 lines
++ 2 copy % Copy X & Y
++ moveto
++ (Job ID: ) RIGHT
++ moveto
++ ({printer-name}-{job-id}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight 2 mul add % y += 1 line
++ 2 copy % Copy X & Y
++ moveto
++ (Title: ) RIGHT
++ moveto
++ ({job-name}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight -1 mul add % y -= 1 line
++ 2 copy % Copy X & Y
++ moveto
++ (Requesting User: ) RIGHT
++ moveto
++ ({job-originating-user-name}) show
++
++ pageWidth 36 mul % x = pageWidth * 1/2 * 72
++ pageHeight 36 mul % y = pageHeight * 1/2 * 72
++ pageHeight -4 mul add % y -= 2 lines
++ 2 copy % Copy X & Y
++ moveto
++ (Billing Info: ) RIGHT
++ moveto
++ ({?job-billing}) show
++
++ % Then the CUPS logo....
++ gsave
++ pageWidth 4 mul
++ pageWidth 6 mul
++ translate
++ pageWidth 9 mul CUPSLOGO
++ grestore
++
++ % And the ESP logo....
++ gsave
++ pageWidth 59 mul
++ pageWidth 6 mul
++ translate
++ pageWidth 6 mul ESPLOGO
++ grestore
++% Show the page...
++grestore
++showpage
++%
++% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $".
++%
++%%EOF
+diff -up cups-1.6.3/filter/common.c.lspp cups-1.6.3/filter/common.c
+--- cups-1.6.3/filter/common.c.lspp 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/filter/common.c 2015-06-10 11:45:38.159441530 +0200
+@@ -30,6 +30,12 @@
+ * Include necessary headers...
+ */
+
++#include "config.h"
++#ifdef WITH_LSPP
++#define _GNU_SOURCE
++#include
++#endif /* WITH_LSPP */
++
+ #include "common.h"
+ #include
+
+@@ -312,6 +318,18 @@ WriteLabelProlog(const char *label, /* I
+ {
+ const char *classification; /* CLASSIFICATION environment variable */
+ const char *ptr; /* Temporary string pointer */
++#ifdef WITH_LSPP
++ int i, /* counter */
++ n, /* counter */
++ lines, /* number of lines needed */
++ line_len, /* index into tmp_label */
++ label_len, /* length of the label in characters */
++ label_index, /* index into the label */
++ longest, /* length of the longest line */
++ longest_line, /* index to the longest line */
++ max_width; /* maximum width in characters */
++ char **wrapped_label; /* label with line breaks */
++#endif /* WITH_LSPP */
+
+
+ /*
+@@ -334,6 +352,124 @@ WriteLabelProlog(const char *label, /* I
+ return;
+ }
+
++#ifdef WITH_LSPP
++ if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
++ {
++ /*
++ * Based on the 12pt fixed width font below determine the max_width
++ */
++ max_width = width / 8;
++ longest_line = 0;
++ longest = 0;
++ classification += 5; // Skip the "LSPP:"
++ label_len = strlen(classification);
++
++ if (label_len > max_width)
++ {
++ lines = 1 + (int)(label_len / max_width);
++ line_len = (int)(label_len / lines);
++ wrapped_label = malloc(sizeof(*wrapped_label) * lines);
++ label_index = i = n = 0;
++ while (classification[label_index])
++ {
++ if ((label_index + line_len) > label_len)
++ break;
++ switch (classification[label_index + line_len + i])
++ {
++ case ':':
++ case ',':
++ case '-':
++ i++;
++ wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
++ label_index += line_len + i;
++ i = 0;
++ break;
++ default:
++ i++;
++ break;
++ }
++ if ((i + line_len) == max_width)
++ {
++ wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
++ label_index = label_index + line_len + i;
++ i = 0;
++ }
++ }
++ wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
++ }
++ else
++ {
++ lines = 1;
++ wrapped_label = malloc(sizeof(*wrapped_label));
++ wrapped_label[0] = (char*)classification;
++ }
++
++ for (n = 0; n < lines; n++ )
++ {
++ printf("userdict/ESPp%c(", ('a' + n));
++ for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
++ if (*ptr < 32 || *ptr > 126)
++ printf("\\%03o", *ptr);
++ else
++ {
++ if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
++ putchar('\\');
++
++ printf("%c", *ptr);
++ }
++ if (i > longest)
++ {
++ longest = i;
++ longest_line = n;
++ }
++ printf(")put\n");
++ }
++
++ /*
++ * For LSPP use a fixed width font so that line wrapping can be calculated
++ */
++
++ puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
++
++ /*
++ * Finally, the procedure to write the labels on the page...
++ */
++
++ printf("userdict/ESPwl{\n"
++ " ESPlf setfont\n");
++ printf(" ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
++ 'a' + longest_line, width * 0.5f);
++ for (n = 1; n < lines; n++)
++ printf(" dup");
++ printf("\n 1 setgray\n");
++ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
++ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
++ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++ printf(" 0 setgray\n");
++ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
++ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
++ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++ for (n = 0; n < lines; n ++)
++ {
++ printf(" dup %.0f moveto ESPp%c show\n",
++ bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
++ printf(" %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
++ }
++ printf(" pop\n"
++ "}bind put\n");
++
++ /*
++ * Do some clean up at the end of the LSPP special case
++ */
++ free(wrapped_label);
++
++ }
++ else
++ {
++#endif /* !WITH_LSPP */
++
+ /*
+ * Set the classification + page label string...
+ */
+@@ -414,7 +550,10 @@ WriteLabelProlog(const char *label, /* I
+ printf(" %.0f moveto ESPpl show\n", top - 14.0);
+ puts("pop");
+ puts("}bind put");
++ }
++#ifdef WITH_LSPP
+ }
++#endif /* WITH_LSPP */
+
+
+ /*
+diff -up cups-1.6.3/filter/pstops.c.lspp cups-1.6.3/filter/pstops.c
+--- cups-1.6.3/filter/pstops.c.lspp 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/filter/pstops.c 2015-06-10 11:45:38.159441530 +0200
+@@ -3202,6 +3202,18 @@ write_label_prolog(pstops_doc_t *doc, /*
+ {
+ const char *classification; /* CLASSIFICATION environment variable */
+ const char *ptr; /* Temporary string pointer */
++#ifdef WITH_LSPP
++ int i, /* counter */
++ n, /* counter */
++ lines, /* number of lines needed */
++ line_len, /* index into tmp_label */
++ label_len, /* length of the label in characters */
++ label_index, /* index into the label */
++ longest, /* length of the longest line */
++ longest_line, /* index to the longest line */
++ max_width; /* maximum width in characters */
++ char **wrapped_label; /* label with line breaks */
++#endif /* WITH_LSPP */
+
+
+ /*
+@@ -3224,6 +3236,124 @@ write_label_prolog(pstops_doc_t *doc, /*
+ return;
+ }
+
++#ifdef WITH_LSPP
++ if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
++ {
++ /*
++ * Based on the 12pt fixed width font below determine the max_width
++ */
++ max_width = width / 8;
++ longest_line = 0;
++ longest = 0;
++ classification += 5; // Skip the "LSPP:"
++ label_len = strlen(classification);
++
++ if (label_len > max_width)
++ {
++ lines = 1 + (int)(label_len / max_width);
++ line_len = (int)(label_len / lines);
++ wrapped_label = malloc(sizeof(*wrapped_label) * lines);
++ label_index = i = n = 0;
++ while (classification[label_index])
++ {
++ if ((label_index + line_len) > label_len)
++ break;
++ switch (classification[label_index + line_len + i])
++ {
++ case ':':
++ case ',':
++ case '-':
++ i++;
++ wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
++ label_index += line_len + i;
++ i = 0;
++ break;
++ default:
++ i++;
++ break;
++ }
++ if ((i + line_len) == max_width)
++ {
++ wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
++ label_index = label_index + line_len + i;
++ i = 0;
++ }
++ }
++ wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
++ }
++ else
++ {
++ lines = 1;
++ wrapped_label = malloc(sizeof(*wrapped_label));
++ wrapped_label[0] = (char*)classification;
++ }
++
++ for (n = 0; n < lines; n++ )
++ {
++ printf("userdict/ESPp%c(", ('a' + n));
++ for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
++ if (*ptr < 32 || *ptr > 126)
++ printf("\\%03o", *ptr);
++ else
++ {
++ if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
++ putchar('\\');
++
++ printf("%c", *ptr);
++ }
++ if (i > longest)
++ {
++ longest = i;
++ longest_line = n;
++ }
++ printf(")put\n");
++ }
++
++ /*
++ * For LSPP use a fixed width font so that line wrapping can be calculated
++ */
++
++ puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
++
++ /*
++ * Finally, the procedure to write the labels on the page...
++ */
++
++ printf("userdict/ESPwl{\n"
++ " ESPlf setfont\n");
++ printf(" ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
++ 'a' + longest_line, width * 0.5f);
++ for (n = 1; n < lines; n++)
++ printf(" dup");
++ printf("\n 1 setgray\n");
++ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
++ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
++ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++ printf(" 0 setgray\n");
++ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
++ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
++ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++ for (n = 0; n < lines; n ++)
++ {
++ printf(" dup %.0f moveto ESPp%c show\n",
++ bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
++ printf(" %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
++ }
++ printf(" pop\n"
++ "}bind put\n");
++
++ /*
++ * Do some clean up at the end of the LSPP special case
++ */
++ free(wrapped_label);
++
++ }
++ else
++ {
++#endif /* !WITH_LSPP */
++
+ /*
+ * Set the classification + page label string...
+ */
+@@ -3302,7 +3432,10 @@ write_label_prolog(pstops_doc_t *doc, /*
+ doc_printf(doc, " %.0f moveto ESPpl show\n", top - 14.0);
+ doc_puts(doc, "pop\n");
+ doc_puts(doc, "}bind put\n");
++ }
++#ifdef WITH_LSPP
+ }
++#endif /* WITH_LSPP */
+
+
+ /*
+diff -up cups-1.6.3/Makedefs.in.lspp cups-1.6.3/Makedefs.in
+--- cups-1.6.3/Makedefs.in.lspp 2015-06-10 11:45:38.075441759 +0200
++++ cups-1.6.3/Makedefs.in 2015-06-10 11:45:38.157441536 +0200
+@@ -146,7 +146,7 @@ LDFLAGS = -L../cgi-bin -L../cups -L../f
+ @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
+ LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ)
+ LINKCUPSIMAGE = @LINKCUPSIMAGE@
+-LIBS = $(LINKCUPS) $(COMMONLIBS)
++LIBS = $(LINKCUPS) $(COMMONLIBS) @LIBAUDIT@ @LIBSELINUX@
+ OPTIM = @OPTIM@
+ OPTIONS =
+ PAMLIBS = @PAMLIBS@
+diff -up cups-1.6.3/scheduler/client.c.lspp cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.lspp 2015-06-10 11:45:38.140441582 +0200
++++ cups-1.6.3/scheduler/client.c 2015-06-10 11:45:38.160441528 +0200
+@@ -41,6 +41,7 @@
+ * valid_host() - Is the Host: field valid?
+ * write_file() - Send a file via HTTP.
+ * write_pipe() - Flag that data is available on the CGI pipe.
++ * client_pid_to_auid() - Get the audit login uid of the client.
+ */
+
+ /*
+@@ -49,10 +50,16 @@
+
+ #include "cupsd.h"
+
++#define _GNU_SOURCE
+ #ifdef HAVE_TCPD_H
+ # include
+ #endif /* HAVE_TCPD_H */
+
++#ifdef WITH_LSPP
++#include
++#include
++#include
++#endif /* WITH_LSPP */
+
+ /*
+ * Local globals...
+@@ -371,6 +378,57 @@ cupsdAcceptClient(cupsd_listener_t *lis)
+ }
+ #endif /* HAVE_TCPD_H */
+
++#ifdef WITH_LSPP
++ if (is_lspp_config())
++ {
++ struct ucred cr;
++ unsigned int cl=sizeof(cr);
++
++ if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0)
++ {
++ /*
++ * client_pid_to_auid() can be racey
++ * In this case the pid is based on a socket connected to the client
++ */
++ if ((con->auid = client_pid_to_auid(cr.pid)) == -1)
++ {
++ close(con->http.fd);
++ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: "
++ "unable to determine client auid for client pid=%d", cr.pid);
++ free(con);
++ return;
++ }
++ cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: peer's pid=%d, uid=%d, gid=%d, auid=%d",
++ cr.pid, cr.uid, cr.gid, con->auid);
++ }
++ else
++ {
++ close(con->http.fd);
++ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getsockopt() failed");
++ free(con);
++ return;
++ }
++
++ /*
++ * get the context of the peer connection
++ */
++ if (getpeercon(con->http.fd, &con->scon))
++ {
++ close(con->http.fd);
++ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getpeercon() failed");
++ free(con);
++ return;
++ }
++
++ cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: client context=%s", con->scon);
++ }
++ else
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: skipping getpeercon()");
++ cupsdSetString(&con->scon, UNKNOWN_SL);
++ }
++#endif /* WITH_LSPP */
++
+ #ifdef AF_LOCAL
+ if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)",
+@@ -678,6 +736,13 @@ cupsdReadClient(cupsd_client_t *con) /*
+ mime_type_t *type; /* MIME type of file */
+ cupsd_printer_t *p; /* Printer */
+ static unsigned request_id = 0; /* Request ID for temp files */
++#ifdef WITH_LSPP
++ security_context_t spoolcon; /* context of the job file */
++ context_t clicon; /* contex_t container for con->scon */
++ context_t tmpcon; /* temp context to swap the level */
++ char *clirange; /* SELinux sensitivity range */
++ char *cliclearance; /* SELinux low end clearance */
++#endif /* WITH_LSPP */
+
+
+ status = HTTP_CONTINUE;
+@@ -2137,6 +2202,67 @@ cupsdReadClient(cupsd_client_t *con) /*
+ fchmod(con->file, 0640);
+ fchown(con->file, RunUser, Group);
+ fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
++#ifdef WITH_LSPP
++ if (strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++ {
++ if (getfilecon(con->filename, &spoolcon) == -1)
++ {
++ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
++ return (cupsdCloseClient(con));
++ }
++ clicon = context_new(con->scon);
++ tmpcon = context_new(spoolcon);
++ freecon(spoolcon);
++ if (!clicon || !tmpcon)
++ {
++ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
++ if (clicon)
++ context_free(clicon);
++ if (tmpcon)
++ context_free(tmpcon);
++ return (cupsdCloseClient(con));
++ }
++ clirange = context_range_get(clicon);
++ if (clirange)
++ {
++ clirange = strdup(clirange);
++ if ((cliclearance = strtok(clirange, "-")) != NULL)
++ {
++ if (context_range_set(tmpcon, cliclearance) == -1)
++ {
++ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
++ free(clirange);
++ context_free(tmpcon);
++ context_free(clicon);
++ return (cupsdCloseClient(con));
++ }
++ }
++ else
++ {
++ if (context_range_set(tmpcon, (context_range_get(clicon))) == -1)
++ {
++ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
++ free(clirange);
++ context_free(tmpcon);
++ context_free(clicon);
++ return (cupsdCloseClient(con));
++ }
++ }
++ free(clirange);
++ }
++ if (setfilecon(con->filename, context_str(tmpcon)) == -1)
++ {
++ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
++ context_free(tmpcon);
++ context_free(clicon);
++ return (cupsdCloseClient(con));
++ }
++ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: %s set to %s",
++ con->filename, context_str(tmpcon));
++ context_free(tmpcon);
++ context_free(clicon);
++ }
++#endif /* WITH_LSPP */
+ }
+
+ if (con->http.state != HTTP_POST_SEND)
+@@ -3647,6 +3773,49 @@ is_path_absolute(const char *path) /* I
+ return (1);
+ }
+
++#ifdef WITH_LSPP
++/*
++ * 'client_pid_to_auid()' - Using the client's pid, read /proc and determine the loginuid.
++ */
++
++uid_t client_pid_to_auid(pid_t clipid)
++{
++ uid_t uid;
++ int len, in;
++ char buf[16] = {0};
++ char fname[32] = {0};
++
++
++ /*
++ * Hopefully this pid is still the one we are interested in.
++ */
++ snprintf(fname, 32, "/proc/%d/loginuid", clipid);
++ in = open(fname, O_NOFOLLOW|O_RDONLY);
++
++ if (in < 0)
++ return -1;
++
++ errno = 0;
++
++ do {
++ len = read(in, buf, sizeof(buf));
++ } while (len < 0 && errno == EINTR);
++
++ close(in);
++
++ if (len < 0 || len >= sizeof(buf))
++ return -1;
++
++ errno = 0;
++ buf[len] = 0;
++ uid = strtol(buf, 0, 10);
++
++ if (errno != 0)
++ return -1;
++ else
++ return uid;
++}
++#endif /* WITH_LSPP */
+
+ /*
+ * 'pipe_command()' - Pipe the output of a command to the remote client.
+diff -up cups-1.6.3/scheduler/client.h.lspp cups-1.6.3/scheduler/client.h
+--- cups-1.6.3/scheduler/client.h.lspp 2015-06-10 11:45:38.076441756 +0200
++++ cups-1.6.3/scheduler/client.h 2015-06-10 11:45:38.160441528 +0200
+@@ -18,6 +18,13 @@
+ #endif /* HAVE_AUTHORIZATION_H */
+
+
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
++#ifdef WITH_LSPP
++#include
++#endif /* WITH_LSPP */
++
+ /*
+ * HTTP client structure...
+ */
+@@ -63,6 +70,10 @@ struct cupsd_client_s
+ #ifdef HAVE_AUTHORIZATION_H
+ AuthorizationRef authref; /* Authorization ref */
+ #endif /* HAVE_AUTHORIZATION_H */
++#ifdef WITH_LSPP
++ security_context_t scon; /* Security context of connection */
++ uid_t auid; /* Audit loginuid of the client */
++#endif /* WITH_LSPP */
+ };
+
+ #define HTTP(con) &((con)->http)
+@@ -135,6 +146,9 @@ extern void cupsdStartListening(void);
+ extern void cupsdStopListening(void);
+ extern void cupsdUpdateCGI(void);
+ extern void cupsdWriteClient(cupsd_client_t *con);
++#ifdef WITH_LSPP
++extern uid_t client_pid_to_auid(pid_t clipid);
++#endif /* WITH_LSPP */
+
+ #ifdef HAVE_SSL
+ extern int cupsdEndTLS(cupsd_client_t *con);
+diff -up cups-1.6.3/scheduler/conf.c.lspp cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.lspp 2015-06-10 11:45:38.140441582 +0200
++++ cups-1.6.3/scheduler/conf.c 2015-06-10 11:45:38.161441525 +0200
+@@ -34,6 +34,7 @@
+ * read_location() - Read a definition.
+ * read_policy() - Read a definition.
+ * set_policy_defaults() - Set default policy values as needed.
++ * is_lspp_config() - Is the system configured for LSPP
+ */
+
+ /*
+@@ -59,6 +60,9 @@
+ # define INADDR_NONE 0xffffffff
+ #endif /* !INADDR_NONE */
+
++#ifdef WITH_LSPP
++# include
++#endif /* WITH_LSPP */
+
+ /*
+ * Configuration variable structure...
+@@ -146,6 +150,10 @@ static const cupsd_var_t cupsd_vars[] =
+ { "ServerName", &ServerName, CUPSD_VARTYPE_STRING },
+ { "StrictConformance", &StrictConformance, CUPSD_VARTYPE_BOOLEAN },
+ { "Timeout", &Timeout, CUPSD_VARTYPE_TIME },
++#ifdef WITH_LSPP
++ { "AuditLog", &AuditLog, CUPSD_VARTYPE_INTEGER },
++ { "PerPageLabels", &PerPageLabels, CUPSD_VARTYPE_BOOLEAN },
++#endif /* WITH_LSPP */
+ { "WebInterface", &WebInterface, CUPSD_VARTYPE_BOOLEAN }
+ };
+ static const cupsd_var_t cupsfiles_vars[] =
+@@ -546,6 +554,9 @@ cupsdReadConfiguration(void)
+ const char *tmpdir; /* TMPDIR environment variable */
+ struct stat tmpinfo; /* Temporary directory info */
+ cupsd_policy_t *p; /* Policy */
++#ifdef WITH_LSPP
++ char *audit_message; /* Audit message string */
++#endif /* WITH_LSPP */
+
+
+ /*
+@@ -853,6 +864,25 @@ cupsdReadConfiguration(void)
+
+ RunUser = getuid();
+
++#ifdef WITH_LSPP
++ if (AuditLog != -1)
++ {
++ /*
++ * ClassifyOverride is set during read_configuration, if its ON, report it now
++ */
++ if (ClassifyOverride)
++ audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
++ "[Config] ClassifyOverride=enabled Users can override print banners",
++ ServerName, NULL, NULL, 1);
++ /*
++ * PerPageLabel is set during read_configuration, if its OFF, report it now
++ */
++ if (!PerPageLabels)
++ audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
++ "[Config] PerPageLabels=disabled", ServerName, NULL, NULL, 1);
++ }
++#endif /* WITH_LSPP */
++
+ cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
+ RemotePort ? "enabled" : "disabled");
+
+@@ -1255,7 +1285,19 @@ cupsdReadConfiguration(void)
+ cupsdClearString(&Classification);
+
+ if (Classification)
++ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
++#ifdef WITH_LSPP
++ if (AuditLog != -1)
++ {
++ audit_message = NULL;
++ cupsdSetStringf(&audit_message, "[Config] Classification=%s", Classification);
++ audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
++ ServerName, NULL, NULL, 1);
++ cupsdClearString(&audit_message);
++ }
++#endif /* WITH_LSPP */
++ }
+
+ /*
+ * Check the MaxClients setting, and then allocate memory for it...
+@@ -3641,6 +3683,18 @@ read_location(cups_file_t *fp, /* I - C
+ return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
+ }
+
++#ifdef WITH_LSPP
++int is_lspp_config()
++{
++ if (Classification != NULL)
++ return ((_cups_strcasecmp(Classification, MLS_CONFIG) == 0)
++ || (_cups_strcasecmp(Classification, TE_CONFIG) == 0)
++ || (_cups_strcasecmp(Classification, SELINUX_CONFIG) == 0));
++ else
++ return 0;
++}
++#endif /* WITH_LSPP */
++
+
+ /*
+ * 'read_policy()' - Read a definition.
+diff -up cups-1.6.3/scheduler/conf.h.lspp cups-1.6.3/scheduler/conf.h
+--- cups-1.6.3/scheduler/conf.h.lspp 2015-06-10 11:45:38.108441669 +0200
++++ cups-1.6.3/scheduler/conf.h 2015-06-10 11:45:38.161441525 +0200
+@@ -251,6 +251,13 @@ VAR int SSLOptions VALUE(CUPSD_SSL_NO
+ /* SSL/TLS options */
+ #endif /* HAVE_SSL */
+
++#ifdef WITH_LSPP
++VAR int AuditLog VALUE(-1),
++ /* File descriptor for audit */
++ PerPageLabels VALUE(TRUE);
++ /* Put the label on each page */
++#endif /* WITH_LSPP */
++
+ #ifdef HAVE_LAUNCHD
+ VAR int LaunchdTimeout VALUE(10);
+ /* Time after which an idle cupsd will exit */
+@@ -269,6 +276,9 @@ int HaveServerCreds VALUE(0);
+ gss_cred_id_t ServerCreds; /* Server's GSS credentials */
+ #endif /* HAVE_GSSAPI */
+
++#ifdef WITH_LSPP
++extern int is_lspp_config(void);
++#endif /* WITH_LSPP */
+
+ /*
+ * Prototypes...
+diff -up cups-1.6.3/scheduler/cupsd.h.lspp cups-1.6.3/scheduler/cupsd.h
+--- cups-1.6.3/scheduler/cupsd.h.lspp 2015-06-10 11:45:38.093441710 +0200
++++ cups-1.6.3/scheduler/cupsd.h 2015-06-10 11:45:38.161441525 +0200
+@@ -13,6 +13,8 @@
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ */
+
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
+
+ /*
+ * Include necessary headers.
+@@ -37,13 +39,20 @@
+ # include
+ #endif /* WIN32 */
+
++#include "config.h"
++#ifdef WITH_LSPP
++# define MLS_CONFIG "mls"
++# define TE_CONFIG "te"
++# define SELINUX_CONFIG "SELinux"
++# define UNKNOWN_SL "UNKNOWN SL"
++#endif /* WITH_LSPP */
++
+ #include "mime.h"
+
+ #if defined(HAVE_CDSASSL)
+ # include
+ #endif /* HAVE_CDSASSL */
+
+-
+ /*
+ * Some OS's don't have hstrerror(), most notably Solaris...
+ */
+diff -up cups-1.6.3/scheduler/ipp.c.lspp cups-1.6.3/scheduler/ipp.c
+--- cups-1.6.3/scheduler/ipp.c.lspp 2015-06-10 11:45:38.155441541 +0200
++++ cups-1.6.3/scheduler/ipp.c 2015-06-10 11:46:28.871303698 +0200
+@@ -35,6 +35,7 @@
+ * cancel_all_jobs() - Cancel all or selected print jobs.
+ * cancel_job() - Cancel a print job.
+ * cancel_subscription() - Cancel a subscription.
++ * check_context() - Check the SELinux context for a user and job
+ * check_rss_recipient() - Check that we do not have a duplicate RSS
+ * feed URI.
+ * check_quotas() - Check quotas for a printer and user.
+@@ -99,6 +100,9 @@
+ * validate_user() - Validate the user for the request.
+ */
+
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+ * Include necessary headers...
+ */
+@@ -122,6 +126,14 @@ extern int mbr_check_membership_by_id(uu
+ # endif /* HAVE_MEMBERSHIPPRIV_H */
+ #endif /* __APPLE__ */
+
++#ifdef WITH_LSPP
++#include
++#include
++#include
++#include
++#include
++#include
++#endif /* WITH_LSPP */
+
+ /*
+ * Local functions...
+@@ -146,6 +158,9 @@ static void cancel_all_jobs(cupsd_client
+ static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
+ static void cancel_subscription(cupsd_client_t *con, int id);
+ static int check_rss_recipient(const char *recipient);
++#ifdef WITH_LSPP
++static int check_context(cupsd_client_t *con, cupsd_job_t *job);
++#endif /* WITH_LSPP */
+ static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
+ static void close_job(cupsd_client_t *con, ipp_attribute_t *uri);
+ static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
+@@ -1299,6 +1314,21 @@ add_job(cupsd_client_t *con, /* I - Cl
+ "time-at-creation",
+ "time-at-processing"
+ };
++#ifdef WITH_LSPP
++ char *audit_message; /* Audit message string */
++ char *printerfile; /* device file pointed to by the printer */
++ char *userheader = NULL; /* User supplied job-sheets[0] */
++ char *userfooter = NULL; /* User supplied job-sheets[1] */
++ int override = 0; /* Was a banner overrode on a job */
++ security_id_t clisid; /* SELinux SID for the client */
++ security_id_t psid; /* SELinux SID for the printer */
++ context_t printercon; /* Printer's context string */
++ struct stat printerstat; /* Printer's stat buffer */
++ security_context_t devcon; /* Printer's SELinux context */
++ struct avc_entry_ref avcref; /* Pointer to the access vector cache */
++ security_class_t tclass; /* Object class for the SELinux check */
++ access_vector_t avr; /* Access method being requested */
++#endif /* WITH_LSPP */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
+@@ -1639,6 +1669,106 @@ add_job(cupsd_client_t *con, /* I - Cl
+ }
+ }
+
++#ifdef WITH_LSPP
++ if (is_lspp_config())
++ {
++ if (!con->scon || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "add_job: missing classification for connection \'%s\'!", printer->name);
++ send_ipp_status(con, IPP_INTERNAL_ERROR, _("Missing required security attributes."));
++ return (NULL);
++ }
++
++ /*
++ * Perform an access check so that if the user gets feedback at enqueue time
++ */
++
++ printerfile = strstr(printer->device_uri, "/dev/");
++ if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
++ printerfile = printer->device_uri + strlen("file:");
++
++ if (printerfile != NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: Attempting an access check on printer device %s",
++ printerfile);
++
++ if (lstat(printerfile, &printerstat) < 0)
++ {
++ if (errno != ENOENT)
++ {
++ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to stat the printer"));
++ return (NULL);
++ }
++ /*
++ * The printer does not exist, so for now assume it's a FileDevice
++ */
++ tclass = SECCLASS_FILE;
++ avr = FILE__WRITE;
++ }
++ else if (S_ISCHR(printerstat.st_mode))
++ {
++ tclass = SECCLASS_CHR_FILE;
++ avr = CHR_FILE__WRITE;
++ }
++ else if (S_ISREG(printerstat.st_mode))
++ {
++ tclass = SECCLASS_FILE;
++ avr = FILE__WRITE;
++ }
++ else
++ {
++ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer is not a character device or regular file"));
++ return (NULL);
++ }
++ static avc_initialized = 0;
++ if (!avc_initialized++)
++ avc_init("cupsd_enqueue_", NULL, NULL, NULL, NULL);
++ avc_entry_ref_init(&avcref);
++ if (avc_context_to_sid(con->scon, &clisid) != 0)
++ {
++ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the client"));
++ return (NULL);
++ }
++ if (getfilecon(printerfile, &devcon) == -1)
++ {
++ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux context of the printer"));
++ return (NULL);
++ }
++ printercon = context_new(devcon);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: printer context %s client context %s",
++ context_str(printercon), con->scon);
++ context_free(printercon);
++
++ if (avc_context_to_sid(devcon, &psid) != 0)
++ {
++ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the printer"));
++ freecon(devcon);
++ return (NULL);
++ }
++ freecon(devcon);
++ if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
++ {
++ /*
++ * The access check failed, so cancel the job and send an audit message
++ */
++ if (AuditLog != -1)
++ {
++ audit_message = NULL;
++ cupsdSetStringf(&audit_message, "job=? auid=%u acct=%s obj=%s refused"
++ " unable to access printer=%s", con->auid,
++ con->username, con->scon, printer->name);
++ audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++ ServerName, NULL, NULL, 0);
++ cupsdClearString(&audit_message);
++ }
++
++ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("SELinux prohibits access to the printer"));
++ return (NULL);
++ }
++ }
++ }
++#endif /* WITH_LSPP */
++
+ if ((job = cupsdAddJob(priority, printer->name)) == NULL)
+ {
+ send_ipp_status(con, IPP_INTERNAL_ERROR,
+@@ -1647,6 +1777,32 @@ add_job(cupsd_client_t *con, /* I - Cl
+ return (NULL);
+ }
+
++#ifdef WITH_LSPP
++ if (is_lspp_config())
++ {
++ /*
++ * duplicate the security context and auid of the connection into the job structure
++ */
++ job->scon = strdup(con->scon);
++ job->auid = con->auid;
++
++ /*
++ * add the security context to the request so that on a restart the security
++ * attributes will be able to be restored
++ */
++ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "security-context",
++ NULL, job->scon);
++ }
++ else
++ {
++ /*
++ * Fill in the security context of the job as unlabeled
++ */
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: setting context of job to %s", UNKNOWN_SL);
++ cupsdSetString(&job->scon, UNKNOWN_SL);
++ }
++#endif /* WITH_LSPP */
++
+ job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
+ job->attrs = con->request;
+ job->dirty = 1;
+@@ -1818,6 +1974,29 @@ add_job(cupsd_client_t *con, /* I - Cl
+ ippSetString(job->attrs, &attr, 0, printer->job_sheets[0]);
+ ippSetString(job->attrs, &attr, 1, printer->job_sheets[1]);
+ }
++#ifdef WITH_LSPP
++ else
++ {
++ /*
++ * The option was present, so capture the user supplied strings
++ */
++ userheader = strdup(attr->values[0].string.text);
++
++ if (attr->num_values > 1)
++ userfooter = strdup(attr->values[1].string.text);
++
++ if (Classification != NULL && (strcmp(userheader, Classification) == 0)
++ && userfooter &&(strcmp(userfooter, Classification) == 0))
++ {
++ /*
++ * Since both values are Classification, the user is not trying to Override
++ */
++ free(userheader);
++ if (userfooter) free(userfooter);
++ userheader = userfooter = NULL;
++ }
++ }
++#endif /* WITH_LSPP */
+
+ job->job_sheets = attr;
+
+@@ -1848,6 +2027,9 @@ add_job(cupsd_client_t *con, /* I - Cl
+ "job-sheets=\"%s,none\", "
+ "job-originating-user-name=\"%s\"",
+ Classification, job->username);
++#ifdef WITH_LSPP
++ override = 1;
++#endif /* WITH_LSPP */
+ }
+ else if (attr->num_values == 2 &&
+ strcmp(attr->values[0].string.text,
+@@ -1866,6 +2048,9 @@ add_job(cupsd_client_t *con, /* I - Cl
+ "job-originating-user-name=\"%s\"",
+ attr->values[0].string.text,
+ attr->values[1].string.text, job->username);
++#ifdef WITH_LSPP
++ override = 1;
++#endif /* WITH_LSPP */
+ }
+ else if (strcmp(attr->values[0].string.text, Classification) &&
+ strcmp(attr->values[0].string.text, "none") &&
+@@ -1886,6 +2071,9 @@ add_job(cupsd_client_t *con, /* I - Cl
+ "job-originating-user-name=\"%s\"",
+ attr->values[0].string.text,
+ attr->values[1].string.text, job->username);
++#ifdef WITH_LSPP
++ override = 1;
++#endif /* WITH_LSPP */
+ }
+ }
+ else if (strcmp(attr->values[0].string.text, Classification) &&
+@@ -1926,8 +2114,52 @@ add_job(cupsd_client_t *con, /* I - Cl
+ "job-sheets=\"%s\", "
+ "job-originating-user-name=\"%s\"",
+ Classification, job->username);
++#ifdef WITH_LSPP
++ override = 1;
++#endif /* WITH_LSPP */
++ }
++#ifdef WITH_LSPP
++ if (is_lspp_config() && AuditLog != -1)
++ {
++ audit_message = NULL;
++
++ if (userheader || userfooter)
++ {
++ if (!override)
++ {
++ /*
++ * The user overrode the banner, so audit it
++ */
++ cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
++ " using banners=%s,%s", job->id, userheader,
++ userfooter, attr->values[0].string.text,
++ (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
++ audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
++ ServerName, NULL, NULL, 1);
++ }
++ else
++ {
++ /*
++ * The user tried to override the banner, audit the failure
++ */
++ cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
++ " ignored banners=%s,%s", job->id, userheader,
++ userfooter, attr->values[0].string.text,
++ (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
++ audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
++ ServerName, NULL, NULL, 0);
++ }
++ cupsdClearString(&audit_message);
++ }
+ }
++
++ if (userheader)
++ free(userheader);
++ if (userfooter)
++ free(userfooter);
++#endif /* WITH_LSPP */
+ }
++
+
+ /*
+ * See if we need to add the starting sheet...
+@@ -3690,6 +3922,111 @@ check_rss_recipient(
+ }
+
+
++#ifdef WITH_LSPP
++/*
++ * 'check_context()' - Check SELinux security context of a user and job
++ */
++
++static int /* O - 1 if OK, 0 if not, -1 on error */
++check_context(cupsd_client_t *con, /* I - Client connection */
++ cupsd_job_t *job) /* I - Job */
++{
++ int enforcing; /* is SELinux in enforcing mode */
++ char filename[1024]; /* Filename of the spool file */
++ security_id_t clisid; /* SELinux SID of the client */
++ security_id_t jobsid; /* SELinux SID of the job */
++ security_id_t filesid; /* SELinux SID of the spool file */
++ struct avc_entry_ref avcref; /* AVC entry cache pointer */
++ security_class_t tclass; /* SELinux security class */
++ access_vector_t avr; /* SELinux access being queried */
++ security_context_t spoolfilecon; /* SELinux context of the spool file */
++
++
++ /*
++ * Validate the input to be sure there are contexts to work with...
++ */
++
++ if (con->scon == NULL || job->scon == NULL
++ || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0
++ || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++ return -1;
++
++ if ((enforcing = security_getenforce()) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Error while determining SELinux enforcement");
++ return -1;
++ }
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "check_context: client context %s job context %s", con->scon, job->scon);
++
++
++ /*
++ * Initialize the avc engine...
++ */
++
++ static avc_initialized = 0;
++ if (! avc_initialized++)
++ {
++ if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable avc_init");
++ return -1;
++ }
++ }
++ if (avc_context_to_sid(con->scon, &clisid) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", con->scon);
++ return -1;
++ }
++ if (avc_context_to_sid(job->scon, &jobsid) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", job->scon);
++ return -1;
++ }
++ avc_entry_ref_init(&avcref);
++ tclass = SECCLASS_FILE;
++ avr = FILE__READ;
++
++ /*
++ * Perform the check with the client as the subject, first with the job as the object
++ * if that fails then with the spool file as the object...
++ */
++
++ if (avc_has_perm_noaudit(clisid, jobsid, tclass, avr, &avcref, NULL) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access based on the client context");
++
++ snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
++ if (getfilecon(filename, &spoolfilecon) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to get spoolfile context");
++ return -1;
++ }
++ if (avc_context_to_sid(spoolfilecon, &filesid) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to determine the SELinux sid for the spool file");
++ freecon(spoolfilecon);
++ return -1;
++ }
++ freecon(spoolfilecon);
++ if (avc_has_perm_noaudit(clisid, filesid, tclass, avr, &avcref, NULL) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access to the spool file");
++ return 0;
++ }
++ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access to the spool file");
++ return 1;
++ }
++ else
++ if (enforcing == 0)
++ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: allowing operation due to permissive mode");
++ else
++ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access based on the client context");
++
++ return 1;
++}
++#endif /* WITH_LSPP */
++
++
+ /*
+ * 'check_quotas()' - Check quotas for a printer and user.
+ */
+@@ -4142,6 +4479,15 @@ copy_banner(cupsd_client_t *con, /* I -
+ char attrname[255], /* Name of attribute */
+ *s; /* Pointer into name */
+ ipp_attribute_t *attr; /* Attribute */
++#ifdef WITH_LSPP
++ const char *mls_label; /* SL of print job */
++ char *jobrange; /* SELinux sensitivity range */
++ char *jobclearance; /* SELinux low end clearance */
++ context_t jobcon; /* SELinux context of the job */
++ context_t tmpcon; /* Temp context to set the level */
++ security_context_t spoolcon; /* Context of the file in the spool */
++#endif /* WITH_LSPP */
++
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+@@ -4177,6 +4523,82 @@ copy_banner(cupsd_client_t *con, /* I -
+
+ fchmod(cupsFileNumber(out), 0640);
+ fchown(cupsFileNumber(out), RunUser, Group);
++#ifdef WITH_LSPP
++ if (job->scon != NULL &&
++ strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++ {
++ if (getfilecon(filename, &spoolcon) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "copy_banner: Unable to get the context of the banner file %s - %s",
++ filename, strerror(errno));
++ job->num_files --;
++ return (0);
++ }
++ tmpcon = context_new(spoolcon);
++ jobcon = context_new(job->scon);
++ freecon(spoolcon);
++ if (!tmpcon || !jobcon)
++ {
++ if (tmpcon)
++ context_free(tmpcon);
++ if (jobcon)
++ context_free(jobcon);
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "copy_banner: Unable to get the SELinux contexts");
++ job->num_files --;
++ return (0);
++ }
++ jobrange = context_range_get(jobcon);
++ if (jobrange)
++ {
++ jobrange = strdup(jobrange);
++ if ((jobclearance = strtok(jobrange, "-")) != NULL)
++ {
++ if (context_range_set(tmpcon, jobclearance) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "copy_banner: Unable to set the level of the context for file %s - %s",
++ filename, strerror(errno));
++ free(jobrange);
++ context_free(jobcon);
++ context_free(tmpcon);
++ job->num_files --;
++ return (0);
++ }
++ }
++ else
++ {
++ if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "copy_banner: Unable to set the level of the context for file %s - %s",
++ filename, strerror(errno));
++ free(jobrange);
++ context_free(jobcon);
++ context_free(tmpcon);
++ job->num_files --;
++ return (0);
++ }
++ }
++ free(jobrange);
++ }
++ if (setfilecon(filename, context_str(tmpcon)) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "copy_banner: Unable to set the context of the banner file %s - %s",
++ filename, strerror(errno));
++ context_free(jobcon);
++ context_free(tmpcon);
++ job->num_files --;
++ return (0);
++ }
++ cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner: %s set to %s",
++ filename, context_str(tmpcon));
++ context_free(jobcon);
++ context_free(tmpcon);
++ }
++#endif /* WITH_LSPP */
+
+ /*
+ * Try the localized banner file under the subdirectory...
+@@ -4271,6 +4693,24 @@ copy_banner(cupsd_client_t *con, /* I -
+ else
+ s = attrname;
+
++#ifdef WITH_LSPP
++ if (strcmp(s, "mls-label") == 0)
++ {
++ if (job->scon != NULL && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++ {
++ jobcon = context_new(job->scon);
++ if (_cups_strcasecmp(name, MLS_CONFIG) == 0)
++ mls_label = context_range_get(jobcon);
++ else if (_cups_strcasecmp(name, TE_CONFIG) == 0)
++ mls_label = context_type_get(jobcon);
++ else // default to using the whole context string
++ mls_label = context_str(jobcon);
++ cupsFilePuts(out, mls_label);
++ context_free(jobcon);
++ }
++ continue;
++ }
++#endif /* WITH_LSPP */
+ if (!strcmp(s, "printer-name"))
+ {
+ cupsFilePuts(out, job->dest);
+@@ -6348,6 +6788,22 @@ get_job_attrs(cupsd_client_t *con, /* I
+
+ exclude = cupsdGetPrivateAttrs(policy, con, printer, job->username);
+
++
++#ifdef WITH_LSPP
++ /*
++ * Check SELinux...
++ */
++ if (is_lspp_config() && check_context(con, job) != 1)
++ {
++ /*
++ * Unfortunately we have to lie to the user...
++ */
++ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
++ return;
++ }
++#endif /* WITH_LSPP */
++
++
+ /*
+ * Copy attributes...
+ */
+@@ -6701,6 +7157,11 @@ get_jobs(cupsd_client_t *con, /* I - C
+ if (username[0] && _cups_strcasecmp(username, job->username))
+ continue;
+
++#ifdef WITH_LSPP
++ if (is_lspp_config() && check_context(con, job) != 1)
++ continue;
++#endif /* WITH_LSPP */
++
+ if (count > 0)
+ ippAddSeparator(con->response);
+
+@@ -11259,6 +11720,11 @@ validate_user(cupsd_job_t *job, /* I
+
+ strlcpy(username, get_username(con), userlen);
+
++#ifdef WITH_LSPP
++ if (is_lspp_config() && check_context(con, job) != 1)
++ return 0;
++#endif /* WITH_LSPP */
++
+ /*
+ * Check the username against the owner...
+ */
+diff -up cups-1.6.3/scheduler/job.c.lspp cups-1.6.3/scheduler/job.c
+--- cups-1.6.3/scheduler/job.c.lspp 2015-06-10 11:45:38.155441541 +0200
++++ cups-1.6.3/scheduler/job.c 2015-06-10 11:45:38.164441517 +0200
+@@ -68,6 +68,9 @@
+ * update_job_attrs() - Update the job-printer-* attributes.
+ */
+
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+ * Include necessary headers...
+ */
+@@ -83,6 +86,14 @@
+ # endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
+ #endif /* __APPLE__ */
+
++#ifdef WITH_LSPP
++#include
++#include
++#include
++#include
++#include
++#include
++#endif /* WITH_LSPP */
+
+ /*
+ * Design Notes for Job Management
+@@ -580,6 +591,14 @@ cupsdContinueJob(cupsd_job_t *job) /* I
+ /* PRINTER_STATE_REASONS env var */
+ rip_max_cache[255];
+ /* RIP_MAX_CACHE env variable */
++#ifdef WITH_LSPP
++ char *audit_message = NULL; /* Audit message string */
++ context_t jobcon; /* SELinux context of the job */
++ char *label_template = NULL; /* SL to put in classification
++ env var */
++ const char *mls_label = NULL; /* SL to put in classification
++ env var */
++#endif /* WITH_LSPP */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+@@ -1092,6 +1111,67 @@ cupsdContinueJob(cupsd_job_t *job) /* I
+ if (final_content_type[0])
+ envp[envc ++] = final_content_type;
+
++#ifdef WITH_LSPP
++ if (is_lspp_config())
++ {
++ if (!job->scon || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++ {
++ if (AuditLog != -1)
++ {
++ audit_message = NULL;
++ cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s",
++ job->id, job->auid, job->username, job->printer->name, title);
++ audit_log_user_message(AuditLog, AUDIT_USER_UNLABELED_EXPORT, audit_message,
++ ServerName, NULL, NULL, 1);
++ cupsdClearString(&audit_message);
++ }
++ }
++ else
++ {
++ jobcon = context_new(job->scon);
++
++ if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME)) == NULL)
++ label_template = strdup(Classification);
++ else if (attr->num_values > 1 &&
++ strcmp(attr->values[1].string.text, "none") != 0)
++ label_template = strdup(attr->values[1].string.text);
++ else
++ label_template = strdup(attr->values[0].string.text);
++
++ if (_cups_strcasecmp(label_template, MLS_CONFIG) == 0)
++ mls_label = context_range_get(jobcon);
++ else if (_cups_strcasecmp(label_template, TE_CONFIG) == 0)
++ mls_label = context_type_get(jobcon);
++ else if (_cups_strcasecmp(label_template, SELINUX_CONFIG) == 0)
++ mls_label = context_str(jobcon);
++ else
++ mls_label = label_template;
++
++ if (mls_label && (PerPageLabels || banner_page))
++ {
++ snprintf(classification, sizeof(classification), "CLASSIFICATION=LSPP:%s", mls_label);
++ envp[envc ++] = classification;
++ }
++
++ if ((AuditLog != -1) && !banner_page)
++ {
++ audit_message = NULL;
++ cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s"
++ " obj=%s label=%s", job->id, job->auid, job->username,
++ job->printer->name, title, job->scon, mls_label?mls_label:"none");
++ audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++ ServerName, NULL, NULL, 1);
++ cupsdClearString(&audit_message);
++ }
++ context_free(jobcon);
++ free(label_template);
++ }
++ }
++ else
++ /*
++ * Fall through to the non-LSPP behavior
++ */
++#endif /* WITH_LSPP */
+ if (Classification && !banner_page)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-sheets",
+@@ -1866,6 +1946,20 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
+ ippSetString(job->attrs, &job->reasons, 0, "none");
+ }
+
++#ifdef WITH_LSPP
++ if ((attr = ippFindAttribute(job->attrs, "security-context", IPP_TAG_NAME)) != NULL)
++ cupsdSetString(&job->scon, attr->values[0].string.text);
++ else if (is_lspp_config())
++ {
++ /*
++ * There was no security context so delete the job
++ */
++ cupsdLogMessage(CUPSD_LOG_ERROR, "LoadAllJobs: Missing or bad security-context attribute in control file \"%s\"!",
++ jobfile);
++ goto error;
++ }
++#endif /* WITH_LSPP */
++
+ job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed",
+ IPP_TAG_INTEGER);
+ job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
+@@ -2259,6 +2353,14 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J
+ {
+ char filename[1024]; /* Job control filename */
+ cups_file_t *fp; /* Job file */
++#ifdef WITH_LSPP
++ security_context_t spoolcon; /* context of the job control file */
++ context_t jobcon; /* contex_t container for job->scon */
++ context_t tmpcon; /* Temp context to swap the level */
++ char *jobclearance; /* SELinux low end clearance */
++ const char *jobrange; /* SELinux sensitivity range */
++ char *jobrange_copy; /* SELinux sensitivity range */
++#endif /* WITH_LSPP */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
+@@ -2271,6 +2373,76 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J
+
+ fchown(cupsFileNumber(fp), RunUser, Group);
+
++#ifdef WITH_LSPP
++ if (job->scon && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++ {
++ if (getfilecon(filename, &spoolcon) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "Unable to get context of job control file \"%s\" - %s.",
++ filename, strerror(errno));
++ return;
++ }
++ jobcon = context_new(job->scon);
++ tmpcon = context_new(spoolcon);
++ freecon(spoolcon);
++ if (!jobcon || !tmpcon)
++ {
++ if (jobcon)
++ context_free(jobcon);
++ if (tmpcon)
++ context_free(tmpcon);
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get SELinux contexts");
++ return;
++ }
++ jobrange = context_range_get(jobcon);
++ if (jobrange)
++ {
++ jobrange_copy = strdup(jobrange);
++ if ((jobclearance = strtok(jobrange_copy, "-")) != NULL)
++ {
++ if (context_range_set(tmpcon, jobclearance) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "Unable to set the range for job control file \"%s\" - %s.",
++ filename, strerror(errno));
++ free(jobrange_copy);
++ context_free(tmpcon);
++ context_free(jobcon);
++ return;
++ }
++ }
++ else
++ {
++ if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "Unable to set the range for job control file \"%s\" - %s.",
++ filename, strerror(errno));
++ free(jobrange_copy);
++ context_free(tmpcon);
++ context_free(jobcon);
++ return;
++ }
++ }
++ free(jobrange_copy);
++ }
++ if (setfilecon(filename, context_str(tmpcon)) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "Unable to set context of job control file \"%s\" - %s.",
++ filename, strerror(errno));
++ context_free(tmpcon);
++ context_free(jobcon);
++ return;
++ }
++ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p): new spool file context=%s",
++ job, context_str(tmpcon));
++ context_free(tmpcon);
++ context_free(jobcon);
++ }
++#endif /* WITH_LSPP */
++
+ job->attrs->state = IPP_IDLE;
+
+ if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
+@@ -3780,6 +3952,18 @@ get_options(cupsd_job_t *job, /* I - Jo
+ banner_page)
+ continue;
+
++#ifdef WITH_LSPP
++ /*
++ * In LSPP mode refuse to honor the page-label
++ */
++ if (is_lspp_config() &&
++ !strcmp(attr->name, "page-label"))
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Ignoring page-label option due to LSPP mode");
++ continue;
++ }
++#endif /* WITH_LSPP */
++
+ /*
+ * Otherwise add them to the list...
+ */
+@@ -4504,6 +4688,19 @@ static void
+ start_job(cupsd_job_t *job, /* I - Job ID */
+ cupsd_printer_t *printer) /* I - Printer to print job */
+ {
++#ifdef WITH_LSPP
++ char *audit_message = NULL; /* Audit message string */
++ char *printerfile = NULL; /* Device file pointed to by the printer */
++ security_id_t clisid; /* SELinux SID for the client */
++ security_id_t psid; /* SELinux SID for the printer */
++ context_t printercon; /* Printer's context string */
++ struct stat printerstat; /* Printer's stat buffer */
++ security_context_t devcon; /* Printer's SELinux context */
++ struct avc_entry_ref avcref; /* Pointer to the access vector cache */
++ security_class_t tclass; /* Object class for the SELinux check */
++ access_vector_t avr; /* Access method being requested */
++#endif /* WITH_LSPP */
++
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))",
+ job, job->id, printer, printer->name);
+
+@@ -4646,6 +4843,108 @@ start_job(cupsd_job_t *job, /* I -
+ fcntl(job->side_pipes[1], F_SETFD,
+ fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC);
+
++#ifdef WITH_LSPP
++ if (is_lspp_config())
++ {
++ /*
++ * Perform an access check before printing, but only if the printer starts with /dev/
++ */
++ printerfile = strstr(printer->device_uri, "/dev/");
++ if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
++ printerfile = printer->device_uri + strlen("file:");
++
++ if (printerfile != NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "StartJob: Attempting to check access on printer device %s", printerfile);
++ if (lstat(printerfile, &printerstat) < 0)
++ {
++ if (errno != ENOENT)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to stat the printer");
++ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++ return ;
++ }
++ /*
++ * The printer does not exist, so for now assume it's a FileDevice
++ */
++ tclass = SECCLASS_FILE;
++ avr = FILE__WRITE;
++ }
++ else if (S_ISCHR(printerstat.st_mode))
++ {
++ tclass = SECCLASS_CHR_FILE;
++ avr = CHR_FILE__WRITE;
++ }
++ else if (S_ISREG(printerstat.st_mode))
++ {
++ tclass = SECCLASS_FILE;
++ avr = FILE__WRITE;
++ }
++ else
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "StartJob: Printer is not a character device or regular file");
++ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++ return ;
++ }
++ static avc_initialized = 0;
++ if (!avc_initialized++)
++ avc_init("cupsd_dequeue_", NULL, NULL, NULL, NULL);
++ avc_entry_ref_init(&avcref);
++ if (avc_context_to_sid(job->scon, &clisid) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "StartJob: Unable to determine the SELinux sid for the job");
++ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++ return ;
++ }
++ if (getfilecon(printerfile, &devcon) == -1)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to get the SELinux context of %s",
++ printerfile);
++ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++ return ;
++ }
++ printercon = context_new(devcon);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "StartJob: printer context %s client context %s",
++ context_str(printercon), job->scon);
++ context_free(printercon);
++
++ if (avc_context_to_sid(devcon, &psid) != 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "StartJob: Unable to determine the SELinux sid for the printer");
++ freecon(devcon);
++ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++ return ;
++ }
++ freecon(devcon);
++
++ if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
++ {
++ /*
++ * The access check failed, so cancel the job and send an audit message
++ */
++ if (AuditLog != -1)
++ {
++ audit_message = NULL;
++ cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s obj=%s canceled"
++ " unable to access printer=%s", job->id,
++ job->auid, (job->username)?job->username:"?", job->scon, printer->name);
++ audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++ ServerName, NULL, NULL, 0);
++ cupsdClearString(&audit_message);
++ }
++
++ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++
++ return ;
++ }
++ }
++ }
++#endif /* WITH_LSPP */
++
+ /*
+ * Now start the first file in the job...
+ */
+diff -up cups-1.6.3/scheduler/job.h.lspp cups-1.6.3/scheduler/job.h
+--- cups-1.6.3/scheduler/job.h.lspp 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/scheduler/job.h 2015-06-10 11:45:38.164441517 +0200
+@@ -13,6 +13,13 @@
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ */
+
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
++#ifdef WITH_LSPP
++#include
++#endif /* WITH_LSPP */
++
+ /*
+ * Constants...
+ */
+@@ -82,6 +89,10 @@ struct cupsd_job_s /**** Job request *
+ int progress; /* Printing progress */
+ int num_keywords; /* Number of PPD keywords */
+ cups_option_t *keywords; /* PPD keywords */
++#ifdef WITH_LSPP
++ security_context_t scon; /* Security context of job */
++ uid_t auid; /* Audit loginuid for this job */
++#endif /* WITH_LSPP */
+ };
+
+ typedef struct cupsd_joblog_s /**** Job log message ****/
+diff -up cups-1.6.3/scheduler/main.c.lspp cups-1.6.3/scheduler/main.c
+--- cups-1.6.3/scheduler/main.c.lspp 2015-06-10 11:45:38.095441704 +0200
++++ cups-1.6.3/scheduler/main.c 2015-06-10 11:45:38.164441517 +0200
+@@ -38,6 +38,8 @@
+ * usage() - Show scheduler usage.
+ */
+
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+ * Include necessary headers...
+ */
+@@ -80,6 +82,9 @@
+ # include
+ #endif /* HAVE_SYS_PARAM_H */
+
++#ifdef WITH_LSPP
++# include
++#endif /* WITH_LSPP */
+
+ /*
+ * Local functions...
+@@ -143,6 +148,9 @@ main(int argc, /* I - Number of comm
+ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
++#if WITH_LSPP
++ auditfail_t failmode; /* Action for audit_open failure */
++#endif /* WITH_LSPP */
+ #ifdef __sgi
+ cups_file_t *fp; /* Fake lpsched lock file */
+ struct stat statbuf; /* Needed for checking lpsched FIFO */
+@@ -526,6 +534,25 @@ main(int argc, /* I - Number of comm
+ #endif /* DEBUG */
+ }
+
++#ifdef WITH_LSPP
++ if ((AuditLog = audit_open()) < 0 )
++ {
++ if (get_auditfail_action(&failmode) == 0)
++ {
++ if (failmode == FAIL_LOG)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to connect to audit subsystem.");
++ AuditLog = -1;
++ }
++ else if (failmode == FAIL_TERMINATE)
++ {
++ fprintf(stderr, "cupsd: unable to start auditing, terminating");
++ return -1;
++ }
++ }
++ }
++#endif /* WITH_LSPP */
++
+ /*
+ * Set the timezone info...
+ */
+@@ -1238,6 +1265,11 @@ main(int argc, /* I - Number of comm
+
+ cupsdStopSelect();
+
++#ifdef WITH_LSPP
++ if (AuditLog != -1)
++ audit_close(AuditLog);
++#endif /* WITH_LSPP */
++
+ return (!stop_scheduler);
+ }
+
+diff -up cups-1.6.3/scheduler/printers.c.lspp cups-1.6.3/scheduler/printers.c
+--- cups-1.6.3/scheduler/printers.c.lspp 2015-06-10 11:45:38.087441726 +0200
++++ cups-1.6.3/scheduler/printers.c 2015-06-10 11:45:38.165441514 +0200
+@@ -56,6 +56,8 @@
+ * write_xml_string() - Write a string with XML escaping.
+ */
+
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+ * Include necessary headers...
+ */
+@@ -80,6 +82,10 @@
+ # include
+ #endif /* __APPLE__ */
+
++#ifdef WITH_LSPP
++# include
++# include
++#endif /* WITH_LSPP */
+
+ /*
+ * Local functions...
+@@ -2107,6 +2113,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
+ ipp_attribute_t *attr; /* Attribute data */
+ char *name, /* Current user/group name */
+ *filter; /* Current filter */
++#ifdef WITH_LSPP
++ char *audit_message; /* Audit message string */
++ char *printerfile; /* Path to a local printer dev */
++ char *rangestr; /* Printer's range if its available */
++ security_context_t devcon; /* Printer SELinux context */
++ context_t printercon; /* context_t for the printer */
++#endif /* WITH_LSPP */
+
+
+ DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
+@@ -2229,6 +2242,45 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
+ attr->values[1].string.text = _cupsStrAlloc(Classification ?
+ Classification : p->job_sheets[1]);
+ }
++#ifdef WITH_LSPP
++ if (AuditLog != -1)
++ {
++ audit_message = NULL;
++ rangestr = NULL;
++ printercon = 0;
++ printerfile = strstr(p->device_uri, "/dev/");
++ if (printerfile == NULL && (strncmp(p->device_uri, "file:/", 6) == 0))
++ printerfile = p->device_uri + strlen("file:");
++
++ if (printerfile != NULL)
++ {
++ if (getfilecon(printerfile, &devcon) == -1)
++ {
++ if(is_selinux_enabled())
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetPrinterAttrs: Unable to get printer context");
++ }
++ else
++ {
++ printercon = context_new(devcon);
++ freecon(devcon);
++ }
++ }
++
++ if (printercon && context_range_get(printercon))
++ rangestr = strdup(context_range_get(printercon));
++ else
++ rangestr = strdup("unknown");
++
++ cupsdSetStringf(&audit_message, "printer=%s uri=%s banners=%s,%s range=%s",
++ p->name, p->sanitized_device_uri, p->job_sheets[0], p->job_sheets[1], rangestr);
++ audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
++ ServerName, NULL, NULL, 1);
++ if (printercon)
++ context_free(printercon);
++ free(rangestr);
++ cupsdClearString(&audit_message);
++ }
++#endif /* WITH_LSPP */
+ }
+
+ p->raw = 0;
+@@ -5315,7 +5367,6 @@ write_irix_state(cupsd_printer_t *p) /*
+ }
+ #endif /* __sgi */
+
+-
+ /*
+ * 'write_xml_string()' - Write a string with XML escaping.
+ */
diff --git a/SOURCES/cups-multilib.patch b/SOURCES/cups-multilib.patch
new file mode 100644
index 0000000..14a8959
--- /dev/null
+++ b/SOURCES/cups-multilib.patch
@@ -0,0 +1,16 @@
+diff -up cups-1.5b1/cups-config.in.multilib cups-1.5b1/cups-config.in
+--- cups-1.5b1/cups-config.in.multilib 2010-06-16 02:48:25.000000000 +0200
++++ cups-1.5b1/cups-config.in 2011-05-23 17:33:31.000000000 +0200
+@@ -22,8 +22,10 @@ prefix=@prefix@
+ exec_prefix=@exec_prefix@
+ bindir=@bindir@
+ includedir=@includedir@
+-libdir=@libdir@
+-imagelibdir=@libdir@
++# Fetch libdir from openssl's pkg-config script. This is a bit
++# of a cheat, but the cups-devel package requires openssl-devel anyway.
++libdir=`pkg-config --variable=libdir openssl`
++imagelibdir=`pkg-config --variable=libdir openssl`
+ datarootdir=@datadir@
+ datadir=@datadir@
+ sysconfdir=@sysconfdir@
diff --git a/SOURCES/cups-net-backends-etimedout-enotconn.patch b/SOURCES/cups-net-backends-etimedout-enotconn.patch
new file mode 100644
index 0000000..328540d
--- /dev/null
+++ b/SOURCES/cups-net-backends-etimedout-enotconn.patch
@@ -0,0 +1,102 @@
+From 4cf66fef48e992ae8f8196db50a742c6276e415b Mon Sep 17 00:00:00 2001
+From: Michael Sweet
+Date: Thu, 5 Oct 2017 15:04:19 -0400
+Subject: [PATCH] The network backends now retry on more error conditions
+ (Issue #5123)
+
+---
+ backend/ipp.c | 5 ++---
+ backend/lpd.c | 5 ++---
+ backend/socket.c | 5 ++---
+ 4 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/backend/ipp.c b/backend/ipp.c
+index 685d4d9df..588ad995e 100644
+--- a/backend/ipp.c
++++ b/backend/ipp.c
+@@ -743,8 +743,7 @@ main(int argc, /* I - Number of command-line args */
+
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
+
+- if (errno == ECONNREFUSED || errno == EHOSTDOWN ||
+- errno == EHOSTUNREACH)
++ if (errno == ECONNREFUSED || errno == EHOSTDOWN || errno == EHOSTUNREACH || errno == ETIMEDOUT || errno == ENOTCONN)
+ {
+ if (contimeout && (time(NULL) - start_time) > contimeout)
+ {
+@@ -763,13 +762,13 @@ main(int argc, /* I - Number of command-line args */
+ break;
+
+ case EHOSTUNREACH :
++ default :
+ _cupsLangPrintFilter(stderr, "WARNING",
+ _("The printer is unreachable at this "
+ "time."));
+ break;
+
+ case ECONNREFUSED :
+- default :
+ _cupsLangPrintFilter(stderr, "WARNING",
+ _("The printer is in use."));
+ break;
+diff --git a/backend/lpd.c b/backend/lpd.c
+index 835f9eaee..4325b7c78 100644
+--- a/backend/lpd.c
++++ b/backend/lpd.c
+@@ -867,8 +867,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
+
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error));
+
+- if (error == ECONNREFUSED || error == EHOSTDOWN ||
+- error == EHOSTUNREACH)
++ if (errno == ECONNREFUSED || errno == EHOSTDOWN || errno == EHOSTUNREACH || errno == ETIMEDOUT || errno == ENOTCONN)
+ {
+ if (contimeout && (time(NULL) - start_time) > contimeout)
+ {
+@@ -886,13 +885,13 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
+ break;
+
+ case EHOSTUNREACH :
++ default :
+ _cupsLangPrintFilter(stderr, "WARNING",
+ _("The printer is unreachable at "
+ "this time."));
+ break;
+
+ case ECONNREFUSED :
+- default :
+ _cupsLangPrintFilter(stderr, "WARNING",
+ _("The printer is in use."));
+ break;
+diff --git a/backend/socket.c b/backend/socket.c
+index 7fc0880f1..c16a1a097 100644
+--- a/backend/socket.c
++++ b/backend/socket.c
+@@ -330,8 +330,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
+
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error));
+
+- if (error == ECONNREFUSED || error == EHOSTDOWN ||
+- error == EHOSTUNREACH)
++ if (errno == ECONNREFUSED || errno == EHOSTDOWN || errno == EHOSTUNREACH || errno == ETIMEDOUT || errno == ENOTCONN)
+ {
+ if (contimeout && (time(NULL) - start_time) > contimeout)
+ {
+@@ -349,13 +348,13 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ break;
+
+ case EHOSTUNREACH :
++ default :
+ _cupsLangPrintFilter(stderr, "WARNING",
+ _("The printer is unreachable at this "
+ "time."));
+ break;
+
+ case ECONNREFUSED :
+- default :
+ _cupsLangPrintFilter(stderr, "WARNING",
+ _("The printer is in use."));
+ break;
+--
+2.13.6
+
diff --git a/SOURCES/cups-no-export-ssllibs.patch b/SOURCES/cups-no-export-ssllibs.patch
new file mode 100644
index 0000000..de277d8
--- /dev/null
+++ b/SOURCES/cups-no-export-ssllibs.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.5.3/config-scripts/cups-ssl.m4.no-export-ssllibs cups-1.5.3/config-scripts/cups-ssl.m4
+--- cups-1.5.3/config-scripts/cups-ssl.m4.no-export-ssllibs 2012-03-21 05:45:48.000000000 +0100
++++ cups-1.5.3/config-scripts/cups-ssl.m4 2012-05-15 16:47:13.753314620 +0200
+@@ -173,7 +173,7 @@ AC_SUBST(IPPALIASES)
+ AC_SUBST(SSLFLAGS)
+ AC_SUBST(SSLLIBS)
+
+-EXPORT_SSLLIBS="$SSLLIBS"
++EXPORT_SSLLIBS=""
+ AC_SUBST(EXPORT_SSLLIBS)
+
+ dnl
diff --git a/SOURCES/cups-no-gcry.patch b/SOURCES/cups-no-gcry.patch
new file mode 100644
index 0000000..69c42dc
--- /dev/null
+++ b/SOURCES/cups-no-gcry.patch
@@ -0,0 +1,37 @@
+diff -up cups-1.6.2/config-scripts/cups-ssl.m4.no-gcry cups-1.6.2/config-scripts/cups-ssl.m4
+--- cups-1.6.2/config-scripts/cups-ssl.m4.no-gcry 2013-06-26 17:26:41.415750243 +0100
++++ cups-1.6.2/config-scripts/cups-ssl.m4 2013-06-26 17:26:41.467750445 +0100
+@@ -93,7 +93,6 @@ if test x$enable_ssl != xno; then
+ dnl Then look for GNU TLS...
+ if test $have_ssl = 0 -a "x$enable_gnutls" != "xno" -a "x$PKGCONFIG" != x; then
+ AC_PATH_PROG(LIBGNUTLSCONFIG,libgnutls-config)
+- AC_PATH_PROG(LIBGCRYPTCONFIG,libgcrypt-config)
+ if $PKGCONFIG --exists gnutls; then
+ have_ssl=1
+ SSLLIBS=`$PKGCONFIG --libs gnutls`
+@@ -111,14 +110,6 @@ if test x$enable_ssl != xno; then
+ if test $have_ssl = 1; then
+ CUPS_SERVERCERT="ssl/server.crt"
+ CUPS_SERVERKEY="ssl/server.key"
+-
+- if $PKGCONFIG --exists gcrypt; then
+- SSLLIBS="$SSLLIBS `$PKGCONFIG --libs gcrypt`"
+- SSLFLAGS="$SSLFLAGS `$PKGCONFIG --cflags gcrypt`"
+- elif test "x$LIBGCRYPTCONFIG" != x; then
+- SSLLIBS="$SSLLIBS `$LIBGCRYPTCONFIG --libs`"
+- SSLFLAGS="$SSLFLAGS `$LIBGCRYPTCONFIG --cflags`"
+- fi
+ fi
+ fi
+
+diff -up cups-1.6.2/cups/http-private.h.no-gcry cups-1.6.2/cups/http-private.h
+--- cups-1.6.2/cups/http-private.h.no-gcry 2012-12-17 22:17:08.000000000 +0000
++++ cups-1.6.2/cups/http-private.h 2013-06-26 17:26:41.468750449 +0100
+@@ -78,7 +78,6 @@ typedef int socklen_t;
+ # elif defined HAVE_GNUTLS
+ # include
+ # include
+-# include
+ # elif defined(HAVE_CDSASSL)
+ # include
+ # include
diff --git a/SOURCES/cups-no-gzip-man.patch b/SOURCES/cups-no-gzip-man.patch
new file mode 100644
index 0000000..cabfcf1
--- /dev/null
+++ b/SOURCES/cups-no-gzip-man.patch
@@ -0,0 +1,18 @@
+diff -up cups-1.6b1/config-scripts/cups-manpages.m4.no-gzip-man cups-1.6b1/config-scripts/cups-manpages.m4
+--- cups-1.6b1/config-scripts/cups-manpages.m4.no-gzip-man 2012-04-23 19:26:57.000000000 +0200
++++ cups-1.6b1/config-scripts/cups-manpages.m4 2012-05-25 14:57:01.959845267 +0200
+@@ -69,10 +69,10 @@ case "$uname" in
+ ;;
+ Linux* | GNU* | Darwin*)
+ # Linux, GNU Hurd, and OS X
+- MAN1EXT=1.gz
+- MAN5EXT=5.gz
+- MAN7EXT=7.gz
+- MAN8EXT=8.gz
++ MAN1EXT=1
++ MAN5EXT=5
++ MAN7EXT=7
++ MAN8EXT=8
+ MAN8DIR=8
+ ;;
+ *)
diff --git a/SOURCES/cups-nodatadelay.patch b/SOURCES/cups-nodatadelay.patch
new file mode 100644
index 0000000..b808a20
--- /dev/null
+++ b/SOURCES/cups-nodatadelay.patch
@@ -0,0 +1,14 @@
+diff -up cups-1.6.3/scheduler/client.c.nodatadelay cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.nodatadelay 2014-09-02 10:50:07.714003098 +0100
++++ cups-1.6.3/scheduler/client.c 2014-09-02 10:50:30.960118311 +0100
+@@ -2138,7 +2138,9 @@ cupsdReadClient(cupsd_client_t *con) /*
+
+ if (con->http.state != HTTP_POST_SEND)
+ {
+- if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0)
++ if (!httpWait(HTTP(con), 0))
++ return;
++ else if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0)
+ {
+ if (con->http.error && con->http.error != EPIPE)
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
diff --git a/SOURCES/cups-peercred.patch b/SOURCES/cups-peercred.patch
new file mode 100644
index 0000000..a106abb
--- /dev/null
+++ b/SOURCES/cups-peercred.patch
@@ -0,0 +1,11 @@
+diff -up cups-1.5b1/scheduler/auth.c.peercred cups-1.5b1/scheduler/auth.c
+--- cups-1.5b1/scheduler/auth.c.peercred 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/auth.c 2011-05-23 18:00:18.000000000 +0200
+@@ -52,6 +52,7 @@
+ * Include necessary headers...
+ */
+
++#define _GNU_SOURCE
+ #include "cupsd.h"
+ #include
+ #ifdef HAVE_SHADOW_H
diff --git a/SOURCES/cups-pid.patch b/SOURCES/cups-pid.patch
new file mode 100644
index 0000000..23ffd47
--- /dev/null
+++ b/SOURCES/cups-pid.patch
@@ -0,0 +1,37 @@
+diff -up cups-1.5b1/scheduler/main.c.pid cups-1.5b1/scheduler/main.c
+--- cups-1.5b1/scheduler/main.c.pid 2011-05-18 22:44:16.000000000 +0200
++++ cups-1.5b1/scheduler/main.c 2011-05-23 18:01:20.000000000 +0200
+@@ -311,6 +311,8 @@ main(int argc, /* I - Number of comm
+ * Setup signal handlers for the parent...
+ */
+
++ pid_t pid;
++
+ #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGUSR1, parent_handler);
+ sigset(SIGCHLD, parent_handler);
+@@ -334,7 +336,7 @@ main(int argc, /* I - Number of comm
+ signal(SIGHUP, SIG_IGN);
+ #endif /* HAVE_SIGSET */
+
+- if (fork() > 0)
++ if ((pid = fork()) > 0)
+ {
+ /*
+ * OK, wait for the child to startup and send us SIGUSR1 or to crash
+@@ -346,7 +348,15 @@ main(int argc, /* I - Number of comm
+ sleep(1);
+
+ if (parent_signal == SIGUSR1)
++ {
++ FILE *f = fopen ("/var/run/cupsd.pid", "w");
++ if (f)
++ {
++ fprintf (f, "%d\n", pid);
++ fclose (f);
++ }
+ return (0);
++ }
+
+ if (wait(&i) < 0)
+ {
diff --git a/SOURCES/cups-res_init.patch b/SOURCES/cups-res_init.patch
new file mode 100644
index 0000000..94a81a4
--- /dev/null
+++ b/SOURCES/cups-res_init.patch
@@ -0,0 +1,26 @@
+diff -up cups-1.6b1/cups/http-addr.c.res_init cups-1.6b1/cups/http-addr.c
+--- cups-1.6b1/cups/http-addr.c.res_init 2012-05-17 00:57:03.000000000 +0200
++++ cups-1.6b1/cups/http-addr.c 2012-05-25 15:51:51.323916352 +0200
+@@ -254,7 +254,8 @@ httpAddrLookup(
+
+ if (error)
+ {
+- if (error == EAI_FAIL)
++ if (error == EAI_FAIL || error == EAI_AGAIN || error == EAI_NODATA ||
++ error == EAI_NONAME)
+ cg->need_res_init = 1;
+
+ return (httpAddrString(addr, name, namelen));
+diff -up cups-1.6b1/cups/http-addrlist.c.res_init cups-1.6b1/cups/http-addrlist.c
+--- cups-1.6b1/cups/http-addrlist.c.res_init 2012-04-23 19:26:57.000000000 +0200
++++ cups-1.6b1/cups/http-addrlist.c 2012-05-25 16:05:05.930377452 +0200
+@@ -540,7 +540,8 @@ httpAddrGetList(const char *hostname, /*
+ }
+ else
+ {
+- if (error == EAI_FAIL)
++ if (error == EAI_FAIL || error == EAI_AGAIN || error == EAI_NODATA ||
++ error == EAI_NONAME)
+ cg->need_res_init = 1;
+
+ _cupsSetError(IPP_INTERNAL_ERROR, gai_strerror(error), 0);
diff --git a/SOURCES/cups-ricoh-deviceid-oid.patch b/SOURCES/cups-ricoh-deviceid-oid.patch
new file mode 100644
index 0000000..c148f95
--- /dev/null
+++ b/SOURCES/cups-ricoh-deviceid-oid.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.5b1/backend/snmp.c.ricoh-deviceid-oid cups-1.5b1/backend/snmp.c
+--- cups-1.5b1/backend/snmp.c.ricoh-deviceid-oid 2011-05-24 17:29:48.000000000 +0200
++++ cups-1.5b1/backend/snmp.c 2011-05-24 17:29:48.000000000 +0200
+@@ -188,6 +188,7 @@ static const int LexmarkProductOID[] = {
+ static const int LexmarkProductOID2[] = { 1,3,6,1,4,1,674,10898,100,2,1,2,1,2,1,-1 };
+ static const int LexmarkDeviceIdOID[] = { 1,3,6,1,4,1,641,2,1,2,1,3,1,-1 };
+ static const int HPDeviceIdOID[] = { 1,3,6,1,4,1,11,2,3,9,1,1,7,0,-1 };
++static const int RicohDeviceIdOID[] = { 1,3,6,1,4,1,367,3,2,1,1,1,11,0,-1 };
+ static const int XeroxProductOID[] = { 1,3,6,1,4,1,128,2,1,3,1,2,0,-1 };
+ static cups_array_t *DeviceURIs = NULL;
+ static int HostNameLookups = 0;
+@@ -1005,6 +1006,9 @@ read_snmp_response(int fd) /* I - SNMP
+ packet.community, CUPS_ASN1_GET_REQUEST,
+ DEVICE_ID, LexmarkDeviceIdOID);
+ _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
++ packet.community, CUPS_ASN1_GET_REQUEST,
++ DEVICE_ID, RicohDeviceIdOID);
++ _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+ packet.community, CUPS_ASN1_GET_REQUEST,
+ DEVICE_PRODUCT, XeroxProductOID);
+ _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
diff --git a/SOURCES/cups-serverbin-compat.patch b/SOURCES/cups-serverbin-compat.patch
new file mode 100644
index 0000000..0ca72fd
--- /dev/null
+++ b/SOURCES/cups-serverbin-compat.patch
@@ -0,0 +1,190 @@
+diff -up cups-1.5b1/scheduler/conf.c.serverbin-compat cups-1.5b1/scheduler/conf.c
+--- cups-1.5b1/scheduler/conf.c.serverbin-compat 2011-05-20 06:24:54.000000000 +0200
++++ cups-1.5b1/scheduler/conf.c 2011-05-23 17:20:33.000000000 +0200
+@@ -491,6 +491,9 @@ cupsdReadConfiguration(void)
+ cupsdClearString(&ServerName);
+ cupsdClearString(&ServerAdmin);
+ cupsdSetString(&ServerBin, CUPS_SERVERBIN);
++#ifdef __x86_64__
++ cupsdSetString(&ServerBin_compat, "/usr/lib64/cups");
++#endif /* __x86_64__ */
+ cupsdSetString(&RequestRoot, CUPS_REQUESTS);
+ cupsdSetString(&CacheDir, CUPS_CACHEDIR);
+ cupsdSetString(&DataDir, CUPS_DATADIR);
+@@ -1378,7 +1381,12 @@ cupsdReadConfiguration(void)
+ * Read the MIME type and conversion database...
+ */
+
++#ifdef __x86_64__
++ snprintf(temp, sizeof(temp), "%s/filter:%s/filter", ServerBin,
++ ServerBin_compat);
++#else
+ snprintf(temp, sizeof(temp), "%s/filter", ServerBin);
++#endif
+ snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);
+
+ MimeDatabase = mimeNew();
+diff -up cups-1.5b1/scheduler/conf.h.serverbin-compat cups-1.5b1/scheduler/conf.h
+--- cups-1.5b1/scheduler/conf.h.serverbin-compat 2011-04-22 19:47:03.000000000 +0200
++++ cups-1.5b1/scheduler/conf.h 2011-05-23 15:34:25.000000000 +0200
+@@ -105,6 +105,10 @@ VAR char *ConfigurationFile VALUE(NULL)
+ /* Root directory for scheduler */
+ *ServerBin VALUE(NULL),
+ /* Root directory for binaries */
++#ifdef __x86_64__
++ *ServerBin_compat VALUE(NULL),
++ /* Compat directory for binaries */
++#endif /* __x86_64__ */
+ *StateDir VALUE(NULL),
+ /* Root directory for state data */
+ *RequestRoot VALUE(NULL),
+diff -up cups-1.5b1/scheduler/env.c.serverbin-compat cups-1.5b1/scheduler/env.c
+--- cups-1.5b1/scheduler/env.c.serverbin-compat 2011-01-11 04:48:42.000000000 +0100
++++ cups-1.5b1/scheduler/env.c 2011-05-23 17:07:17.000000000 +0200
+@@ -218,8 +218,13 @@ cupsdUpdateEnv(void)
+ set_if_undefined("LD_PRELOAD", NULL);
+ set_if_undefined("NLSPATH", NULL);
+ if (find_env("PATH") < 0)
++#ifdef __x86_64__
++ cupsdSetEnvf("PATH", "%s/filter:%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR
++ ":/bin:/usr/bin", ServerBin, ServerBin_compat);
++#else /* ! defined(__x86_64__) */
+ cupsdSetEnvf("PATH", "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR
+ ":/bin:/usr/bin", ServerBin);
++#endif
+ set_if_undefined("SERVER_ADMIN", ServerAdmin);
+ set_if_undefined("SHLIB_PATH", NULL);
+ set_if_undefined("SOFTWARE", CUPS_MINIMAL);
+diff -up cups-1.5b1/scheduler/ipp.c.serverbin-compat cups-1.5b1/scheduler/ipp.c
+--- cups-1.5b1/scheduler/ipp.c.serverbin-compat 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/ipp.c 2011-05-23 16:09:57.000000000 +0200
+@@ -2586,9 +2586,18 @@ add_printer(cupsd_client_t *con, /* I -
+ * Could not find device in list!
+ */
+
++#ifdef __x86_64__
++ snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin_compat,
++ scheme);
++ if (access(srcfile, X_OK))
++ {
++#endif /* __x86_64__ */
+ send_ipp_status(con, IPP_NOT_POSSIBLE,
+ _("Bad device-uri scheme \"%s\"."), scheme);
+ return;
++#ifdef __x86_64__
++ }
++#endif /* __x86_64__ */
+ }
+ }
+
+diff -up cups-1.5b1/scheduler/job.c.serverbin-compat cups-1.5b1/scheduler/job.c
+--- cups-1.5b1/scheduler/job.c.serverbin-compat 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/job.c 2011-05-23 16:18:57.000000000 +0200
+@@ -1047,8 +1047,32 @@ cupsdContinueJob(cupsd_job_t *job) /* I
+ i ++, filter = (mime_filter_t *)cupsArrayNext(filters))
+ {
+ if (filter->filter[0] != '/')
+- snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
+- filter->filter);
++ {
++ snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
++ filter->filter);
++#ifdef __x86_64__
++ if (access(command, F_OK))
++ {
++ snprintf(command, sizeof(command), "%s/filter/%s",
++ ServerBin_compat, filter->filter);
++ if (!access(command, F_OK))
++ {
++ /* Not in the correct directory, but found it in the compat
++ * directory. Issue a warning. */
++ cupsdLogMessage(CUPSD_LOG_INFO,
++ "Filter '%s' not in %s/filter!",
++ filter->filter, ServerBin);
++ }
++ else
++ {
++ /* Not in the compat directory either; make any error
++ * messages use the correct directory name then. */
++ snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
++ filter->filter);
++ }
++ }
++#endif /* __x86_64__ */
++ }
+ else
+ strlcpy(command, filter->filter, sizeof(command));
+
+@@ -1199,6 +1223,28 @@ cupsdContinueJob(cupsd_job_t *job) /* I
+ {
+ cupsdClosePipe(job->back_pipes);
+ cupsdClosePipe(job->side_pipes);
++#ifdef __x86_64__
++ if (access(command, F_OK))
++ {
++ snprintf(command, sizeof(command), "%s/backend/%s", ServerBin_compat,
++ scheme);
++ if (!access(command, F_OK))
++ {
++ /* Not in the correct directory, but we found it in the compat
++ * directory. Issue a warning. */
++ cupsdLogMessage(CUPSD_LOG_INFO,
++ "Backend '%s' not in %s/backend!", scheme,
++ ServerBin);
++ }
++ else
++ {
++ /* Not in the compat directory either; make any error
++ messages use the correct directory name then. */
++ snprintf(command, sizeof(command), "%s/backend/%s", ServerBin,
++ scheme);
++ }
++ }
++#endif /* __x86_64__ */
+
+ close(job->status_pipes[1]);
+ job->status_pipes[1] = -1;
+diff -up cups-1.5b1/scheduler/printers.c.serverbin-compat cups-1.5b1/scheduler/printers.c
+--- cups-1.5b1/scheduler/printers.c.serverbin-compat 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/printers.c 2011-05-23 17:09:04.000000000 +0200
+@@ -1030,9 +1030,19 @@ cupsdLoadAllPrinters(void)
+ * Backend does not exist, stop printer...
+ */
+
++#ifdef __x86_64__
++ snprintf(line, sizeof(line), "%s/backend/%s", ServerBin_compat,
++ p->device_uri);
++ if (access(line, 0))
++ {
++#endif /* __x86_64__ */
++
+ p->state = IPP_PRINTER_STOPPED;
+ snprintf(p->state_message, sizeof(p->state_message),
+ "Backend %s does not exist!", line);
++#ifdef __x86_64__
++ }
++#endif /* __x86_64__ */
+ }
+ }
+
+@@ -3621,8 +3631,20 @@ add_printer_filter(
+ else
+ snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program);
+
++#ifdef __x86_64__
++ if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
++ cupsdLogFCMessage, p) == _CUPS_FILE_CHECK_MISSING) {
++ snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin_compat,
++ program);
++ if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
++ cupsdLogFCMessage, p) == _CUPS_FILE_CHECK_MISSING)
++ snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin,
++ program);
++ }
++#else /* ! defined(__x86_64__) */
+ _cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
+ cupsdLogFCMessage, p);
++#endif
+ }
+
+ /*
diff --git a/SOURCES/cups-start-service.patch b/SOURCES/cups-start-service.patch
new file mode 100644
index 0000000..26952cf
--- /dev/null
+++ b/SOURCES/cups-start-service.patch
@@ -0,0 +1,9 @@
+diff -up cups-1.6.3/data/cups.service.in.start-service cups-1.6.3/data/cups.service.in
+--- cups-1.6.3/data/cups.service.in.start-service 2015-07-21 16:14:18.837479112 +0100
++++ cups-1.6.3/data/cups.service.in 2015-07-21 16:14:42.965396925 +0100
+@@ -8,4 +8,4 @@ PrivateTmp=true
+
+ [Install]
+ Also=cups.socket cups.path
+-WantedBy=printer.target
++WantedBy=multi-user.target printer.target
diff --git a/SOURCES/cups-state-message.patch b/SOURCES/cups-state-message.patch
new file mode 100644
index 0000000..8134b68
--- /dev/null
+++ b/SOURCES/cups-state-message.patch
@@ -0,0 +1,45 @@
+diff -up cups-1.6.3/scheduler/job.c.state-message cups-1.6.3/scheduler/job.c
+--- cups-1.6.3/scheduler/job.c.state-message 2017-01-17 13:00:04.298739909 +0100
++++ cups-1.6.3/scheduler/job.c 2017-01-18 16:29:00.347457271 +0100
+@@ -3638,6 +3638,13 @@ finalize_job(cupsd_job_t *job, /* I - J
+ cupsArrayRemove(PrintingJobs, job);
+
+ /*
++ * Clear informational messages...
++ */
++
++ if (job->status_level > CUPSD_LOG_ERROR)
++ job->printer->state_message[0] = '\0';
++
++ /*
+ * Apply any PPD updates...
+ */
+
+diff -up cups-1.6.3/xcode/CUPS.xcodeproj/project.pbxproj.state-message cups-1.6.3/xcode/CUPS.xcodeproj/project.pbxproj
+--- cups-1.6.3/xcode/CUPS.xcodeproj/project.pbxproj.state-message 2017-01-17 13:00:40.004504156 +0100
++++ cups-1.6.3/xcode/CUPS.xcodeproj/project.pbxproj 2017-01-18 16:34:02.409677280 +0100
+@@ -2653,7 +2653,7 @@
+ 72BF96371333042100B1EAD7 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+- LastUpgradeCheck = 0440;
++ LastUpgradeCheck = 0800;
+ ORGANIZATIONNAME = "Apple Inc.";
+ };
+ buildConfigurationList = 72BF963A1333042100B1EAD7 /* Build configuration list for PBXProject "CUPS" */;
+@@ -3968,6 +3968,7 @@
+ 72BF963C1333042100B1EAD7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
++ ASSETCATALOG_COMPRESSION = lossless;
+ ARCHS = "$(NATIVE_ARCH_ACTUAL)";
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
+@@ -3994,6 +3995,7 @@
+ 72BF963D1333042100B1EAD7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
++ ASSETCATALOG_COMPRESSION = "respect-asset-catalog";
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
diff --git a/SOURCES/cups-str3382.patch b/SOURCES/cups-str3382.patch
new file mode 100644
index 0000000..2e8736d
--- /dev/null
+++ b/SOURCES/cups-str3382.patch
@@ -0,0 +1,64 @@
+diff -up cups-1.5b1/cups/tempfile.c.str3382 cups-1.5b1/cups/tempfile.c
+--- cups-1.5b1/cups/tempfile.c.str3382 2010-03-24 01:45:34.000000000 +0100
++++ cups-1.5b1/cups/tempfile.c 2011-05-24 16:04:47.000000000 +0200
+@@ -33,6 +33,7 @@
+ # include
+ #else
+ # include
++# include
+ #endif /* WIN32 || __EMX__ */
+
+
+@@ -54,7 +55,7 @@ cupsTempFd(char *filename, /* I - Point
+ char tmppath[1024]; /* Windows temporary directory */
+ DWORD curtime; /* Current time */
+ #else
+- struct timeval curtime; /* Current time */
++ mode_t old_umask; /* Old umask before using mkstemp() */
+ #endif /* WIN32 */
+
+
+@@ -105,33 +106,25 @@ cupsTempFd(char *filename, /* I - Point
+
+ snprintf(filename, len - 1, "%s/%05lx%08lx", tmpdir,
+ GetCurrentProcessId(), curtime);
+-#else
+- /*
+- * Get the current time of day...
+- */
+-
+- gettimeofday(&curtime, NULL);
+-
+- /*
+- * Format a string using the hex time values...
+- */
+-
+- snprintf(filename, len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(),
+- (unsigned)(curtime.tv_sec + curtime.tv_usec + tries));
+-#endif /* WIN32 */
+
+ /*
+ * Open the file in "exclusive" mode, making sure that we don't
+ * stomp on an existing file or someone's symlink crack...
+ */
+
+-#ifdef WIN32
+ fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
+ _S_IREAD | _S_IWRITE);
+-#elif defined(O_NOFOLLOW)
+- fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
+ #else
+- fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
++
++ /*
++ * Use the standard mkstemp() call to make a temporary filename
++ * securely. -- andrew.wood@jdplc.com
++ */
++ snprintf(filename, len - 1, "%s/cupsXXXXXX", tmpdir);
++
++ old_umask = umask(0077);
++ fd = mkstemp(filename);
++ umask(old_umask);
+ #endif /* WIN32 */
+
+ if (fd < 0 && errno != EEXIST)
diff --git a/SOURCES/cups-str4326.patch b/SOURCES/cups-str4326.patch
new file mode 100644
index 0000000..2683e25
--- /dev/null
+++ b/SOURCES/cups-str4326.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.6.3/scheduler/ipp.c.str4326 cups-1.6.3/scheduler/ipp.c
+--- cups-1.6.3/scheduler/ipp.c.str4326 2014-01-07 09:59:34.787935368 +0000
++++ cups-1.6.3/scheduler/ipp.c 2014-01-07 09:59:34.855935681 +0000
+@@ -3,7 +3,7 @@
+ *
+ * IPP routines for the CUPS scheduler.
+ *
+- * Copyright 2007-2013 by Apple Inc.
++ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * This file contains Kerberos support code, copyright 2006 by
+@@ -6522,7 +6522,7 @@ get_jobs(cupsd_client_t *con, /* I - C
+ {
+ job_comparison = -1;
+ job_state = IPP_JOB_STOPPED;
+- list = Jobs;
++ list = ActiveJobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "completed"))
+ {
diff --git a/SOURCES/cups-str4327.patch b/SOURCES/cups-str4327.patch
new file mode 100644
index 0000000..f5cb51f
--- /dev/null
+++ b/SOURCES/cups-str4327.patch
@@ -0,0 +1,30 @@
+diff -up cups-1.7.0/cups/usersys.c.str4327 cups-1.7.0/cups/usersys.c
+--- cups-1.7.0/cups/usersys.c.str4327 2013-07-10 15:08:39.000000000 +0100
++++ cups-1.7.0/cups/usersys.c 2014-01-08 16:30:40.443026913 +0000
+@@ -875,7 +875,25 @@ _cupsSetDefaults(void)
+ cups_expiredcerts = getenv("CUPS_EXPIREDCERTS");
+
+ if ((cups_user = getenv("CUPS_USER")) == NULL)
+- cups_user = getenv("USER");
++ {
++ /*
++ * Try the USER environment variable...
++ */
++
++ if ((cups_user = getenv("USER")) != NULL)
++ {
++ /*
++ * Validate USER matches the current UID, otherwise don't allow it to
++ * override things... This makes sure that printing after doing su or
++ * sudo records the correct username.
++ */
++
++ struct passwd *pw; /* Account information */
++
++ if ((pw = getpwnam(cups_user)) == NULL || pw->pw_uid != getuid())
++ cups_user = NULL;
++ }
++ }
+
+ /*
+ * Then, if needed, read the ~/.cups/client.conf or /etc/cups/client.conf
diff --git a/SOURCES/cups-str4380.patch b/SOURCES/cups-str4380.patch
new file mode 100644
index 0000000..84753ca
--- /dev/null
+++ b/SOURCES/cups-str4380.patch
@@ -0,0 +1,20 @@
+diff -up cups-1.6.3/cups/dest.c.str4380 cups-1.6.3/cups/dest.c
+--- cups-1.6.3/cups/dest.c.str4380 2014-09-02 10:44:24.753303299 +0100
++++ cups-1.6.3/cups/dest.c 2014-09-02 10:44:24.785303458 +0100
+@@ -951,11 +951,11 @@ cupsEnumDests(
+ * Get Bonjour-shared printers...
+ */
+
+- data.type = type;
+- data.mask = mask;
+- data.devices = cupsArrayNew3((cups_array_func_t)cups_dnssd_compare_devices,
+- NULL, NULL, 0, NULL,
+- (cups_afree_func_t)cups_dnssd_free_device);
++ data.type = type;
++ data.mask = mask;
++ data.cb = cb;
++ data.user_data = user_data;
++ data.devices = cupsArrayNew3((cups_array_func_t)cups_dnssd_compare_devices, NULL, NULL, 0, NULL, (cups_afree_func_t)cups_dnssd_free_device);
+
+ # ifdef HAVE_DNSSD
+ if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError)
diff --git a/SOURCES/cups-str4440.patch b/SOURCES/cups-str4440.patch
new file mode 100644
index 0000000..258d3bc
--- /dev/null
+++ b/SOURCES/cups-str4440.patch
@@ -0,0 +1,13 @@
+diff -up cups-1.6.3/scheduler/client.c.str4440 cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.str4440 2014-09-02 11:02:03.363550036 +0100
++++ cups-1.6.3/scheduler/client.c 2014-09-02 11:02:34.114702446 +0100
+@@ -2075,6 +2075,9 @@ cupsdReadClient(cupsd_client_t *con) /*
+ * Grab any request data from the connection...
+ */
+
++ if (!httpWait(HTTP(con), 0))
++ return;
++
+ if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
diff --git a/SOURCES/cups-str4461.patch b/SOURCES/cups-str4461.patch
new file mode 100644
index 0000000..5d60d68
--- /dev/null
+++ b/SOURCES/cups-str4461.patch
@@ -0,0 +1,177 @@
+diff -up cups-1.6.3/notifier/rss.c.str4461 cups-1.6.3/notifier/rss.c
+--- cups-1.6.3/notifier/rss.c.str4461 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/notifier/rss.c 2014-09-02 12:14:40.911974011 +0100
+@@ -1,27 +1,16 @@
+ /*
+ * "$Id: rss.c 7824 2008-08-01 21:11:55Z mike $"
+ *
+- * RSS notifier for CUPS.
++ * RSS notifier for CUPS.
+ *
+- * Copyright 2007-2012 by Apple Inc.
+- * Copyright 2007 by Easy Software Products.
++ * Copyright 2007-2014 by Apple Inc.
++ * Copyright 2007 by Easy Software Products.
+ *
+- * These coded instructions, statements, and computer programs are the
+- * property of Apple Inc. and are protected by Federal copyright
+- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+- * which should have been included with this file. If this file is
+- * file is missing or damaged, see the license at "http://www.cups.org/".
+- *
+- * Contents:
+- *
+- * main() - Main entry for the test notifier.
+- * compare_rss() - Compare two messages.
+- * delete_message() - Free all memory used by a message.
+- * load_rss() - Load an existing RSS feed file.
+- * new_message() - Create a new RSS message.
+- * password_cb() - Return the cached password.
+- * save_rss() - Save messages to a RSS file.
+- * xml_escape() - Copy a string, escaping &, <, and > as needed.
++ * These coded instructions, statements, and computer programs are the
++ * property of Apple Inc. and are protected by Federal copyright
++ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
++ * which should have been included with this file. If this file is
++ * file is missing or damaged, see the license at "http://www.cups.org/".
+ */
+
+ /*
+@@ -29,6 +18,7 @@
+ */
+
+ #include
++#include
+ #include
+ #include
+ #include
+@@ -629,6 +619,8 @@ save_rss(cups_array_t *rss, /* I - RSS
+ return (0);
+ }
+
++ fchmod(fileno(fp), 0644);
++
+ fputs("\n", fp);
+ fputs("\n", fp);
+ fputs(" \n", fp);
+diff -up cups-1.6.3/scheduler/client.c.str4461 cups-1.6.3/scheduler/client.c
+--- cups-1.6.3/scheduler/client.c.str4461 2014-09-02 12:12:39.165354482 +0100
++++ cups-1.6.3/scheduler/client.c 2014-09-02 12:13:49.131710518 +0100
+@@ -3133,6 +3133,7 @@ get_file(cupsd_client_t *con, /* I - C
+ char *ptr; /* Pointer info filename */
+ int plen; /* Remaining length after pointer */
+ char language[7]; /* Language subdirectory, if any */
++ int perm_check = 1; /* Do permissions check? */
+
+
+ /*
+@@ -3142,17 +3143,27 @@ get_file(cupsd_client_t *con, /* I - C
+ language[0] = '\0';
+
+ if (!strncmp(con->uri, "/ppd/", 5) && !strchr(con->uri + 5, '/'))
++ {
+ snprintf(filename, len, "%s%s", ServerRoot, con->uri);
++
++ perm_check = 0;
++ }
+ else if (!strncmp(con->uri, "/icons/", 7) && !strchr(con->uri + 7, '/'))
+ {
+ snprintf(filename, len, "%s/%s", CacheDir, con->uri + 7);
+ if (access(filename, F_OK) < 0)
+ snprintf(filename, len, "%s/images/generic.png", DocumentRoot);
++
++ perm_check = 0;
+ }
+ else if (!strncmp(con->uri, "/rss/", 5) && !strchr(con->uri + 5, '/'))
+ snprintf(filename, len, "%s/rss/%s", CacheDir, con->uri + 5);
+- else if (!strncmp(con->uri, "/admin/conf/", 12))
+- snprintf(filename, len, "%s%s", ServerRoot, con->uri + 11);
++ else if (!strcmp(con->uri, "/admin/conf/cupsd.conf"))
++ {
++ strlcpy(filename, ConfigurationFile, len);
++
++ perm_check = 0;
++ }
+ else if (!strncmp(con->uri, "/admin/log/", 11))
+ {
+ if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/')
+@@ -3163,6 +3174,8 @@ get_file(cupsd_client_t *con, /* I - C
+ strlcpy(filename, PageLog, len);
+ else
+ return (NULL);
++
++ perm_check = 0;
+ }
+ else if (con->language)
+ {
+@@ -3228,7 +3241,7 @@ get_file(cupsd_client_t *con, /* I - C
+ * not allow access...
+ */
+
+- if (!status && !(filestats->st_mode & S_IROTH))
++ if (!status && perm_check && !(filestats->st_mode & S_IROTH))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename);
+ return (NULL);
+@@ -3336,7 +3349,7 @@ get_file(cupsd_client_t *con, /* I - C
+ * not allow access...
+ */
+
+- if (!status && !(filestats->st_mode & S_IROTH))
++ if (!status && perm_check && !(filestats->st_mode & S_IROTH))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename);
+ return (NULL);
+diff -up cups-1.6.3/scheduler/conf.c.str4461 cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.str4461 2014-09-02 12:12:39.143354370 +0100
++++ cups-1.6.3/scheduler/conf.c 2014-09-02 12:12:39.169354502 +0100
+@@ -1116,7 +1116,7 @@ cupsdReadConfiguration(void)
+
+ if ((cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser,
+ Group, 1, 1) < 0 ||
+- cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser,
++ cupsdCheckPermissions(CacheDir, NULL, 0770, RunUser,
+ Group, 1, 1) < 0 ||
+ cupsdCheckPermissions(temp, NULL, 0775, RunUser,
+ Group, 1, 1) < 0 ||
+diff -up cups-1.6.3/scheduler/ipp.c.str4461 cups-1.6.3/scheduler/ipp.c
+--- cups-1.6.3/scheduler/ipp.c.str4461 2014-09-02 12:12:39.150354405 +0100
++++ cups-1.6.3/scheduler/ipp.c 2014-09-02 12:12:57.752449066 +0100
+@@ -2777,7 +2777,6 @@ add_printer(cupsd_client_t *con, /* I -
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Copied PPD file successfully");
+- chmod(dstfile, 0644);
+ }
+ else
+ {
+@@ -4726,7 +4725,7 @@ copy_model(cupsd_client_t *con, /* I -
+ * Open the destination file for a copy...
+ */
+
+- if ((dst = cupsFileOpen(to, "wb")) == NULL)
++ if ((dst = cupsdCreateConfFile(to, ConfigFilePerm)) == NULL)
+ {
+ cupsFreeOptions(num_defaults, defaults);
+ cupsFileClose(src);
+@@ -4781,7 +4780,7 @@ copy_model(cupsd_client_t *con, /* I -
+
+ unlink(tempfile);
+
+- return (cupsFileClose(dst));
++ return (cupsdCloseCreatedConfFile(dst, to));
+ }
+
+
+diff -up cups-1.6.3/scheduler/Makefile.str4461 cups-1.6.3/scheduler/Makefile
+--- cups-1.6.3/scheduler/Makefile.str4461 2014-09-02 12:12:39.171354512 +0100
++++ cups-1.6.3/scheduler/Makefile 2014-09-02 12:14:04.265787530 +0100
+@@ -174,7 +174,7 @@ install-data:
+ echo Creating $(REQUESTS)/tmp...
+ $(INSTALL_DIR) -m 1770 -g $(CUPS_GROUP) $(REQUESTS)/tmp
+ echo Creating $(CACHEDIR)...
+- $(INSTALL_DIR) -m 775 -g $(CUPS_GROUP) $(CACHEDIR)
++ $(INSTALL_DIR) -m 770 -g $(CUPS_GROUP) $(CACHEDIR)
+ if test "x$(INITDIR)" != x; then \
+ echo Installing init scripts...; \
+ $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/init.d; \
diff --git a/SOURCES/cups-str4475.patch b/SOURCES/cups-str4475.patch
new file mode 100644
index 0000000..aa1da28
--- /dev/null
+++ b/SOURCES/cups-str4475.patch
@@ -0,0 +1,24 @@
+diff -up cups-1.6.3/cgi-bin/admin.c.str4475 cups-1.6.3/cgi-bin/admin.c
+--- cups-1.6.3/cgi-bin/admin.c.str4475 2014-09-02 12:09:43.875462488 +0100
++++ cups-1.6.3/cgi-bin/admin.c 2014-09-02 12:09:48.883487972 +0100
+@@ -1917,7 +1917,7 @@ do_config_server(http_t *http) /* I - H
+ }
+ else
+ {
+- cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
++ cgiSetVariable("refresh_page", "5;URL=/admin/");
+
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiCopyTemplateLang("restart.tmpl");
+diff -up cups-1.6.3/templates/restart.tmpl.str4475 cups-1.6.3/templates/restart.tmpl
+--- cups-1.6.3/templates/restart.tmpl.str4475 2008-10-08 23:50:16.000000000 +0100
++++ cups-1.6.3/templates/restart.tmpl 2014-09-02 12:09:48.883487972 +0100
+@@ -2,7 +2,7 @@
+
+ Change Settings
+
+- Please stand by while the server restarts...
+
+
diff --git a/SOURCES/cups-str4476.patch b/SOURCES/cups-str4476.patch
new file mode 100644
index 0000000..25b76f8
--- /dev/null
+++ b/SOURCES/cups-str4476.patch
@@ -0,0 +1,504 @@
+diff -up cups-1.6.3/cups/http.c.str4476 cups-1.6.3/cups/http.c
+--- cups-1.6.3/cups/http.c.str4476 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/cups/http.c 2015-06-23 14:05:39.872805417 +0100
+@@ -175,6 +175,8 @@ static int http_write_ssl(http_t *http,
+ * Local globals...
+ */
+
++static int tls_options = 0; /* Options for TLS connections */
++
+ static const char * const http_fields[] =
+ {
+ "Accept-Language",
+@@ -3722,7 +3724,10 @@ http_send(http_t *http, /* I - Con
+ if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
+ {
+ httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
+- httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
++ if (tls_options & _HTTP_TLS_ALLOW_SSL3)
++ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.1,TLS/1.0,SSL/3.0");
++ else
++ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.1,TLS/1.0");
+ }
+ #endif /* HAVE_SSL */
+
+@@ -3959,6 +3964,10 @@ http_setup_ssl(http_t *http) /* I - Con
+ context = SSL_CTX_new(SSLv23_client_method());
+
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
++ if (!(tls_options & _HTTP_TLS_ALLOW_SSL3))
++ SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* Don't use SSLv3 */
++ if (!(tls_options & _HTTP_TLS_ALLOW_RC4))
++ SSL_CTX_set_cipher_list(context, "DEFAULT:-RC4");
+
+ bio = BIO_new(_httpBIOMethods());
+ BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
+@@ -4018,7 +4027,16 @@ http_setup_ssl(http_t *http) /* I - Con
+ gnutls_certificate_allocate_credentials(credentials);
+
+ gnutls_init(&http->tls, GNUTLS_CLIENT);
+- gnutls_set_default_priority(http->tls);
++ if (!tls_options)
++ gnutls_priority_set_direct(http->tls, "NORMAL:-ARCFOUR-128:-VERS-SSL3.0", NULL);
++ else if ((tls_options & _HTTP_TLS_ALLOW_SSL3) &&
++ (tls_options & _HTTP_TLS_ALLOW_RC4))
++ gnutls_priority_set_direct(http->tls, "NORMAL", NULL);
++ else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
++ gnutls_priority_set_direct(http->tls, "NORMAL:-ARCFOUR-128", NULL);
++ else
++ gnutls_priority_set_direct(http->tls, "NORMAL:-VERS-SSL3.0", NULL);
++
+ gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname,
+ strlen(hostname));
+ gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials);
+@@ -4433,7 +4451,10 @@ http_upgrade(http_t *http) /* I - Conne
+
+ httpClearFields(http);
+ httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade");
+- httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2, TLS/1.1, TLS/1.0, SSL/3.0");
++ if (tls_options & _HTTP_TLS_ALLOW_SSL3)
++ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2, TLS/1.1, TLS/1.0, SSL/3.0");
++ else
++ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2, TLS/1.1, TLS/1.0");
+
+ if ((ret = httpOptions(http, "*")) == 0)
+ {
+@@ -4764,6 +4785,16 @@ http_write_ssl(http_t *http, /* I -
+ }
+ #endif /* HAVE_SSL */
+
++/*
++ * '_httpTLSSetOptions()' - Set TLS/SSL options.
++ */
++
++void
++_httpTLSSetOptions(int options)
++{
++ tls_options = options;
++}
++
+
+ /*
+ * End of "$Id: http.c 7850 2008-08-20 00:07:25Z mike $".
+diff -up cups-1.6.3/cups/http-private.h.str4476 cups-1.6.3/cups/http-private.h
+--- cups-1.6.3/cups/http-private.h.str4476 2015-06-23 14:04:45.244230171 +0100
++++ cups-1.6.3/cups/http-private.h 2015-06-23 14:05:39.873805409 +0100
+@@ -140,6 +140,10 @@ extern "C" {
+ #define _HTTP_RESOLVE_FQDN 2 /* Resolve to a FQDN */
+ #define _HTTP_RESOLVE_FAXOUT 4 /* Resolve FaxOut service? */
+
++/* care - these should be the same values as the CUPSD_SSL_* equivalents */
++#define _HTTP_TLS_ALLOW_RC4 2
++#define _HTTP_TLS_ALLOW_SSL3 4
++
+
+ /*
+ * Types and functions for SSL support...
+@@ -377,6 +381,8 @@ extern const char *_httpResolveURI(const
+ extern int _httpUpdate(http_t *http, http_status_t *status);
+ extern int _httpWait(http_t *http, int msec, int usessl);
+
++extern void _httpTLSSetOptions(int options);
++
+
+ /*
+ * C++ magic...
+diff -up cups-1.6.3/cups/usersys.c.str4476 cups-1.6.3/cups/usersys.c
+--- cups-1.6.3/cups/usersys.c.str4476 2015-06-23 14:04:45.268229986 +0100
++++ cups-1.6.3/cups/usersys.c 2015-06-23 14:05:39.873805409 +0100
+@@ -72,7 +72,8 @@ static void cups_read_client_conf(cups_f
+ #endif /* HAVE_GSSAPI */
+ const char *cups_anyroot,
+ const char *cups_expiredroot,
+- const char *cups_expiredcerts);
++ const char *cups_expiredcerts,
++ int ssl_options);
+
+
+ /*
+@@ -257,6 +258,9 @@ cupsSetEncryption(http_encryption_t e) /
+ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
+
+
++ if (cg->encryption == (http_encryption_t)-1)
++ _cupsSetDefaults();
++
+ cg->encryption = e;
+
+ if (cg->http)
+@@ -823,7 +827,36 @@ _cupsSetDefaults(void)
+ if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] ||
+ !cg->user[0] || !cg->ipp_port)
+ {
++ /*
++ * Look for CUPS_SERVERROOT/client.conf...
++ */
++
++ snprintf(filename, sizeof(filename), "%s/client.conf",
++ cg->cups_serverroot);
++ fp = cupsFileOpen(filename, "r");
++
++ /*
++ * Read the configuration file and apply any environment variables; both
++ * functions handle NULL cups_file_t pointers...
++ */
++
++ cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user,
++#ifdef HAVE_GSSAPI
++ cups_gssservicename,
++#endif /* HAVE_GSSAPI */
++ cups_anyroot, cups_expiredroot,
++ cups_expiredcerts, 1);
++
++ /*
++ * Then user defaults, if it is safe to do so...
++ */
++
++#ifdef HAVE_GETEUID
++ if ((geteuid() == getuid() || !getuid()) && getegid() == getgid() &&
++ (home = getenv("HOME")) != NULL)
++#else
+ if ((home = getenv("HOME")) != NULL)
++#endif
+ {
+ /*
+ * Look for ~/.cups/client.conf...
+@@ -831,33 +864,20 @@ _cupsSetDefaults(void)
+
+ snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home);
+ fp = cupsFileOpen(filename, "r");
+- }
+- else
+- fp = NULL;
+
+- if (!fp)
+- {
+ /*
+- * Look for CUPS_SERVERROOT/client.conf...
++ * Read the configuration file and apply any environment variables; both
++ * functions handle NULL cups_file_t pointers...
+ */
+
+- snprintf(filename, sizeof(filename), "%s/client.conf",
+- cg->cups_serverroot);
+- fp = cupsFileOpen(filename, "r");
+- }
+-
+- /*
+- * Read the configuration file and apply any environment variables; both
+- * functions handle NULL cups_file_t pointers...
+- */
+-
+- cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user,
++ cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user,
+ #ifdef HAVE_GSSAPI
+- cups_gssservicename,
++ cups_gssservicename,
+ #endif /* HAVE_GSSAPI */
+- cups_anyroot, cups_expiredroot,
+- cups_expiredcerts);
+- cupsFileClose(fp);
++ cups_anyroot, cups_expiredroot,
++ cups_expiredcerts, 0);
++ cupsFileClose(fp);
++ }
+ }
+ }
+
+@@ -879,7 +899,8 @@ cups_read_client_conf(
+ #endif /* HAVE_GSSAPI */
+ const char *cups_anyroot, /* I - CUPS_ANYROOT env var */
+ const char *cups_expiredroot, /* I - CUPS_EXPIREDROOT env var */
+- const char *cups_expiredcerts) /* I - CUPS_EXPIREDCERTS env var */
++ const char *cups_expiredcerts, /* I - CUPS_EXPIREDCERTS env var */
++ int ssl_options) /* I - Allow setting of SSLOptions? */
+ {
+ int linenum; /* Current line number */
+ char line[1024], /* Line from file */
+@@ -952,6 +973,43 @@ cups_read_client_conf(
+ cups_gssservicename = gss_service_name;
+ }
+ #endif /* HAVE_GSSAPI */
++ else if (ssl_options && !_cups_strcasecmp(line, "SSLOptions") && value)
++ {
++ /*
++ * SSLOptions [AllowRC4] [AllowSSL3] [None]
++ */
++
++ int options = 0; /* SSL/TLS options */
++ char *start, /* Start of option */
++ *end; /* End of option */
++
++ for (start = value; *start; start = end)
++ {
++ /*
++ * Find end of keyword...
++ */
++
++ end = start;
++ while (*end && !_cups_isspace(*end))
++ end++;
++
++ if (*end)
++ *end++ = '\0';
++
++ /*
++ * Compare...
++ */
++
++ if (!_cups_strcasecmp(start, "AllowRC4"))
++ options |= _HTTP_TLS_ALLOW_RC4;
++ else if (!_cups_strcasecmp(start, "AllowSSL3"))
++ options |= _HTTP_TLS_ALLOW_SSL3;
++ else if (!_cups_strcasecmp(start, "None"))
++ options = 0;
++ }
++
++ _httpTLSSetOptions(options);
++ }
+ }
+
+ /*
+diff -up cups-1.6.3/doc/help/ref-client-conf.html.str4476 cups-1.6.3/doc/help/ref-client-conf.html
+--- cups-1.6.3/doc/help/ref-client-conf.html.str4476 2013-06-25 15:38:12.000000000 +0100
++++ cups-1.6.3/doc/help/ref-client-conf.html 2015-06-23 14:05:39.873805409 +0100
+@@ -76,6 +76,26 @@ present, only the last one is used. This
+
+
+
++
++
++Examples
++
++
++SSLOptions None
++SSLOptions AllowSSL3
++SSLOptions AllowRC4
++
++
++Description
++
++Sets encryption options (only in /etc/cups/client.conf). By
++default, CUPS only supports encryption using TLS v1.0 or higher using
++known secure cipher suites. The AllowRC4 option enables the
++128-bit RC4 cipher suites, which are required for some older clients
++that do not implement newer ones. The AllowSSL3 option enables
++SSL v3.0, which is required for some older clients that do not support
++TLS v1.0.
++
+ CUPS 1.6/OS X 10.8User
+
+ Examples
+diff -up cups-1.6.3/doc/help/ref-cupsd-conf.html.in.str4476 cups-1.6.3/doc/help/ref-cupsd-conf.html.in
+--- cups-1.6.3/doc/help/ref-cupsd-conf.html.in.str4476 2013-05-10 17:52:10.000000000 +0100
++++ cups-1.6.3/doc/help/ref-cupsd-conf.html.in 2015-06-23 14:05:39.873805409 +0100
+@@ -2011,23 +2011,23 @@ SetEnv MY_ENV_VAR foo
+ variable that should be passed to child processes.
+
+
+-
++
+
+ Examples
+
+
+-SSLListen 127.0.0.1:443
+-SSLListen 192.0.2.1:443
++SSLOptions 127.0.0.1:443
++SSLOptions 192.0.2.1:443
+
+
+ Description
+
+-The SSLListen
directive specifies a network
++
The SSLOptions
directive specifies a network
+ address and port to listen for secure connections. Multiple
+-SSLListen
directives can be provided to listen on
++SSLOptions
directives can be provided to listen on
+ multiple addresses.
+
+-The SSLListen
directive is similar to the The SSLOptions
directive is similar to the SSLPort
directive but allows you
+ to restrict access to specific interfaces or networks.
+
+@@ -2039,15 +2039,22 @@ to restrict access to specific interface
+
+ SSLOptions None
+ SSLOptions NoEmptyFragments
++SSLOptions AllowSSL3
++SSLOptions AllowRC4
+
+
+ Description
+
+ The SSLOptions
directive specifies additional SSL/TLS
+-protocol options to use for encrypted connected. Currently only two
+-options are supported - None
(the default) for the most
+-secure mode and NoEmptyFragments
to allow CUPS to work with
+-Microsoft Windows with the FIPS conformance mode enabled.
++protocol options to use for encrypted connected. By default, CUPS only
++supports encryption using TLS v1.0 or higher using known secure cipher
++suites. The NoEmptyFragments
option allows CUPS to work
++with Microsoft Windows with the FIPS conformance mode
++enabled. The AllowRC4
option enables the 128-bit RC4
++cipher suites, which are required for some older clients that do not
++implement newer ones. The AllowSSL3
option enables SSL
++v3.0, which is required for some older clients that do not support TLS
++v1.0.
+
+
+
+diff -up cups-1.6.3/man/client.conf.man.in.str4476 cups-1.6.3/man/client.conf.man.in
+--- cups-1.6.3/man/client.conf.man.in.str4476 2013-06-25 15:38:12.000000000 +0100
++++ cups-1.6.3/man/client.conf.man.in 2015-06-23 14:05:39.874805401 +0100
+@@ -53,6 +53,15 @@ Specifies the address and optionally the
+ server running CUPS 1.3.12 and earlier. \fBNote: Not supported on OS X 10.7 or
+ later.\fR
+ .TP 5
++SSLOptions \fR[\fIAllowRC4\fR] [\fIAllow SSL3\fR]
++.br
++Sets SSL/TLS protocol options for encrypted connections. By default,
++CUPS only supports encryption using TLS v1.0 or higher using known
++secure cipher suites. The \fIAllowRC4\fR option enables the 128-bit
++RC4 cipher suites, which are required for some older clients that do
++not implement newer ones. The \fIAllowSSL3\fR option enables SSL v3.0,
++which is required for some older clients that do not support TLS v1.0.
++.TP 5
+ User name
+ .br
+ Specifies the default user name to use for requests.
+diff -up cups-1.6.3/man/cupsd.conf.man.in.str4476 cups-1.6.3/man/cupsd.conf.man.in
+--- cups-1.6.3/man/cupsd.conf.man.in.str4476 2015-06-23 14:04:45.278229909 +0100
++++ cups-1.6.3/man/cupsd.conf.man.in 2015-06-23 14:05:39.874805401 +0100
+@@ -480,9 +480,16 @@ Listens on the specified address and por
+ .TP 5
+ SSLOptions None
+ .TP 5
+-SSLOptions NoEmptyFragments
++SSLOptions \fR[\fINoEmptyFragments\fR] [\fIAllowRC4\fR] [\fIAllow SSL3\fR]
+ .br
+-Sets SSL/TLS protocol options for encrypted connections.
++Sets SSL/TLS protocol options for encrypted connections. By default,
++CUPS only supports encryption using TLS v1.0 or higher using known
++secure cipher suites. The \fINoEmptyFragments\fR option allows CUPS to
++work with Microsoft Windows with the FIPS conformance mode
++enabled. The \fIAllowRC4\fR option enables the 128-bit RC4 cipher
++suites, which are required for some older clients that do not
++implement newer ones. The \fIAllowSSL3\fR option enables SSL v3.0,
++which is required for some older clients that do not support TLS v1.0.
+ .TP 5
+ SSLPort
+ .br
+diff -up cups-1.6.3/scheduler/conf.c.str4476 cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.str4476 2015-06-23 14:04:45.298229754 +0100
++++ cups-1.6.3/scheduler/conf.c 2015-06-23 14:05:39.874805401 +0100
+@@ -3361,17 +3361,54 @@ read_cupsd_conf(cups_file_t *fp) /* I -
+ else if (!_cups_strcasecmp(line, "SSLOptions"))
+ {
+ /*
++ * SSLOptions [AllowRC4] [AllowSSL3] [NoEmptyFragments] [None]
++ */
++
++ int options = 0; /* SSL/TLS options */
++
++ /*
+ * SSLOptions options
+ */
+
+- if (!value || !_cups_strcasecmp(value, "none"))
+- SSLOptions = CUPSD_SSL_NONE;
+- else if (!_cups_strcasecmp(value, "noemptyfragments"))
+- SSLOptions = CUPSD_SSL_NOEMPTY;
+- else
+- cupsdLogMessage(CUPSD_LOG_ERROR,
+- "Unknown value \"%s\" for SSLOptions directive on "
+- "line %d.", value, linenum);
++ if (value)
++ {
++ char *start, /* Start of option */
++ *end; /* End of option */
++
++ for (start = value; *start; start = end)
++ {
++ /*
++ * Find end of keyword...
++ */
++
++ end = start;
++ while (*end && !_cups_isspace(*end))
++ end++;
++
++ if (*end)
++ *end++ = '\0';
++
++ /*
++ * Compare...
++ */
++
++ if (!_cups_strcasecmp(start, "NoEmptyFragments"))
++ options |= CUPSD_SSL_NOEMPTY;
++ else if (!_cups_strcasecmp(start, "AllowRC4"))
++ options |= CUPSD_SSL_ALLOW_RC4;
++ else if (!_cups_strcasecmp(start, "AllowSSL3"))
++ options |= CUPSD_SSL_ALLOW_SSL3;
++ else if (!_cups_strcasecmp(start, "None"))
++ options = 0;
++ else
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "Unknown value \"%s\" for SSLOptions directive on "
++ "line %d.", start, linenum);
++ }
++ }
++
++ SSLOptions = options;
++ _httpTLSSetOptions (SSLOptions & ~CUPSD_SSL_NOEMPTY);
+ }
+ #endif /* HAVE_SSL */
+ else if (!_cups_strcasecmp(line, "AccessLog") ||
+diff -up cups-1.6.3/scheduler/conf.h.str4476 cups-1.6.3/scheduler/conf.h
+--- cups-1.6.3/scheduler/conf.h.str4476 2015-06-23 14:04:45.298229754 +0100
++++ cups-1.6.3/scheduler/conf.h 2015-06-23 14:05:39.874805401 +0100
+@@ -78,6 +78,8 @@ typedef enum
+
+ #define CUPSD_SSL_NONE 0 /* No special options */
+ #define CUPSD_SSL_NOEMPTY 1 /* Do not insert empty fragments */
++#define CUPSD_SSL_ALLOW_RC4 2 /* Allow RC4 cipher suites */
++#define CUPSD_SSL_ALLOW_SSL3 4 /* Allow SSL 3.0 */
+
+
+ /*
+diff -up cups-1.6.3/scheduler/tls-gnutls.c.str4476 cups-1.6.3/scheduler/tls-gnutls.c
+--- cups-1.6.3/scheduler/tls-gnutls.c.str4476 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/scheduler/tls-gnutls.c 2015-06-23 14:05:39.874805401 +0100
+@@ -114,7 +114,15 @@ cupsdStartTLS(cupsd_client_t *con) /* I
+ ServerKey, GNUTLS_X509_FMT_PEM);
+
+ gnutls_init(&con->http.tls, GNUTLS_SERVER);
+- gnutls_set_default_priority(con->http.tls);
++ if (!SSLOptions)
++ gnutls_priority_set_direct(con->http.tls, "NORMAL:-ARCFOUR-128:-VERS-SSL3.0", NULL);
++ else if ((SSLOptions & CUPSD_SSL_ALLOW_SSL3) &&
++ (SSLOptions & CUPSD_SSL_ALLOW_RC4))
++ gnutls_priority_set_direct(con->http.tls, "NORMAL", NULL);
++ else if (SSLOptions & CUPSD_SSL_ALLOW_SSL3)
++ gnutls_priority_set_direct(con->http.tls, "NORMAL:-ARCFOUR-128", NULL);
++ else
++ gnutls_priority_set_direct(con->http.tls, "NORMAL:-VERS-SSL3.0", NULL);
+
+ gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials);
+ gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con));
+diff -up cups-1.6.3/scheduler/tls-openssl.c.str4476 cups-1.6.3/scheduler/tls-openssl.c
+--- cups-1.6.3/scheduler/tls-openssl.c.str4476 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/scheduler/tls-openssl.c 2015-06-23 14:05:39.875805393 +0100
+@@ -107,6 +107,10 @@ cupsdStartTLS(cupsd_client_t *con) /* I
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
+ if (SSLOptions & CUPSD_SSL_NOEMPTY)
+ SSL_CTX_set_options(context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
++ if (!(SSLOptions & CUPSD_SSL_ALLOW_SSL3))
++ SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* Don't use SSLv3 */
++ if (!(SSLOptions & CUPSD_SSL_ALLOW_RC4))
++ SSL_CTX_set_cipher_list(context, "DEFAULT:-RC4");
+ SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
+ SSL_CTX_use_certificate_chain_file(context, ServerCertificate);
+
diff --git a/SOURCES/cups-str4500.patch b/SOURCES/cups-str4500.patch
new file mode 100644
index 0000000..cabe572
--- /dev/null
+++ b/SOURCES/cups-str4500.patch
@@ -0,0 +1,16 @@
+diff -up cups-2.0.0/cups/util.c.str4500 cups-2.0.0/cups/util.c
+--- cups-2.0.0/cups/util.c.str4500 2014-10-15 12:59:27.105942488 +0100
++++ cups-2.0.0/cups/util.c 2014-10-15 13:03:38.618187112 +0100
+@@ -846,10 +846,10 @@ cupsGetPPD3(http_t *http, /* I - H
+
+ snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", cg->cups_serverroot,
+ name);
+- if (!stat(ppdname, &ppdinfo))
++ if (!stat(ppdname, &ppdinfo) && !access(ppdname, R_OK))
+ {
+ /*
+- * OK, the file exists, use it!
++ * OK, the file exists and is readable, use it!
+ */
+
+ if (buffer[0])
diff --git a/SOURCES/cups-str4551.patch b/SOURCES/cups-str4551.patch
new file mode 100644
index 0000000..553e74d
--- /dev/null
+++ b/SOURCES/cups-str4551.patch
@@ -0,0 +1,34 @@
+diff -up cups-1.6.3/filter/raster.c.str4551 cups-1.6.3/filter/raster.c
+--- cups-1.6.3/filter/raster.c.str4551 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/filter/raster.c 2015-06-10 11:58:55.393299339 +0200
+@@ -281,7 +281,10 @@ cupsRasterReadHeader(
+ */
+
+ if (!cups_raster_read_header(r))
++ {
++ memset(h, 0, sizeof(cups_page_header_t));
+ return (0);
++ }
+
+ /*
+ * Copy the header to the user-supplied buffer...
+@@ -310,7 +313,10 @@ cupsRasterReadHeader2(
+ */
+
+ if (!cups_raster_read_header(r))
++ {
++ memset(h, 0, sizeof(cups_page_header2_t));
+ return (0);
++ }
+
+ /*
+ * Copy the header to the user-supplied buffer...
+@@ -988,7 +994,7 @@ cups_raster_read_header(
+
+ cups_raster_update(r);
+
+- return (r->header.cupsBytesPerLine != 0 && r->header.cupsHeight != 0);
++ return (r->header.cupsBytesPerLine != 0 && r->header.cupsHeight != 0 && (r->header.cupsBytesPerLine % r->bpp) == 0);
+ }
+
+
diff --git a/SOURCES/cups-str4591.patch b/SOURCES/cups-str4591.patch
new file mode 100644
index 0000000..69bd762
--- /dev/null
+++ b/SOURCES/cups-str4591.patch
@@ -0,0 +1,56 @@
+diff -up cups-1.6.3/scheduler/conf.c.str4591 cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.str4591 2015-06-23 14:05:39.874805401 +0100
++++ cups-1.6.3/scheduler/conf.c 2015-06-23 14:10:38.364395201 +0100
+@@ -1245,6 +1245,19 @@ cupsdReadConfiguration(void)
+
+ cupsdUpdateEnv();
+
++ /*
++ * Validate the default error policy...
++ */
++
++ if (strcmp(ErrorPolicy, "retry-current-job") &&
++ strcmp(ErrorPolicy, "abort-job") &&
++ strcmp(ErrorPolicy, "retry-job") &&
++ strcmp(ErrorPolicy, "stop-printer"))
++ {
++ cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid ErrorPolicy \"%s\", resetting to \"stop-printer\".", ErrorPolicy);
++ cupsdSetString(&ErrorPolicy, "stop-printer");
++ }
++
+ /*
+ * Update default paper size setting as needed...
+ */
+diff -up cups-1.6.3/scheduler/printers.c.str4591 cups-1.6.3/scheduler/printers.c
+--- cups-1.6.3/scheduler/printers.c.str4591 2015-06-23 14:04:45.301229731 +0100
++++ cups-1.6.3/scheduler/printers.c 2015-06-23 14:10:52.717276314 +0100
+@@ -3,7 +3,7 @@
+ *
+ * Printer routines for the CUPS scheduler.
+ *
+- * Copyright 2007-2012 by Apple Inc.
++ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+@@ -1303,10 +1303,17 @@ cupsdLoadAllPrinters(void)
+ else if (!_cups_strcasecmp(line, "ErrorPolicy"))
+ {
+ if (value)
+- cupsdSetString(&p->error_policy, value);
++ {
++ if (strcmp(value, "retry-current-job") &&
++ strcmp(value, "abort-job") &&
++ strcmp(value, "retry-job") &&
++ strcmp(value, "stop-printer"))
++ cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid ErrorPolicy \"%s\" on line %d or printers.conf.", ErrorPolicy, linenum);
++ else
++ cupsdSetString(&p->error_policy, value);
++ }
+ else
+- cupsdLogMessage(CUPSD_LOG_ERROR,
+- "Syntax error on line %d of printers.conf.", linenum);
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum);
+ }
+ else if (!_cups_strcasecmp(line, "Attribute") && value)
+ {
diff --git a/SOURCES/cups-str4609.patch b/SOURCES/cups-str4609.patch
new file mode 100644
index 0000000..a397b46
--- /dev/null
+++ b/SOURCES/cups-str4609.patch
@@ -0,0 +1,327 @@
+diff -up cups-1.6.3/cgi-bin/ipp-var.c.str4609 cups-1.6.3/cgi-bin/ipp-var.c
+--- cups-1.6.3/cgi-bin/ipp-var.c.str4609 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/cgi-bin/ipp-var.c 2015-06-10 11:44:39.584600734 +0200
+@@ -1230,21 +1230,7 @@ cgiSetIPPObjectVars(
+ * Rewrite URIs...
+ */
+
+- if (!strcmp(name, "member_uris"))
+- {
+- char url[1024]; /* URL for class member... */
+-
+-
+- cgiRewriteURL(attr->values[i].string.text, url,
+- sizeof(url), NULL);
+-
+- snprintf(valptr, sizeof(value) - (valptr - value),
+- "%s", url,
+- strrchr(attr->values[i].string.text, '/') + 1);
+- }
+- else
+- cgiRewriteURL(attr->values[i].string.text, valptr,
+- sizeof(value) - (valptr - value), NULL);
++ cgiRewriteURL(attr->values[i].string.text, valptr, sizeof(value) - (valptr - value), NULL);
+ break;
+ }
+
+diff -up cups-1.6.3/cgi-bin/template.c.str4609 cups-1.6.3/cgi-bin/template.c
+--- cups-1.6.3/cgi-bin/template.c.str4609 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/cgi-bin/template.c 2015-06-10 11:44:39.584600734 +0200
+@@ -659,39 +659,7 @@ cgi_puts(const char *s, /* I - String
+ while (*s)
+ {
+ if (*s == '<')
+- {
+- /*
+- * Pass and , otherwise quote it...
+- */
+-
+- if (!_cups_strncasecmp(s, "", out);
+- }
+- else if (!_cups_strncasecmp(s, "", 4))
+- {
+- fputs("", out);
+- s += 3;
+- }
+- else
+- fputs("<", out);
+- }
++ fputs("<", out);
+ else if (*s == '>')
+ fputs(">", out);
+ else if (*s == '\"')
+diff -up cups-1.6.3/scheduler/ipp.c.str4609 cups-1.6.3/scheduler/ipp.c
+--- cups-1.6.3/scheduler/ipp.c.str4609 2015-06-10 11:44:39.577600753 +0200
++++ cups-1.6.3/scheduler/ipp.c 2015-06-10 11:44:39.585600731 +0200
+@@ -482,8 +482,7 @@ cupsdProcessIPPRequest(
+ * Remote unauthenticated user masquerading as local root...
+ */
+
+- _cupsStrFree(username->values[0].string.text);
+- username->values[0].string.text = _cupsStrAlloc(RemoteRoot);
++ ippSetString(con->request, &username, 0, RemoteRoot);
+ }
+ }
+
+@@ -1665,7 +1664,7 @@ add_job(cupsd_client_t *con, /* I - Cl
+ cupsdSetString(&job->username, con->username);
+
+ if (attr)
+- cupsdSetString(&attr->values[0].string.text, con->username);
++ ippSetString(job->attrs, &attr, 0, con->username);
+ }
+ else if (attr)
+ {
+@@ -1683,9 +1682,8 @@ add_job(cupsd_client_t *con, /* I - Cl
+ "job-originating-user-name", NULL, job->username);
+ else
+ {
+- attr->group_tag = IPP_TAG_JOB;
+- _cupsStrFree(attr->name);
+- attr->name = _cupsStrAlloc("job-originating-user-name");
++ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
++ ippSetName(job->attrs, &attr, "job-originating-user-name");
+ }
+
+ if (con->username[0] || auth_info)
+@@ -1716,48 +1714,11 @@ add_job(cupsd_client_t *con, /* I - Cl
+ * Also, we can only have 1 value and it must be a name value.
+ */
+
+- switch (attr->value_tag)
+- {
+- case IPP_TAG_STRING :
+- case IPP_TAG_TEXTLANG :
+- case IPP_TAG_NAMELANG :
+- case IPP_TAG_TEXT :
+- case IPP_TAG_NAME :
+- case IPP_TAG_KEYWORD :
+- case IPP_TAG_URI :
+- case IPP_TAG_URISCHEME :
+- case IPP_TAG_CHARSET :
+- case IPP_TAG_LANGUAGE :
+- case IPP_TAG_MIMETYPE :
+- /*
+- * Free old strings...
+- */
+-
+- for (i = 0; i < attr->num_values; i ++)
+- {
+- _cupsStrFree(attr->values[i].string.text);
+- attr->values[i].string.text = NULL;
+- if (attr->values[i].string.language)
+- {
+- _cupsStrFree(attr->values[i].string.language);
+- attr->values[i].string.language = NULL;
+- }
+- }
+-
+- default :
+- break;
+- }
+-
+- /*
+- * Use the default connection hostname instead...
+- */
+-
+- attr->value_tag = IPP_TAG_NAME;
+- attr->num_values = 1;
+- attr->values[0].string.text = _cupsStrAlloc(con->http.hostname);
++ ippDeleteAttribute(job->attrs, attr);
++ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-host-name", NULL, con->http.hostname);
+ }
+-
+- attr->group_tag = IPP_TAG_JOB;
++ else
++ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
+ }
+ else
+ {
+@@ -1854,8 +1815,8 @@ add_job(cupsd_client_t *con, /* I - Cl
+
+ attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
+ 2, NULL, NULL);
+- attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
+- attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]);
++ ippSetString(job->attrs, &attr, 0, printer->job_sheets[0]);
++ ippSetString(job->attrs, &attr, 1, printer->job_sheets[1]);
+ }
+
+ job->job_sheets = attr;
+@@ -1881,7 +1842,7 @@ add_job(cupsd_client_t *con, /* I - Cl
+ * Force the leading banner to have the classification on it...
+ */
+
+- cupsdSetString(&attr->values[0].string.text, Classification);
++ ippSetString(job->attrs, &attr, 0, Classification);
+
+ cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
+ "job-sheets=\"%s,none\", "
+@@ -1898,7 +1859,7 @@ add_job(cupsd_client_t *con, /* I - Cl
+ * Can't put two different security markings on the same document!
+ */
+
+- cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
++ ippSetString(job->attrs, &attr, 1, attr->values[0].string.text);
+
+ cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
+ "job-sheets=\"%s,%s\", "
+@@ -1938,18 +1899,18 @@ add_job(cupsd_client_t *con, /* I - Cl
+ if (attr->num_values > 1 &&
+ !strcmp(attr->values[0].string.text, attr->values[1].string.text))
+ {
+- cupsdSetString(&(attr->values[0].string.text), Classification);
+- cupsdSetString(&(attr->values[1].string.text), Classification);
++ ippSetString(job->attrs, &attr, 0, Classification);
++ ippSetString(job->attrs, &attr, 1, Classification);
+ }
+ else
+ {
+ if (attr->num_values == 1 ||
+ strcmp(attr->values[0].string.text, "none"))
+- cupsdSetString(&(attr->values[0].string.text), Classification);
++ ippSetString(job->attrs, &attr, 0, Classification);
+
+ if (attr->num_values > 1 &&
+ strcmp(attr->values[1].string.text, "none"))
+- cupsdSetString(&(attr->values[1].string.text), Classification);
++ ippSetString(job->attrs, &attr, 1, Classification);
+ }
+
+ if (attr->num_values > 1)
+@@ -3185,8 +3146,8 @@ authenticate_job(cupsd_client_t *con, /
+
+ if (attr)
+ {
+- attr->value_tag = IPP_TAG_KEYWORD;
+- cupsdSetString(&(attr->values[0].string.text), "no-hold");
++ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
++ ippSetString(job->attrs, &attr, 0, "no-hold");
+ }
+
+ /*
+@@ -8413,11 +8374,7 @@ print_job(cupsd_client_t *con, /* I -
+ filetype->type);
+
+ if (format)
+- {
+- _cupsStrFree(format->values[0].string.text);
+-
+- format->values[0].string.text = _cupsStrAlloc(mimetype);
+- }
++ ippSetString(con->request, &format, 0, mimetype);
+ else
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+ "document-format", NULL, mimetype);
+@@ -8952,10 +8909,8 @@ release_job(cupsd_client_t *con, /* I -
+
+ if (attr)
+ {
+- _cupsStrFree(attr->values[0].string.text);
+-
+- attr->value_tag = IPP_TAG_KEYWORD;
+- attr->values[0].string.text = _cupsStrAlloc("no-hold");
++ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
++ ippSetString(job->attrs, &attr, 0, "no-hold");
+
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
+ "Job job-hold-until value changed by user.");
+@@ -9648,11 +9603,7 @@ send_document(cupsd_client_t *con, /* I
+
+ if ((jformat = ippFindAttribute(job->attrs, "document-format",
+ IPP_TAG_MIMETYPE)) != NULL)
+- {
+- _cupsStrFree(jformat->values[0].string.text);
+-
+- jformat->values[0].string.text = _cupsStrAlloc(mimetype);
+- }
++ ippSetString(job->attrs, &jformat, 0, mimetype);
+ else
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+ "document-format", NULL, mimetype);
+diff -up cups-1.6.3/scheduler/job.c.str4609 cups-1.6.3/scheduler/job.c
+--- cups-1.6.3/scheduler/job.c.str4609 2015-06-10 11:44:39.495600976 +0200
++++ cups-1.6.3/scheduler/job.c 2015-06-10 11:44:39.586600728 +0200
+@@ -430,7 +430,7 @@ cupsdCheckJobs(void)
+
+ if ((attr = ippFindAttribute(job->attrs, "job-actual-printer-uri",
+ IPP_TAG_URI)) != NULL)
+- cupsdSetString(&attr->values[0].string.text, printer->uri);
++ ippSetString(job->attrs, &attr, 0, printer->uri);
+ else
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI,
+ "job-actual-printer-uri", NULL, printer->uri);
+@@ -2138,7 +2138,7 @@ cupsdMoveJob(cupsd_job_t *job, /* I
+
+ if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
+ IPP_TAG_URI)) != NULL)
+- cupsdSetString(&(attr->values[0].string.text), p->uri);
++ ippSetString(job->attrs, &attr, 0, p->uri);
+
+ cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job,
+ "Job #%d moved from %s to %s.", job->id, olddest,
+@@ -2329,7 +2329,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (attr)
+- cupsdSetString(&(attr->values[0].string.text), when);
++ ippSetString(job->attrs, &attr, 0, when);
+ else
+ attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-hold-until", NULL, when);
+@@ -2583,8 +2583,8 @@ cupsdSetJobState(
+
+ if (attr)
+ {
+- attr->value_tag = IPP_TAG_KEYWORD;
+- cupsdSetString(&(attr->values[0].string.text), "no-hold");
++ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
++ ippSetString(job->attrs, &attr, 0, "no-hold");
+ }
+
+ default :
+@@ -4531,7 +4531,7 @@ start_job(cupsd_job_t *job, /* I -
+ "job-printer-state-message",
+ IPP_TAG_TEXT);
+ if (job->printer_message)
+- cupsdSetString(&(job->printer_message->values[0].string.text), "");
++ ippSetString(job->attrs, &job->printer_message, 0, "");
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-printing");
+ cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
+@@ -5109,15 +5109,14 @@ update_job_attrs(cupsd_job_t *job, /* I
+ if (job->state_value != IPP_JOB_PROCESSING &&
+ job->status_level == CUPSD_LOG_INFO)
+ {
+- cupsdSetString(&(job->printer_message->values[0].string.text), "");
++ ippSetString(job->attrs, &job->printer_message, 0, "");
+
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+ }
+ else if (job->printer->state_message[0] && do_message)
+ {
+- cupsdSetString(&(job->printer_message->values[0].string.text),
+- job->printer->state_message);
++ ippSetString(job->attrs, &job->printer_message, 0, job->printer->state_message);
+
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
diff --git a/SOURCES/cups-str4646.patch b/SOURCES/cups-str4646.patch
new file mode 100644
index 0000000..b0f15c3
--- /dev/null
+++ b/SOURCES/cups-str4646.patch
@@ -0,0 +1,13 @@
+diff -up cups-1.6.3/scheduler/job.c.str4646 cups-1.6.3/scheduler/job.c
+--- cups-1.6.3/scheduler/job.c.str4646 2015-06-29 10:03:10.922536717 +0100
++++ cups-1.6.3/scheduler/job.c 2015-06-29 10:03:16.930638827 +0100
+@@ -456,7 +456,9 @@ cupsdCheckJobs(void)
+ * Start the job...
+ */
+
++ cupsArraySave(ActiveJobs);
+ start_job(job, printer);
++ cupsArrayRestore(ActiveJobs);
+ }
+ }
+ }
diff --git a/SOURCES/cups-str4648.patch b/SOURCES/cups-str4648.patch
new file mode 100644
index 0000000..0072bae
--- /dev/null
+++ b/SOURCES/cups-str4648.patch
@@ -0,0 +1,61 @@
+diff -up cups-1.6.3/scheduler/ipp.c.str4648 cups-1.6.3/scheduler/ipp.c
+--- cups-1.6.3/scheduler/ipp.c.str4648 2015-07-08 10:24:31.389942557 +0100
++++ cups-1.6.3/scheduler/ipp.c 2015-07-08 10:24:51.042104284 +0100
+@@ -3392,6 +3392,8 @@ cancel_all_jobs(cupsd_client_t *con, /*
+ }
+
+ con->response->request.status.status_code = IPP_OK;
++
++ cupsdCheckJobs();
+ }
+
+
+diff -up cups-1.6.3/scheduler/job.c.str4648 cups-1.6.3/scheduler/job.c
+--- cups-1.6.3/scheduler/job.c.str4648 2015-07-08 10:24:31.399942636 +0100
++++ cups-1.6.3/scheduler/job.c 2015-07-08 10:24:51.043104293 +0100
+@@ -267,8 +267,6 @@ cupsdCancelJobs(const char *dest, /* I -
+ "Job canceled by user.");
+ }
+ }
+-
+- cupsdCheckJobs();
+ }
+
+
+@@ -3488,13 +3486,6 @@ finalize_job(cupsd_job_t *job, /* I - J
+
+ job->printer->job = NULL;
+ job->printer = NULL;
+-
+- /*
+- * Try printing another job...
+- */
+-
+- if (printer_state != IPP_PRINTER_STOPPED)
+- cupsdCheckJobs();
+ }
+
+
+@@ -4744,6 +4735,8 @@ update_job(cupsd_job_t *job) /* I - Job
+ *ptr; /* Pointer update... */
+ int loglevel, /* Log level for message */
+ event = 0; /* Events? */
++ cupsd_printer_t *printer = job->printer;
++ /* Printer */
+ static const char * const levels[] = /* Log levels */
+ {
+ "NONE",
+@@ -5063,10 +5056,11 @@ update_job(cupsd_job_t *job) /* I - Job
+ finalize_job(job, 1);
+
+ /*
+- * Check for new jobs...
++ * Try printing another job...
+ */
+
+- cupsdCheckJobs();
++ if (printer->state != IPP_PRINTER_STOPPED)
++ cupsdCheckJobs();
+ }
+ }
+
diff --git a/SOURCES/cups-strict-ppd-line-length.patch b/SOURCES/cups-strict-ppd-line-length.patch
new file mode 100644
index 0000000..b2697ec
--- /dev/null
+++ b/SOURCES/cups-strict-ppd-line-length.patch
@@ -0,0 +1,30 @@
+diff -up cups-1.5b1/cups/ppd.c.strict-ppd-line-length cups-1.5b1/cups/ppd.c
+--- cups-1.5b1/cups/ppd.c.strict-ppd-line-length 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/cups/ppd.c 2011-05-24 15:46:13.000000000 +0200
+@@ -2786,7 +2786,7 @@ ppd_read(cups_file_t *fp, /* I - Fil
+ *lineptr++ = ch;
+ col ++;
+
+- if (col > (PPD_MAX_LINE - 1))
++ if (col > (PPD_MAX_LINE - 1) && cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ /*
+ * Line is too long...
+@@ -2847,7 +2847,7 @@ ppd_read(cups_file_t *fp, /* I - Fil
+ {
+ col ++;
+
+- if (col > (PPD_MAX_LINE - 1))
++ if (col > (PPD_MAX_LINE - 1) && cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ /*
+ * Line is too long...
+@@ -2906,7 +2906,7 @@ ppd_read(cups_file_t *fp, /* I - Fil
+ {
+ col ++;
+
+- if (col > (PPD_MAX_LINE - 1))
++ if (col > (PPD_MAX_LINE - 1) && cg->ppd_conform == PPD_CONFORM_STRICT)
+ {
+ /*
+ * Line is too long...
diff --git a/SOURCES/cups-stringpool-setprinterattr.patch b/SOURCES/cups-stringpool-setprinterattr.patch
new file mode 100644
index 0000000..18c18dd
--- /dev/null
+++ b/SOURCES/cups-stringpool-setprinterattr.patch
@@ -0,0 +1,64 @@
+diff -up cups-1.6.2/scheduler/printers.c.stringpool-setprinterattr cups-1.6.2/scheduler/printers.c
+--- cups-1.6.2/scheduler/printers.c.stringpool-setprinterattr 2013-06-13 12:16:07.525680621 +0100
++++ cups-1.6.2/scheduler/printers.c 2013-06-13 12:16:07.567680782 +0100
+@@ -1925,6 +1925,7 @@ cupsdSetPrinterAttr(
+ ipp_attribute_t *attr; /* Attribute */
+ int i, /* Looping var */
+ count; /* Number of values */
++ char *value_dup; /* Copy of attribute value string */
+ char *ptr, /* Pointer into value */
+ *start, /* Start of value */
+ quote; /* Quote character */
+@@ -1993,16 +1994,24 @@ cupsdSetPrinterAttr(
+ return;
+ }
+
+- for (i = 0; i < count; i ++)
++ if ((value_dup = strdup(value)) == NULL)
+ {
+- if ((ptr = strchr(value, ',')) != NULL)
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to copy attribute value.");
++ return;
++ }
++
++ for (i = 0, start = value_dup; i < count; i ++)
++ {
++ if ((ptr = strchr(start, ',')) != NULL)
+ *ptr++ = '\0';
+
+- attr->values[i].integer = strtol(value, NULL, 10);
++ attr->values[i].integer = strtol(start, NULL, 10);
+
+ if (ptr)
+- value = ptr;
++ start = ptr;
+ }
++
++ free(value_dup);
+ }
+ else
+ {
+@@ -2043,7 +2052,13 @@ cupsdSetPrinterAttr(
+ return;
+ }
+
+- for (i = 0, quote = '\0', ptr = value; i < count; i ++)
++ if ((value_dup = strdup(value)) == NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to copy attribute value.");
++ return;
++ }
++
++ for (i = 0, quote = '\0', ptr = value_dup; i < count; i ++)
+ {
+ for (start = ptr; *ptr; ptr ++)
+ {
+@@ -2071,6 +2086,8 @@ cupsdSetPrinterAttr(
+
+ attr->values[i].string.text = _cupsStrAlloc(start);
+ }
++
++ free(value_dup);
+ }
+ }
+
diff --git a/SOURCES/cups-synconclose.patch b/SOURCES/cups-synconclose.patch
new file mode 100644
index 0000000..b157cfa
--- /dev/null
+++ b/SOURCES/cups-synconclose.patch
@@ -0,0 +1,128 @@
+diff -up cups-1.6.3/conf/cups-files.conf.in.synconclose cups-1.6.3/conf/cups-files.conf.in
+--- cups-1.6.3/conf/cups-files.conf.in.synconclose 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/conf/cups-files.conf.in 2013-11-04 11:37:32.063897669 +0000
+@@ -8,6 +8,9 @@
+ # List of events that are considered fatal errors for the scheduler...
+ #FatalErrors @CUPS_FATAL_ERRORS@
+
++# Do we call fsync() after writing configuration or status files?
++#SyncOnClose Yes
++
+ # Default user and group for filters/backends/helper programs; this cannot be
+ # any user or group that resolves to ID 0 for security reasons...
+ #User @CUPS_USER@
+diff -up cups-1.6.3/doc/help/ref-cups-files-conf.html.in.synconclose cups-1.6.3/doc/help/ref-cups-files-conf.html.in
+--- cups-1.6.3/doc/help/ref-cups-files-conf.html.in.synconclose 2013-05-10 17:52:10.000000000 +0100
++++ cups-1.6.3/doc/help/ref-cups-files-conf.html.in 2013-11-04 11:39:51.104528571 +0000
+@@ -437,6 +437,31 @@ to resolve relative paths in the cu
+ default server directory is /etc/cups.
+
+
++
++
++Examples
++
++
++SyncOnClose No
++SyncOnClose Yes
++
++
++Description
++
++The SyncOnClose
directive determines whether the scheduler
++flushes changes to configuration and state files to disk. The default is
++Yes
. The option No
relies on the operating
++system to schedule a suitable time to write changes to disk.
++
++Note:
++
++Setting SyncOnClose
to Yes
makes the scheduler use the fsync(2)
system call to write all changes to disk, however the drive or network file system server may still delay writing data to disk. Do not depend on this functionality to prevent data loss in the event of unexpected hardware failure.
++
++Enabling SyncOnClose
may also cause the scheduler to periodically become unresponsive while it waits for changes to be written.
++
++
++
++
+
+
+ Examples
+diff -up cups-1.6.3/man/cups-files.conf.man.in.synconclose cups-1.6.3/man/cups-files.conf.man.in
+--- cups-1.6.3/man/cups-files.conf.man.in.synconclose 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/man/cups-files.conf.man.in 2013-11-04 11:39:51.104528571 +0000
+@@ -122,6 +122,12 @@ ServerRoot directory
+ .br
+ Specifies the directory where the server configuration files can be found.
+ .TP 5
++SyncOnClose Yes
++.TP 5
++SyncOnClose No
++Specifies whether the scheduler calls \fIfsync(2)\fR after writing configuration
++or state files. The default is Yes.
++.TP 5
+ SystemGroup group-name [group-name ...]
+ .br
+ Specifies the group(s) to use for System class authentication.
+diff -up cups-1.6.3/scheduler/conf.c.synconclose cups-1.6.3/scheduler/conf.c
+--- cups-1.6.3/scheduler/conf.c.synconclose 2013-11-04 11:37:21.497849726 +0000
++++ cups-1.6.3/scheduler/conf.c 2013-11-04 11:39:51.106528580 +0000
+@@ -174,6 +174,7 @@ static const cupsd_var_t cupsfiles_vars[
+ { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME },
+ { "SMBConfigFile", &SMBConfigFile, CUPSD_VARTYPE_STRING },
+ { "StateDir", &StateDir, CUPSD_VARTYPE_STRING },
++ { "SyncOnClose", &SyncOnClose, CUPSD_VARTYPE_BOOLEAN },
+ #ifdef HAVE_AUTHORIZATION_H
+ { "SystemGroupAuthKey", &SystemGroupAuthKey, CUPSD_VARTYPE_STRING },
+ #endif /* HAVE_AUTHORIZATION_H */
+@@ -738,6 +739,7 @@ cupsdReadConfiguration(void)
+ ReloadTimeout = DEFAULT_KEEPALIVE;
+ RootCertDuration = 300;
+ StrictConformance = FALSE;
++ SyncOnClose = TRUE;
+ Timeout = DEFAULT_TIMEOUT;
+ WebInterface = CUPS_DEFAULT_WEBIF;
+
+diff -up cups-1.6.3/scheduler/conf.h.synconclose cups-1.6.3/scheduler/conf.h
+--- cups-1.6.3/scheduler/conf.h.synconclose 2013-11-04 11:37:21.498849730 +0000
++++ cups-1.6.3/scheduler/conf.h 2013-11-04 11:37:32.064897673 +0000
+@@ -177,6 +177,8 @@ VAR int ClassifyOverride VALUE(0),
+ /* Which errors are fatal? */
+ StrictConformance VALUE(FALSE),
+ /* Require strict IPP conformance? */
++ SyncOnClose VALUE(FALSE),
++ /* Call fsync() when closing files? */
+ LogFilePerm VALUE(0644);
+ /* Permissions for log files */
+ VAR cupsd_loglevel_t LogLevel VALUE(CUPSD_LOG_WARN);
+diff -up cups-1.6.3/scheduler/file.c.synconclose cups-1.6.3/scheduler/file.c
+--- cups-1.6.3/scheduler/file.c.synconclose 2013-06-07 02:12:52.000000000 +0100
++++ cups-1.6.3/scheduler/file.c 2013-11-04 11:37:32.064897673 +0000
+@@ -109,6 +109,29 @@ cupsdCloseCreatedConfFile(
+
+
+ /*
++ * Synchronize changes to disk if SyncOnClose is enabled.
++ */
++
++ if (SyncOnClose)
++ {
++ if (cupsFileFlush(fp))
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to write changes to \"%s\": %s",
++ filename, strerror(errno));
++ cupsFileClose(fp);
++ return (-1);
++ }
++
++ if (fsync(cupsFileNumber(fp)))
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to sync changes to \"%s\": %s",
++ filename, strerror(errno));
++ cupsFileClose(fp);
++ return (-1);
++ }
++ }
++
++ /*
+ * First close the file...
+ */
+
diff --git a/SOURCES/cups-system-auth.patch b/SOURCES/cups-system-auth.patch
new file mode 100644
index 0000000..60117a9
--- /dev/null
+++ b/SOURCES/cups-system-auth.patch
@@ -0,0 +1,38 @@
+diff -up cups-1.5b1/conf/cups.password-auth.system-auth cups-1.5b1/conf/cups.password-auth
+--- cups-1.5b1/conf/cups.password-auth.system-auth 2011-05-23 17:27:27.000000000 +0200
++++ cups-1.5b1/conf/cups.password-auth 2011-05-23 17:27:27.000000000 +0200
+@@ -0,0 +1,4 @@
++#%PAM-1.0
++# Use password-auth common PAM configuration for the daemon
++auth include password-auth
++account include password-auth
+diff -up cups-1.5b1/conf/cups.system-auth.system-auth cups-1.5b1/conf/cups.system-auth
+--- cups-1.5b1/conf/cups.system-auth.system-auth 2011-05-23 17:27:27.000000000 +0200
++++ cups-1.5b1/conf/cups.system-auth 2011-05-23 17:27:27.000000000 +0200
+@@ -0,0 +1,3 @@
++#%PAM-1.0
++auth include system-auth
++account include system-auth
+diff -up cups-1.5b1/conf/Makefile.system-auth cups-1.5b1/conf/Makefile
+--- cups-1.5b1/conf/Makefile.system-auth 2011-05-12 07:21:56.000000000 +0200
++++ cups-1.5b1/conf/Makefile 2011-05-23 17:27:27.000000000 +0200
+@@ -90,10 +90,16 @@ install-data:
+ done
+ -if test x$(PAMDIR) != x; then \
+ $(INSTALL_DIR) -m 755 $(BUILDROOT)$(PAMDIR); \
+- if test -r $(BUILDROOT)$(PAMDIR)/cups ; then \
+- $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \
++ if test -f /etc/pam.d/password-auth; then \
++ $(INSTALL_DATA) cups.password-auth $(BUILDROOT)$(PAMDIR)/cups; \
++ elif test -f /etc/pam.d/system-auth; then \
++ $(INSTALL_DATA) cups.system-auth $(BUILDROOT)$(PAMDIR)/cups; \
+ else \
+- $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \
++ if test -r $(BUILDROOT)$(PAMDIR)/cups ; then \
++ $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \
++ else \
++ $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \
++ fi ; \
+ fi ; \
+ fi
+
diff --git a/SOURCES/cups-systemd-socket.patch b/SOURCES/cups-systemd-socket.patch
new file mode 100644
index 0000000..ff03f7c
--- /dev/null
+++ b/SOURCES/cups-systemd-socket.patch
@@ -0,0 +1,396 @@
+diff -up cups-1.6.2/config.h.in.systemd-socket cups-1.6.2/config.h.in
+--- cups-1.6.2/config.h.in.systemd-socket 2012-12-17 23:17:08.000000000 +0100
++++ cups-1.6.2/config.h.in 2013-03-18 18:53:53.768961644 +0100
+@@ -487,6 +487,13 @@
+
+
+ /*
++ * Do we have systemd support?
++ */
++
++#undef HAVE_SYSTEMD
++
++
++/*
+ * Various scripting languages...
+ */
+
+diff -up cups-1.6.2/config-scripts/cups-systemd.m4.systemd-socket cups-1.6.2/config-scripts/cups-systemd.m4
+--- cups-1.6.2/config-scripts/cups-systemd.m4.systemd-socket 2013-03-18 18:53:53.769961630 +0100
++++ cups-1.6.2/config-scripts/cups-systemd.m4 2013-03-18 18:53:53.769961630 +0100
+@@ -0,0 +1,36 @@
++dnl
++dnl "$Id$"
++dnl
++dnl systemd stuff for CUPS.
++
++dnl Find whether systemd is available
++
++SDLIBS=""
++AC_ARG_WITH([systemdsystemunitdir],
++ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
++ [], [with_systemdsystemunitdir=$($PKGCONFIG --variable=systemdsystemunitdir systemd)])
++if test "x$with_systemdsystemunitdir" != xno; then
++ AC_MSG_CHECKING(for libsystemd-daemon)
++ if $PKGCONFIG --exists libsystemd-daemon; then
++ AC_MSG_RESULT(yes)
++ SDCFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
++ SDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
++ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
++ AC_DEFINE(HAVE_SYSTEMD)
++ else
++ AC_MSG_RESULT(no)
++ fi
++fi
++
++if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then
++ SYSTEMD_UNITS="cups.service cups.socket cups.path"
++else
++ SYSTEMD_UNITS=""
++fi
++
++AC_SUBST(SYSTEMD_UNITS)
++AC_SUBST(SDLIBS)
++
++dnl
++dnl "$Id$"
++dnl
+diff -up cups-1.6.2/configure.in.systemd-socket cups-1.6.2/configure.in
+--- cups-1.6.2/configure.in.systemd-socket 2013-03-18 18:00:03.000000000 +0100
++++ cups-1.6.2/configure.in 2013-03-18 18:55:30.773612461 +0100
+@@ -33,6 +33,7 @@ sinclude(config-scripts/cups-pam.m4)
+ sinclude(config-scripts/cups-largefile.m4)
+ sinclude(config-scripts/cups-dnssd.m4)
+ sinclude(config-scripts/cups-launchd.m4)
++sinclude(config-scripts/cups-systemd.m4)
+ sinclude(config-scripts/cups-defaults.m4)
+ sinclude(config-scripts/cups-scripting.m4)
+
+@@ -67,6 +68,9 @@ AC_OUTPUT(Makedefs
+ conf/snmp.conf
+ cups-config
+ data/testprint
++ data/cups.service
++ data/cups.socket
++ data/cups.path
+ desktop/cups.desktop
+ doc/help/ref-cups-files-conf.html
+ doc/help/ref-cupsd-conf.html
+diff -up cups-1.6.2/cups/usersys.c.systemd-socket cups-1.6.2/cups/usersys.c
+--- cups-1.6.2/cups/usersys.c.systemd-socket 2013-03-12 15:26:28.000000000 +0100
++++ cups-1.6.2/cups/usersys.c 2013-03-18 18:53:53.769961630 +0100
+@@ -964,7 +964,7 @@ cups_read_client_conf(
+ struct stat sockinfo; /* Domain socket information */
+
+ if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&
+- (sockinfo.st_mode & S_IRWXO) == S_IRWXO)
++ (sockinfo.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))
+ cups_server = CUPS_DEFAULT_DOMAINSOCKET;
+ else
+ #endif /* CUPS_DEFAULT_DOMAINSOCKET */
+diff -up cups-1.6.2/data/cups.path.in.systemd-socket cups-1.6.2/data/cups.path.in
+--- cups-1.6.2/data/cups.path.in.systemd-socket 2013-03-18 18:53:53.770961616 +0100
++++ cups-1.6.2/data/cups.path.in 2013-03-18 18:53:53.770961616 +0100
+@@ -0,0 +1,8 @@
++[Unit]
++Description=CUPS Printer Service Spool
++
++[Path]
++PathExistsGlob=@CUPS_REQUESTS@/d*
++
++[Install]
++WantedBy=multi-user.target
+diff -up cups-1.6.2/data/cups.service.in.systemd-socket cups-1.6.2/data/cups.service.in
+--- cups-1.6.2/data/cups.service.in.systemd-socket 2013-03-18 18:53:53.770961616 +0100
++++ cups-1.6.2/data/cups.service.in 2013-03-18 18:53:53.770961616 +0100
+@@ -0,0 +1,11 @@
++[Unit]
++Description=CUPS Printing Service
++After=network.target
++
++[Service]
++ExecStart=@sbindir@/cupsd -f
++PrivateTmp=true
++
++[Install]
++Also=cups.socket cups.path
++WantedBy=printer.target
+diff -up cups-1.6.2/data/cups.socket.in.systemd-socket cups-1.6.2/data/cups.socket.in
+--- cups-1.6.2/data/cups.socket.in.systemd-socket 2013-03-18 18:53:53.770961616 +0100
++++ cups-1.6.2/data/cups.socket.in 2013-03-18 18:53:53.770961616 +0100
+@@ -0,0 +1,8 @@
++[Unit]
++Description=CUPS Printing Service Sockets
++
++[Socket]
++ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
++
++[Install]
++WantedBy=sockets.target
+diff -up cups-1.6.2/data/Makefile.systemd-socket cups-1.6.2/data/Makefile
+--- cups-1.6.2/data/Makefile.systemd-socket 2011-08-27 11:23:01.000000000 +0200
++++ cups-1.6.2/data/Makefile 2013-03-18 18:53:53.770961616 +0100
+@@ -100,6 +100,12 @@ install-data:
+ $(INSTALL_DATA) $$file $(DATADIR)/ppdc; \
+ done
+ $(INSTALL_DIR) -m 755 $(DATADIR)/profiles
++ if test "x$(SYSTEMD_UNITS)" != "x" ; then \
++ $(INSTALL_DIR) -m 755 $(SYSTEMDUNITDIR); \
++ for file in $(SYSTEMD_UNITS); do \
++ $(INSTALL_DATA) $$file $(SYSTEMDUNITDIR); \
++ done; \
++ fi
+
+
+ #
+@@ -143,6 +149,9 @@ uninstall:
+ -$(RMDIR) $(DATADIR)/data
+ -$(RMDIR) $(DATADIR)/banners
+ -$(RMDIR) $(DATADIR)
++ for file in $(SYSTEMD_UNITS); do \
++ $(RM) $(SYSTEMDUNITDIR)/$$file; \
++ done
+
+
+ #
+diff -up cups-1.6.2/Makedefs.in.systemd-socket cups-1.6.2/Makedefs.in
+--- cups-1.6.2/Makedefs.in.systemd-socket 2013-03-18 18:53:53.758961783 +0100
++++ cups-1.6.2/Makedefs.in 2013-03-18 18:53:53.771961602 +0100
+@@ -134,11 +134,13 @@ CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@
+ CXXLIBS = @CXXLIBS@
+ DBUS_NOTIFIER = @DBUS_NOTIFIER@
+ DBUS_NOTIFIERLIBS = @DBUS_NOTIFIERLIBS@
++SYSTEMD_UNITS = @SYSTEMD_UNITS@
+ DNSSD_BACKEND = @DNSSD_BACKEND@
+ DSOFLAGS = -L../cups @DSOFLAGS@
+ DSOLIBS = @DSOLIBS@ $(COMMONLIBS)
+ DNSSDLIBS = @DNSSDLIBS@
+ LAUNCHDLIBS = @LAUNCHDLIBS@
++SDLIBS = @SDLIBS@
+ LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \
+ -L../scheduler @LDARCHFLAGS@ \
+ @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
+@@ -229,6 +231,7 @@ PAMFILE = @PAMFILE@
+
+ DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
+ DBUSDIR = @DBUSDIR@
++SYSTEMDUNITDIR = $(BUILDROOT)@systemdsystemunitdir@
+
+
+ #
+diff -up cups-1.6.2/scheduler/client.h.systemd-socket cups-1.6.2/scheduler/client.h
+--- cups-1.6.2/scheduler/client.h.systemd-socket 2012-03-22 21:30:20.000000000 +0100
++++ cups-1.6.2/scheduler/client.h 2013-03-18 18:53:53.771961602 +0100
+@@ -77,6 +77,9 @@ typedef struct
+ int fd; /* File descriptor for this server */
+ http_addr_t address; /* Bind address of socket */
+ http_encryption_t encryption; /* To encrypt or not to encrypt... */
++#ifdef HAVE_SYSTEMD
++ int is_systemd; /* Is this a systemd socket? */
++#endif /* HAVE_SYSTEMD */
+ } cupsd_listener_t;
+
+
+diff -up cups-1.6.2/scheduler/listen.c.systemd-socket cups-1.6.2/scheduler/listen.c
+--- cups-1.6.2/scheduler/listen.c.systemd-socket 2011-04-16 01:38:13.000000000 +0200
++++ cups-1.6.2/scheduler/listen.c 2013-03-18 18:53:53.771961602 +0100
+@@ -401,7 +401,11 @@ cupsdStopListening(void)
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ {
+- if (lis->fd != -1)
++ if (lis->fd != -1
++#ifdef HAVE_SYSTEMD
++ && !lis->is_systemd
++#endif /* HAVE_SYSTEMD */
++ )
+ {
+ #ifdef WIN32
+ closesocket(lis->fd);
+diff -up cups-1.6.2/scheduler/main.c.systemd-socket cups-1.6.2/scheduler/main.c
+--- cups-1.6.2/scheduler/main.c.systemd-socket 2013-03-18 18:53:53.724962256 +0100
++++ cups-1.6.2/scheduler/main.c 2013-03-18 18:53:53.772961588 +0100
+@@ -26,6 +26,8 @@
+ * launchd_checkin() - Check-in with launchd and collect the listening
+ * fds.
+ * launchd_checkout() - Update the launchd KeepAlive file as needed.
++ * systemd_checkin() - Check-in with systemd and collect the
++ * listening fds.
+ * parent_handler() - Catch USR1/CHLD signals...
+ * process_children() - Process all dead children...
+ * select_timeout() - Calculate the select timeout value.
+@@ -62,6 +64,10 @@
+ # endif /* !LAUNCH_JOBKEY_SERVICEIPC */
+ #endif /* HAVE_LAUNCH_H */
+
++#ifdef HAVE_SYSTEMD
++#include
++#endif /* HAVE_SYSTEMD */
++
+ #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
+ # include
+ #endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
+@@ -83,6 +89,9 @@
+ static void launchd_checkin(void);
+ static void launchd_checkout(void);
+ #endif /* HAVE_LAUNCHD */
++#ifdef HAVE_SYSTEMD
++static void systemd_checkin(void);
++#endif /* HAVE_SYSTEMD */
+ static void parent_handler(int sig);
+ static void process_children(void);
+ static void sigchld_handler(int sig);
+@@ -581,6 +590,13 @@ main(int argc, /* I - Number of comm
+ }
+ #endif /* HAVE_LAUNCHD */
+
++#ifdef HAVE_SYSTEMD
++ /*
++ * If we were started by systemd get the listen sockets file descriptors...
++ */
++ systemd_checkin();
++#endif /* HAVE_SYSTEMD */
++
+ /*
+ * Startup the server...
+ */
+@@ -791,6 +807,15 @@ main(int argc, /* I - Number of comm
+ }
+ #endif /* HAVE_LAUNCHD */
+
++#ifdef HAVE_SYSTEMD
++ /*
++ * If we were started by systemd get the listen sockets file
++ * descriptors...
++ */
++
++ systemd_checkin();
++#endif /* HAVE_SYSTEMD */
++
+ /*
+ * Startup the server...
+ */
+@@ -1552,6 +1577,102 @@ launchd_checkout(void)
+ }
+ #endif /* HAVE_LAUNCHD */
+
++#ifdef HAVE_SYSTEMD
++static void
++systemd_checkin(void)
++{
++ int n, fd;
++
++ n = sd_listen_fds(0);
++ if (n < 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "systemd_checkin: Failed to acquire sockets from systemd - %s",
++ strerror(-n));
++ exit(EXIT_FAILURE);
++ return;
++ }
++
++ if (n == 0)
++ return;
++
++ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
++ {
++ http_addr_t addr;
++ socklen_t addrlen = sizeof (addr);
++ int r;
++ cupsd_listener_t *lis;
++ char s[256];
++
++ r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1);
++ if (r < 0)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "systemd_checkin: Unable to verify socket type - %s",
++ strerror(-r));
++ continue;
++ }
++
++ if (!r)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "systemd_checkin: Socket not of the right type");
++ continue;
++ }
++
++ if (getsockname(fd, (struct sockaddr*) &addr, &addrlen))
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "systemd_checkin: Unable to get local address - %s",
++ strerror(errno));
++ continue;
++ }
++
++ /*
++ * Try to match the systemd socket address to one of the listeners...
++ */
++
++ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
++ lis;
++ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
++ if (httpAddrEqual(&lis->address, &addr))
++ break;
++
++ if (lis)
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "systemd_checkin: Matched existing listener %s with fd %d...",
++ httpAddrString(&(lis->address), s, sizeof(s)), fd);
++ }
++ else
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "systemd_checkin: Adding new listener %s with fd %d...",
++ httpAddrString(&addr, s, sizeof(s)), fd);
++
++ if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_ERROR,
++ "systemd_checkin: Unable to allocate listener - "
++ "%s.", strerror(errno));
++ exit(EXIT_FAILURE);
++ }
++
++ cupsArrayAdd(Listeners, lis);
++
++ memcpy(&lis->address, &addr, sizeof(lis->address));
++ }
++
++ lis->fd = fd;
++ lis->is_systemd = 1;
++
++# ifdef HAVE_SSL
++ if (_httpAddrPort(&(lis->address)) == 443)
++ lis->encryption = HTTP_ENCRYPT_ALWAYS;
++# endif /* HAVE_SSL */
++ }
++}
++#endif /* HAVE_SYSTEMD */
+
+ /*
+ * 'parent_handler()' - Catch USR1/CHLD signals...
+diff -up cups-1.6.2/scheduler/Makefile.systemd-socket cups-1.6.2/scheduler/Makefile
+--- cups-1.6.2/scheduler/Makefile.systemd-socket 2012-05-21 19:40:22.000000000 +0200
++++ cups-1.6.2/scheduler/Makefile 2013-03-18 18:53:53.772961588 +0100
+@@ -371,7 +371,7 @@ cupsd: $(CUPSDOBJS) $(LIBCUPSMIME) ../cu
+ $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime \
+ $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
+ $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \
+- $(LIBGSSAPI) $(LIBWRAP)
++ $(LIBGSSAPI) $(LIBWRAP) $(SDLIBS)
+
+ cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
+ echo Linking $@...
+@@ -379,7 +379,7 @@ cupsd-static: $(CUPSDOBJS) libcupsmime.a
+ $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
+ ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \
+ $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
+- $(LIBWRAP)
++ $(LIBWRAP) $(SDLIBS)
+
+ tls.o: tls-darwin.c tls-gnutls.c tls-openssl.c
+
diff --git a/SOURCES/cups-uri-compat.patch b/SOURCES/cups-uri-compat.patch
new file mode 100644
index 0000000..2520a5b
--- /dev/null
+++ b/SOURCES/cups-uri-compat.patch
@@ -0,0 +1,51 @@
+diff -up cups-1.5b1/backend/usb-unix.c.uri-compat cups-1.5b1/backend/usb-unix.c
+--- cups-1.5b1/backend/usb-unix.c.uri-compat 2011-05-24 15:59:05.000000000 +0200
++++ cups-1.5b1/backend/usb-unix.c 2011-05-24 16:02:03.000000000 +0200
+@@ -63,11 +63,34 @@ print_device(const char *uri, /* I - De
+ int device_fd; /* USB device */
+ ssize_t tbytes; /* Total number of bytes written */
+ struct termios opts; /* Parallel port options */
++ char *fixed_uri = strdup (uri);
++ char *p;
+
+
+ (void)argc;
+ (void)argv;
+
++ p = strchr (fixed_uri, ':');
++ if (p++ != NULL)
++ {
++ char *e;
++ p += strspn (p, "/");
++ e = strchr (p, '/');
++ if (e > p)
++ {
++ size_t mfrlen = e - p;
++ e++;
++ if (!strncasecmp (e, p, mfrlen))
++ {
++ char *x = e + mfrlen;
++ if (!strncmp (x, "%20", 3))
++ /* Take mfr name out of mdl name for compatibility with
++ * Fedora 11 before bug #507244 was fixed. */
++ strcpy (e, x + 3); puts(fixed_uri);
++ }
++ }
++ }
++
+ /*
+ * Open the USB port device...
+ */
+@@ -107,10 +130,10 @@ print_device(const char *uri, /* I - De
+ _cups_strncasecmp(hostname, "Minolta", 7);
+ #endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */
+
+- if (use_bc && !strncmp(uri, "usb:/dev/", 9))
++ if (use_bc && !strncmp(fixed_uri, "usb:/dev/", 9))
+ use_bc = 0;
+
+- if ((device_fd = open_device(uri, &use_bc)) == -1)
++ if ((device_fd = open_device(fixed_uri, &use_bc)) == -1)
+ {
+ if (getenv("CLASS") != NULL)
+ {
diff --git a/SOURCES/cups-usb-paperout.patch b/SOURCES/cups-usb-paperout.patch
new file mode 100644
index 0000000..f1f73f0
--- /dev/null
+++ b/SOURCES/cups-usb-paperout.patch
@@ -0,0 +1,52 @@
+diff -up cups-1.5b1/backend/usb-unix.c.usb-paperout cups-1.5b1/backend/usb-unix.c
+--- cups-1.5b1/backend/usb-unix.c.usb-paperout 2011-05-24 15:51:39.000000000 +0200
++++ cups-1.5b1/backend/usb-unix.c 2011-05-24 15:51:39.000000000 +0200
+@@ -30,6 +30,11 @@
+
+ #include
+
++#ifdef __linux
++#include
++#include
++#endif /* __linux */
++
+
+ /*
+ * Local functions...
+@@ -334,7 +339,19 @@ open_device(const char *uri, /* I - Dev
+ if (!strncmp(uri, "usb:/dev/", 9))
+ #ifdef __linux
+ {
+- return (open(uri + 4, O_RDWR | O_EXCL));
++ fd = open(uri + 4, O_RDWR | O_EXCL);
++
++ if (fd != -1)
++ {
++ /*
++ * Tell the driver to return from write() with errno==ENOSPACE
++ * on paper-out.
++ */
++ unsigned int t = 1;
++ ioctl (fd, LPABORT, &t);
++ }
++
++ return fd;
+ }
+ else if (!strncmp(uri, "usb://", 6))
+ {
+@@ -400,7 +417,14 @@ open_device(const char *uri, /* I - Dev
+ if (!strcmp(uri, device_uri))
+ {
+ /*
+- * Yes, return this file descriptor...
++ * Yes, tell the driver to return from write() with
++ * errno==ENOSPACE on paper-out.
++ */
++ unsigned int t = 1;
++ ioctl (fd, LPABORT, &t);
++
++ /*
++ * Return this file descriptor...
+ */
+
+ fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n",
diff --git a/SOURCES/cups-usb-timeout.patch b/SOURCES/cups-usb-timeout.patch
new file mode 100644
index 0000000..9d21dea
--- /dev/null
+++ b/SOURCES/cups-usb-timeout.patch
@@ -0,0 +1,30 @@
+diff -up cups-1.7.0/backend/usb-libusb.c.usb-timeout cups-1.7.0/backend/usb-libusb.c
+--- cups-1.7.0/backend/usb-libusb.c.usb-timeout 2013-07-17 16:51:43.000000000 +0100
++++ cups-1.7.0/backend/usb-libusb.c 2013-11-28 16:44:03.785124015 +0000
+@@ -496,7 +496,7 @@ print_device(const char *uri, /* I - De
+ iostatus = libusb_bulk_transfer(g.printer->handle,
+ g.printer->write_endp,
+ print_buffer, g.print_bytes,
+- &bytes, 60000);
++ &bytes, 0);
+ /*
+ * Ignore timeout errors, but retain the number of bytes written to
+ * avoid sending duplicate data...
+@@ -519,7 +519,7 @@ print_device(const char *uri, /* I - De
+ iostatus = libusb_bulk_transfer(g.printer->handle,
+ g.printer->write_endp,
+ print_buffer, g.print_bytes,
+- &bytes, 60000);
++ &bytes, 0);
+ }
+
+ /*
+@@ -534,7 +534,7 @@ print_device(const char *uri, /* I - De
+ iostatus = libusb_bulk_transfer(g.printer->handle,
+ g.printer->write_endp,
+ print_buffer, g.print_bytes,
+- &bytes, 60000);
++ &bytes, 0);
+ }
+
+ if (iostatus)
diff --git a/SOURCES/cups-usblp-quirks.patch b/SOURCES/cups-usblp-quirks.patch
new file mode 100644
index 0000000..b626715
--- /dev/null
+++ b/SOURCES/cups-usblp-quirks.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.6.3/backend/usb-libusb.c.usblp-quirks cups-1.6.3/backend/usb-libusb.c
+--- cups-1.6.3/backend/usb-libusb.c.usblp-quirks 2013-06-07 03:12:52.000000000 +0200
++++ cups-1.6.3/backend/usb-libusb.c 2013-07-12 11:39:33.000000000 +0200
+@@ -158,6 +158,8 @@ static const struct quirk_printer_struct
+ Printer, https://bugs.launchpad.net/bugs/1032456 */
+ { 0x04a9, 0x1717, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP510
+ Printer, https://bugs.launchpad.net/bugs/1050009 */
++ { 0x04a9, 0x1730, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP540
++ Printer, https://bugzilla.redhat.com/967873 */
+ { 0x04a9, 0x173d, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP550
+ Printer, http://www.cups.org/str.php?L4155 */
+ { 0x04a9, 0x173e, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP560
diff --git a/SOURCES/cups-use-ipp1.1.patch b/SOURCES/cups-use-ipp1.1.patch
new file mode 100644
index 0000000..41855fc
--- /dev/null
+++ b/SOURCES/cups-use-ipp1.1.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.6.3/cups/usersys.c.use-ipp1.1 cups-1.6.3/cups/usersys.c
+--- cups-1.6.3/cups/usersys.c.use-ipp1.1 2013-07-12 11:41:45.368837618 +0200
++++ cups-1.6.3/cups/usersys.c 2013-07-12 11:41:45.391837299 +0200
+@@ -366,7 +366,7 @@ cupsSetServer(const char *server) /* I -
+ cg->server_version = 22;
+ }
+ else
+- cg->server_version = 20;
++ cg->server_version = 11;
+
+ if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL &&
+ !strchr(port, ']') && isdigit(port[1] & 255))
diff --git a/SOURCES/cups-web-devices-timeout.patch b/SOURCES/cups-web-devices-timeout.patch
new file mode 100644
index 0000000..fa3a320
--- /dev/null
+++ b/SOURCES/cups-web-devices-timeout.patch
@@ -0,0 +1,19 @@
+diff -up cups-1.7rc1/cgi-bin/admin.c.web-devices-timeout cups-1.7rc1/cgi-bin/admin.c
+--- cups-1.7rc1/cgi-bin/admin.c.web-devices-timeout 2013-05-29 12:51:34.000000000 +0100
++++ cups-1.7rc1/cgi-bin/admin.c 2013-08-16 16:01:17.308264287 +0100
+@@ -1019,13 +1019,13 @@ do_am_printer(http_t *http, /* I - HTTP
+ }
+
+ /*
+- * Scan for devices for up to 30 seconds...
++ * Scan for devices for up to 10 seconds...
+ */
+
+ fputs("DEBUG: Getting list of devices...\n", stderr);
+
+ current_device = 0;
+- if (cupsGetDevices(http, 5, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
++ if (cupsGetDevices(http, 10, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
+ (cups_device_cb_t)choose_device_cb,
+ (void *)title) == IPP_OK)
+ {
diff --git a/SOURCES/cups.logrotate b/SOURCES/cups.logrotate
new file mode 100644
index 0000000..773c70f
--- /dev/null
+++ b/SOURCES/cups.logrotate
@@ -0,0 +1,5 @@
+/var/log/cups/*_log {
+ missingok
+ notifempty
+ sharedscripts
+}
diff --git a/SOURCES/macros.cups b/SOURCES/macros.cups
new file mode 100644
index 0000000..5b560d9
--- /dev/null
+++ b/SOURCES/macros.cups
@@ -0,0 +1 @@
+%_cups_serverbin %(/usr/bin/cups-config --serverbin)
diff --git a/SOURCES/ncp.backend b/SOURCES/ncp.backend
new file mode 100755
index 0000000..d57ada1
--- /dev/null
+++ b/SOURCES/ncp.backend
@@ -0,0 +1,51 @@
+#!/bin/sh
+# This is a modified version of 'ncpprint'. It can now be used as a CUPS
+# backend.
+# Modifications:
+# Copyright (C) 2002 Red Hat, inc
+# Copyright (C) 2002 Tim Waugh
+# Before modification: shipped as /usr/share/printconf/util/ncpprint
+
+if [ -z "$*" ]
+then
+ # This is where we would enumerate all the URIs we support.
+ # Patches welcome.
+ exit 0
+fi
+
+FILE=$6
+if [ -z "$FILE" ]
+then
+ FILE=-
+fi
+
+# $DEVICE_URI is 'ncp://[user:password@]server/queue'
+URI=${DEVICE_URI#*://}
+queue=${URI#*/}
+URI=${URI%/$queue}
+server=${URI#*@}
+URI=${URI%$server}
+URI=${URI%@}
+if [ -n "$URI" ]
+then
+ user=${URI%:*}
+ URI=${URI#$user}
+ password=${URI#:}
+fi
+
+#echo user: ${user-(none)}
+#echo password: ${password-(none)}
+#echo server: $server
+#echo queue: $queue
+
+if [ -n "$user" ]
+then
+ if [ -n "$password" ]
+ then
+ /usr/bin/nprint -S "$server" -q "$queue" -U "$user" -P "$password" -N "$FILE" 2>/dev/null
+ else
+ /usr/bin/nprint -S "$server" -q "$queue" -U "$user" -n -N "$FILE" 2>/dev/null
+ fi
+else
+ /usr/bin/nprint -S "$server" -q "$queue" -N "$FILE" 2>/dev/null
+fi
diff --git a/SPECS/cups.spec b/SPECS/cups.spec
new file mode 100644
index 0000000..5b3d2a2
--- /dev/null
+++ b/SPECS/cups.spec
@@ -0,0 +1,3440 @@
+%global use_alternatives 1
+%global lspp 1
+
+# {_exec_prefix}/lib/cups is correct, even on x86_64.
+# It is not used for shared objects but for executables.
+# It's more of a libexec-style ({_libexecdir}) usage,
+# but we use lib for compatibility with 3rd party drivers (at upstream request).
+%global cups_serverbin %{_exec_prefix}/lib/cups
+
+Summary: CUPS printing system
+Name: cups
+Epoch: 1
+Version: 1.6.3
+Release: 35%{?dist}
+License: GPLv2
+Group: System Environment/Daemons
+Url: http://www.cups.org/
+Source: http://www.cups.org/software/%{version}/cups-%{version}-source.tar.bz2
+# Pixmap for desktop file
+Source2: cupsprinter.png
+# socket unit for cups-lpd service
+Source3: cups-lpd.socket
+# cups-lpd service unit configuration
+Source4: cups-lpd@.service
+# Logrotate configuration
+Source6: cups.logrotate
+# Backend for NCP protocol
+Source7: ncp.backend
+Source8: macros.cups
+
+Patch1: cups-no-gzip-man.patch
+Patch2: cups-system-auth.patch
+Patch3: cups-multilib.patch
+Patch4: cups-dbus-utf8.patch
+Patch5: cups-banners.patch
+Patch6: cups-serverbin-compat.patch
+Patch7: cups-no-export-ssllibs.patch
+Patch8: cups-direct-usb.patch
+Patch9: cups-lpr-help.patch
+Patch10: cups-peercred.patch
+Patch11: cups-pid.patch
+Patch12: cups-eggcups.patch
+Patch13: cups-driverd-timeout.patch
+Patch14: cups-strict-ppd-line-length.patch
+Patch15: cups-logrotate.patch
+Patch16: cups-usb-paperout.patch
+Patch17: cups-res_init.patch
+Patch18: cups-filter-debug.patch
+Patch19: cups-uri-compat.patch
+Patch20: cups-str3382.patch
+Patch21: cups-0755.patch
+Patch22: cups-hp-deviceid-oid.patch
+Patch23: cups-dnssd-deviceid.patch
+Patch24: cups-ricoh-deviceid-oid.patch
+Patch25: cups-systemd-socket.patch
+Patch26: cups-lpd-manpage.patch
+Patch27: cups-avahi-address.patch
+Patch28: cups-usblp-quirks.patch
+Patch29: cups-enum-all.patch
+Patch30: cups-stringpool-setprinterattr.patch
+Patch31: cups-dymo-deviceid.patch
+Patch32: cups-use-ipp1.1.patch
+Patch33: cups-no-gcry.patch
+Patch34: cups-avahi-no-threaded.patch
+Patch35: cups-gz-crc.patch
+Patch36: cups-ipp-multifile.patch
+Patch37: cups-full-relro.patch
+Patch38: cups-web-devices-timeout.patch
+Patch39: cups-synconclose.patch
+Patch40: cups-str4500.patch
+Patch41: cups-dbus-notifier.patch
+Patch42: cups-usb-timeout.patch
+Patch43: cups-str4326.patch
+Patch44: cups-str4327.patch
+Patch45: cups-CVE-2014-2856.patch
+Patch46: cups-str4380.patch
+Patch47: cups-colord-interface.patch
+Patch48: cups-nodatadelay.patch
+Patch49: cups-str4440.patch
+Patch50: cups-error-policy-manpage.patch
+Patch51: cups-CVE-2014-3537.patch
+Patch52: cups-CVE-2014-5029-5030-5031.patch
+Patch53: cups-str4461.patch
+Patch54: cups-str4475.patch
+Patch55: cups-failover-backend.patch
+Patch56: cups-str4609.patch
+Patch57: cups-str4551.patch
+Patch58: cups-str4476.patch
+Patch59: cups-str4591.patch
+Patch60: cups-str4646.patch
+Patch61: cups-str4648.patch
+Patch62: cups-start-service.patch
+Patch63: cups-163-enotif.patch
+Patch64: cups-163-fdleak.patch
+Patch65: cups-state-message.patch
+Patch66: cups-1.6.3-resolv_reload.patch
+Patch67: cups-1.6.3-legacy-iso88591.patch
+Patch68: cups-1.6.3-ypbind.patch
+Patch69: cups-1.6.3-overriden-h.patch
+Patch70: cups-net-backends-etimedout-enotconn.patch
+Patch71: cups-1.6.3-tlsv12.patch
+Patch72: cups-1.6.3-page-count.patch
+
+Patch100: cups-lspp.patch
+
+Requires: %{name}-filesystem = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+Requires: %{name}-client%{?_isa} = %{epoch}:%{version}-%{release}
+
+Provides: cupsddk cupsddk-drivers
+
+BuildRequires: pam-devel pkgconfig
+BuildRequires: openssl-devel libacl-devel
+BuildRequires: openldap-devel
+BuildRequires: libusb1-devel
+BuildRequires: krb5-devel
+BuildRequires: avahi-devel
+BuildRequires: systemd, systemd-devel
+BuildRequires: dbus-devel
+BuildRequires: automake
+
+# Make sure we get postscriptdriver tags.
+BuildRequires: python-cups
+
+%if %lspp
+BuildRequires: libselinux-devel
+BuildRequires: audit-libs-devel
+%endif
+
+Requires: dbus
+
+# Requires working PrivateTmp (bug #807672)
+Requires(pre): systemd
+Requires(post): systemd
+Requires(post): systemd-sysv
+Requires(post): grep, sed
+Requires(preun): systemd
+Requires(postun): systemd
+
+# We ship udev rules which use setfacl.
+Requires: systemd
+Requires: acl
+
+# Make sure we have some filters for converting to raster format.
+Requires: ghostscript-cups
+
+%package client
+Summary: CUPS printing system - client programs
+Group: System Environment/Daemons
+License: GPLv2
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+%if %use_alternatives
+Provides: /usr/bin/lpq /usr/bin/lpr /usr/bin/lp /usr/bin/cancel /usr/bin/lprm /usr/bin/lpstat
+Requires: /usr/sbin/alternatives
+%endif
+Provides: lpr
+
+%package devel
+Summary: CUPS printing system - development environment
+Group: Development/Libraries
+License: LGPLv2
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+Requires: openssl-devel
+Requires: krb5-devel
+Requires: zlib-devel
+Provides: cupsddk-devel
+
+%package libs
+Summary: CUPS printing system - libraries
+Group: System Environment/Libraries
+License: LGPLv2 and zlib
+
+%package filesystem
+Summary: CUPS printing system - directory layout
+Group: System Environment/Base
+BuildArch: noarch
+Requires: cups-filters
+
+%package lpd
+Summary: CUPS printing system - lpd emulation
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+Provides: lpd
+
+%package ipptool
+Summary: CUPS printing system - tool for performing IPP requests
+Group: System Environment/Daemons
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+
+%description
+CUPS printing system provides a portable printing layer for
+UNIX® operating systems. It has been developed by Apple Inc.
+to promote a standard printing solution for all UNIX vendors and users.
+CUPS provides the System V and Berkeley command-line interfaces.
+
+%description client
+CUPS printing system provides a portable printing layer for
+UNIX® operating systems. This package contains command-line client
+programs.
+
+%description devel
+CUPS printing system provides a portable printing layer for
+UNIX® operating systems. This is the development package for creating
+additional printer drivers, and other CUPS services.
+
+%description libs
+CUPS printing system provides a portable printing layer for
+UNIX® operating systems. It has been developed by Apple Inc.
+to promote a standard printing solution for all UNIX vendors and users.
+CUPS provides the System V and Berkeley command-line interfaces.
+The cups-libs package provides libraries used by applications to use CUPS
+natively, without needing the lp/lpr commands.
+
+%description filesystem
+CUPS printing system provides a portable printing layer for
+UNIX® operating systems. This package provides some directories which are
+required by other packages that add CUPS drivers (i.e. filters, backends etc.).
+
+%description lpd
+CUPS printing system provides a portable printing layer for
+UNIX® operating systems. This is the package that provides standard
+lpd emulation.
+
+%description ipptool
+Sends IPP requests to the specified URI and tests and/or displays the results.
+
+%prep
+%setup -q
+# Don't gzip man pages in the Makefile, let rpmbuild do it.
+%patch1 -p1 -b .no-gzip-man
+# Use the system pam configuration.
+%patch2 -p1 -b .system-auth
+# Prevent multilib conflict in cups-config script.
+%patch3 -p1 -b .multilib
+# Ensure attributes are valid UTF-8 in dbus notifier (bug #863387).
+%patch4 -p1 -b .dbus-utf8
+# Ignore rpm save/new files in the banners directory.
+%patch5 -p1 -b .banners
+# Use compatibility fallback path for ServerBin.
+%patch6 -p1 -b .serverbin-compat
+# Don't export SSLLIBS to cups-config.
+%patch7 -p1 -b .no-export-ssllibs
+# Allow file-based usb device URIs.
+%patch8 -p1 -b .direct-usb
+# Add --help option to lpr.
+%patch9 -p1 -b .lpr-help
+# Fix compilation of peer credentials support.
+%patch10 -p1 -b .peercred
+# Maintain a cupsd.pid file.
+%patch11 -p1 -b .pid
+# Fix implementation of com.redhat.PrinterSpooler D-Bus object.
+%patch12 -p1 -b .eggcups
+# Increase driverd timeout to 70s to accommodate foomatic (bug #744715).
+%patch13 -p1 -b .driverd-timeout
+# Only enforce maximum PPD line length when in strict mode.
+%patch14 -p1 -b .strict-ppd-line-length
+# Re-open the log if it has been logrotated under us.
+%patch15 -p1 -b .logrotate
+# Support for errno==ENOSPACE-based USB paper-out reporting.
+%patch16 -p1 -b .usb-paperout
+# Re-initialise the resolver on failure in httpAddrGetList() (bug #567353).
+%patch17 -p1 -b .res_init
+# Log extra debugging information if no filters are available.
+%patch18 -p1 -b .filter-debug
+# Allow the usb backend to understand old-style URI formats.
+%patch19 -p1 -b .uri-compat
+# Fix temporary filename creation.
+%patch20 -p1 -b .str3382
+# Use mode 0755 for binaries and libraries where appropriate.
+%patch21 -p1 -b .0755
+# Add an SNMP query for HP's device ID OID (STR #3552).
+%patch22 -p1 -b .hp-deviceid-oid
+# Mark DNS-SD Device IDs that have been guessed at with "FZY:1;".
+%patch23 -p1 -b .dnssd-deviceid
+# Add an SNMP query for Ricoh's device ID OID (STR #3552).
+%patch24 -p1 -b .ricoh-deviceid-oid
+# Add support for systemd socket activation (patch from Lennart
+# Poettering).
+%patch25 -p1 -b .systemd-socket
+# Talk about systemd in cups-lpd manpage (part of bug #884641).
+%patch26 -p1 -b .lpd-manpage
+# Use IP address when resolving DNSSD URIs (bug #948288).
+%patch27 -p1 -b .avahi-address
+# Added usblp quirk for Canon PIXMA MP540 (bug #967873).
+%patch28 -p1 -b .usblp-quirks
+# Return from cupsEnumDests() once all records have been returned.
+%patch29 -p1 -b .enum-all
+# Prevent stringpool damage leading to memory leaks (bug #974048).
+%patch30 -p1 -b .stringpool-setprinterattr
+# Added IEEE 1284 Device ID for a Dymo device (bug #747866).
+%patch31 -p1 -b .dymo-deviceid
+# Default to IPP/1.1 for now (bug #977813).
+%patch32 -p1 -b .use-ipp1.1
+# Don't link against libgcrypt needlessly.
+%patch33 -p1 -b .no-gcry
+# Don't use D-Bus from two threads (bug #979748).
+%patch34 -p1 -b .avahi-no-threaded
+# Avoid sign-extending CRCs for gz decompression (bug #983486).
+%patch35 -p1 -b .gz-crc
+# Fixes for jobs with multiple files and multiple formats.
+%patch36 -p1 -b .ipp-multifile
+# Full relro (bug #996740).
+%patch37 -p1 -b .full-relro
+# Increase web interface get-devices timeout to 10s (bug #996664).
+%patch38 -p1 -b .web-devices-timeout
+# Add SyncOnClose option (bug #984883).
+%patch39 -p1 -b .synconclose
+# Fix cupsGetPPD3() so it doesn't give the caller an unreadable file
+# (part of fix for CVE-2014-5031, STR #4500).
+%patch40 -p1 -b .str4500
+# Avoid stale lockfile in dbus notifier (bug #1030666).
+%patch41 -p1 -b .dbus-notifier
+# Prevent USB timeouts causing incorrect print output (bug #1036057).
+%patch42 -p1 -b .usb-timeout
+# Return jobs in rank order when handling IPP-Get-Jobs (bug #1046841).
+%patch43 -p1 -b .str4326
+# Apply upstream patch to improve cupsUser() (bug #1046845).
+%patch44 -p1 -b .str4327
+# Apply upstream patch to fix cross-site scripting flaw (CVE-2014-2856,
+# bug #1087122).
+%patch45 -p1 -b .CVE-2014-2856
+# Fix for cupsEnumDest() 'removed' callbacks (bug #1072954, STR #4380).
+%patch46 -p1 -b .str4380
+# Use colord interface correctly (bug #1087323).
+%patch47 -p1 -b .colord-interface
+# Apply upstream patch to avoid 10 second timeouts in cupsd caused by
+# reading when no data ready (bug #1110259).
+%patch48 -p1 -b .nodatadelay
+# Avoid race condition in cupsdReadClient() (bug #1113045).
+%patch49 -p1 -b .str4440
+# Describe ErrorPolicy in the cupsd.conf man page (bug #1120591).
+%patch50 -p1 -b .error-policy-manpage
+# Apply upstream patch to fix privilege escalation due to insufficient
+# checking (CVE-2014-3537, bug #1115576).
+%patch51 -p1 -b .CVE-2014-3537
+# Apply upstream patch to fix CVE-2014-5029 (bug #1122600),
+# CVE-2014-5030 (bug #1128764), CVE-2014-5031 (bug #1128767).
+%patch52 -p1 -b .CVE-2014-5029-5030-5031
+# Fix conf/log file reading for authenticated users (STR #4461).
+%patch53 -p1 -b .str4461
+# Fix icon display in web interface during server restart (STR #4475).
+%patch54 -p1 -b .str4475
+# Support for failover without load-balancing (bug #1115219).
+%patch55 -p1 -b .failover-backend
+# Improper Update of Reference Count -- CVE-2015-1158
+# Cross-Site Scripting -- CVE-2015-1159
+# (bug #1229985)
+%patch56 -p1 -b .str4609
+# cupsRasterReadPixels buffer overflow -- CVE-2014-9679 (bug #1229985).
+%patch57 -p1 -b .str4551
+# Don't use SSLv3 by default (bug #1161172, STR #4476).
+%patch58 -p1 -b .str4476
+# Validate ErrorPolicy in configuration (bug #1196218, STR #4591).
+%patch59 -p1 -b .str4591
+# Fix slow resume of jobs after restart (bug #1233006, STR #4646).
+%patch60 -p1 -b .str4646
+# Don't start jobs while cancelling others (bug #1233002, STR #4648).
+%patch61 -p1 -b .str4648
+# Start cups.service in multi-user target by default (bug #1236184).
+%patch62 -p1 -b .start-service
+# Email notifications ("lp -m") for printer classes don't work (bug #1257751)
+%patch63 -p1 -b .enotif
+# Gnome-settings-daemon leaks file descriptors (bug #1297035)
+%patch64 -p1 -b .fdleak
+# Printer State Message not cleared upon successful print job completion (bug #1353096)
+%patch65 -p1 -b .state-message
+# CUPS does not recognize changes to /etc/resolv.conf until CUPS restart (bug #1325692)
+%patch66 -p1 -b .resolv_reload
+# cups-lpd program did not catch all legacy usage of ISO-8859-1 (bug #1386751)
+%patch67 -p1 -b .legacy-iso88591
+# CUPS may fail to start if NIS groups are used (bug #1441860)
+%patch68 -p1 -b .ypbind
+# The -h option is overridden by _cupsSetDefaults settings when the IPP port is not given (bug #1430882)
+%patch69 -p1 -b .overriden-h
+%if %lspp
+# LSPP support.
+%patch100 -p1 -b .lspp
+%endif
+# Failover backend won't fail-over if the printer is disconnected (bug #1469816)
+%patch70 -p1 -b .net-backends-etimedout-enotconn
+# Remove weak SSL/TLS ciphers from CUPS (bug #1466497)
+%patch71 -p1 -b .tlsv12
+# CUPS print jobs show incorrect number under the "pages" column (bug #1434153)
+%patch72 -p1 -b .page-count
+
+sed -i -e '1iMaxLogSize 0' conf/cupsd.conf.in
+
+# Let's look at the compilation command lines.
+perl -pi -e "s,^.SILENT:,," Makedefs.in
+
+f=CREDITS.txt
+mv "$f" "$f"~
+iconv -f MACINTOSH -t UTF-8 "$f"~ > "$f"
+rm -f "$f"~
+
+aclocal -I config-scripts
+autoconf -I config-scripts
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS -fstack-protector-all -DLDAP_DEPRECATED=1"
+# --enable-debug to avoid stripping binaries
+%configure --with-docdir=%{_datadir}/%{name}/www --enable-debug \
+%if %lspp
+ --enable-lspp \
+%endif
+ --with-cupsd-file-perm=0755 \
+ --with-log-file-perm=0600 \
+ --enable-relro \
+ --with-dbusdir=%{_sysconfdir}/dbus-1 \
+ --with-php=/usr/bin/php-cgi \
+ --enable-avahi \
+ --enable-threads --enable-openssl \
+ --enable-webif \
+ --with-xinetd=no \
+ localedir=%{_datadir}/locale
+
+# If we got this far, all prerequisite libraries must be here.
+make %{?_smp_mflags}
+
+%install
+make BUILDROOT=$RPM_BUILD_ROOT install
+
+rm -rf $RPM_BUILD_ROOT%{_initddir} \
+ $RPM_BUILD_ROOT%{_sysconfdir}/init.d \
+ $RPM_BUILD_ROOT%{_sysconfdir}/rc?.d
+mkdir -p $RPM_BUILD_ROOT%{_unitdir}
+
+find $RPM_BUILD_ROOT%{_datadir}/cups/model -name "*.ppd" |xargs gzip -n9f
+
+%if %use_alternatives
+pushd $RPM_BUILD_ROOT%{_bindir}
+for i in cancel lp lpq lpr lprm lpstat; do
+ mv $i $i.cups
+done
+cd $RPM_BUILD_ROOT%{_sbindir}
+mv lpc lpc.cups
+cd $RPM_BUILD_ROOT%{_mandir}/man1
+for i in cancel lp lpq lpr lprm lpstat; do
+ mv $i.1 $i-cups.1
+done
+cd $RPM_BUILD_ROOT%{_mandir}/man8
+mv lpc.8 lpc-cups.8
+popd
+%endif
+
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/pixmaps $RPM_BUILD_ROOT%{_sysconfdir}/X11/sysconfig $RPM_BUILD_ROOT%{_sysconfdir}/X11/applnk/System $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d
+install -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_datadir}/pixmaps
+install -p -m 644 %{SOURCE3} %{buildroot}%{_unitdir}
+install -p -m 644 %{SOURCE4} %{buildroot}%{_unitdir}
+install -p -m 644 %{SOURCE6} $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/cups
+install -p -m 755 %{SOURCE7} $RPM_BUILD_ROOT%{cups_serverbin}/backend/ncp
+
+# Ship an rpm macro for where to put driver executables.
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/rpm/
+install -m 0644 %{SOURCE8} $RPM_BUILD_ROOT%{_sysconfdir}/rpm/
+
+# Ship a printers.conf file, and a client.conf file. That way, they get
+# their SELinux file contexts set correctly.
+touch $RPM_BUILD_ROOT%{_sysconfdir}/cups/printers.conf
+touch $RPM_BUILD_ROOT%{_sysconfdir}/cups/classes.conf
+touch $RPM_BUILD_ROOT%{_sysconfdir}/cups/client.conf
+touch $RPM_BUILD_ROOT%{_sysconfdir}/cups/subscriptions.conf
+touch $RPM_BUILD_ROOT%{_sysconfdir}/cups/lpoptions
+
+# LSB 3.2 printer driver directory
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/ppd
+
+# Remove unshipped files.
+rm -rf $RPM_BUILD_ROOT%{_mandir}/cat? $RPM_BUILD_ROOT%{_mandir}/*/cat?
+rm -f $RPM_BUILD_ROOT%{_datadir}/applications/cups.desktop
+rm -rf $RPM_BUILD_ROOT%{_datadir}/icons
+# there are pdf-banners shipped with cups-filters (#919489)
+rm -f $RPM_BUILD_ROOT%{_datadir}/cups/banners/{classified,confidential,secret,standard,topsecret,unclassified}
+rm -f $RPM_BUILD_ROOT%{_datadir}/cups/data/testprint
+
+# install /usr/lib/tmpfiles.d/cups.conf (bug #656566, bug #893834)
+mkdir -p ${RPM_BUILD_ROOT}%{_tmpfilesdir}
+cat > ${RPM_BUILD_ROOT}%{_tmpfilesdir}/cups.conf < ${RPM_BUILD_ROOT}%{_tmpfilesdir}/cups-lp.conf < %{name}.lang
+
+%post
+%systemd_post %{name}.path %{name}.socket %{name}.service
+
+# Remove old-style certs directory; new-style is /var/run
+# (see bug #194581 for why this is necessary).
+rm -rf %{_sysconfdir}/cups/certs
+rm -f %{_localstatedir}/cache/cups/*.ipp %{_localstatedir}/cache/cups/*.cache
+
+# Deal with config migration due to CVE-2012-5519 (STR #4223)
+IN=%{_sysconfdir}/cups/cupsd.conf
+OUT=%{_sysconfdir}/cups/cups-files.conf
+copiedany=no
+for keyword in AccessLog CacheDir ConfigFilePerm \
+ DataDir DocumentRoot ErrorLog FatalErrors \
+ FileDevice FontPath Group LogFilePerm \
+ LPDConfigFile PageLog Printcap PrintcapFormat \
+ RemoteRoot RequestRoot ServerBin ServerCertificate \
+ ServerKey ServerRoot SMBConfigFile StateDir \
+ SystemGroup SystemGroupAuthKey TempDir User; do
+ if ! [ -f "$IN" ] || ! /bin/grep -wiq ^$keyword "$IN"; then continue; fi
+ copy=yes
+ if /bin/grep -wiq ^$keyword "$OUT"; then
+ if [ "`/bin/grep -wi ^$keyword "$IN"`" == \
+ "`/bin/grep -wi ^$keyword "$OUT"`" ]; then
+ copy=no
+ else
+ /bin/sed -i -e "s,^$keyword\b,#$keyword,i" "$OUT" || :
+ fi
+ fi
+ if [ "$copy" == "yes" ]; then
+ if [ "$copiedany" == "no" ]; then
+ (cat >> "$OUT" <> "$OUT") || :
+ copiedany=yes
+ fi
+
+ /bin/sed -i -e "s,^$keyword\b,#$keyword,i" "$IN" || :
+done
+
+# Comment out mistaken move of AccessLogLevel to
+# cups-files.conf (bug #1235035).
+for keyword in AccessLogLevel PageLogFormat; do
+ /bin/sed -i -e "s,^$keyword\b,#$keyword,i" "$OUT" || :
+done
+
+exit 0
+
+%post client
+%if %use_alternatives
+/usr/sbin/alternatives --install %{_bindir}/lpr print %{_bindir}/lpr.cups 40 \
+ --slave %{_bindir}/lp print-lp %{_bindir}/lp.cups \
+ --slave %{_bindir}/lpq print-lpq %{_bindir}/lpq.cups \
+ --slave %{_bindir}/lprm print-lprm %{_bindir}/lprm.cups \
+ --slave %{_bindir}/lpstat print-lpstat %{_bindir}/lpstat.cups \
+ --slave %{_bindir}/cancel print-cancel %{_bindir}/cancel.cups \
+ --slave %{_sbindir}/lpc print-lpc %{_sbindir}/lpc.cups \
+ --slave %{_mandir}/man1/cancel.1.gz print-cancelman %{_mandir}/man1/cancel-cups.1.gz \
+ --slave %{_mandir}/man1/lp.1.gz print-lpman %{_mandir}/man1/lp-cups.1.gz \
+ --slave %{_mandir}/man8/lpc.8.gz print-lpcman %{_mandir}/man8/lpc-cups.8.gz \
+ --slave %{_mandir}/man1/lpq.1.gz print-lpqman %{_mandir}/man1/lpq-cups.1.gz \
+ --slave %{_mandir}/man1/lpr.1.gz print-lprman %{_mandir}/man1/lpr-cups.1.gz \
+ --slave %{_mandir}/man1/lprm.1.gz print-lprmman %{_mandir}/man1/lprm-cups.1.gz \
+ --slave %{_mandir}/man1/lpstat.1.gz print-lpstatman %{_mandir}/man1/lpstat-cups.1.gz
+%endif
+exit 0
+
+%post lpd
+%systemd_post cups-lpd.socket
+exit 0
+
+%post libs -p /sbin/ldconfig
+
+%postun libs -p /sbin/ldconfig
+
+%preun
+%systemd_preun %{name}.path %{name}.socket %{name}.service
+exit 0
+
+%preun client
+%if %use_alternatives
+if [ $1 -eq 0 ] ; then
+ /usr/sbin/alternatives --remove print %{_bindir}/lpr.cups
+fi
+%endif
+exit 0
+
+%preun lpd
+%systemd_preun cups-lpd.socket
+exit 0
+
+%postun
+%systemd_postun_with_restart %{name}.service
+exit 0
+
+%postun lpd
+%systemd_postun_with_restart cups-lpd.socket
+exit 0
+
+%triggerun -- %{name} < 1:1.5-0.9
+# Save the current service runlevel info
+# User must manually run systemd-sysv-convert --apply cups
+# to migrate them to systemd targets
+%{_bindir}/systemd-sysv-convert --save %{name} >/dev/null 2>&1 || :
+
+# This package is allowed to autostart:
+/bin/systemctl --no-reload enable %{name}.{service,socket,path} >/dev/null 2>&1 || :
+
+# Run these because the SysV package being removed won't do them
+/sbin/chkconfig --del cups >/dev/null 2>&1 || :
+/bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || :
+
+%triggerin -- samba-client
+ln -sf %{_libexecdir}/samba/cups_backend_smb %{cups_serverbin}/backend/smb || :
+exit 0
+
+%triggerun -- samba-client
+[ $2 = 0 ] || exit 0
+rm -f %{cups_serverbin}/backend/smb
+
+%files -f %{name}.lang
+%doc README.txt CREDITS.txt CHANGES.txt
+%dir %attr(0755,root,lp) %{_sysconfdir}/cups
+%dir %attr(0755,root,lp) %{_localstatedir}/run/cups
+%dir %attr(0511,lp,sys) %{_localstatedir}/run/cups/certs
+%{_tmpfilesdir}/cups.conf
+%{_tmpfilesdir}/cups-lp.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0640,root,lp) %{_sysconfdir}/cups/cupsd.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0640,root,lp) %{_sysconfdir}/cups/cups-files.conf
+%attr(0640,root,lp) %{_sysconfdir}/cups/cupsd.conf.default
+%verify(not md5 size mtime) %config(noreplace) %attr(0644,root,lp) %{_sysconfdir}/cups/client.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0600,root,lp) %{_sysconfdir}/cups/classes.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0600,root,lp) %{_sysconfdir}/cups/printers.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0644,root,lp) %{_sysconfdir}/cups/snmp.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0640,root,lp) %{_sysconfdir}/cups/subscriptions.conf
+%{_sysconfdir}/cups/interfaces
+%verify(not md5 size mtime) %config(noreplace) %attr(0644,root,lp) %{_sysconfdir}/cups/lpoptions
+%dir %attr(0755,root,lp) %{_sysconfdir}/cups/ppd
+%dir %attr(0700,root,lp) %{_sysconfdir}/cups/ssl
+%config(noreplace) %{_sysconfdir}/pam.d/cups
+%config(noreplace) %{_sysconfdir}/logrotate.d/cups
+%dir %{_datadir}/%{name}/www
+%dir %{_datadir}/%{name}/www/ca
+%dir %{_datadir}/%{name}/www/cs
+%dir %{_datadir}/%{name}/www/es
+%dir %{_datadir}/%{name}/www/fr
+%dir %{_datadir}/%{name}/www/ja
+%dir %{_datadir}/%{name}/www/ru
+%{_datadir}/%{name}/www/images
+%{_datadir}/%{name}/www/*.css
+%doc %{_datadir}/%{name}/www/index.html
+%doc %{_datadir}/%{name}/www/help
+%doc %{_datadir}/%{name}/www/robots.txt
+%doc %{_datadir}/%{name}/www/ca/index.html
+%doc %{_datadir}/%{name}/www/cs/index.html
+%doc %{_datadir}/%{name}/www/es/index.html
+%doc %{_datadir}/%{name}/www/fr/index.html
+%doc %{_datadir}/%{name}/www/ja/index.html
+%doc %{_datadir}/%{name}/www/ru/index.html
+%{_unitdir}/%{name}.service
+%{_unitdir}/%{name}.socket
+%{_unitdir}/%{name}.path
+%{_bindir}/cupstestppd
+%{_bindir}/cupstestdsc
+%{_bindir}/ppd*
+%{cups_serverbin}/backend/*
+%{cups_serverbin}/cgi-bin
+%dir %{cups_serverbin}/daemon
+%{cups_serverbin}/daemon/cups-deviced
+%{cups_serverbin}/daemon/cups-driverd
+%{cups_serverbin}/daemon/cups-exec
+%{cups_serverbin}/notifier
+%{cups_serverbin}/filter/*
+%{cups_serverbin}/monitor
+%{_mandir}/man[1578]/*
+# client subpackage
+%exclude %{_mandir}/man1/lp*.1.gz
+%exclude %{_mandir}/man1/cancel-cups.1.gz
+%exclude %{_mandir}/man8/lpc-cups.8.gz
+# devel subpackage
+%exclude %{_mandir}/man1/cups-config.1.gz
+# ipptool subpackage
+%exclude %{_mandir}/man1/ipptool.1.gz
+%exclude %{_mandir}/man5/ipptoolfile.5.gz
+# lpd subpackage
+%exclude %{_mandir}/man8/cups-lpd.8.gz
+%{_sbindir}/*
+# client subpackage
+%exclude %{_sbindir}/lpc.cups
+%dir %{_datadir}/cups/templates
+%dir %{_datadir}/cups/templates/ca
+%dir %{_datadir}/cups/templates/cs
+%dir %{_datadir}/cups/templates/es
+%dir %{_datadir}/cups/templates/fr
+%dir %{_datadir}/cups/templates/ja
+%dir %{_datadir}/cups/templates/ru
+%{_datadir}/cups/templates/*.tmpl
+%{_datadir}/cups/templates/ca/*.tmpl
+%{_datadir}/cups/templates/cs/*.tmpl
+%{_datadir}/cups/templates/es/*.tmpl
+%{_datadir}/cups/templates/fr/*.tmpl
+%{_datadir}/cups/templates/ja/*.tmpl
+%{_datadir}/cups/templates/ru/*.tmpl
+%dir %attr(1770,root,lp) %{_localstatedir}/spool/cups/tmp
+%dir %attr(0710,root,lp) %{_localstatedir}/spool/cups
+%dir %attr(0755,lp,sys) %{_localstatedir}/log/cups
+%{_datadir}/pixmaps/cupsprinter.png
+%config(noreplace) %{_sysconfdir}/dbus-1/system.d/cups.conf
+%{_datadir}/cups/drv/sample.drv
+%{_datadir}/cups/examples
+%{_datadir}/cups/mime/mime.types
+%{_datadir}/cups/mime/mime.convs
+%{_datadir}/cups/ppdc/*.defs
+%{_datadir}/cups/ppdc/*.h
+
+%files client
+%{_sbindir}/lpc.cups
+%{_bindir}/cancel*
+%{_bindir}/lp*
+%{_mandir}/man1/lp*.1.gz
+%{_mandir}/man1/cancel-cups.1.gz
+%{_mandir}/man8/lpc-cups.8.gz
+
+%files libs
+%doc LICENSE.txt
+%{_libdir}/*.so.*
+
+%files filesystem
+%dir %{cups_serverbin}
+%dir %{cups_serverbin}/backend
+%dir %{cups_serverbin}/driver
+%dir %{cups_serverbin}/filter
+%dir %{_datadir}/cups
+%if %lspp
+%{_datadir}/cups/banners/*
+%endif
+#%%dir %%{_datadir}/cups/charsets
+%dir %{_datadir}/cups/data
+%dir %{_datadir}/cups/drv
+%dir %{_datadir}/cups/mime
+%dir %{_datadir}/cups/model
+%dir %{_datadir}/cups/ppdc
+%dir %{_datadir}/ppd
+
+%files devel
+%{_bindir}/cups-config
+%{_libdir}/*.so
+%{_includedir}/cups
+%{_mandir}/man1/cups-config.1.gz
+%{_sysconfdir}/rpm/macros.cups
+
+%files lpd
+%{_unitdir}/cups-lpd.socket
+%{_unitdir}/cups-lpd@.service
+%{cups_serverbin}/daemon/cups-lpd
+%{_mandir}/man8/cups-lpd.8.gz
+
+%files ipptool
+%{_bindir}/ipptool
+%dir %{_datadir}/cups/ipptool
+%{_datadir}/cups/ipptool/*
+%{_mandir}/man1/ipptool.1.gz
+%{_mandir}/man5/ipptoolfile.5.gz
+
+%changelog
+* Fri Dec 15 2017 Zdenek Dohnal - 1:1.6.3-35
+- 1466497 - Remove weak SSL/TLS ciphers from CUPS - fixing covscan issues
+
+* Mon Dec 11 2017 Zdenek Dohnal - 1:1.6.3-34
+- 1466497 - Remove weak SSL/TLS ciphers from CUPS - fixing the patch
+
+* Wed Nov 01 2017 Zdenek Dohnal - 1:1.6.3-33
+- 1466497 - Remove weak SSL/TLS ciphers from CUPS
+- 1434153 - CUPS print jobs show incorrect number under the "pages" column
+
+* Wed Oct 25 2017 Zdenek Dohnal - 1:1.6.3-32
+- 1468747 - CUPS failover backend allows multiple jobs to get stuck in failed queue
+- 1469816 - Failover backend won't fail-over if the printer is disconnected
+
+* Mon Sep 25 2017 Zdenek Dohnal - 1:1.6.3-31
+- 1430882 - The -h option is overridden by _cupsSetDefaults settings when the IPP port is not given
+
+* Fri Sep 22 2017 Zdenek Dohnal - 1:1.6.3-30
+- 1386751 - cups-lpd program did not catch all legacy usage of ISO-8859-1
+- 1441860 - CUPS may fail to start if NIS groups are used
+
+* Thu Apr 06 2017 Zdenek Dohnal - 1:1.6.3-29
+- fixing cups-1.6.3-resolv_reload.patch for rhbz#1325692
+
+* Thu Mar 09 2017 Zdenek Dohnal - 1:1.6.3-28
+- 1325692 - CUPS does not recognize changes to /etc/resolv.conf until CUPS restart
+
+* Wed Jul 20 2016 Zdenek Dohnal - 1:1.6.3-27
+- 1353096 - Printer State Message not cleared upon successful print job completion
+
+* Wed Jun 15 2016 Zdenek Dohnal - 1:1.6.3-26
+- 1302055 - Change symlink for smb backend to /usr/libexec/samba/cups_backend_smb
+
+* Wed Apr 27 2016 Zdenek Dohnal - 1:1.6.3-25
+- 1297035 - gnome-settings-daemon leaks file descriptors
+- 1257751 - Email notifications ("lp -m") for printer classes don't work
+
+* Tue Apr 19 2016 Zdenek Dohnal - 1:1.6.3-24
+- Fixing once more 1257051, 1259770
+
+* Tue Apr 19 2016 Zdenek Dohnal - 1:1.6.3-23
+- 1257051 - cups-lpd man page incomplete
+- 1275790 - spec file includes triggers with overlapping version intervals
+- 1259770 - permission changed after writing to /etc/cups/subscriptions.conf
+
+* Tue Jul 21 2015 Tim Waugh - 1:1.6.3-22
+- Start cups.service in multi-user target by default (bug #1236184),
+ not just cups.socket.
+
+* Wed Jul 8 2015 Tim Waugh - 1:1.6.3-21
+- Use upstream patch for STR #4648 (bug #1233002).
+
+* Tue Jun 30 2015 Tim Waugh - 1:1.6.3-20
+- Don't start jobs while cancelling others (bug #1233002, STR #4648).
+- Fix slow resume of jobs after restart (bug #1233006, STR #4646).
+- Fixes for post-install scriptlet (bug #1235035).
+
+* Tue Jun 23 2015 Tim Waugh - 1:1.6.3-19
+- Validate ErrorPolicy in configuration (bug #1196218, STR #4591).
+- Don't use SSLv3 by default (bug #1161172, STR #4476).
+
+* Wed Jun 10 2015 Jiri Popelka - 1:1.6.3-18
+- CVE-2015-1158, CVE-2015-1159, CVE-2014-9679 (bug #1229985).
+
+* Tue Oct 21 2014 Tim Waugh - 1:1.6.3-17
+- Support for failover without load-balancing (bug #1115219).
+- Fix cupsGetPPD3() so it doesn't give the caller an unreadable file
+ (part of fix for CVE-2014-5031, STR #4500).
+- Can no longer reproduce bug #1010580 so removing final-content-type
+ patch as it causes issues for some backends (bug #1149245).
+- Start cups.service after network.target (bug #1144780).
+
+* Tue Sep 2 2014 Tim Waugh - 1:1.6.3-16
+- Apply upstream patch to fix CVE-2014-5029 (bug #1122600),
+ CVE-2014-5030 (bug #1128764), CVE-2014-5031 (bug #1128767). Also:
+ - Fix conf/log file reading for authenticated users (STR #4461).
+ - Fix icon display in web interface during server restart (STR #4475).
+- Apply upstream patch to fix privilege escalation due to insufficient
+ checking (CVE-2014-3537, bug #1115576).
+- Describe ErrorPolicy in the cupsd.conf man page (bug #1120591).
+- Reduce package dependencies (bug #1115057):
+ - New client subpackage containing command line client tools.
+ - Removed 'Requires: /sbin/chkconfig'.
+ - Moved 'Provides: lpd' to lpd subpackage.
+- Avoid race condition in cupsdReadClient() (bug #1113045).
+- Apply upstream patch to avoid 10 second timeouts in cupsd caused by
+ reading when no data ready (bug #1110259).
+- Use colord interface correctly (bug #1087323).
+- Fix for cupsEnumDest() 'removed' callbacks (bug #1072954, STR #4380).
+
+* Fri Jul 25 2014 Tim Waugh - 1:1.6.3-15
+- Apply upstream patch to fix cross-site scripting flaw (CVE-2014-2856,
+ bug #1087122).
+
+* Fri Jan 24 2014 Daniel Mach - 1:1.6.3-14
+- Mass rebuild 2014-01-24
+
+* Mon Jan 13 2014 Tim Waugh - 1:1.6.3-13
+- Apply upstream patch to improve cupsUser() (bug #1046845).
+
+* Tue Jan 7 2014 Tim Waugh - 1:1.6.3-12
+- Return jobs in rank order when handling IPP-Get-Jobs (bug #1046841).
+- dbus notifier: call _exit when handling SIGTERM (STR #4314, bug #1030666).
+- Use '-f' when using rm in %%setup section (bug #1046374).
+
+* Fri Dec 27 2013 Daniel Mach - 1:1.6.3-11
+- Mass rebuild 2013-12-27
+
+* Thu Nov 28 2013 Tim Waugh - 1:1.6.3-10
+- Prevent USB timeouts causing incorrect print output (bug #1036057).
+
+* Tue Nov 19 2013 Tim Waugh - 1:1.6.3-9
+- Avoid stale lockfile in dbus notifier (bug #1030666).
+
+* Thu Oct 31 2013 Tim Waugh - 1:1.6.3-8
+- Set the default for SyncOnClose to Yes.
+
+* Fri Sep 27 2013 Tim Waugh - 1:1.6.3-7
+- Reverted upstream change to FINAL_CONTENT_TYPE in order to fix
+ printing to remote CUPS servers (bug #1013040).
+
+* Wed Aug 21 2013 Jaromír Končický - 1:1.6.3-6
+- Add SyncOnClose option (bug #984883).
+
+* Fri Aug 16 2013 Tim Waugh
+- Increase web interface get-devices timeout to 10s (bug #996664).
+
+* Thu Aug 15 2013 Tim Waugh
+- Build with full read-only relocations (bug #996740).
+
+* Tue Aug 6 2013 Tim Waugh
+- Fixes for jobs with multiple files and multiple formats.
+
+* Wed Jul 24 2013 Tim Waugh - 1:1.6.3-5
+- Fixed cups-config, broken by last change (bug #987660).
+
+* Tue Jul 23 2013 Tim Waugh - 1:1.6.3-4
+- Added LSPP banner pages back in (bug #974362).
+
+* Mon Jul 22 2013 Tim Waugh - 1:1.6.3-3
+- Removed stale comment in spec file.
+- Link against OpenSSL instead of GnuTLS.
+
+* Thu Jul 18 2013 Tim Waugh - 1:1.6.3-2
+- Fixed downoad URL to point to the actual source, not a download
+ page.
+
+* Fri Jul 12 2013 Jiri Popelka - 1:1.6.3-1
+- 1.6.3
+
+* Thu Jul 11 2013 Tim Waugh 1:1.6.2-18
+- Avoid sign-extending CRCs for gz decompression (bug #983486).
+
+* Wed Jul 10 2013 Tim Waugh 1:1.6.2-17
+- Fixed download URL.
+
+* Wed Jul 10 2013 Jiri Popelka - 1:1.6.2-16
+- Remove pstops cost factor tweak from conf/mime.convs.in
+
+* Mon Jul 1 2013 Tim Waugh 1:1.6.2-15
+- Don't use D-Bus from two threads (bug #979748).
+
+* Fri Jun 28 2013 Tim Waugh 1:1.6.2-14
+- Fix for DNSSD name resolution.
+
+* Wed Jun 26 2013 Tim Waugh 1:1.6.2-13
+- Don't link against libgcrypt needlessly.
+
+* Wed Jun 26 2013 Tim Waugh 1:1.6.2-12
+- Default to IPP/1.1 for now (bug #977813).
+
+* Tue Jun 25 2013 Tim Waugh 1:1.6.2-11
+- Added usblp quirk for Canon PIXMA MP540 (bug #967873).
+
+* Tue Jun 18 2013 Tim Waugh 1:1.6.2-10
+- Added IEEE 1284 Device ID for a Dymo device (bug #747866).
+
+* Thu Jun 13 2013 Tim Waugh 1:1.6.2-9
+- Prevent stringpool damage leading to memory leaks (bug #974048).
+
+* Tue Jun 4 2013 Tim Waugh - 1:1.6.2-8
+- Return from cupsEnumDests() once all records have been returned.
+
+* Thu May 23 2013 Jiri Popelka - 1:1.6.2-7
+- Added more USB quirks for the libusb-based backend (STR #4311)
+
+* Thu May 23 2013 Jiri Popelka - 1:1.6.2-6
+- don't ship Russian web templates because they're broken (#960571, STR #4310)
+
+* Wed May 15 2013 Jiri Popelka - 1:1.6.2-5
+- move cups/ppdc/ to filesystem subpackage
+
+* Wed Apr 10 2013 Tim Waugh
+- cups-dbus-utf.patch: now that the scheduler only accepts valid UTF-8
+ strings for job-name, there's no need to validate it as UTF-8 in the
+ dbus notifier.
+
+* Thu Apr 4 2013 Tim Waugh 1:1.6.2-4
+- Use IP address when resolving DNSSD URIs (bug #948288).
+
+* Thu Mar 28 2013 Tim Waugh 1:1.6.2-3
+- Check for cupsd.conf existence prior to grepping it (bug #928816).
+
+* Tue Mar 19 2013 Jiri Popelka - 1:1.6.2-2
+- revert previous bug #919489 fix (i.e we don't ship banners now)
+
+* Mon Mar 18 2013 Jiri Popelka - 1:1.6.2-1
+- 1.6.2
+
+* Wed Mar 13 2013 Jiri Popelka - 1:1.6.1-26
+- ship banners again (#919489)
+
+* Tue Mar 5 2013 Tim Waugh 1:1.6.1-25
+- Talk about systemd in cups-lpd manpage (part of bug #884641).
+
+* Tue Mar 5 2013 Tim Waugh 1:1.6.1-24
+- Documentation fixes from STR #4223 (bug #915981).
+
+* Wed Feb 27 2013 Jiri Popelka - 1:1.6.1-23
+- Removed obsolete browsing directives from cupsd.conf (bug #880826, STR #4157).
+- Updated summary and descriptions (#882982).
+- Fixed bogus dates in changelog.
+
+* Fri Feb 15 2013 Tim Waugh 1:1.6.1-22
+- Applied colorman fix from STR #4232 and STR #4276.
+
+* Wed Feb 13 2013 Fedora Release Engineering - 1:1.6.1-21
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Fri Jan 18 2013 Jiri Popelka 1:1.6.1-20
+- Add quirk rule for Canon MP210 (#847923).
+
+* Mon Jan 14 2013 Jiri Popelka 1:1.6.1-19
+- Fix unowned directories (#894531).
+
+* Thu Jan 10 2013 Jiri Popelka 1:1.6.1-18
+- Clean /var/spool/cups/tmp with tmpfiles.d instead of tmpwatch&cron (#893834).
+
+* Wed Dec 19 2012 Jiri Popelka 1:1.6.1-17
+- Migrate cups-lpd from xinetd to systemd socket activatable service (#884641).
+- Clean up old Requires/Conflicts/Obsoletes/Provides.
+
+* Thu Dec 6 2012 Tim Waugh 1:1.6.1-16
+- Additional fix relating to CVE-2012-5519 to avoid misleading error
+ message about actions to take to enable file device URIs.
+
+* Tue Dec 4 2012 Tim Waugh 1:1.6.1-15
+- Small error handling improvements in the configuration migration
+ script.
+
+* Mon Dec 3 2012 Jiri Popelka 1:1.6.1-14
+- move ipptoolfile(5) to ipptool subpackage
+
+* Mon Dec 3 2012 Tim Waugh 1:1.6.1-13
+- Applied additional upstream patch for CVE-2012-5519 so that the
+ RemoteRoot keyword is recognised in the correct configuration file.
+
+* Wed Nov 28 2012 Tim Waugh 1:1.6.1-12
+- Fixed paths in config migration %%post script.
+- Set default cups-files.conf filename.
+
+* Mon Nov 26 2012 Tim Waugh 1:1.6.1-11
+- Apply upstream fix for CVE-2012-5519 (STR #4223, bug #875898).
+ Migrate configuration keywords as needed.
+
+* Mon Nov 19 2012 Tim Waugh 1:1.6.1-10
+- Re-enable the web interface as it is required for adjusting server
+ settings (bug #878090).
+
+* Tue Nov 6 2012 Tim Waugh 1:1.6.1-9
+- Disable the web interface by default (bug #864522).
+
+* Tue Oct 30 2012 Tim Waugh 1:1.6.1-8
+- Ensure attributes are valid UTF-8 in dbus notifier (bug #863387).
+
+* Mon Oct 29 2012 Tim Waugh 1:1.6.1-7
+- Removed broken cups-get-classes patch (bug #870612).
+
+* Mon Oct 22 2012 Jiri Popelka 1:1.6.1-6
+- Add quirk rule for Xerox Phaser 3124 (#867392)
+- backport more quirk rules (STR #4191)
+
+* Thu Sep 20 2012 Tim Waugh 1:1.6.1-5
+- The cups-libs subpackage contains code distributed under the zlib
+ license (md5.c).
+
+* Thu Aug 23 2012 Jiri Popelka 1:1.6.1-4
+- quirk handler for port reset done by new USB backend (bug #847923, STR #4155)
+
+* Mon Aug 13 2012 Jiri Popelka 1:1.6.1-3
+- fixed usage of parametrized systemd macros (#847405)
+
+* Wed Aug 08 2012 Jiri Popelka 1:1.6.1-2
+- Requires: cups-filters
+
+* Wed Aug 08 2012 Jiri Popelka 1:1.6.1-1
+- 1.6.1
+ - simplified systemd.patch due to removed CUPS Browsing protocol (STR #3922)
+ - removed:
+ textonly filter - moved to cups-filters
+ pstopdf filter - cups-filters also has pstopdf (different)
+ PHP module - moved to cups-filters (STR #3932)
+ serial.patch - moved to cups-filters
+ getpass.patch - r10140 removed the getpass() use
+ snmp-quirks.patch - fixed upstream (r10493)
+ avahi patches - merged upstream (STR #3066)
+ icc.patch - merged upstream (STR #3808)
+ - TODO:
+ - do we need cups-build.patch ?
+- added filesystem sub-package (#624695)
+- use macroized systemd scriptlets
+
+* Thu Jul 26 2012 Jiri Popelka 1:1.5.4-1
+- 1.5.4
+
+* Tue Jul 24 2012 Tim Waugh 1:1.5.3-5
+- Don't enable IP-based systemd socket activation by default (bug #842365).
+
+* Wed Jul 18 2012 Fedora Release Engineering - 1:1.5.3-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jun 05 2012 Jiri Popelka 1:1.5.3-3
+- Require systemd instead of udev.
+
+* Mon May 28 2012 Jiri Popelka 1:1.5.3-2
+- Buildrequire libusb1 (STR #3477)
+
+* Tue May 15 2012 Jiri Popelka 1:1.5.3-1
+- 1.5.3
+
+* Wed May 09 2012 Jiri Popelka 1:1.5.2-13
+- Add triggers for samba4-client. (#817110)
+- No need to define BuildRoot and clean it in clean and install section anymore.
+- %%defattr no longer needed in %%files sections.
+
+* Tue Apr 17 2012 Jiri Popelka 1:1.5.2-12
+- Install /usr/lib/tmpfiles.d/cups-lp.conf to support /dev/lp* devices (#812641)
+- Move /etc/tmpfiles.d/cups.conf to /usr/lib/tmpfiles.d/ (#812641)
+
+* Tue Apr 17 2012 Jiri Popelka 1:1.5.2-11
+- The IPP backend did not always setup username/password authentication
+ for printers (bug #810007, STR #3985)
+- Detect authentication errors for all requests.
+ (bug #810007, upstream commit revision10277)
+
+* Thu Mar 29 2012 Tim Waugh 1:1.5.2-10
+- Removed private-shared-object-provides filter lines as they are not
+ necessary (see bug #807767 comment #3).
+
+* Thu Mar 29 2012 Mamoru Tasaka - 1:1.5.2-9
+- Rebuild against fixed rpm (bug #807767)
+
+* Wed Mar 28 2012 Tim Waugh 1:1.5.2-8
+- Avoid systemd PrivateTmp bug by explicitly requiring the fixed
+ version of systemd (bug #807672).
+
+* Fri Mar 16 2012 Tim Waugh 1:1.5.2-7
+- Removed debugging messages from systemd-socket patch.
+
+* Wed Mar 14 2012 Tim Waugh 1:1.5.2-6
+- Pulled in bugfixes from Avahi patches on fedorapeople.org.
+
+* Tue Feb 28 2012 Jiri Popelka 1:1.5.2-5
+- If the translated message is empty return the original message
+ (bug #797570, STR #4033).
+
+* Thu Feb 23 2012 Tim Waugh 1:1.5.2-4
+- cups-polld: restart polling on error (bug #769292, STR #4031).
+
+* Thu Feb 16 2012 Tim Waugh 1:1.5.2-3
+- Removed hard requirement on colord as it is optional.
+
+* Wed Feb 15 2012 Tim Waugh 1:1.5.2-2
+- Synthesize notify-printer-uri for job-completed events where the job
+ never started processing (bug #784786, STR #4014).
+- Removed banners from LSPP patch on Dan Walsh's advice.
+
+* Mon Feb 06 2012 Jiri Popelka 1:1.5.2-1
+- 1.5.2
+- Updated FSF address in pstopdf and textonly filters
+
+* Wed Jan 18 2012 Remi Collet 1:1.5.0-28
+- build against php 5.4.0, patch for STR #3999
+- add filter to fix private-shared-object-provides
+- add %%check for php extension
+
+* Tue Jan 17 2012 Tim Waugh 1:1.5.0-27
+- Use PrivateTmp=true in the service file (bug #782495).
+
+* Tue Jan 17 2012 Tim Waugh 1:1.5.0-26
+- Replace newline characters with spaces in reported Device IDs
+ (bug #782129, STR #4005).
+- Don't accept Device URIs of '\0' from SNMP devices
+ (bug #770646, STR #4004).
+
+* Fri Jan 13 2012 Fedora Release Engineering - 1:1.5.0-25
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Wed Dec 21 2011 Tim Waugh 1:1.5.0-24
+- Fixed textonly filter to work with single copies (bug #738412).
+
+* Fri Dec 9 2011 Tim Waugh 1:1.5.0-23
+- Detangle cups-serverbin-compat.patch from cups-lspp.patch.
+- Bind to datagram socket as well in systemd cups.socket unit file, to
+ prevent that port being stolen by another service (bug #760070).
+
+* Fri Nov 11 2011 Tim Waugh 1:1.5.0-22
+- Fixed trigger (bug #748841).
+
+* Wed Nov 9 2011 Tim Waugh 1:1.5.0-21
+- Set correct systemd service default on upgrade, once updates are
+ applied (bug #748841).
+
+* Fri Nov 4 2011 Tim Waugh 1:1.5.0-20
+- Set the correct PostScript command filter for e.g. foomatic queues
+ (STR #3973).
+
+* Mon Oct 31 2011 Tim Waugh 1:1.5.0-19
+- Set correct systemd service default on upgrade (bug #748841).
+
+* Wed Oct 19 2011 Tim Waugh 1:1.5.0-18
+- Make sure to guard against retrying the Avahi connection whilst
+ already doing so (Ubuntu #877967).
+
+* Tue Oct 18 2011 Tim Waugh 1:1.5.0-17
+- Use libsystemd-daemon instead of bundling sd-daemon.c.
+
+* Tue Oct 11 2011 Tim Waugh 1:1.5.0-16
+- Use upstream fix for driverd issue (bug #742989).
+- Array handling fixes for DNSSDPrinters.
+- Array handling fixes for Avahi poll implementation.
+- Increase client blocking timeout from 30s to 70s (bug #744715).
+- Set BindIPv6Only=ipv6-only in systemd socket unit file as better fix
+ for bug #737230.
+
+* Fri Oct 7 2011 Tim Waugh 1:1.5.0-15
+- Fixed Timeouts array comparison function (Ubuntu #860691).
+
+* Wed Oct 5 2011 Tim Waugh 1:1.5.0-14
+- Handle "localhost" resolving to 127.0.0.1 on IPv6-addressed systems
+ (bug #737230).
+
+* Tue Oct 4 2011 Tim Waugh 1:1.5.0-13
+- Work around PPDs cache handling issue (bug #742989).
+
+* Tue Oct 4 2011 Tim Waugh 1:1.5.0-12
+- More fixes for systemd socket activation:
+ - relax permissions check for domain socket in libcups.
+ - initialise addrlen before calling getsockname().
+
+* Mon Oct 03 2011 Richard Hughes 1:1.5.0-11
+- Updated colord patch with fixes to DeleteDevice.
+- Resolves https://bugzilla.redhat.com/show_bug.cgi?id=741697
+
+* Wed Sep 28 2011 Tim Waugh 1:1.5.0-10
+- Fixed string manipulation in the dbus notifier (STR #3947, bug #741833).
+
+* Thu Sep 22 2011 Tim Waugh 1:1.5.0-9
+- Fixed systemd socket activation support (bug #738709, bug #738710).
+
+* Wed Sep 14 2011 Tim Waugh 1:1.5.0-8
+- Prevent libcups crash in cups-get-classes patch (bug #736698).
+
+* Thu Sep 1 2011 Tim Waugh 1:1.5.0-7
+- Use PathExistsGlob instead of DirectoryNotEmpty in cups.path
+ (bug #734435).
+
+* Fri Aug 19 2011 Tim Waugh 1:1.5.0-6
+- Tighten explicit libs sub-package requirement so that it includes
+ the correct architecture as well (bug #731421 comment #8).
+
+* Fri Aug 19 2011 Tim Waugh 1:1.5.0-5
+- Avoid GIF reader loop (CVE-2011-2896, STR #3914, bug #727800).
+
+* Wed Aug 17 2011 Tim Waugh 1:1.5.0-4
+- Enable systemd units by default (bug #731421).
+
+* Mon Aug 8 2011 Tim Waugh 1:1.5.0-3
+- Updated avahi support to register sub-types.
+
+* Fri Aug 5 2011 Tim Waugh 1:1.5.0-2
+- Ported avahi support from 1.4.
+
+* Tue Jul 26 2011 Jiri Popelka 1:1.5.0-1
+- 1.5.0
+
+* Wed Jul 20 2011 Tim Waugh 1:1.5-0.16.rc1
+- Don't delete job data files when restarted (STR #3880).
+
+* Fri Jul 15 2011 Tim Waugh 1:1.5-0.15.rc1
+- Ship an rpm macro for where to put driver executables.
+
+* Thu Jul 7 2011 Tim Waugh 1:1.5-0.14.rc1
+- Undo last change which had no effect. We already remove the .SILENT
+ target from the Makefile as part of the build.
+
+* Thu Jul 7 2011 Tim Waugh 1:1.5-0.13.rc1
+- Make build log verbose enough to include compiler flags used.
+
+* Tue Jul 5 2011 Tim Waugh 1:1.5-0.12.rc1
+- Removed udev rules file as it is no longer necessary.
+
+* Tue Jul 5 2011 Tim Waugh 1:1.5-0.11.rc1
+- Add support for systemd socket activation (patch from Lennart
+ Poettering).
+
+* Wed Jun 29 2011 Tim Waugh 1:1.5-0.10.rc1
+- Don't use portreserve any more. Better approach is to use systemd
+ socket activation (not yet done).
+
+* Wed Jun 29 2011 Tim Waugh 1:1.5-0.9.rc1
+- Ship systemd service unit instead of SysV initscript (bug #690766).
+
+* Wed Jun 29 2011 Tim Waugh 1:1.5-0.8.rc1
+- Tag localization files correctly (bug #716421).
+
+* Wed Jun 15 2011 Jiri Popelka 1:1.5-0.7.rc1
+- 1.5rc1
+
+* Sat Jun 04 2011 Richard Hughes 1:1.5-0.6.b2
+- Updated colord patch with fixes from Tim Waugh.
+
+* Tue May 31 2011 Jiri Popelka 1:1.5-0.5.b2
+- enable LSPP support again
+
+* Tue May 31 2011 Richard Hughes 1:1.5-0.4.b2
+- Updated colord patch against 1.5 upstream and fixes from Tim Waugh.
+
+* Tue May 31 2011 Jiri Popelka 1:1.5-0.3.b2
+- fix lspp.patch to not include "config.h" in cups/cups.h (#709384)
+
+* Thu May 26 2011 Jiri Popelka 1:1.5-0.2.b2
+- 1.5b2
+
+* Tue May 24 2011 Jiri Popelka 1:1.5-0.1.b1
+- 1.5b1
+ - removed cups-texttops-rotate-page.patch (#572338 is CANTFIX)
+ - removed cups-page-label.patch (#520141 seems to be CANTFIX)
+
+* Wed May 18 2011 Tim Waugh 1:1.4.6-17
+- Package parallel port printer device nodes (bug #678804).
+
+* Tue May 17 2011 Richard Hughes 1:1.4.6-16
+- Updated colord patch from upstream review.
+
+* Fri Mar 25 2011 Jiri Popelka 1:1.4.6-15
+- Polished patches according to results from static analysis of code (bug #690130).
+
+* Thu Mar 10 2011 Tim Waugh 1:1.4.6-14
+- Fixed some typos in colord patch.
+- LSPP: only warn when unable to get printer context.
+
+* Mon Mar 07 2011 Richard Hughes 1:1.4.6-13
+- Updated colord patch.
+
+* Fri Feb 25 2011 Tim Waugh 1:1.4.6-12
+- Fixed build failure due to php_zend_api macro type.
+
+* Fri Feb 25 2011 Tim Waugh 1:1.4.6-11
+- Fixed dbus notifier support for job-state-changed.
+
+* Thu Feb 10 2011 Jiri Popelka 1:1.4.6-10
+- Remove testing cups-usb-buffer-size.patch (bug #661814).
+
+* Tue Feb 08 2011 Fedora Release Engineering - 1:1.4.6-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Tue Feb 01 2011 Jiri Popelka 1:1.4.6-8
+- Use Till's patch to fix USB-Parallel adapter cable problem (bug #624564).
+
+* Tue Jan 25 2011 Tim Waugh 1:1.4.6-7
+- Some fixes for the AvahiClient callback (bug #672143).
+
+* Tue Jan 18 2011 Tim Waugh 1:1.4.6-6
+- Don't use --enable-pie configure option as it has been removed and
+ is now assumed. See STR #3691.
+
+* Fri Jan 14 2011 Tim Waugh 1:1.4.6-5
+- ICC colord support.
+
+* Wed Jan 12 2011 Tim Waugh 1:1.4.6-4
+- Properly separated serverbin-compat and lspp patches.
+- Updated ICC patch (still not yet applied).
+
+* Tue Jan 11 2011 Tim Waugh 1:1.4.6-3
+- Build requires automake for avahi support.
+
+* Mon Jan 10 2011 Tim Waugh 1:1.4.6-2
+- Use a smaller buffer when writing to USB devices (bug #661814).
+- Handle EAI_NONAME when resolving hostnames (bug #617208).
+
+* Fri Jan 07 2011 Jiri Popelka 1:1.4.6-1
+- 1.4.6.
+
+* Fri Dec 31 2010 Tim Waugh 1:1.4.5-10
+- Some Avahi support fixes from Till Kamppeter.
+
+* Fri Dec 24 2010 Tim Waugh 1:1.4.5-9
+- Native Avahi support for announcing printers on the network.
+
+* Wed Dec 22 2010 Tim Waugh 1:1.4.5-8
+- Don't crash when job queued for browsed printer that times out
+ (bug #660604).
+
+* Mon Dec 13 2010 Jiri Popelka 1:1.4.5-7
+- Call avc_init() only once to not leak file descriptors (bug #654075).
+
+* Thu Dec 9 2010 Tim Waugh 1:1.4.5-6
+- The cups-config man page has been moved to the devel sub-package.
+- The php sub-package now explicitly requires the libs package with
+ the same version and release (bug #646814).
+
+* Tue Dec 7 2010 Tim Waugh 1:1.4.5-5
+- Fixed character encoding in CREDITS.txt.
+- Mark D-Bus configuration file as config file.
+- Don't mark MIME types and convs files as config files. Overrides
+ can be placed as new *.types/*.convs files in /etc/cups.
+- Don't mark banners as config files. Better is to provide new
+ banners.
+- Don't mark templates and www files as config files. A better way to
+ provide local overrides is to use a different ServerRoot setting.
+ Note that a recent security fix required changed to template files.
+- Provide versioned LPRng symbol for rpmlint.
+
+* Mon Dec 6 2010 Tim Waugh
+- /usr/sbin/cupsd should be mode 0755 (bug #546004).
+
+* Fri Dec 03 2010 Jiri Popelka 1:1.4.5-4
+- Changed subsystem lock file name in initscript
+ so the service is correctly stopped on reboot or halt (bug #659391).
+
+* Fri Nov 26 2010 Jiri Popelka 1:1.4.5-3
+- BuildRequires python-cups instead of pycups.
+
+* Fri Nov 26 2010 Jiri Popelka 1:1.4.5-2
+- Added /etc/tmpfiles.d/cups.conf to enable /var/run/cups directory on tmpfs (#656566).
+
+* Fri Nov 12 2010 Jiri Popelka 1:1.4.5-1
+- 1.4.5.
+- No longer need CVE-2010-2941, str3608
+
+* Thu Nov 11 2010 Tim Waugh 1:1.4.4-12
+- Applied patch to fix cupsd memory corruption vulnerability
+ (CVE-2010-2941, bug #652161).
+- Don't crash when MIME database could not be loaded (bug #610088).
+
+* Wed Sep 29 2010 jkeating - 1:1.4.4-11
+- Rebuilt for gcc bug 634757
+
+* Fri Sep 17 2010 Tim Waugh 1:1.4.4-10
+- Perform locking for gnutls and avoid libgcrypt's broken
+ locking (bug #607159).
+- Build with --enable-threads again (bug #607159).
+- Force the use of gnutls despite thread-safety concerns (bug #607159).
+
+* Wed Sep 15 2010 Tim Waugh
+- Fixed serverbin-compat patch to avoid misleading "filter not
+ available" messages (bug #633779).
+
+* Mon Aug 23 2010 Tim Waugh
+- Fixed SNMP quirks parsing.
+
+* Fri Aug 20 2010 Tim Waugh 1:1.4.4-9
+- Use better upstream fix for STR #3608 (bug #606909).
+
+* Fri Aug 13 2010 Tim Waugh 1:1.4.4-8
+- Specify udevadm trigger action in initscript (bug #623959).
+
+* Tue Aug 3 2010 Tim Waugh
+- Merged F-12 change:
+ - Use numeric addresses for interfaces unless HostNameLookups are
+ turned on (bug #583054).
+
+* Tue Jul 13 2010 Jiri Popelka 1:1.4.4-7
+- Added restartlog to initscript usage output (bug #612996).
+
+* Mon Jul 12 2010 Jiri Popelka 1:1.4.4-6
+- Moved LICENSE.txt to libs sub-package.
+
+* Mon Jun 28 2010 Tim Waugh 1:1.4.4-5
+- Avoid empty notify-subscribed-event attributes (bug #606909,
+ STR #3608).
+
+* Thu Jun 24 2010 Tim Waugh 1:1.4.4-4
+- Use gnutls again but disable threading (bug #607159).
+
+* Tue Jun 22 2010 Tim Waugh 1:1.4.4-3
+- Rebuilt to keep correct package n-v-r ordering between releases.
+
+* Fri Jun 18 2010 Tim Waugh 1:1.4.4-2
+- Re-enabled SSL support by using OpenSSL instead of gnutls.
+
+* Fri Jun 18 2010 Tim Waugh 1:1.4.4-1
+- 1.4.4. Fixes several security vulnerabilities (bug #605399):
+ CVE-2010-0540, CVE-2010-0542, CVE-2010-1748. No longer need str3503,
+ str3399, str3505, str3541, str3425p2 or CVE-2010-0302 patches.
+
+* Thu Jun 10 2010 Tim Waugh
+- Removed unapplied gnutls-gcrypt-threads patch. Fixed typos in
+ descriptions for lpd and php sub-packages.
+
+* Wed Jun 9 2010 Tim Waugh 1:1.4.3-11
+- Use upstream method of handling SNMP quirks in PPDs (STR #3551,
+ bug #581825).
+
+* Tue Jun 01 2010 Jiri Popelka 1:1.4.3-10
+- Added back still useful str3425.patch.
+ Second part of STR #3425 is still not fixed in 1.4.3
+
+* Tue May 18 2010 Tim Waugh 1:1.4.3-9
+- Adjust texttops output to be in natural orientation (STR #3563).
+ This fixes page-label orientation when texttops is used in the
+ filter chain (bug #572338).
+
+* Thu May 13 2010 Tim Waugh 1:1.4.3-8
+- Fixed Ricoh Device ID OID (STR #3552).
+
+* Tue May 11 2010 Tim Waugh 1:1.4.3-7
+- Add an SNMP query for Ricoh's device ID OID (STR #3552).
+
+* Fri Apr 16 2010 Tim Waugh 1:1.4.3-6
+- Mark DNS-SD Device IDs that have been guessed at with "FZY:1;".
+
+* Fri Apr 16 2010 Jiri Popelka 1:1.4.3-5
+- Fixed str3541.patch
+
+* Tue Apr 13 2010 Tim Waugh 1:1.4.3-4
+- Add an SNMP query for HP's device ID OID (STR #3552).
+
+* Tue Apr 13 2010 Tim Waugh 1:1.4.3-3
+- Handle SNMP supply level quirks (bug #581825).
+
+* Wed Mar 31 2010 Tim Waugh 1:1.4.3-2
+- Another BrowsePoll fix: handle EAI_NODATA as well (bug #567353).
+
+* Wed Mar 31 2010 Jiri Popelka 1:1.4.3-1
+- 1.4.3.
+- No longer need CVE-2009-3553, str3381, str3390, str3391,
+ str3403, str3407, str3413, str3418, str3422, str3425,
+ str3428, str3431, str3435, str3436, str3439, str3440,
+ str3442, str3448, str3458, str3460, cups-sidechannel-intrs,
+ negative-snmp-string-length, cups-media-empty-warning patches.
+
+* Tue Mar 30 2010 Jiri Popelka 1:1.4.2-36
+- Fixed lpstat to adhere to -o option (bug #577901, STR #3541).
+
+* Wed Mar 10 2010 Jiri Popelka 1:1.4.2-35
+- Fixed (for the third time) patch for STR #3425 to correctly
+ remove job info files in /var/spool/cups (bug #571830).
+
+* Fri Mar 5 2010 Tim Waugh - 1:1.4.2-34
+- Applied patch for CVE-2010-0302 (incomplete fix for CVE-2009-3553,
+ bug #557775).
+- Added comments for all sources and patches.
+
+* Tue Mar 2 2010 Tim Waugh - 1:1.4.2-33
+- Don't own filesystem locale directories (bug #569403).
+- Don't apply gcrypt threading patch (bug #553834).
+- Don't treat SIGPIPE as an error (bug #569770).
+
+* Wed Feb 24 2010 Jiri Popelka 1:1.4.2-32
+- Fixed cupsGetNamedDest() so it falls back to the real default
+ printer when a default from configuration file does not exist (bug #565569, STR #3503).
+
+* Tue Feb 23 2010 Tim Waugh - 1:1.4.2-31
+- Update classes.conf when a class member printer is deleted
+ (bug #565878, STR #3505).
+
+* Tue Feb 23 2010 Tim Waugh - 1:1.4.2-30
+- Re-initialize the resolver if getnameinfo() returns EAI_AGAIN
+ (bug #567353).
+
+* Mon Feb 15 2010 Jiri Popelka 1:1.4.2-29
+- Improve cups-gnutls-gcrypt-threads.patch (#564841, STR #3461).
+
+* Thu Feb 4 2010 Tim Waugh - 1:1.4.2-28
+- Rebuild for postscriptdriver tags.
+
+* Fri Jan 22 2010 Tim Waugh - 1:1.4.2-27
+- Make sure we have some filters for converting to raster format.
+
+* Fri Jan 15 2010 Tim Waugh - 1:1.4.2-26
+- Reset status after successful ipp job (bug #548219, STR #3460).
+
+* Thu Jan 14 2010 Tim Waugh - 1:1.4.2-24
+- Install udev rules in correct place (bug #530378).
+- Don't mark initscript as config file.
+
+* Wed Jan 13 2010 Tim Waugh - 1:1.4.2-23
+- Use %%{_initddir}, %%{_sysconfdir} and SMP make flags.
+- Use mode 0755 for binaries and libraries where appropriate.
+- Fix lpd obsoletes tag.
+
+* Thu Dec 24 2009 Tim Waugh - 1:1.4.2-22
+- Removed use of prereq and buildprereq.
+- Fixed use of '%%' in changelog.
+- Versioned explicit obsoletes/provides.
+- Use tabs throughout.
+
+* Wed Dec 23 2009 Tim Waugh - 1:1.4.2-21
+- Fixed patch for STR #3425 again by adding in back-ported change from
+ svn revision 8929 (bug #549899). No longer need
+ delete-active-printer patch.
+
+* Tue Dec 22 2009 Tim Waugh - 1:1.4.2-20
+- Fixed ipp authentication for servers requiring authentication for
+ IPP-Get-Printer-Attributes (bug #548873, STR #3458).
+
+* Mon Dec 21 2009 Tim Waugh - 1:1.4.2-19
+- Ensure proper thread-safety in gnutls's use of libgcrypt
+ (bug #544619).
+
+* Sat Dec 19 2009 Tim Waugh - 1:1.4.2-18
+- Fixed patch for STR #3425 by adding in back-ported change from svn
+ revision 8936 (bug #548904).
+
+* Thu Dec 10 2009 Tim Waugh - 1:1.4.2-17
+- Fixed invalid read in cupsAddDest (bug #537460).
+
+* Wed Dec 9 2009 Tim Waugh - 1:1.4.2-15
+- Use upstream patch to fix scheduler crash when an active printer was
+ deleted (rev 8914).
+
+* Tue Dec 8 2009 Tim Waugh - 1:1.4.2-14
+- The scheduler did not use the Get-Job-Attributes policy for a
+ printer (STR #3431).
+- The scheduler added two job-name attributes to each job object
+ (STR #3428).
+- The scheduler did not clean out completed jobs when
+ PreserveJobHistory was turned off (STR #3425).
+- The web interface did not show completed jobs (STR #3436).
+- Authenticated printing did not always work when printing directly to
+ a remote server (STR #3435).
+- Use upstream patch to stop the network backends incorrectly clearing
+ the media-empty-warning state (rev 8896).
+- Use upstream patch to fix interrupt handling in the side-channel
+ APIs (rev 8896).
+- Use upstream patch to handle negative SNMP string lengths (rev 8896).
+- Use upstream fix for SNMP detection (bug #542857, STR #3413).
+- Use the text filter for text/css files (bug #545026, STR #3442).
+- Show conflicting option values in web UI (bug #544326, STR #3440).
+- Use upstream fix for adjustment of conflicting options
+ (bug #533426, STR #3439).
+- No longer requires paps. The texttopaps filter MIME conversion file
+ is now provided by the paps package (bug #545036).
+- Moved %%{_datadir}/cups/ppdc/*.h to the main package (bug #545348).
+
+* Fri Dec 4 2009 Tim Waugh - 1:1.4.2-13
+- The web interface prevented conflicting options from being adjusted
+ (bug #533426, STR #3439).
+
+* Thu Dec 3 2009 Tim Waugh - 1:1.4.2-12
+- Fixes for SNMP scanning with Lexmark printers (bug #542857, STR #3413).
+
+* Mon Nov 23 2009 Tim Waugh 1:1.4.2-10
+- Undo last change as it was incorrect.
+
+* Mon Nov 23 2009 Tim Waugh 1:1.4.2-9
+- Fixed small typos introduced in fix for bug #536741.
+
+* Fri Nov 20 2009 Jiri Popelka 1:1.4.2-8
+- Do not translate russian links showing completed jobs
+ (bug #539354, STR #3422).
+
+* Thu Nov 19 2009 Tim Waugh 1:1.4.2-7
+- Applied patch to fix CVE-2009-3553 (bug #530111, STR #3200).
+
+* Tue Nov 17 2009 Tim Waugh 1:1.4.2-6
+- Fixed display of current driver (bug #537182, STR #3418).
+- Fixed out-of-memory handling when loading jobs (bug #538054,
+ STR #3407).
+
+* Mon Nov 16 2009 Tim Waugh 1:1.4.2-5
+- Fixed typo in admin web template (bug #537884, STR #3403).
+- Reset SIGPIPE handler for child processes (bug #537886, STR #3399).
+
+* Mon Nov 16 2009 Tim Waugh 1:1.4.2-4
+- Upstream fix for GNU TLS error handling bug (bug #537883, STR #3381).
+
+* Wed Nov 11 2009 Jiri Popelka 1:1.4.2-3
+- Fixed lspp-patch to avoid memory leak (bug #536741).
+
+* Tue Nov 10 2009 Tim Waugh 1:1.4.2-2
+- Added explicit version dependency on cups-libs to cups-lpd
+ (bug #502205).
+
+* Tue Nov 10 2009 Tim Waugh 1:1.4.2-1
+- 1.4.2. No longer need str3380, str3332, str3356, str3396 patches.
+- Removed postscript.ppd.gz (bug #533371).
+- Renumbered patches and sources.
+
+* Tue Nov 3 2009 Tim Waugh 1:1.4.1-14
+- Removed stale patch from STR #2831 which was causing problems with
+ number-up (bug #532516).
+
+* Tue Oct 27 2009 Jiri Popelka 1:1.4.1-13
+- Fix incorrectly applied patch from #STR3285 (bug #531108).
+- Set the PRINTER_IS_SHARED variable for admin.cgi (bug #529634, #STR3390).
+- Pass through serial parameters correctly in web interface (bug #529635, #STR3391).
+- Fixed German translation (bug #531144, #STR3396).
+
+* Tue Oct 20 2009 Jiri Popelka 1:1.4.1-12
+- Fix cups-lpd to create unique temporary data files (bug #529838).
+
+* Mon Oct 19 2009 Tim Waugh 1:1.4.1-11
+- Fixed German translation (bug #529575, STR #3380).
+
+* Thu Oct 15 2009 Tim Waugh 1:1.4.1-10
+- Don't ship pstoraster -- it is now provided by the ghostscript-cups
+ package.
+
+* Thu Oct 8 2009 Tim Waugh 1:1.4.1-9
+- Fixed naming of 'Generic PostScript Printer' entry.
+
+* Wed Oct 7 2009 Tim Waugh 1:1.4.1-8
+- Use upstream patch for STR #3356 (bug #526405).
+
+* Fri Oct 2 2009 Tim Waugh 1:1.4.1-7
+- Fixed orientation of page labels when printing text in landscape
+ mode (bug #520141, STR #3334).
+
+* Wed Sep 30 2009 Tim Waugh 1:1.4.1-6
+- Don't use cached PPD for raw queue (bug #526405, STR #3356).
+
+* Wed Sep 23 2009 Jiri Popelka 1:1.4.1-5
+- Fixed cups.init to be LSB compliant (bug #521641)
+
+* Mon Sep 21 2009 Jiri Popelka 1:1.4.1-4
+- Changed cups.init to be LSB compliant (bug #521641), i.e.
+ return code "2" (instead of "3") if invalid arguments
+ return code "4" if restarting service under nonprivileged user
+ return code "5" if cupsd not exist or is not executable
+ return code "6" if cupsd.conf not exist
+
+* Wed Sep 16 2009 Tomas Mraz