summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cups-0755.patch32
-rw-r--r--cups-CVE-2011-2896.patch33
-rw-r--r--cups-avahi-1-config.patch42
-rw-r--r--cups-avahi-2-backend.patch1117
-rw-r--r--cups-avahi-3-timeouts.patch381
-rw-r--r--cups-avahi-4-poll.patch529
-rw-r--r--cups-avahi-5-services.patch1191
-rw-r--r--cups-banners.patch12
-rw-r--r--cups-build.patch42
-rw-r--r--cups-cups-get-classes.patch89
-rw-r--r--cups-direct-usb.patch27
-rw-r--r--cups-dnssd-deviceid.patch38
-rw-r--r--cups-driverd-timeout.patch33
-rw-r--r--cups-eggcups.patch130
-rw-r--r--cups-filter-debug.patch32
-rw-r--r--cups-getpass.patch50
-rw-r--r--cups-hp-deviceid-oid.patch21
-rw-r--r--cups-icc.patch1042
-rw-r--r--cups-logrotate.patch63
-rw-r--r--cups-lpd11
-rw-r--r--cups-lpr-help.patch48
-rw-r--r--cups-lspp.patch2811
-rw-r--r--cups-multilib.patch16
-rw-r--r--cups-no-export-ssllibs.patch12
-rw-r--r--cups-no-gzip-man.patch18
-rw-r--r--cups-peercred.patch11
-rw-r--r--cups-pid.patch37
-rw-r--r--cups-ps-command-filter.patch13
-rw-r--r--cups-res_init.patch26
-rw-r--r--cups-ricoh-deviceid-oid.patch21
-rw-r--r--cups-serial.patch11
-rw-r--r--cups-serverbin-compat.patch190
-rw-r--r--cups-snmp-quirks.patch115
-rw-r--r--cups-str3382.patch64
-rw-r--r--cups-str3921.patch14
-rw-r--r--cups-str3947.patch26
-rw-r--r--cups-strict-ppd-line-length.patch30
-rw-r--r--cups-system-auth.patch38
-rw-r--r--cups-systemd-socket.patch396
-rw-r--r--cups-uri-compat.patch51
-rw-r--r--cups-usb-paperout.patch52
-rwxr-xr-xcups.cron8
-rw-r--r--cups.logrotate5
-rw-r--r--cups.spec2920
-rw-r--r--cupsprinter.pngbin0 -> 2129 bytes
-rw-r--r--macros.cups1
-rwxr-xr-xncp.backend51
-rw-r--r--pstopdf55
-rwxr-xr-xtextonly.filter124
-rw-r--r--textonly.ppd47
50 files changed, 12126 insertions, 0 deletions
diff --git a/cups-0755.patch b/cups-0755.patch
new file mode 100644
index 0000000..8e66476
--- /dev/null
+++ b/cups-0755.patch
@@ -0,0 +1,32 @@
+diff -up cups-1.5b1/Makedefs.in.0755 cups-1.5b1/Makedefs.in
+--- cups-1.5b1/Makedefs.in.0755 2011-05-24 16:43:27.000000000 +0200
++++ cups-1.5b1/Makedefs.in 2011-05-24 16:43:27.000000000 +0200
+@@ -41,13 +41,13 @@ SHELL = /bin/sh
+ # Installation programs...
+ #
+
+-INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@
++INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 755 @INSTALL_STRIP@
+ 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 -up cups-1.5b1/scheduler/Makefile.0755 cups-1.5b1/scheduler/Makefile
+--- cups-1.5b1/scheduler/Makefile.0755 2011-05-12 00:17:34.000000000 +0200
++++ cups-1.5b1/scheduler/Makefile 2011-05-24 16:43:27.000000000 +0200
+@@ -213,7 +213,7 @@ install-data:
+ install-exec:
+ echo Installing programs in $(SBINDIR)...
+ $(INSTALL_DIR) -m 755 $(SBINDIR)
+- $(INSTALL_BIN) -m 500 cupsd $(SBINDIR)
++ $(INSTALL_BIN) -m 755 cupsd $(SBINDIR)
+ $(INSTALL_BIN) cupsfilter $(SBINDIR)
+ -if test "x`uname`" = xDarwin; then \
+ $(INSTALL_DIR) $(BUILDROOT)/System/Library/Printers/Libraries; \
diff --git a/cups-CVE-2011-2896.patch b/cups-CVE-2011-2896.patch
new file mode 100644
index 0000000..a949b9d
--- /dev/null
+++ b/cups-CVE-2011-2896.patch
@@ -0,0 +1,33 @@
+diff -up cups-1.4.8/filter/image-gif.c.CVE-2011-2896 cups-1.4.8/filter/image-gif.c
+--- cups-1.4.8/filter/image-gif.c.CVE-2011-2896 2011-06-20 21:37:51.000000000 +0100
++++ cups-1.4.8/filter/image-gif.c 2011-08-19 11:33:37.547911212 +0100
+@@ -648,11 +648,13 @@ gif_read_lzw(FILE *fp, /* I - File to
+
+ if (code == max_code)
+ {
+- *sp++ = firstcode;
+- code = oldcode;
++ if (sp < (stack + 8192))
++ *sp++ = firstcode;
++
++ code = oldcode;
+ }
+
+- while (code >= clear_code)
++ while (code >= clear_code && sp < (stack + 8192))
+ {
+ *sp++ = table[1][code];
+ if (code == table[0][code])
+@@ -661,8 +663,10 @@ gif_read_lzw(FILE *fp, /* I - File to
+ code = table[0][code];
+ }
+
+- *sp++ = firstcode = table[1][code];
+- code = max_code;
++ if (sp < (stack + 8192))
++ *sp++ = firstcode = table[1][code];
++
++ code = max_code;
+
+ if (code < 4096)
+ {
diff --git a/cups-avahi-1-config.patch b/cups-avahi-1-config.patch
new file mode 100644
index 0000000..663eb39
--- /dev/null
+++ b/cups-avahi-1-config.patch
@@ -0,0 +1,42 @@
+diff -up cups-1.5.0/config.h.in.avahi-1-config cups-1.5.0/config.h.in
+--- cups-1.5.0/config.h.in.avahi-1-config 2011-06-16 21:12:16.000000000 +0100
++++ cups-1.5.0/config.h.in 2011-08-05 15:04:09.535759988 +0100
+@@ -390,6 +390,13 @@
+
+
+ /*
++ * Do we have Avahi for DNS Service Discovery?
++ */
++
++#undef HAVE_AVAHI
++
++
++/*
+ * Do we have <sys/ioctl.h>?
+ */
+
+diff -up cups-1.5.0/config-scripts/cups-dnssd.m4.avahi-1-config cups-1.5.0/config-scripts/cups-dnssd.m4
+--- cups-1.5.0/config-scripts/cups-dnssd.m4.avahi-1-config 2011-05-12 06:21:56.000000000 +0100
++++ cups-1.5.0/config-scripts/cups-dnssd.m4 2011-08-05 15:04:09.525760307 +0100
+@@ -23,6 +23,21 @@ AC_ARG_WITH(dnssd-includes, [ --with-dn
+ DNSSDLIBS=""
+ DNSSD_BACKEND=""
+
++AC_ARG_ENABLE(avahi, [ --enable-avahi turn on DNS Service Discovery support, default=no],
++ [if test x$enable_avahi = xyes; then
++ AC_MSG_CHECKING(for Avahi)
++ if $PKGCONFIG --exists avahi-client; then
++ AC_MSG_RESULT(yes)
++ CFLAGS="$CFLAGS `$PKGCONFIG --cflags avahi-client`"
++ DNSSDLIBS="`$PKGCONFIG --libs avahi-client`"
++ DNSSD_BACKEND="dnssd"
++ AC_DEFINE(HAVE_AVAHI)
++ enable_dnssd=no
++ else
++ AC_MSG_RESULT(no)
++ fi
++ fi])
++
+ if test x$enable_dnssd != xno; then
+ AC_CHECK_HEADER(dns_sd.h, [
+ case "$uname" in
diff --git a/cups-avahi-2-backend.patch b/cups-avahi-2-backend.patch
new file mode 100644
index 0000000..c576043
--- /dev/null
+++ b/cups-avahi-2-backend.patch
@@ -0,0 +1,1117 @@
+diff -up cups-1.5.0/backend/dnssd.c.avahi-2-backend cups-1.5.0/backend/dnssd.c
+--- cups-1.5.0/backend/dnssd.c.avahi-2-backend 2011-08-05 15:04:46.182591844 +0100
++++ cups-1.5.0/backend/dnssd.c 2011-08-05 15:05:13.868710181 +0100
+@@ -15,14 +15,21 @@
+ *
+ * Contents:
+ *
++ * next_txt_record() - Get next TXT record from a cups_txt_records_t.
++ * parse_txt_record_pair() - Read key/value pair in cups_txt_records_t.
+ * main() - Browse for printers.
+ * browse_callback() - Browse devices.
+ * browse_local_callback() - Browse local devices.
+ * compare_devices() - Compare two devices.
+ * exec_backend() - Execute the backend that corresponds to the
+ * resolved service name.
++ * device_type() - Get DNS-SD type enumeration from string.
+ * get_device() - Create or update a device.
+ * query_callback() - Process query data.
++ * avahi_client_callback() - Avahi client callback function.
++ * avahi_query_callback() - Avahi query callback function.
++ * avahi_browse_callback() - Avahi browse callback function.
++ * find_device() - Find a device from its name and domain.
+ * sigterm_handler() - Handle termination signals...
+ * unquote() - Unquote a name string.
+ */
+@@ -33,7 +40,18 @@
+
+ #include "backend-private.h"
+ #include <cups/array.h>
+-#include <dns_sd.h>
++#ifdef HAVE_DNSSD
++# include <dns_sd.h>
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++# include <avahi-client/client.h>
++# include <avahi-client/lookup.h>
++# include <avahi-common/simple-watch.h>
++# include <avahi-common/domain.h>
++# include <avahi-common/error.h>
++# include <avahi-common/malloc.h>
++#define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX
++#endif /* HAVE_AVAHI */
+
+
+ /*
+@@ -53,7 +71,12 @@ typedef enum
+
+ typedef struct
+ {
++#ifdef HAVE_DNSSD
+ DNSServiceRef ref; /* Service reference for resolve */
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ int resolved; /* Did we resolve the device? */
++#endif /* HAVE_AVAHI */
+ char *name, /* Service name */
+ *domain, /* Domain name */
+ *fullName, /* Full name */
+@@ -65,6 +88,20 @@ typedef struct
+ sent; /* Did we list the device? */
+ } cups_device_t;
+
++typedef struct
++{
++ char key[256];
++ char value[256];
++
++#ifdef HAVE_DNSSD
++ const uint8_t *data;
++ const uint8_t *datanext;
++ const uint8_t *dataend;
++#else /* HAVE_AVAHI */
++ AvahiStringList *txt;
++#endif /* HAVE_DNSSD */
++} cups_txt_records_t;
++
+
+ /*
+ * Local globals...
+@@ -78,6 +115,7 @@ static int job_canceled = 0;
+ * Local functions...
+ */
+
++#ifdef HAVE_DNSSD
+ static void browse_callback(DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+@@ -93,12 +131,6 @@ static void browse_local_callback(DNSSe
+ const char *regtype,
+ const char *replyDomain,
+ void *context);
+-static int compare_devices(cups_device_t *a, cups_device_t *b);
+-static void exec_backend(char **argv);
+-static cups_device_t *get_device(cups_array_t *devices,
+- const char *serviceName,
+- const char *regtype,
+- const char *replyDomain);
+ static void query_callback(DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+@@ -107,9 +139,118 @@ static void query_callback(DNSServiceRe
+ uint16_t rrclass, uint16_t rdlen,
+ const void *rdata, uint32_t ttl,
+ void *context);
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++static void avahi_client_callback (AvahiClient *client,
++ AvahiClientState state,
++ void *context);
++static void avahi_browse_callback (AvahiServiceBrowser *browser,
++ AvahiIfIndex interface,
++ AvahiProtocol protocol,
++ AvahiBrowserEvent event,
++ const char *serviceName,
++ const char *regtype,
++ const char *replyDomain,
++ AvahiLookupResultFlags flags,
++ void *context);
++#endif /* HAVE_AVAHI */
++
++static cups_device_t * find_device (cups_array_t *devices,
++ cups_txt_records_t *txt,
++ cups_device_t *dkey);
++static int compare_devices(cups_device_t *a, cups_device_t *b);
++static void exec_backend(char **argv);
++static cups_device_t *get_device(cups_array_t *devices,
++ const char *serviceName,
++ const char *regtype,
++ const char *replyDomain);
+ static void sigterm_handler(int sig);
+ static void unquote(char *dst, const char *src, size_t dstsize);
+
++#ifdef HAVE_AVAHI
++static AvahiSimplePoll *simple_poll = NULL;
++static int avahi_got_callback;
++#endif /* HAVE_AVAHI */
++
++
++/*
++ * 'next_txt_record()' - Get next TXT record from a cups_txt_records_t.
++ */
++
++static cups_txt_records_t *
++next_txt_record (cups_txt_records_t *txt)
++{
++#ifdef HAVE_DNSSD
++ txt->data = txt->datanext;
++#else /* HAVE_AVAHI */
++ txt->txt = avahi_string_list_get_next (txt->txt);
++ if (txt->txt == NULL)
++ return NULL;
++#endif /* HAVE_DNSSD */
++
++ return txt;
++}
++
++
++/*
++ * 'parse_txt_record_pair()' - Read key/value pair in cups_txt_records_t.
++ */
++
++static int
++parse_txt_record_pair (cups_txt_records_t *txt)
++{
++#ifdef HAVE_DNSSD
++ uint8_t datalen;
++ uint8_t *data = txt->data;
++ char *ptr;
++
++ /*
++ * Read a key/value pair starting with an 8-bit length. Since the
++ * length is 8 bits and the size of the key/value buffers is 256, we
++ * don't need to check for overflow...
++ */
++
++ datalen = *data++;
++ if (!datalen || (data + datalen) >= txt->dataend)
++ return NULL;
++ txt->datanext = data + datalen;
++
++ for (ptr = txt->key; data < txt->datanext && *data != '='; data ++)
++ *ptr++ = *data;
++ *ptr = '\0';
++
++ if (data < txt->datanext && *data == '=')
++ {
++ data++;
++
++ if (data < datanext)
++ memcpy (txt->value, data, txt->datanext - data);
++ value[txt->datanext - data] = '\0';
++ }
++ else
++ return 1;
++#else /* HAVE_AVAHI */
++ char *key, *value;
++ size_t len;
++ avahi_string_list_get_pair (txt->txt, &key, &value, &len);
++ if (len > sizeof (txt->value) - 1)
++ len = sizeof (txt->value) - 1;
++
++ memcpy (txt->value, value, len);
++ txt->value[len] = '\0';
++ len = strlen (key);
++ if (len > sizeof (txt->key) - 1)
++ len = sizeof (txt->key) - 1;
++
++ memcpy (txt->key, key, len);
++ txt->key[len] = '\0';
++ avahi_free (key);
++ avahi_free (value);
++#endif /* HAVE_AVAHI */
++
++ return 0;
++}
++
+
+ /*
+ * 'main()' - Browse for printers.
+@@ -120,6 +261,13 @@ main(int argc, /* I - Number of comm
+ char *argv[]) /* I - Command-line arguments */
+ {
+ const char *name; /* Backend name */
++ cups_array_t *devices; /* Device array */
++ cups_device_t *device; /* Current device */
++ char uriName[1024]; /* Unquoted fullName for URI */
++#ifdef HAVE_DNSSD
++ int fd; /* Main file descriptor */
++ fd_set input; /* Input set for select() */
++ struct timeval timeout; /* Timeout for select() */
+ DNSServiceRef main_ref, /* Main service reference */
+ fax_ipp_ref, /* IPP fax service reference */
+ ipp_ref, /* IPP service reference */
+@@ -133,12 +281,11 @@ main(int argc, /* I - Number of comm
+ pdl_datastream_ref, /* AppSocket service reference */
+ printer_ref, /* LPD service reference */
+ riousbprint_ref; /* Remote IO service reference */
+- int fd; /* Main file descriptor */
+- fd_set input; /* Input set for select() */
+- struct timeval timeout; /* Timeout for select() */
+- cups_array_t *devices; /* Device array */
+- cups_device_t *device; /* Current device */
+- char uriName[1024]; /* Unquoted fullName for URI */
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ AvahiClient *client;
++ int error;
++#endif /* HAVE_AVAHI */
+ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+@@ -198,6 +345,49 @@ main(int argc, /* I - Number of comm
+ * Browse for different kinds of printers...
+ */
+
++#ifdef HAVE_AVAHI
++ if ((simple_poll = avahi_simple_poll_new ()) == NULL)
++ {
++ perror ("ERROR: Unable to create avahi simple poll object");
++ return (1);
++ }
++
++ client = avahi_client_new (avahi_simple_poll_get (simple_poll),
++ 0, avahi_client_callback, NULL, &error);
++ if (!client)
++ {
++ perror ("DEBUG: Unable to create avahi client");
++ return (0);
++ }
++
++ avahi_service_browser_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ "_fax-ipp._tcp", NULL, 0,
++ avahi_browse_callback, devices);
++ avahi_service_browser_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ "_ipp._tcp", NULL, 0,
++ avahi_browse_callback, devices);
++ avahi_service_browser_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ "_ipp-tls._tcp", NULL, 0,
++ avahi_browse_callback, devices);
++ avahi_service_browser_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ "_pdl-datastream._tcp",
++ NULL, 0,
++ avahi_browse_callback,
++ devices);
++ avahi_service_browser_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ "_printer._tcp", NULL, 0,
++ avahi_browse_callback, devices);
++ avahi_service_browser_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ "_riousbprint._tcp", NULL, 0,
++ avahi_browse_callback, devices);
++#endif /* HAVE_AVAHI */
++#ifdef HAVE_DNSSD
+ if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError)
+ {
+ perror("ERROR: Unable to create service connection");
+@@ -258,6 +448,7 @@ main(int argc, /* I - Number of comm
+ riousbprint_ref = main_ref;
+ DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0,
+ "_riousbprint._tcp", NULL, browse_callback, devices);
++#endif /* HAVE_DNSSD */
+
+ /*
+ * Loop until we are killed...
+@@ -265,6 +456,9 @@ main(int argc, /* I - Number of comm
+
+ while (!job_canceled)
+ {
++ int announce = 0;
++
++#ifdef HAVE_DNSSD
+ FD_ZERO(&input);
+ FD_SET(fd, &input);
+
+@@ -284,11 +478,35 @@ main(int argc, /* I - Number of comm
+ }
+ else
+ {
++ announce = 1;
++ }
++#else /* HAVE_AVAHI */
++ int r;
++ avahi_got_callback = 0;
++ r = avahi_simple_poll_iterate (simple_poll, 1);
++ if (r != 0 && r != EINTR)
++ {
++ /*
++ * We've been told to exit the loop. Perhaps the connection to
++ * avahi failed.
++ */
++
++ break;
++ }
++
++ if (avahi_got_callback)
++ announce = 1;
++#endif /* HAVE_DNSSD */
++
++ if (announce)
++ {
+ /*
+ * Announce any devices we've found...
+ */
+
++#ifdef HAVE_DNSSD
+ DNSServiceErrorType status; /* DNS query status */
++#endif /* HAVE_DNSSD */
+ cups_device_t *best; /* Best matching device */
+ char device_uri[1024]; /* Device URI */
+ int count; /* Number of queries */
+@@ -302,6 +520,7 @@ main(int argc, /* I - Number of comm
+ if (device->sent)
+ sent ++;
+
++#ifdef HAVE_DNSSD
+ if (device->ref)
+ count ++;
+
+@@ -333,14 +552,23 @@ main(int argc, /* I - Number of comm
+ count ++;
+ }
+ }
+- else if (!device->sent)
++ else
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ if (!device->resolved)
++ continue;
++ else
++#endif /* HAVE_AVAHI */
++ if (!device->sent)
+ {
++#ifdef HAVE_DNSSD
+ /*
+ * Got the TXT records, now report the device...
+ */
+
+ DNSServiceRefDeallocate(device->ref);
+ device->ref = 0;
++#endif /* HAVE_DNSSD */
+
+ if (!best)
+ best = device;
+@@ -401,6 +629,7 @@ main(int argc, /* I - Number of comm
+ }
+
+
++#ifdef HAVE_DNSSD
+ /*
+ * 'browse_callback()' - Browse devices.
+ */
+@@ -489,6 +718,7 @@ browse_local_callback(
+ device->fullName);
+ device->sent = 1;
+ }
++#endif /* HAVE_DNSSD */
+
+
+ /*
+@@ -569,6 +799,41 @@ exec_backend(char **argv) /* I - Comman
+
+
+ /*
++ * 'device_type()' - Get DNS-SD type enumeration from string.
++ */
++
++static int
++device_type (const char *regtype)
++{
++#ifdef HAVE_AVAHI
++ if (!strcmp(regtype, "_ipp._tcp"))
++ return (CUPS_DEVICE_IPP);
++ else if (!strcmp(regtype, "_ipps._tcp") ||
++ !strcmp(regtype, "_ipp-tls._tcp"))
++ return (CUPS_DEVICE_IPPS);
++ else if (!strcmp(regtype, "_fax-ipp._tcp"))
++ return (CUPS_DEVICE_FAX_IPP);
++ else if (!strcmp(regtype, "_printer._tcp"))
++ return (CUPS_DEVICE_PDL_DATASTREAM);
++#else
++ if (!strcmp(regtype, "_ipp._tcp."))
++ return (CUPS_DEVICE_IPP);
++ else if (!strcmp(regtype, "_ipps._tcp.") ||
++ !strcmp(regtype, "_ipp-tls._tcp."))
++ return (CUPS_DEVICE_IPPS);
++ else if (!strcmp(regtype, "_fax-ipp._tcp."))
++ return (CUPS_DEVICE_FAX_IPP);
++ else if (!strcmp(regtype, "_printer._tcp."))
++ return (CUPS_DEVICE_PRINTER);
++ else if (!strcmp(regtype, "_pdl-datastream._tcp."))
++ return (CUPS_DEVICE_PDL_DATASTREAM);
++#endif /* HAVE_AVAHI */
++
++ return (CUPS_DEVICE_RIOUSBPRINT);
++}
++
++
++/*
+ * 'get_device()' - Create or update a device.
+ */
+
+@@ -589,20 +854,7 @@ get_device(cups_array_t *devices, /* I -
+ */
+
+ key.name = (char *)serviceName;
+-
+- if (!strcmp(regtype, "_ipp._tcp."))
+- key.type = CUPS_DEVICE_IPP;
+- else if (!strcmp(regtype, "_ipps._tcp.") ||
+- !strcmp(regtype, "_ipp-tls._tcp."))
+- key.type = CUPS_DEVICE_IPPS;
+- else if (!strcmp(regtype, "_fax-ipp._tcp."))
+- key.type = CUPS_DEVICE_FAX_IPP;
+- else if (!strcmp(regtype, "_printer._tcp."))
+- key.type = CUPS_DEVICE_PRINTER;
+- else if (!strcmp(regtype, "_pdl-datastream._tcp."))
+- key.type = CUPS_DEVICE_PDL_DATASTREAM;
+- else
+- key.type = CUPS_DEVICE_RIOUSBPRINT;
++ key.type = device_type (regtype);
+
+ for (device = cupsArrayFind(devices, &key);
+ device;
+@@ -622,8 +874,14 @@ get_device(cups_array_t *devices, /* I -
+ free(device->domain);
+ device->domain = strdup(replyDomain);
+
++#ifdef HAVE_DNSSD
+ DNSServiceConstructFullName(fullName, device->name, regtype,
+ replyDomain);
++#else /* HAVE_AVAHI */
++ avahi_service_name_join (fullName, kDNSServiceMaxDomainName,
++ serviceName, regtype, replyDomain);
++#endif /* HAVE_DNSSD */
++
+ free(device->fullName);
+ device->fullName = strdup(fullName);
+ }
+@@ -643,6 +901,9 @@ get_device(cups_array_t *devices, /* I -
+ device->domain = strdup(replyDomain);
+ device->type = key.type;
+ device->priority = 50;
++#ifdef HAVE_AVAHI
++ device->resolved = 0;
++#endif /* HAVE_AVAHI */
+
+ cupsArrayAdd(devices, device);
+
+@@ -650,13 +911,20 @@ get_device(cups_array_t *devices, /* I -
+ * Set the "full name" of this service, which is used for queries...
+ */
+
++#ifdef HAVE_DNSSD
+ DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain);
++#else /* HAVE_AVAHI */
++ avahi_service_name_join (fullName, kDNSServiceMaxDomainName,
++ serviceName, regtype, replyDomain);
++#endif /* HAVE_DNSSD */
++
+ device->fullName = strdup(fullName);
+
+ return (device);
+ }
+
+
++#ifdef HAVE_DNSSD
+ /*
+ * 'query_callback()' - Process query data.
+ */
+@@ -680,7 +948,7 @@ query_callback(
+ *ptr; /* Pointer into string */
+ cups_device_t dkey, /* Search key */
+ *device; /* Device */
+-
++ cups_txt_records_t txt;
+
+ fprintf(stderr, "DEBUG2: query_callback(sdRef=%p, flags=%x, "
+ "interfaceIndex=%d, errorCode=%d, fullName=\"%s\", "
+@@ -714,94 +982,233 @@ query_callback(
+ if ((ptr = strstr(name, "._")) != NULL)
+ *ptr = '\0';
+
+- if (strstr(fullName, "_ipp._tcp."))
+- dkey.type = CUPS_DEVICE_IPP;
+- else if (strstr(fullName, "_ipps._tcp.") ||
+- strstr(fullName, "_ipp-tls._tcp."))
+- dkey.type = CUPS_DEVICE_IPPS;
+- else if (strstr(fullName, "_fax-ipp._tcp."))
+- dkey.type = CUPS_DEVICE_FAX_IPP;
+- else if (strstr(fullName, "_printer._tcp."))
+- dkey.type = CUPS_DEVICE_PRINTER;
+- else if (strstr(fullName, "_pdl-datastream._tcp."))
+- dkey.type = CUPS_DEVICE_PDL_DATASTREAM;
++ dkey.type = device_type (fullName);
++
++ txt.data = rdata;
++ txt.dataend = rdata + rdlen;
++ device = find_device ((cups_array_t *) context, &txt, &dkey);
++ if (!device)
++ fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName);
++}
++#endif /* HAVE_DNSSD */
++
++
++#ifdef HAVE_AVAHI
++/*
++ * 'avahi_client_callback()' - Avahi client callback function.
++ */
++
++static void
++avahi_client_callback(AvahiClient *client,
++ AvahiClientState state,
++ void *context)
++{
++ /*
++ * If the connection drops, quit.
++ */
++
++ if (state == AVAHI_CLIENT_FAILURE)
++ {
++ fprintf (stderr, "ERROR: Avahi connection failed\n");
++ avahi_simple_poll_quit (simple_poll);
++ }
++}
++
++
++/*
++ * 'avahi_query_callback()' - Avahi query callback function.
++ */
++
++static void
++avahi_query_callback(AvahiServiceResolver *resolver,
++ AvahiIfIndex interface,
++ AvahiProtocol protocol,
++ AvahiResolverEvent event,
++ const char *name,
++ const char *type,
++ const char *domain,
++ const char *host_name,
++ const AvahiAddress *address,
++ uint16_t port,
++ AvahiStringList *txt,
++ AvahiLookupResultFlags flags,
++ void *context)
++{
++ AvahiClient *client;
++ cups_device_t key,
++ *device;
++ char uqname[1024],
++ *ptr;
++ cups_txt_records_t txtr;
++
++ client = avahi_service_resolver_get_client (resolver);
++ if (event != AVAHI_RESOLVER_FOUND)
++ {
++ if (event == AVAHI_RESOLVER_FAILURE)
++ {
++ fprintf (stderr, "ERROR: %s\n",
++ avahi_strerror (avahi_client_errno (client)));
++ }
++
++ avahi_service_resolver_free (resolver);
++ return;
++ }
++
++ /*
++ * Set search key for device.
++ */
++
++ key.name = uqname;
++ unquote (uqname, name, sizeof (uqname));
++ if ((ptr = strstr(name, "._")) != NULL)
++ *ptr = '\0';
++
++ key.domain = (char *) domain;
++ key.type = device_type (type);
++
++ /*
++ * Find the device and the the TXT information.
++ */
++
++ txtr.txt = txt;
++ device = find_device ((cups_array_t *) context, &txtr, &key);
++ if (device)
++ {
++ /*
++ * Let the main loop know to announce the device.
++ */
++
++ device->resolved = 1;
++ avahi_got_callback = 1;
++ }
+ else
+- dkey.type = CUPS_DEVICE_RIOUSBPRINT;
++ fprintf (stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", name);
++
++ avahi_service_resolver_free (resolver);
++}
++
++
++/*
++ * 'avahi_browse_callback()' - Avahi browse callback function.
++ */
++
++static void
++avahi_browse_callback(AvahiServiceBrowser *browser,
++ AvahiIfIndex interface,
++ AvahiProtocol protocol,
++ AvahiBrowserEvent event,
++ const char *name,
++ const char *type,
++ const char *domain,
++ AvahiLookupResultFlags flags,
++ void *context)
++{
++ AvahiClient *client = avahi_service_browser_get_client (browser);
++
++ switch (event)
++ {
++ case AVAHI_BROWSER_FAILURE:
++ fprintf (stderr, "ERROR: %s\n",
++ avahi_strerror (avahi_client_errno (client)));
++ avahi_simple_poll_quit (simple_poll);
++ return;
++
++ case AVAHI_BROWSER_NEW:
++ /*
++ * This object is new on the network.
++ */
++
++ if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
++ {
++ /*
++ * This comes from the local machine so ignore it.
++ */
++
++ fprintf (stderr, "DEBUG: ignoring local service %s\n", name);
++ }
++ else
++ {
++ /*
++ * Create a device entry for it if it doesn't yet exist.
++ */
++
++ get_device ((cups_array_t *)context, name, type, domain);
++
++ /*
++ * Now look for a TXT entry.
++ */
++
++ if (avahi_service_resolver_new (client, interface, protocol,
++ name, type, domain,
++ AVAHI_PROTO_UNSPEC, 0,
++ avahi_query_callback, context) == NULL)
++ {
++ fprintf (stderr, "ERROR: failed to resolve service %s: %s\n",
++ name, avahi_strerror (avahi_client_errno (client)));
++ }
++ }
++
++ break;
++
++ case AVAHI_BROWSER_REMOVE:
++ case AVAHI_BROWSER_ALL_FOR_NOW:
++ case AVAHI_BROWSER_CACHE_EXHAUSTED:
++ break;
++ }
++}
++#endif /* HAVE_AVAHI */
++
+
+- for (device = cupsArrayFind(devices, &dkey);
++/*
++ * 'find_device()' - Find a device from its name and domain.
++ */
++
++static cups_device_t *
++find_device (cups_array_t *devices,
++ cups_txt_records_t *txt,
++ cups_device_t *dkey)
++{
++ cups_device_t *device;
++ char *ptr;
++
++ for (device = cupsArrayFind(devices, dkey);
+ device;
+ device = cupsArrayNext(devices))
+ {
+- if (_cups_strcasecmp(device->name, dkey.name) ||
+- _cups_strcasecmp(device->domain, dkey.domain))
++ if (_cups_strcasecmp(device->name, dkey->name) ||
++ _cups_strcasecmp(device->domain, dkey->domain))
+ {
+ device = NULL;
+ break;
+ }
+- else if (device->type == dkey.type)
++ else if (device->type == dkey->type)
+ {
+ /*
+ * Found it, pull out the priority and make and model from the TXT
+ * record and save it...
+ */
+
+- const uint8_t *data, /* Pointer into data */
+- *datanext, /* Next key/value pair */
+- *dataend; /* End of entire TXT record */
+- uint8_t datalen; /* Length of current key/value pair */
+- char key[256], /* Key string */
+- value[256], /* Value string */
+- make_and_model[512],
++ char make_and_model[512],
+ /* Manufacturer and model */
+ model[256], /* Model */
+- device_id[2048];/* 1284 device ID */
+-
++ device_id[2048]; /* 1284 device ID */
+
+ device_id[0] = '\0';
+ make_and_model[0] = '\0';
+
+ strcpy(model, "Unknown");
+
+- for (data = rdata, dataend = data + rdlen;
+- data < dataend;
+- data = datanext)
++ for (;;)
+ {
+- /*
+- * Read a key/value pair starting with an 8-bit length. Since the
+- * length is 8 bits and the size of the key/value buffers is 256, we
+- * don't need to check for overflow...
+- */
+-
+- datalen = *data++;
+-
+- if (!datalen || (data + datalen) >= dataend)
+- break;
+-
+- datanext = data + datalen;
+-
+- for (ptr = key; data < datanext && *data != '='; data ++)
+- *ptr++ = *data;
+- *ptr = '\0';
++ char *key;
++ char *value;
+
+- if (data < datanext && *data == '=')
+- {
+- data ++;
+-
+- if (data < datanext)
+- memcpy(value, data, datanext - data);
+- value[datanext - data] = '\0';
++ if (parse_txt_record_pair (txt))
++ goto next;
+
+- fprintf(stderr, "DEBUG2: query_callback: \"%s=%s\".\n",
+- key, value);
+- }
+- else
+- {
+- fprintf(stderr, "DEBUG2: query_callback: \"%s\" with no value.\n",
+- key);
+- continue;
+- }
+-
+- if (!_cups_strncasecmp(key, "usb_", 4))
++ key = txt->key;
++ value = txt->value;
++ if (!strncasecmp(key, "usb_", 4))
+ {
+ /*
+ * Add USB device ID information...
+@@ -856,6 +1263,10 @@ query_callback(
+ if (device->type == CUPS_DEVICE_PRINTER)
+ device->sent = 1;
+ }
++
++ next:
++ if (next_txt_record (txt) == NULL)
++ break;
+ }
+
+ if (device->device_id)
+@@ -912,11 +1323,9 @@ query_callback(
+ }
+ }
+
+- if (!device)
+- fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName);
++ return device;
+ }
+
+-
+ /*
+ * 'sigterm_handler()' - Handle termination signals...
+ */
+diff -up cups-1.5.0/cups/http-support.c.avahi-2-backend cups-1.5.0/cups/http-support.c
+--- cups-1.5.0/cups/http-support.c.avahi-2-backend 2011-06-10 23:06:26.000000000 +0100
++++ cups-1.5.0/cups/http-support.c 2011-08-05 15:05:13.870710117 +0100
+@@ -43,6 +43,10 @@
+ * http_copy_decode() - Copy and decode a URI.
+ * http_copy_encode() - Copy and encode a URI.
+ * http_resolve_cb() - Build a device URI for the given service name.
++ * avahi_resolve_uri_client_cb()
++ * - Avahi client callback for resolving URI.
++ * avahi_resolve_uri_resolver_cb()
++ * - Avahi resolver callback for resolving URI.
+ */
+
+ /*
+@@ -60,6 +64,11 @@
+ # include <sys/select.h>
+ # endif /* WIN32 */
+ #endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++# include <avahi-client/client.h>
++# include <avahi-client/lookup.h>
++# include <avahi-common/simple-watch.h>
++#endif /* HAVE_AVAHI */
+
+
+ /*
+@@ -127,6 +136,24 @@ static void DNSSD_API http_resolve_cb(DN
+ void *context);
+ #endif /* HAVE_DNSSD */
+
++#ifdef HAVE_AVAHI
++static void avahi_resolve_uri_client_cb(AvahiClient *client,
++ AvahiClientState state,
++ void *simple_poll);
++static void avahi_resolve_uri_resolver_cb(AvahiServiceResolver *resolver,
++ AvahiIfIndex interface,
++ AvahiProtocol protocol,
++ AvahiResolverEvent event,
++ const char *name,
++ const char *type,
++ const char *domain,
++ const char *host_name,
++ const AvahiAddress *address,
++ uint16_t port,
++ AvahiStringList *txt,
++ AvahiLookupResultFlags flags,
++ void *context);
++#endif /* HAVE_AVAHI */
+
+ /*
+ * 'httpAssembleURI()' - Assemble a uniform resource identifier from its
+@@ -1431,6 +1458,9 @@ _httpResolveURI(
+
+ if (strstr(hostname, "._tcp"))
+ {
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
++ char *regtype, /* Pointer to type in hostname */
++ *domain; /* Pointer to domain in hostname */
+ #ifdef HAVE_DNSSD
+ # ifdef WIN32
+ # pragma comment(lib, "dnssd.lib")
+@@ -1449,6 +1479,17 @@ _httpResolveURI(
+ fd_set input_set; /* Input set for select() */
+ struct timeval stimeout; /* Timeout value for select() */
+ #endif /* HAVE_POLL */
++#else /* HAVE_AVAHI */
++ AvahiSimplePoll *simple_poll;
++ AvahiClient *client;
++ int error;
++ struct
++ {
++ AvahiSimplePoll *poll;
++ _http_uribuf_t uribuf;
++ } user_data;
++#endif /* HAVE_DNSSD */
++
+
+ if (options & _HTTP_RESOLVE_STDERR)
+ fprintf(stderr, "DEBUG: Resolving \"%s\"...\n", hostname);
+@@ -1485,9 +1526,16 @@ _httpResolveURI(
+ if (domain)
+ *domain++ = '\0';
+
++#ifdef HAVE_DNSSD
+ uribuf.buffer = resolved_uri;
+ uribuf.bufsize = resolved_size;
+ uribuf.options = options;
++#else
++ user_data.uribuf.buffer = resolved_uri;
++ user_data.uribuf.bufsize = resolved_size;
++ user_data.uribuf.options = options;
++#endif
++
+ resolved_uri[0] = '\0';
+
+ DEBUG_printf(("6_httpResolveURI: Resolving hostname=\"%s\", regtype=\"%s\", "
+@@ -1501,6 +1549,7 @@ _httpResolveURI(
+
+ uri = NULL;
+
++#ifdef HAVE_DNSSD
+ if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError)
+ {
+ localref = ref;
+@@ -1608,6 +1657,36 @@ _httpResolveURI(
+
+ DNSServiceRefDeallocate(ref);
+ }
++#else /* HAVE_AVAHI */
++ if ((simple_poll = avahi_simple_poll_new ()) != NULL)
++ {
++ if ((client = avahi_client_new (avahi_simple_poll_get (simple_poll),
++ 0, avahi_resolve_uri_client_cb,
++ &simple_poll, &error)) != NULL)
++ {
++ user_data.poll = simple_poll;
++ if (avahi_service_resolver_new (client, AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC, hostname,
++ regtype, domain, AVAHI_PROTO_UNSPEC, 0,
++ avahi_resolve_uri_resolver_cb,
++ &user_data) != NULL)
++ {
++ avahi_simple_poll_loop (simple_poll);
++
++ /*
++ * Collect the result.
++ */
++
++ if (resolved_uri[0])
++ uri = resolved_uri;
++ }
++
++ avahi_client_free (client);
++ }
++
++ avahi_simple_poll_free (simple_poll);
++ }
++#endif /* HAVE_DNSSD */
+
+ if (options & _HTTP_RESOLVE_STDERR)
+ {
+@@ -1619,13 +1698,13 @@ _httpResolveURI(
+ fputs("STATE: -connecting-to-device,offline-report\n", stderr);
+ }
+
+-#else
++#else /* HAVE_DNSSD || HAVE_AVAHI */
+ /*
+ * No DNS-SD support...
+ */
+
+ uri = NULL;
+-#endif /* HAVE_DNSSD */
++#endif /* HAVE_DNSSD || HAVE_AVAHI */
+
+ if ((options & _HTTP_RESOLVE_STDERR) && !uri)
+ _cupsLangPrintFilter(stderr, "ERROR", _("Unable to find printer."));
+@@ -1895,6 +1974,116 @@ http_resolve_cb(
+ #endif /* HAVE_DNSSD */
+
+
++#ifdef HAVE_AVAHI
++/*
++ * 'avahi_resolve_uri_client_cb()' - Avahi client callback for resolving URI.
++ */
++
++static void
++avahi_resolve_uri_client_cb (AvahiClient *client,
++ AvahiClientState state,
++ void *simple_poll)
++{
++ DEBUG_printf(("avahi_resolve_uri_client_callback(client=%p, state=%d, "
++ "simple_poll=%p)\n", client, state, simple_poll));
++
++ /*
++ * If the connection drops, quit.
++ */
++
++ if (state == AVAHI_CLIENT_FAILURE)
++ avahi_simple_poll_quit (simple_poll);
++}
++
++
++/*
++ * 'avahi_resolve_uri_resolver_cb()' - Avahi resolver callback for resolving
++ * URI.
++ */
++
++static void
++avahi_resolve_uri_resolver_cb (AvahiServiceResolver *resolver,
++ AvahiIfIndex interface,
++ AvahiProtocol protocol,
++ AvahiResolverEvent event,
++ const char *name,
++ const char *type,
++ const char *domain,
++ const char *host_name,
++ const AvahiAddress *address,
++ uint16_t port,
++ AvahiStringList *txt,
++ AvahiLookupResultFlags flags,
++ void *context)
++{
++ const char *scheme; /* URI scheme */
++ char rp[256]; /* Remote printer */
++ AvahiStringList *pair;
++ char *value;
++ size_t valueLen = 0;
++ char addr[AVAHI_ADDRESS_STR_MAX];
++ struct
++ {
++ AvahiSimplePoll *poll;
++ _http_uribuf_t uribuf;
++ } *poll_uribuf = context;
++
++ DEBUG_printf(("avahi_resolve_uri_resolver_callback(resolver=%p, "
++ "interface=%d, protocol=%d, event=%d, name=\"%s\", "
++ "type=\"%s\", domain=\"%s\", host_name=\"%s\", address=%p, "
++ "port=%d, txt=%p, flags=%d, context=%p)\n",
++ resolver, interface, protocol, event, name, type, domain,
++ host_name, address, port, txt, flags, context));
++
++ if (event != AVAHI_RESOLVER_FOUND)
++ {
++ avahi_service_resolver_free (resolver);
++ avahi_simple_poll_quit (poll_uribuf->poll);
++ return;
++ }
++
++ /*
++ * Figure out the scheme from the full name...
++ */
++
++ if (strstr(type, "_ipp."))
++ scheme = "ipp";
++ else if (strstr(type, "_printer."))
++ scheme = "lpd";
++ else if (strstr(type, "_pdl-datastream."))
++ scheme = "socket";
++ else
++ scheme = "riousbprint";
++
++ /*
++ * Extract the "remote printer key from the TXT record...
++ */
++
++ if ((pair = avahi_string_list_find (txt, "rp")) != NULL)
++ {
++ avahi_string_list_get_pair (pair, NULL, &value, &valueLen);
++ rp[0] = '/';
++ memcpy (rp + 1, value, valueLen);
++ rp[valueLen + 1] = '\0';
++ }
++ else
++ rp[0] = '\0';
++
++ /*
++ * Assemble the final device URI...
++ */
++
++ avahi_address_snprint (addr, AVAHI_ADDRESS_STR_MAX, address);
++ httpAssembleURI(HTTP_URI_CODING_ALL, poll_uribuf->uribuf.buffer,
++ poll_uribuf->uribuf.bufsize, scheme, NULL,
++ addr, port, rp);
++ DEBUG_printf(("avahi_resolve_uri_resolver_callback: Resolved URI is \"%s\"\n",
++ poll_uribuf->uribuf.buffer));
++ avahi_simple_poll_quit (poll_uribuf->poll);
++}
++#endif /* HAVE_AVAHI */
++
++
+ /*
+ * End of "$Id: http-support.c 9820 2011-06-10 22:06:26Z mike $".
+ */
diff --git a/cups-avahi-3-timeouts.patch b/cups-avahi-3-timeouts.patch
new file mode 100644
index 0000000..1c547c0
--- /dev/null
+++ b/cups-avahi-3-timeouts.patch
@@ -0,0 +1,381 @@
+diff -up cups-1.5.0/scheduler/cupsd.h.avahi-3-timeouts cups-1.5.0/scheduler/cupsd.h
+--- cups-1.5.0/scheduler/cupsd.h.avahi-3-timeouts 2011-05-11 23:17:34.000000000 +0100
++++ cups-1.5.0/scheduler/cupsd.h 2011-10-07 13:20:41.522867324 +0100
+@@ -140,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...
+@@ -173,6 +182,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...
+@@ -242,6 +256,20 @@ 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 */
++
++extern int cupsdRemoveFile(const char *filename);
++
+
+ /*
+ * End of "$Id: cupsd.h 9766 2011-05-11 22:17:34Z mike $".
+diff -up cups-1.5.0/scheduler/main.c.avahi-3-timeouts cups-1.5.0/scheduler/main.c
+--- cups-1.5.0/scheduler/main.c.avahi-3-timeouts 2011-10-07 13:20:36.875954675 +0100
++++ cups-1.5.0/scheduler/main.c 2011-10-07 13:20:41.524867282 +0100
+@@ -146,6 +146,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
+@@ -535,6 +539,14 @@ main(int argc, /* I - Number of comm
+
+ httpInitialize();
+
++#ifdef HAVE_AVAHI
++ /*
++ * Initialize timed callback structures.
++ */
++
++ cupsdInitTimeouts();
++#endif /* HAVE_AVAHI */
++
+ cupsdStartServer();
+
+ /*
+@@ -874,6 +886,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...
+@@ -1787,6 +1809,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 */
+
+
+ /*
+@@ -1829,6 +1855,19 @@ select_timeout(int fds) /* I - Number
+ }
+ #endif /* __APPLE__ */
+
++#ifdef HAVE_AVAHI
++ /*
++ * See if there are any scheduled timed callbacks to run.
++ */
++
++ tmo = cupsdNextTimeout (&tmo_delay);
++ if (tmo)
++ {
++ timeout = tmo_delay;
++ why = "run a timed callback";
++ }
++#endif /* HAVE_AVAHI */
++
+ /*
+ * Check whether we are accepting new connections...
+ */
+diff -up cups-1.5.0/scheduler/Makefile.avahi-3-timeouts cups-1.5.0/scheduler/Makefile
+--- cups-1.5.0/scheduler/Makefile.avahi-3-timeouts 2011-10-07 13:20:36.955953170 +0100
++++ cups-1.5.0/scheduler/Makefile 2011-10-07 13:20:41.521867343 +0100
+@@ -39,7 +39,8 @@ CUPSDOBJS = \
+ server.o \
+ statbuf.o \
+ subscriptions.o \
+- sysman.o
++ sysman.o \
++ timeout.o
+ LIBOBJS = \
+ filter.o \
+ mime.o \
+diff -up cups-1.5.0/scheduler/timeout.c.avahi-3-timeouts cups-1.5.0/scheduler/timeout.c
+--- cups-1.5.0/scheduler/timeout.c.avahi-3-timeouts 2011-10-07 13:20:41.525867259 +0100
++++ cups-1.5.0/scheduler/timeout.c 2011-10-07 13:20:41.525867259 +0100
+@@ -0,0 +1,235 @@
++/*
++ * "$Id$"
++ *
++ * Timeout functions for the Common UNIX Printing System (CUPS).
++ *
++ * Copyright (C) 2010, 2011 Red Hat, Inc.
++ * Authors:
++ * Tim Waugh <twaugh@redhat.com>
++ *
++ * 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 <config.h>
++
++#ifdef HAVE_AVAHI /* Applies to entire file... */
++
++/*
++ * Include necessary headers...
++ */
++
++#include "cupsd.h"
++
++#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
++# include <malloc.h>
++#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
++
++#ifdef HAVE_AVAHI
++# include <avahi-common/timeval.h>
++#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/cups-avahi-4-poll.patch b/cups-avahi-4-poll.patch
new file mode 100644
index 0000000..189e83d
--- /dev/null
+++ b/cups-avahi-4-poll.patch
@@ -0,0 +1,529 @@
+diff -up cups-1.5.0/scheduler/avahi.c.avahi-4-poll cups-1.5.0/scheduler/avahi.c
+--- cups-1.5.0/scheduler/avahi.c.avahi-4-poll 2011-10-11 10:56:50.102288037 +0100
++++ cups-1.5.0/scheduler/avahi.c 2011-10-11 10:56:50.102288037 +0100
+@@ -0,0 +1,441 @@
++/*
++ * "$Id$"
++ *
++ * Avahi poll implementation for the CUPS scheduler.
++ *
++ * Copyright (C) 2010, 2011 Red Hat, Inc.
++ * Authors:
++ * Tim Waugh <twaugh@redhat.com>
++ *
++ * 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 <config.h>
++
++#ifdef HAVE_AVAHI /* Applies to entire file... */
++
++/*
++ * Include necessary headers...
++ */
++
++#include "cupsd.h"
++
++#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
++# include <malloc.h>
++#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
++
++#ifdef HAVE_AVAHI
++# include <avahi-common/timeval.h>
++#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.5.0/scheduler/avahi.h.avahi-4-poll cups-1.5.0/scheduler/avahi.h
+--- cups-1.5.0/scheduler/avahi.h.avahi-4-poll 2011-10-11 10:56:50.102288037 +0100
++++ cups-1.5.0/scheduler/avahi.h 2011-10-11 10:56:50.119287724 +0100
+@@ -0,0 +1,69 @@
++/*
++ * "$Id$"
++ *
++ * Avahi poll implementation for the CUPS scheduler.
++ *
++ * Copyright (C) 2010, 2011 Red Hat, Inc.
++ * Authors:
++ * Tim Waugh <twaugh@redhat.com>
++ *
++ * 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 <config.h>
++
++#ifdef HAVE_AVAHI
++# include <avahi-client/client.h>
++# include <avahi-client/publish.h>
++#endif /* HAVE_AVAHI */
++
++#ifdef HAVE_AUTHORIZATION_H
++# include <Security/Authorization.h>
++#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.5.0/scheduler/Makefile.avahi-4-poll cups-1.5.0/scheduler/Makefile
+--- cups-1.5.0/scheduler/Makefile.avahi-4-poll 2011-10-11 10:56:45.868365861 +0100
++++ cups-1.5.0/scheduler/Makefile 2011-10-11 10:56:50.101288055 +0100
+@@ -17,6 +17,7 @@ include ../Makedefs
+
+ CUPSDOBJS = \
+ auth.o \
++ avahi.o \
+ banners.o \
+ cert.o \
+ classes.o \
diff --git a/cups-avahi-5-services.patch b/cups-avahi-5-services.patch
new file mode 100644
index 0000000..9713bbc
--- /dev/null
+++ b/cups-avahi-5-services.patch
@@ -0,0 +1,1191 @@
+diff -up cups-1.5.0/cgi-bin/admin.c.avahi-5-services cups-1.5.0/cgi-bin/admin.c
+--- cups-1.5.0/cgi-bin/admin.c.avahi-5-services 2011-05-20 04:49:49.000000000 +0100
++++ cups-1.5.0/cgi-bin/admin.c 2011-10-19 11:53:32.123177998 +0100
+@@ -1643,7 +1643,7 @@ do_config_server(http_t *http) /* I - H
+ else
+ local_protocols[0] = '\0';
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (cgiGetVariable("BROWSE_LOCAL_DNSSD"))
+ {
+ if (local_protocols[0])
+@@ -1651,7 +1651,7 @@ do_config_server(http_t *http) /* I - H
+ else
+ strcat(local_protocols, "dnssd");
+ }
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ #ifdef HAVE_LDAP
+ if (cgiGetVariable("BROWSE_LOCAL_LDAP"))
+@@ -2718,9 +2718,9 @@ do_menu(http_t *http) /* I - HTTP conn
+ #endif /* HAVE_GSSAPI */
+ cgiSetVariable("KERBEROS", "");
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ cgiSetVariable("HAVE_DNSSD", "1");
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ #ifdef HAVE_LDAP
+ cgiSetVariable("HAVE_LDAP", "1");
+diff -up cups-1.5.0/scheduler/client.c.avahi-5-services cups-1.5.0/scheduler/client.c
+--- cups-1.5.0/scheduler/client.c.avahi-5-services 2011-06-10 22:16:18.000000000 +0100
++++ cups-1.5.0/scheduler/client.c 2011-10-19 11:53:32.127177926 +0100
+@@ -4987,7 +4987,7 @@ valid_host(cupsd_client_t *con) /* I -
+ !strncmp(host, "[::1]:", 6));
+ }
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ /*
+ * Check if the hostname is something.local (Bonjour); if so, allow it.
+ */
+@@ -4996,7 +4996,7 @@ valid_host(cupsd_client_t *con) /* I -
+ (!_cups_strcasecmp(end, ".local") || !_cups_strncasecmp(end, ".local:", 7) ||
+ !_cups_strcasecmp(end, ".local.") || !_cups_strncasecmp(end, ".local.:", 8)))
+ return (1);
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ /*
+ * Check if the hostname is an IP address...
+diff -up cups-1.5.0/scheduler/conf.c.avahi-5-services cups-1.5.0/scheduler/conf.c
+--- cups-1.5.0/scheduler/conf.c.avahi-5-services 2011-10-19 11:53:31.895182225 +0100
++++ cups-1.5.0/scheduler/conf.c 2011-10-19 11:53:32.131177850 +0100
+@@ -651,7 +651,7 @@ cupsdReadConfiguration(void)
+ Browsing = CUPS_DEFAULT_BROWSING;
+ DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ cupsdSetString(&DNSSDRegType, "_ipp._tcp,_cups");
+ #endif /* HAVE_DNSSD */
+
+diff -up cups-1.5.0/scheduler/dirsvc.c.avahi-5-services cups-1.5.0/scheduler/dirsvc.c
+--- cups-1.5.0/scheduler/dirsvc.c.avahi-5-services 2011-10-19 11:53:32.011180075 +0100
++++ cups-1.5.0/scheduler/dirsvc.c 2011-10-19 11:53:58.916681461 +0100
+@@ -27,6 +27,7 @@
+ * ldap_connect() - Start new LDAP connection
+ * ldap_reconnect() - Reconnect to LDAP Server
+ * ldap_disconnect() - Disconnect from LDAP Server
++ * cupsdStartAvahiClient() - Start an Avahi client if needed
+ * cupsdStartBrowsing() - Start sending and receiving broadcast
+ * information.
+ * cupsdStartPolling() - Start polling servers as needed.
+@@ -40,11 +41,12 @@
+ * dequote() - Remote quotes from a string.
+ * dnssdAddAlias() - Add a DNS-SD alias name.
+ * dnssdBuildTxtRecord() - Build a TXT record from printer info.
+- * dnssdComparePrinters() - Compare the registered names of two printers.
+ * dnssdDeregisterPrinter() - Stop sending broadcast information for a
+ * printer.
+ * dnssdPackTxtRecord() - Pack an array of key/value pairs into the TXT
+ * record format.
++ * avahiPackTxtRecord() - Pack an array of key/value pairs into an
++ * AvahiStringList.
+ * dnssdRegisterCallback() - DNSServiceRegister callback.
+ * dnssdRegisterPrinter() - Start sending broadcast information for a
+ * printer or update the broadcast contents.
+@@ -83,6 +85,7 @@
+ */
+
+ #include "cupsd.h"
++#include <assert.h>
+ #include <grp.h>
+
+ #ifdef HAVE_DNSSD
+@@ -97,6 +100,17 @@
+ # endif /* HAVE_SYSTEMCONFIGURATION */
+ # endif /* __APPLE__ */
+ #endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++# include <avahi-common/domain.h>
++#endif /* HAVE_AVAHI */
++
++
++#ifdef HAVE_DNSSD
++typedef char *cupsd_txt_record_t;
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++typedef AvahiStringList *cupsd_txt_record_t;
++#endif /* HAVE_AVAHI */
+
+
+ /*
+@@ -159,27 +173,38 @@ static void update_polling(void);
+ static void update_smb(int onoff);
+
+
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
++static cupsd_txt_record_t dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
++ int for_lpd);
++static void dnssdDeregisterPrinter(cupsd_printer_t *p);
++static void dnssdRegisterPrinter(cupsd_printer_t *p);
++static void dnssdStop(void);
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
++
+ #ifdef HAVE_DNSSD
+ # ifdef HAVE_COREFOUNDATION
+ static void dnssdAddAlias(const void *key, const void *value,
+ void *context);
+ # endif /* HAVE_COREFOUNDATION */
+-static char *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
+- int for_lpd);
+-static int dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
+-static void dnssdDeregisterPrinter(cupsd_printer_t *p);
+-static char *dnssdPackTxtRecord(int *txt_len, char *keyvalue[][2],
+- int count);
+ static void dnssdRegisterCallback(DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ const char *name, const char *regtype,
+ const char *domain, void *context);
+-static void dnssdRegisterPrinter(cupsd_printer_t *p);
+-static void dnssdStop(void);
+ static void dnssdUpdate(void);
+ #endif /* HAVE_DNSSD */
+
++#ifdef HAVE_AVAHI
++static AvahiStringList *avahiPackTxtRecord(char *keyvalue[][2],
++ int count);
++static void avahi_entry_group_cb (AvahiEntryGroup *group,
++ AvahiEntryGroupState state,
++ void *userdata);
++static void avahi_client_cb (AvahiClient *client,
++ AvahiClientState state,
++ void *userdata);
++#endif /* HAVE_AVAHI */
++
+ #ifdef HAVE_LDAP
+ static const char * const ldap_attrs[] =/* CUPS LDAP attributes */
+ {
+@@ -283,10 +308,10 @@ cupsdDeregisterPrinter(
+ ldap_dereg_printer(p);
+ #endif /* HAVE_LDAP */
+
+-#ifdef HAVE_DNSSD
+- if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
++ if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD))
+ dnssdDeregisterPrinter(p);
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+ }
+
+
+@@ -702,10 +727,10 @@ cupsdRegisterPrinter(cupsd_printer_t *p)
+ slpRegisterPrinter(p); */
+ #endif /* HAVE_LIBSLP */
+
+-#ifdef HAVE_DNSSD
+- if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
++ if ((BrowseLocalProtocols & BROWSE_DNSSD))
+ dnssdRegisterPrinter(p);
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+ }
+
+
+@@ -1419,6 +1444,36 @@ ldap_disconnect(LDAP *ld) /* I - LDAP h
+ #endif /* HAVE_LDAP */
+
+
++#ifdef HAVE_AVAHI
++/*
++ * 'cupsdStartAvahiClient()' - Start an Avahi client if needed
++ */
++
++void
++cupsdStartAvahiClient(void)
++{
++ int error = 0;
++
++ if (!AvahiCupsClient && !AvahiCupsClientConnecting)
++ {
++ if (!AvahiCupsPollHandle)
++ AvahiCupsPollHandle = avahi_cups_poll_new ();
++
++ if (AvahiCupsPollHandle)
++ {
++ if (avahi_client_new (avahi_cups_poll_get (AvahiCupsPollHandle),
++ AVAHI_CLIENT_NO_FAIL,
++ avahi_client_cb, NULL,
++ &error) != NULL)
++ AvahiCupsClientConnecting = 1;
++ else
++ cupsdLogMessage (CUPSD_LOG_WARN, "Avahi client failed: %d", error);
++ }
++ }
++}
++#endif /* HAVE_AVAHI */
++
++
+ /*
+ * 'cupsdStartBrowsing()' - Start sending and receiving broadcast information.
+ */
+@@ -1542,13 +1597,16 @@ cupsdStartBrowsing(void)
+ else
+ BrowseSocket = -1;
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_DNSSD)
+ {
++#ifdef HAVE_DNSSD
+ DNSServiceErrorType error; /* Error from service creation */
++#endif /* HAVE_DNSSD */
+ cupsd_listener_t *lis; /* Current listening socket */
+
+
++#ifdef HAVE_DNSSD
+ /*
+ * First create a "master" connection for all registrations...
+ */
+@@ -1573,6 +1631,7 @@ cupsdStartBrowsing(void)
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+
+ cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
++#endif /* HAVE_DNSSD */
+
+ /*
+ * Then get the port we use for registrations. If we are not listening
+@@ -1598,17 +1657,23 @@ cupsdStartBrowsing(void)
+ */
+
+ if (BrowseRemoteProtocols & BROWSE_DNSSD)
+- DNSSDPrinters = cupsArrayNew((cups_array_func_t)dnssdComparePrinters,
+- NULL);
++ DNSSDPrinters = cupsArrayNew(NULL, NULL);
+
+ /*
+ * Set the computer name and register the web interface...
+ */
+
+ cupsdUpdateDNSSDName();
++
++#ifdef HAVE_AVAHI
++ cupsdStartAvahiClient ();
++#endif /* HAVE_AVAHI */
++
++#ifdef HAVE_DNSSD
+ }
+- }
+ #endif /* HAVE_DNSSD */
++ }
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ #ifdef HAVE_LIBSLP
+ if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP)
+@@ -1834,10 +1899,10 @@ cupsdStopBrowsing(void)
+ BrowseSocket = -1;
+ }
+
+-#ifdef HAVE_DNSSD
+- if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
++ if ((BrowseLocalProtocols & BROWSE_DNSSD))
+ dnssdStop();
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ #ifdef HAVE_LIBSLP
+ if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) &&
+@@ -1902,7 +1967,7 @@ cupsdStopPolling(void)
+ }
+
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ /*
+ * 'cupsdUpdateDNSSDName()' - Update the computer name we use for browsing...
+ */
+@@ -1910,8 +1975,14 @@ cupsdStopPolling(void)
+ void
+ cupsdUpdateDNSSDName(void)
+ {
++#ifdef HAVE_DNSSD
+ DNSServiceErrorType error; /* Error from service creation */
+ char webif[1024]; /* Web interface share name */
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ int ret; /* Error from service creation */
++ char webif[AVAHI_LABEL_MAX]; /* Web interface share name */
++#endif /* HAVE_AVAHI */
+ # ifdef HAVE_SYSTEMCONFIGURATION
+ SCDynamicStoreRef sc; /* Context for dynamic store */
+ CFDictionaryRef btmm; /* Back-to-My-Mac domains */
+@@ -2042,6 +2113,7 @@ cupsdUpdateDNSSDName(void)
+ else
+ strlcpy(webif, "CUPS Web Interface", sizeof(webif));
+
++#ifdef HAVE_DNSSD
+ if (WebIFRef)
+ DNSServiceRefDeallocate(WebIFRef);
+
+@@ -2054,9 +2126,45 @@ cupsdUpdateDNSSDName(void)
+ NULL)) != kDNSServiceErr_NoError)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "DNS-SD web interface registration failed: %d", error);
++#endif /* HAVE_DNSSD */
++
++#ifdef HAVE_AVAHI
++ if (!AvahiCupsClient)
++ /*
++ * Client not yet running.
++ */
++ return;
++
++ if (AvahiWebIFGroup)
++ avahi_entry_group_reset (AvahiWebIFGroup);
++ else
++ AvahiWebIFGroup = avahi_entry_group_new (AvahiCupsClient,
++ avahi_entry_group_cb,
++ NULL);
++
++ if (AvahiWebIFGroup)
++ {
++ ret = avahi_entry_group_add_service (AvahiWebIFGroup,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0, /* flags */
++ webif, /* name */
++ "_http._tcp", /* type */
++ NULL, /* domain */
++ NULL, /* host */
++ DNSSDPort, /* port */
++ "path=/", NULL);
++ if (ret == 0)
++ ret = avahi_entry_group_commit (AvahiWebIFGroup);
++
++ if (ret != 0)
++ cupsdLogMessage (CUPSD_LOG_ERROR,
++ "Avahi web interface registration failed: %d", ret);
++ }
++#endif /* HAVE_AVAHI */
+ }
+ }
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+
+ #ifdef HAVE_LDAP
+@@ -2334,13 +2442,15 @@ dnssdAddAlias(const void *key, /* I - K
+ "Bad Back to My Mac domain in dynamic store!");
+ }
+ # endif /* HAVE_COREFOUNDATION */
++#endif /* HAVE_DNSSD */
+
+
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ /*
+ * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
+ */
+
+-static char * /* O - TXT record */
++static cupsd_txt_record_t /* O - TXT record */
+ dnssdBuildTxtRecord(
+ int *txt_len, /* O - TXT record length */
+ cupsd_printer_t *p, /* I - Printer information */
+@@ -2379,7 +2489,12 @@ dnssdBuildTxtRecord(
+ keyvalue[i ][0] = "ty";
+ keyvalue[i++][1] = p->make_model ? p->make_model : "Unknown";
+
+- snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName);
++ snprintf(admin_hostname, sizeof(admin_hostname),
++ "%s.local"
++#ifdef HAVE_DNSSD
++ "." /* terminating dot no good for Avahi */
++#endif /* HAVE_DNSSD */
++ , DNSSDHostName);
+ httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
+ "http", NULL, admin_hostname, DNSSDPort, "/%s/%s",
+ (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
+@@ -2462,19 +2577,12 @@ dnssdBuildTxtRecord(
+ * Then pack them into a proper txt record...
+ */
+
++#ifdef HAVE_DNSSD
+ return (dnssdPackTxtRecord(txt_len, keyvalue, i));
+-}
+-
+-
+-/*
+- * 'dnssdComparePrinters()' - Compare the registered names of two printers.
+- */
+-
+-static int /* O - Result of comparison */
+-dnssdComparePrinters(cupsd_printer_t *a,/* I - First printer */
+- cupsd_printer_t *b)/* I - Second printer */
+-{
+- return (_cups_strcasecmp(a->reg_name, b->reg_name));
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ return (avahiPackTxtRecord(keyvalue, i));
++#endif /* HAVE_AVAHI */
+ }
+
+
+@@ -2489,6 +2597,10 @@ dnssdDeregisterPrinter(
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdDeregisterPrinter(%s)", p->name);
+
++#ifdef HAVE_DNSSD
++ if (!DNSSDRef)
++ return;
++
+ /*
+ * Closing the socket deregisters the service
+ */
+@@ -2524,6 +2636,24 @@ dnssdDeregisterPrinter(
+ free(p->printer_txt);
+ p->printer_txt = NULL;
+ }
++#endif /* HAVE_DNSSD */
++
++#ifdef HAVE_AVAHI
++ if (p->avahi_group)
++ {
++ avahi_entry_group_reset (p->avahi_group);
++ avahi_entry_group_free (p->avahi_group);
++ p->avahi_group = NULL;
++
++ if (p->ipp_txt)
++ avahi_string_list_free (p->ipp_txt);
++
++ if (p->printer_txt)
++ avahi_string_list_free (p->printer_txt);
++
++ p->ipp_txt = p->printer_txt = NULL;
++ }
++#endif /* HAVE_AVAHI */
+
+ /*
+ * Remove the printer from the array of DNS-SD printers, then clear the
+@@ -2533,8 +2663,10 @@ dnssdDeregisterPrinter(
+ cupsArrayRemove(DNSSDPrinters, p);
+ cupsdClearString(&p->reg_name);
+ }
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+
++#ifdef HAVE_DNSSD
+ /*
+ * 'dnssdPackTxtRecord()' - Pack an array of key/value pairs into the
+ * TXT record format.
+@@ -2644,8 +2776,10 @@ dnssdRegisterCallback(
+ LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED;
+ }
+ }
++#endif /* HAVE_DNSSD */
+
+
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ /*
+ * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
+ * or update the broadcast contents.
+@@ -2654,20 +2788,40 @@ dnssdRegisterCallback(
+ static void
+ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
+ {
++#ifdef HAVE_DNSSD
+ DNSServiceErrorType se; /* dnssd errors */
+ char *ipp_txt, /* IPP TXT record buffer */
+ *printer_txt, /* LPD TXT record buffer */
+- name[1024], /* Service name */
+- *nameptr; /* Pointer into name */
++ name[1024]; /* Service name */
+ int ipp_len, /* IPP TXT record length */
+ printer_len, /* LPD TXT record length */
+ printer_port; /* LPD port number */
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ int ret; /* Error code */
++ AvahiStringList *ipp_txt, /* IPP TXT record */
++ *printer_txt; /* LPD TXT record */
++ char name[AVAHI_LABEL_MAX], /* Service name */
++ fullsubtype[AVAHI_LABEL_MAX]; /* Full subtype */
++ char *regtype_copy, /* Writeable copy of reg type */
++ *subtype, /* Current service sub type */
++ *nextsubtype; /* Next service sub type */
++#endif /* HAVE_AVAHI */
++ char *nameptr; /* Pointer into name */
+ const char *regtype; /* Registration type */
+
+
++#ifdef HAVE_DNSSD
++ if (!DNSSDRef)
++ return;
++
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
+ !p->ipp_ref ? "new" : "update");
+-
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
++ !p->avahi_group ? "new" : "update");
++#endif /* HAVE_AVAHI */
+ /*
+ * If per-printer sharing was just disabled make sure we're not
+ * registered before returning.
+@@ -2686,12 +2840,36 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
+ if (p->info && strlen(p->info) > 0)
+ {
+ if (DNSSDComputerName)
+- snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
++ {
++ /*
++ * Make sure there is room for at least 15 characters of
++ * DNSSDComputerName.
++ */
++
++ assert(sizeof(name) >= 15 + 4);
++ nameptr = name + strlcpy(name, p->info,
++ sizeof(name) - 4 -
++ strnlen(DNSSDComputerName, 15));
++ nameptr += strlcpy(nameptr, " @ ", sizeof(name) - (nameptr - name));
++ strlcpy(nameptr, DNSSDComputerName, sizeof(name) - (nameptr - name));
++ }
+ else
+ strlcpy(name, p->info, sizeof(name));
+ }
+ else if (DNSSDComputerName)
+- snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
++ {
++ /*
++ * Make sure there is room for at least 15 characters of
++ * DNSSDComputerName.
++ */
++
++ assert(sizeof(name) >= 15 + 4);
++ nameptr = name + strlcpy(name, p->info,
++ sizeof(name) - 4 -
++ strnlen(DNSSDComputerName, 15));
++ nameptr += strlcpy(nameptr, " @ ", sizeof(name) - (nameptr - name));
++ strlcpy(nameptr, DNSSDComputerName, sizeof(name) - (nameptr - name));
++ }
+ else
+ strlcpy(name, p->name, sizeof(name));
+
+@@ -2712,6 +2890,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
+ * Register IPP and (optionally) LPD...
+ */
+
++#ifdef HAVE_DNSSD
+ ipp_len = 0; /* anti-compiler-warning-code */
+ ipp_txt = dnssdBuildTxtRecord(&ipp_len, p, 0);
+
+@@ -2884,6 +3063,209 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
+
+ if (printer_txt)
+ free(printer_txt);
++#endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ if (!AvahiCupsClient)
++ /*
++ * Client not running yet. The client callback will call us again later.
++ */
++ return;
++
++ ipp_txt = dnssdBuildTxtRecord(NULL, p, 0);
++ printer_txt = dnssdBuildTxtRecord(NULL, p, 1);
++ regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" : DNSSDRegType;
++
++ if (p->avahi_group && p->ipp_txt && ipp_txt &&
++ !avahi_string_list_equal (p->ipp_txt, ipp_txt))
++ {
++ /*
++ * Update the existing registration...
++ */
++
++ avahi_string_list_free (p->ipp_txt);
++
++ if (p->printer_txt)
++ avahi_string_list_free (p->printer_txt);
++
++ /*
++ * Update the service group entry.
++ */
++
++ regtype_copy = strdup (regtype);
++ subtype = strchr (regtype_copy, ',');
++ if (subtype)
++ *subtype = '\0';
++
++ cupsdLogMessage (CUPSD_LOG_DEBUG,
++ "Updating TXT record for %s (%s)", name, regtype_copy);
++ ret = avahi_entry_group_update_service_txt_strlst (p->avahi_group,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0, name,
++ regtype_copy,
++ NULL, ipp_txt);
++ free (regtype_copy);
++
++ if (ret < 0)
++ goto update_failed;
++
++ p->ipp_txt = ipp_txt;
++ ipp_txt = NULL;
++
++ if (BrowseLocalProtocols & BROWSE_LPD)
++ {
++ ret = avahi_entry_group_update_service_txt_strlst (p->avahi_group,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0, name,
++ "_printer._tcp", NULL,
++ printer_txt);
++ if (ret < 0)
++ goto update_failed;
++
++ p->printer_txt = printer_txt;
++ printer_txt = NULL;
++ }
++
++ ret = avahi_entry_group_commit (p->avahi_group);
++ if (ret < 0)
++ {
++ update_failed:
++ cupsdLogMessage (CUPSD_LOG_ERROR,
++ "Failed to update TXT record for %s: %d",
++ name, ret);
++ avahi_entry_group_reset (p->avahi_group);
++ avahi_entry_group_free (p->avahi_group);
++ p->avahi_group = NULL;
++ ipp_txt = p->ipp_txt;
++ p->ipp_txt = NULL;
++ }
++ }
++
++ if (!p->avahi_group)
++ {
++ /*
++ * Initial registration. Use the _fax subtype for fax queues...
++ */
++
++ p->avahi_group = avahi_entry_group_new (AvahiCupsClient,
++ avahi_entry_group_cb,
++ p);
++
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "Registering Avahi printer %s with name \"%s\" and "
++ "type \"%s\"", p->name, name, regtype);
++
++ if (!p->avahi_group)
++ {
++ ret = 0;
++ goto add_failed;
++ }
++
++ /*
++ * Add each service type (DNSSDRegType may contain several,
++ * separated by commas).
++ */
++
++ subtype = regtype_copy = strdup (regtype);
++ while (subtype && *subtype)
++ {
++ nextsubtype = strchr (subtype, ',');
++ if (nextsubtype)
++ *nextsubtype++ = '\0';
++
++ if (subtype == regtype_copy)
++ {
++ /*
++ * Main type entry.
++ */
++
++ cupsdLogMessage (CUPSD_LOG_DEBUG,
++ "Adding TXT record for %s (%s)", name, regtype_copy);
++ ret = avahi_entry_group_add_service_strlst (p->avahi_group,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0, name, regtype_copy,
++ NULL, NULL,
++ DNSSDPort,
++ ipp_txt);
++ }
++ else
++ {
++ /*
++ * Sub-type entry.
++ */
++
++ snprintf (fullsubtype, sizeof(fullsubtype),
++ "%s._sub.%s", subtype, regtype_copy);
++ cupsdLogMessage (CUPSD_LOG_DEBUG,
++ "Adding TXT record for %s (%s)", name, fullsubtype);
++ ret = avahi_entry_group_add_service_subtype (p->avahi_group,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0, name,
++ regtype_copy,
++ NULL, fullsubtype);
++ }
++
++ if (ret < 0)
++ {
++ free (regtype_copy);
++ goto add_failed;
++ }
++
++ subtype = nextsubtype;
++ }
++
++ free (regtype_copy);
++ p->ipp_txt = ipp_txt;
++ ipp_txt = NULL;
++
++ if (BrowseLocalProtocols & BROWSE_LPD)
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "Registering Avahi printer %s with name \"%s\" and "
++ "type \"_printer._tcp\"", p->name, name);
++
++ ret = avahi_entry_group_add_service_strlst (p->avahi_group,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0, name,
++ "_printer._tcp", NULL, NULL,
++ 515,
++ printer_txt);
++ if (ret < 0)
++ goto add_failed;
++
++ p->printer_txt = printer_txt;
++ printer_txt = NULL;
++ }
++
++ ret = avahi_entry_group_commit (p->avahi_group);
++
++ if (ret < 0)
++ {
++ add_failed:
++ cupsdLogMessage (CUPSD_LOG_ERROR,
++ "Failed to add Avahi entry for %s: %d",
++ name, ret);
++ if (p->avahi_group)
++ {
++ avahi_entry_group_reset (p->avahi_group);
++ avahi_entry_group_free (p->avahi_group);
++ p->avahi_group = NULL;
++ }
++ ipp_txt = p->ipp_txt;
++ p->ipp_txt = NULL;
++ }
++ }
++
++ if (ipp_txt)
++ avahi_string_list_free (ipp_txt);
++
++ if (printer_txt)
++ avahi_string_list_free (printer_txt);
++#endif /* HAVE_AVAHI */
+ }
+
+
+@@ -2896,6 +3278,10 @@ dnssdStop(void)
+ {
+ cupsd_printer_t *p; /* Current printer */
+
++#ifdef HAVE_DNSSD
++ if (!DNSSDRef)
++ return;
++#endif /* HAVE_DNSSD */
+
+ /*
+ * De-register the individual printers
+@@ -2906,6 +3292,7 @@ dnssdStop(void)
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ dnssdDeregisterPrinter(p);
+
++#ifdef HAVE_DNSSD
+ /*
+ * Shutdown the rest of the service refs...
+ */
+@@ -2926,14 +3313,17 @@ dnssdStop(void)
+
+ DNSServiceRefDeallocate(DNSSDRef);
+ DNSSDRef = NULL;
++#endif /* HAVE_DNSSD */
+
+ cupsArrayDelete(DNSSDPrinters);
+ DNSSDPrinters = NULL;
+
+ DNSSDPort = 0;
+ }
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+
++#ifdef HAVE_DNSSD
+ /*
+ * 'dnssdUpdate()' - Handle DNS-SD queries.
+ */
+@@ -2955,6 +3345,153 @@ dnssdUpdate(void)
+ #endif /* HAVE_DNSSD */
+
+
++#ifdef HAVE_AVAHI
++/*
++ * 'avahiPackTxtRecord()' - Pack an array of key/value pairs into an
++ * AvahiStringList.
++ */
++
++static AvahiStringList * /* O - new string list */
++avahiPackTxtRecord(char *keyvalue[][2], /* I - Table of key value pairs */
++ int count) /* I - Number of items in table */
++{
++ AvahiStringList *strlst = NULL;
++ char **elements;
++ size_t len;
++ int i = 0;
++
++ elements = malloc ((1 + count) * sizeof (char *));
++ if (!elements)
++ goto cleanup;
++
++ for (i = 0; i < count; i++)
++ {
++ len = (1 + strlen (keyvalue[i][0]) +
++ (keyvalue[i][1] ? 1 + strlen (keyvalue[i][1]) : 1));
++ elements[i] = malloc (len * sizeof (char));
++ if (!elements[i])
++ goto cleanup;
++
++ snprintf (elements[i], len, "%s=%s", keyvalue[i][0], keyvalue[i][1]);
++ }
++
++ strlst = avahi_string_list_new_from_array ((const char **) elements, count);
++
++cleanup:
++ while (--i >= 0)
++ free (elements[i]);
++
++ free (elements);
++ return (strlst);
++}
++
++
++/*
++ * 'avahi_entry_group_cb()' - Avahi entry group callback function.
++ */
++static void
++avahi_entry_group_cb (AvahiEntryGroup *group,
++ AvahiEntryGroupState state,
++ void *userdata)
++{
++ char *name;
++
++ if (userdata)
++ name = ((cupsd_printer_t *) userdata)->reg_name;
++ else
++ name = "CUPS web interface";
++
++ switch (state)
++ {
++ case AVAHI_ENTRY_GROUP_UNCOMMITED:
++ case AVAHI_ENTRY_GROUP_REGISTERING:
++ break;
++
++ case AVAHI_ENTRY_GROUP_ESTABLISHED:
++ cupsdLogMessage (CUPSD_LOG_DEBUG,
++ "Avahi entry group established for %s", name);
++ break;
++
++ default:
++ cupsdLogMessage (CUPSD_LOG_DEBUG,
++ "Avahi entry group %s has state %d",
++ name, state);
++ break;
++ }
++}
++
++
++/*
++ * 'avahi_client_cb()' - Avahi client callback function.
++ */
++static void
++avahi_client_cb (AvahiClient *client,
++ AvahiClientState state,
++ void *userdata)
++{
++ cupsd_printer_t *printer;
++ switch (state)
++ {
++ case AVAHI_CLIENT_S_RUNNING:
++ /*
++ * Avahi client started successfully.
++ */
++ AvahiCupsClient = client;
++ AvahiCupsClientConnecting = 0;
++ cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client started");
++
++ cupsdUpdateDNSSDName ();
++
++ for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
++ printer;
++ printer = (cupsd_printer_t *)cupsArrayNext(Printers))
++ if (Browsing && (BrowseLocalProtocols & BROWSE_DNSSD) &&
++ (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
++ CUPS_PRINTER_SCANNER))) && printer->shared)
++ dnssdRegisterPrinter (printer);
++
++ break;
++
++ case AVAHI_CLIENT_CONNECTING:
++ /*
++ * No Avahi daemon, client is waiting.
++ */
++ cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client connecting");
++ break;
++
++ case AVAHI_CLIENT_S_REGISTERING:
++ /*
++ * Not yet registered.
++ */
++ cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client registering");
++ break;
++
++ case AVAHI_CLIENT_FAILURE:
++ /*
++ * Avahi client failed, close it to allow a clean restart.
++ */
++ cupsdLogMessage (CUPSD_LOG_ERROR,
++ "Avahi client failed, "
++ "closing client to allow a clean restart");
++
++ for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
++ printer;
++ printer = (cupsd_printer_t *)cupsArrayNext(Printers))
++ dnssdDeregisterPrinter (printer);
++
++ avahi_client_free(client);
++ AvahiCupsClientConnecting = 0;
++ AvahiCupsClient = NULL;
++
++ break;
++
++ default:
++ cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client state: %d", state);
++ }
++}
++#endif /* HAVE_AVAHI */
++
++
+ /*
+ * 'get_auth_info_required()' - Get the auth-info-required value to advertise.
+ */
+diff -up cups-1.5.0/scheduler/dirsvc.h.avahi-5-services cups-1.5.0/scheduler/dirsvc.h
+--- cups-1.5.0/scheduler/dirsvc.h.avahi-5-services 2011-03-21 02:12:14.000000000 +0000
++++ cups-1.5.0/scheduler/dirsvc.h 2011-10-19 11:53:32.138177721 +0100
+@@ -31,6 +31,10 @@
+ # endif /* HAVE_LDAP_SSL_H */
+ #endif /* HAVE_LDAP */
+
++#ifdef HAVE_AVAHI
++# include <avahi-client/publish.h>
++#endif /* HAVE_AVAHI */
++
+ /*
+ * Browse protocols...
+ */
+@@ -131,19 +135,22 @@ VAR int PollPipe VALUE(0);
+ VAR cupsd_statbuf_t *PollStatusBuffer VALUE(NULL);
+ /* Status buffer for pollers */
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ VAR char *DNSSDComputerName VALUE(NULL),
+ /* Computer/server name */
+ *DNSSDHostName VALUE(NULL),
+ /* Hostname */
+ *DNSSDRegType VALUE(NULL);
+ /* Bonjour registration type */
+-VAR cups_array_t *DNSSDAlias VALUE(NULL);
+- /* List of dynamic ServerAlias's */
+ VAR int DNSSDPort VALUE(0);
+ /* Port number to register */
+ VAR cups_array_t *DNSSDPrinters VALUE(NULL);
+ /* Printers we have registered */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
++
++#ifdef HAVE_DNSSD
++VAR cups_array_t *DNSSDAlias VALUE(NULL);
++ /* List of dynamic ServerAlias's */
+ VAR DNSServiceRef DNSSDRef VALUE(NULL),
+ /* Master DNS-SD service reference */
+ WebIFRef VALUE(NULL),
+@@ -152,6 +159,17 @@ VAR DNSServiceRef DNSSDRef VALUE(NULL),
+ /* Remote printer browse reference */
+ #endif /* HAVE_DNSSD */
+
++#ifdef HAVE_AVAHI
++VAR AvahiCupsPoll *AvahiCupsPollHandle VALUE(NULL);
++ /* AvahiCupsPoll object */
++VAR AvahiClient *AvahiCupsClient VALUE(NULL);
++ /* AvahiClient object */
++VAR int AvahiCupsClientConnecting VALUE(0);
++ /* Is AvahiClient object connecting? */
++VAR AvahiEntryGroup *AvahiWebIFGroup VALUE(NULL);
++ /* Web interface entry group */
++#endif /* HAVE_AVAHI */
++
+ #ifdef HAVE_LIBSLP
+ VAR SLPHandle BrowseSLPHandle VALUE(NULL);
+ /* SLP API handle */
+@@ -195,13 +213,14 @@ extern void cupsdRegisterPrinter(cupsd_p
+ extern void cupsdRestartPolling(void);
+ extern void cupsdSaveRemoteCache(void);
+ extern void cupsdSendBrowseList(void);
++extern void cupsdStartAvahiClient(void);
+ extern void cupsdStartBrowsing(void);
+ extern void cupsdStartPolling(void);
+ extern void cupsdStopBrowsing(void);
+ extern void cupsdStopPolling(void);
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ extern void cupsdUpdateDNSSDName(void);
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+ #ifdef HAVE_LDAP
+ extern void cupsdUpdateLDAPBrowse(void);
+ #endif /* HAVE_LDAP */
+diff -up cups-1.5.0/scheduler/ipp.c.avahi-5-services cups-1.5.0/scheduler/ipp.c
+--- cups-1.5.0/scheduler/ipp.c.avahi-5-services 2011-10-19 11:53:31.978180686 +0100
++++ cups-1.5.0/scheduler/ipp.c 2011-10-19 11:53:32.147177555 +0100
+@@ -6096,7 +6096,7 @@ copy_printer_attrs(
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
+ ippTimeToDate(curtime));
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (!ra || cupsArrayFind(ra, "printer-dns-sd-name"))
+ {
+ if (printer->reg_name)
+@@ -6106,7 +6106,7 @@ copy_printer_attrs(
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
+ "printer-dns-sd-name", 0);
+ }
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ if (!ra || cupsArrayFind(ra, "printer-error-policy"))
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
+diff -up cups-1.5.0/scheduler/main.c.avahi-5-services cups-1.5.0/scheduler/main.c
+--- cups-1.5.0/scheduler/main.c.avahi-5-services 2011-10-19 11:53:32.101178406 +0100
++++ cups-1.5.0/scheduler/main.c 2011-10-19 11:53:32.151177479 +0100
+@@ -120,6 +120,10 @@ main(int argc, /* I - Number of comm
+ cupsd_listener_t *lis; /* Current listener */
+ time_t current_time, /* Current time */
+ activity, /* Client activity timer */
++#ifdef HAVE_AVAHI
++ avahi_client_time, /* Time for next Avahi client
++ check */
++#endif /* HAVE_AVAHI */
+ browse_time, /* Next browse send time */
+ senddoc_time, /* Send-Document time */
+ expire_time, /* Subscription expire time */
+@@ -672,6 +676,9 @@ main(int argc, /* I - Number of comm
+ */
+
+ current_time = time(NULL);
++#ifdef HAVE_AVAHI
++ avahi_client_time = current_time;
++#endif /* HAVE_AVAHI */
+ browse_time = current_time;
+ event_time = current_time;
+ expire_time = current_time;
+@@ -894,6 +901,16 @@ main(int argc, /* I - Number of comm
+ tmo = cupsdNextTimeout (&tmo_delay);
+ if (tmo && tmo_delay == 0)
+ cupsdRunTimeout (tmo);
++
++ /*
++ * Try to restart the Avahi client every 10 seconds if needed...
++ */
++
++ if ((current_time - avahi_client_time) >= 10)
++ {
++ avahi_client_time = current_time;
++ cupsdStartAvahiClient();
++ }
+ #endif /* HAVE_AVAHI */
+
+ #ifndef __APPLE__
+diff -up cups-1.5.0/scheduler/printers.c.avahi-5-services cups-1.5.0/scheduler/printers.c
+--- cups-1.5.0/scheduler/printers.c.avahi-5-services 2011-10-19 11:53:31.916181835 +0100
++++ cups-1.5.0/scheduler/printers.c 2011-10-19 11:53:32.156177388 +0100
+@@ -883,9 +883,9 @@ cupsdDeletePrinter(
+ cupsdClearString(&p->alert);
+ cupsdClearString(&p->alert_description);
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ cupsdClearString(&p->pdl);
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+
+ cupsArrayDelete(p->filetypes);
+
+@@ -3787,7 +3787,7 @@ add_printer_formats(cupsd_printer_t *p)
+ attr->values[i].string.text = _cupsStrAlloc(mimetype);
+ }
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ {
+ char pdl[1024]; /* Buffer to build pdl list */
+ mime_filter_t *filter; /* MIME filter looping var */
+@@ -3843,7 +3843,7 @@ add_printer_formats(cupsd_printer_t *p)
+
+ cupsdSetString(&p->pdl, pdl);
+ }
+-#endif /* HAVE_DNSSD */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
+ }
+
+
+diff -up cups-1.5.0/scheduler/printers.h.avahi-5-services cups-1.5.0/scheduler/printers.h
+--- cups-1.5.0/scheduler/printers.h.avahi-5-services 2011-03-18 18:42:46.000000000 +0000
++++ cups-1.5.0/scheduler/printers.h 2011-10-19 11:53:32.157177369 +0100
+@@ -16,6 +16,9 @@
+ #ifdef HAVE_DNSSD
+ # include <dns_sd.h>
+ #endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++# include "avahi.h"
++#endif /* HAVE_AVAHI */
+ #include <cups/pwg-private.h>
+
+
+@@ -95,16 +98,23 @@ struct cupsd_printer_s
+ time_t marker_time; /* Last time marker attributes were updated */
+ _ppd_cache_t *pc; /* PPD cache and mapping data */
+
+-#ifdef HAVE_DNSSD
++#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ char *reg_name, /* Name used for service registration */
+- *pdl, /* pdl value for TXT record */
+- *ipp_txt, /* IPP TXT record contents */
++ *pdl; /* pdl value for TXT record */
++#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
++#ifdef HAVE_DNSSD
++ char *ipp_txt, /* IPP TXT record contents */
+ *printer_txt; /* LPD TXT record contents */
+ int ipp_len, /* IPP TXT record length */
+ printer_len; /* LPD TXT record length */
+ DNSServiceRef ipp_ref, /* Reference for _ipp._tcp,_cups */
+ printer_ref; /* Reference for _printer._tcp */
+ #endif /* HAVE_DNSSD */
++#ifdef HAVE_AVAHI
++ AvahiStringList *ipp_txt, /* IPP TXT record */
++ *printer_txt; /* LPD TXT record */
++ AvahiEntryGroup *avahi_group; /* Avahi entry group */
++#endif /* HAVE_AVAHI */
+ };
+
+
diff --git a/cups-banners.patch b/cups-banners.patch
new file mode 100644
index 0000000..aa19282
--- /dev/null
+++ b/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/cups-build.patch b/cups-build.patch
new file mode 100644
index 0000000..c229a76
--- /dev/null
+++ b/cups-build.patch
@@ -0,0 +1,42 @@
+diff -up cups-1.5b1/Makedefs.in.build cups-1.5b1/Makedefs.in
+--- cups-1.5b1/Makedefs.in.build 2011-05-04 06:28:00.000000000 +0200
++++ cups-1.5b1/Makedefs.in 2011-05-24 15:54:03.000000000 +0200
+@@ -138,7 +138,7 @@ BACKLIBS = @BACKLIBS@
+ BANNERTOPS = @BANNERTOPS@
+ BUILDDIRS = @BUILDDIRS@
+ CFLAGS = @CPPFLAGS@ @CFLAGS@
+-COMMONLIBS = @LIBS@
++COMMONLIBS = @LIBS@ $(DNSSDLIBS)
+ CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@
+ CXXLIBS = @CXXLIBS@
+ DBUS_NOTIFIER = @DBUS_NOTIFIER@
+diff -up cups-1.5b1/scheduler/dirsvc.c.build cups-1.5b1/scheduler/dirsvc.c
+--- cups-1.5b1/scheduler/dirsvc.c.build 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/dirsvc.c 2011-05-24 15:55:26.000000000 +0200
+@@ -2047,7 +2047,7 @@ cupsdUpdateDNSSDName(void)
+
+ WebIFRef = DNSSDRef;
+ if ((error = DNSServiceRegister(&WebIFRef,
+- kDNSServiceFlagsShareConnection,
++ 0,
+ 0, webif, "_http._tcp", NULL,
+ NULL, htons(DNSSDPort), 7,
+ "\006path=/", dnssdRegisterCallback,
+@@ -2769,7 +2769,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
+ do
+ {
+ p->ipp_ref = DNSSDRef;
+- if ((se = DNSServiceRegister(&p->ipp_ref, kDNSServiceFlagsShareConnection,
++ if ((se = DNSServiceRegister(&p->ipp_ref, 0,
+ 0, name, regtype, NULL, NULL,
+ htons(DNSSDPort), ipp_len, ipp_txt,
+ dnssdRegisterCallback,
+@@ -2866,7 +2866,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
+
+ p->printer_ref = DNSSDRef;
+ if ((se = DNSServiceRegister(&p->printer_ref,
+- kDNSServiceFlagsShareConnection,
++ 0,
+ 0, name, "_printer._tcp", NULL, NULL,
+ htons(printer_port), printer_len, printer_txt,
+ dnssdRegisterCallback,
diff --git a/cups-cups-get-classes.patch b/cups-cups-get-classes.patch
new file mode 100644
index 0000000..c998852
--- /dev/null
+++ b/cups-cups-get-classes.patch
@@ -0,0 +1,89 @@
+diff -up cups-1.5.0/cups/dest.c.cups-get-classes cups-1.5.0/cups/dest.c
+--- cups-1.5.0/cups/dest.c.cups-get-classes 2011-05-20 04:49:49.000000000 +0100
++++ cups-1.5.0/cups/dest.c 2011-09-14 12:10:05.111635428 +0100
+@@ -534,6 +534,7 @@ _cupsGetDests(http_t *http, /* I -
+ char uri[1024]; /* printer-uri value */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
++ int get_classes; /* Whether we need to fetch class */
+ #ifdef __APPLE__
+ char media_default[41]; /* Default paper size */
+ #endif /* __APPLE__ */
+@@ -590,6 +591,8 @@ _cupsGetDests(http_t *http, /* I -
+ * printer-uri [for IPP_GET_PRINTER_ATTRIBUTES]
+ */
+
++ get_classes = (op == CUPS_GET_PRINTERS);
++
+ request = ippNewRequest(op);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+@@ -647,6 +650,23 @@ _cupsGetDests(http_t *http, /* I -
+ attr->value_tag != IPP_TAG_URI)
+ continue;
+
++ if (get_classes &&
++
++ /* Is this a class? */
++ ((attr->value_tag == IPP_TAG_ENUM &&
++ !strcmp(attr->name, "printer-type") &&
++ (attr->values[0].integer & CUPS_PRINTER_CLASS)) ||
++
++ /* Or, is this an attribute from CUPS 1.2 or later? */
++ !strcmp(attr->name, "auth-info-required") ||
++ !strncmp(attr->name, "marker-", 7) ||
++ !strcmp(attr->name, "printer-commands") ||
++ !strcmp(attr->name, "printer-is-shared")))
++ /* We are talking to a recent enough CUPS server that
++ * CUPS_GET_PRINTERS returns classes as well.
++ */
++ get_classes = 0;
++
+ if (!strcmp(attr->name, "auth-info-required") ||
+ !strcmp(attr->name, "device-uri") ||
+ !strcmp(attr->name, "marker-change-time") ||
+@@ -738,6 +758,28 @@ _cupsGetDests(http_t *http, /* I -
+ continue;
+ }
+
++ /*
++ * If we sent a CUPS_GET_CLASSES request, check whether
++ * CUPS_GET_PRINTERS already gave us this destination and exit
++ * early if so.
++ */
++
++ if (op == CUPS_GET_CLASSES && num_dests > 0)
++ {
++ int diff;
++ cups_find_dest (printer_name, NULL, num_dests, *dests, 0, &diff);
++ if (diff == 0)
++ {
++ /*
++ * Found it. The CUPS server already gave us the classes in
++ * its CUPS_GET_PRINTERS response.
++ */
++
++ cupsFreeOptions(num_options, options);
++ break;
++ }
++ }
++
+ if ((dest = cups_add_dest(printer_name, NULL, &num_dests, dests)) != NULL)
+ {
+ dest->num_options = num_options;
+@@ -754,6 +796,15 @@ _cupsGetDests(http_t *http, /* I -
+ }
+
+ /*
++ * If this is a CUPS_GET_PRINTERS request but we didn't see any
++ * classes we might be talking to an older CUPS server that requires
++ * CUPS_GET_CLASSES as well.
++ */
++
++ if (get_classes)
++ num_dests = _cupsGetDests (http, CUPS_GET_CLASSES, name, dests);
++
++ /*
+ * Return the count...
+ */
+
diff --git a/cups-direct-usb.patch b/cups-direct-usb.patch
new file mode 100644
index 0000000..4e25ce7
--- /dev/null
+++ b/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/cups-dnssd-deviceid.patch b/cups-dnssd-deviceid.patch
new file mode 100644
index 0000000..dedbcb2
--- /dev/null
+++ b/cups-dnssd-deviceid.patch
@@ -0,0 +1,38 @@
+diff -up cups-1.5b1/backend/dnssd.c.dnssd-deviceid cups-1.5b1/backend/dnssd.c
+--- cups-1.5b1/backend/dnssd.c.dnssd-deviceid 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/backend/dnssd.c 2011-05-24 17:28:18.000000000 +0200
+@@ -817,15 +817,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)
+ {
+ /*
+@@ -835,7 +842,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/cups-driverd-timeout.patch b/cups-driverd-timeout.patch
new file mode 100644
index 0000000..fac583b
--- /dev/null
+++ b/cups-driverd-timeout.patch
@@ -0,0 +1,33 @@
+diff -up cups-1.5.0/cups/http.c.driverd-timeout cups-1.5.0/cups/http.c
+--- cups-1.5.0/cups/http.c.driverd-timeout 2011-10-10 17:03:54.181458460 +0100
++++ cups-1.5.0/cups/http.c 2011-10-10 17:04:01.452321912 +0100
+@@ -1314,7 +1314,7 @@ httpGets(char *line, /* I - Line to
+ * No newline; see if there is more data to be read...
+ */
+
+- while (!_httpWait(http, http->blocking ? 30000 : 10000, 1))
++ while (!_httpWait(http, http->blocking ? 70000 : 10000, 1))
+ {
+ if (http->timeout_cb && (*http->timeout_cb)(http, http->timeout_data))
+ continue;
+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/cups-eggcups.patch b/cups-eggcups.patch
new file mode 100644
index 0000000..de413f9
--- /dev/null
+++ b/cups-eggcups.patch
@@ -0,0 +1,130 @@
+diff -up cups-1.5b1/backend/ipp.c.eggcups cups-1.5b1/backend/ipp.c
+--- cups-1.5b1/backend/ipp.c.eggcups 2011-05-21 06:02:41.000000000 +0200
++++ cups-1.5b1/backend/ipp.c 2011-05-23 18:07:45.000000000 +0200
+@@ -133,6 +133,70 @@ static cups_array_t *state_reasons; /* A
+ static char tmpfilename[1024] = "";
+ /* Temporary spool file name */
+
++#if HAVE_DBUS
++#include <dbus/dbus.h>
++
++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...
+@@ -1461,6 +1525,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 */
++
+ ippDelete(response);
+
+ if (job_canceled)
+diff -up cups-1.5b1/backend/Makefile.eggcups cups-1.5b1/backend/Makefile
+--- cups-1.5b1/backend/Makefile.eggcups 2011-05-04 06:28:00.000000000 +0200
++++ cups-1.5b1/backend/Makefile 2011-05-23 18:03:22.000000000 +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.5b1/scheduler/subscriptions.c.eggcups cups-1.5b1/scheduler/subscriptions.c
+--- cups-1.5b1/scheduler/subscriptions.c.eggcups 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/subscriptions.c 2011-05-23 18:03:22.000000000 +0200
+@@ -1310,13 +1310,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;
+
+@@ -1352,7 +1352,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/cups-filter-debug.patch b/cups-filter-debug.patch
new file mode 100644
index 0000000..2a42343
--- /dev/null
+++ b/cups-filter-debug.patch
@@ -0,0 +1,32 @@
+diff -up cups-1.5b1/scheduler/job.c.filter-debug cups-1.5b1/scheduler/job.c
+--- cups-1.5b1/scheduler/job.c.filter-debug 2011-05-24 15:58:07.000000000 +0200
++++ cups-1.5b1/scheduler/job.c 2011-05-24 15:58:07.000000000 +0200
+@@ -557,10 +557,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/cups-getpass.patch b/cups-getpass.patch
new file mode 100644
index 0000000..7b089a7
--- /dev/null
+++ b/cups-getpass.patch
@@ -0,0 +1,50 @@
+diff -up cups-1.5b1/cups/usersys.c.getpass cups-1.5b1/cups/usersys.c
+--- cups-1.5b1/cups/usersys.c.getpass 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/cups/usersys.c 2011-05-24 15:41:33.000000000 +0200
+@@ -43,6 +43,8 @@
+ #include "cups-private.h"
+ #include <stdlib.h>
+ #include <sys/stat.h>
++#include <termios.h>
++#include <signal.h>
+ #ifdef WIN32
+ # include <windows.h>
+ #else
+@@ -501,13 +503,31 @@ _cupsGetPassword(const char *prompt) /*
+ * empty password is treated as canceling the authentication request.
+ */
+
+- const char *password = getpass(prompt);
+- /* Password string */
+-
+- if (!password || !password[0])
+- return (NULL);
+- else
++ static char password[100];
++ struct termios oldtio, newtio;
++ sigset_t oldset, newset;
++ int nread;
++ sigprocmask (SIG_BLOCK, NULL, &newset);
++ sigaddset (&newset, SIGINT);
++ sigaddset (&newset, SIGTSTP);
++ sigprocmask (SIG_BLOCK, &newset, &oldset);
++ tcgetattr (STDIN_FILENO, &oldtio);
++ newtio = oldtio;
++ newtio.c_lflag &= ~ECHO;
++ tcsetattr (STDIN_FILENO, TCSAFLUSH, &newtio);
++ fputs (prompt, stdout);
++ fflush (stdout);
++ nread = read (STDIN_FILENO, password, sizeof (password));
++ tcsetattr (STDIN_FILENO, TCSAFLUSH, &oldtio);
++ fputc ('\n', stdout);
++ sigprocmask (SIG_SETMASK, &oldset, NULL);
++ if (nread > 0)
++ {
++ password[nread - 1] = '\0';
+ return (password);
++ }
++ else
++ return (NULL);
+ #endif /* WIN32 */
+ }
+
diff --git a/cups-hp-deviceid-oid.patch b/cups-hp-deviceid-oid.patch
new file mode 100644
index 0000000..da5136a
--- /dev/null
+++ b/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/cups-icc.patch b/cups-icc.patch
new file mode 100644
index 0000000..db4ae22
--- /dev/null
+++ b/cups-icc.patch
@@ -0,0 +1,1042 @@
+From db29c24e3ff75938775aa1f4072e346aeb7f6a9c Mon Sep 17 00:00:00 2001
+From: Richard Hughes <richard@hughsie.com>
+Date: Tue, 1 Mar 2011 16:05:48 +0000
+Subject: [PATCH] Add colord support to CUPS which allows Linux printers to be
+ color managed
+
+This functionality is possible because of lots of help from Tim Waugh -- thanks!
+---
+ scheduler/Makefile | 1 +
+ scheduler/colord.c | 784 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ scheduler/colord.h | 41 +++
+ scheduler/ipp.c | 18 +-
+ scheduler/printers.c | 69 +++++
+ scheduler/printers.h | 4 +
+ 6 files changed, 914 insertions(+), 3 deletions(-)
+ create mode 100644 scheduler/colord.c
+ create mode 100644 scheduler/colord.h
+
+diff --git a/scheduler/Makefile b/scheduler/Makefile
+index 3c7da8e..b9c47d3 100644
+--- a/scheduler/Makefile
++++ b/scheduler/Makefile
+@@ -27,6 +27,7 @@ CUPSDOBJS = \
+ file.o \
+ main.o \
+ ipp.o \
++ colord.o \
+ listen.o \
+ job.o \
+ log.o \
+diff --git a/scheduler/colord.c b/scheduler/colord.c
+new file mode 100644
+index 0000000..bd06e1c
+--- /dev/null
++++ b/scheduler/colord.c
+@@ -0,0 +1,784 @@
++/*
++ * "$Id$"
++ *
++ * colord integration for the CUPS scheduler.
++ *
++ * Copyright 2011 Red Hat, Inc.
++ *
++ * 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:
++ *
++ * colordRegisterPrinter() - Register profiles for a printer.
++ * colordUnregisterPrinter() - Unregister profiles for a printer.
++ * colordStart() - Get a connection to the system bus.
++ * colordStop() - Release any connection to the system bus
++ * so that added profiles and devices are
++ * automatically removed.
++ */
++
++/*
++ * Include necessary headers...
++ */
++
++#include "cupsd.h"
++
++#ifdef HAVE_DBUS
++
++#include <dbus/dbus.h>
++#include <cups/ppd-private.h>
++
++/*
++ * Defines used by colord. See the reference docs for further details:
++ * http://colord.hughsie.com/api/ref-dbus.html
++ */
++#define COLORD_SCOPE_NORMAL "normal" /* System scope */
++#define COLORD_SCOPE_TEMP "temp" /* Process scope */
++#define COLORD_SCOPE_DISK "disk" /* Lives forever, as stored in DB */
++
++#define COLORD_RELATION_SOFT "soft" /* Mapping is not default */
++#define COLORD_RELATION_HARD "hard" /* Explicitly mapped profile */
++
++#define COLORD_SPACE_RGB "rgb" /* RGB colorspace */
++#define COLORD_SPACE_CMYK "cmyk" /* CMYK colorspace */
++#define COLORD_SPACE_GRAY "gray" /* Gray colorspace */
++#define COLORD_SPACE_UNKNOWN "unknown" /* Unknown colorspace */
++
++#define COLORD_MODE_PHYSICAL "physical" /* Actual device */
++#define COLORD_MODE_VIRTUAL "virtual" /* Virtual device with no hardware */
++
++#define COLORD_KIND_PRINTER "printer" /* printing output device */
++
++/* the timeout for connecting to colord */
++#define COLORD_DBUS_TIMEOUT 5000 /* ms */
++
++/* This is static */
++static DBusConnection *con = NULL;
++
++/*
++ * 'colordStart()' - Get a connection to the system bus.
++ */
++
++void
++colordStart(void)
++{
++ if (con)
++ return;
++ con = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
++}
++
++/*
++ * 'colordStop()' - Release any connection to the system bus so that
++ * added profiles and devices are automatically removed.
++ */
++
++void
++colordStop(void)
++{
++ if (con == NULL)
++ return;
++ dbus_connection_unref(con);
++ con = NULL;
++}
++
++/*
++ * 'message_dict_add_strings()' - add two strings to a dictionary.
++ */
++
++static void
++message_dict_add_strings (DBusMessageIter *dict,
++ const char *key,
++ const char *value)
++{
++ DBusMessageIter entry;
++ dbus_message_iter_open_container(dict,
++ DBUS_TYPE_DICT_ENTRY,
++ NULL,
++ &entry);
++ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
++ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &value);
++ dbus_message_iter_close_container(dict, &entry);
++}
++
++/*
++ * 'colordCreateProfile()' - Create a color profile for a printer.
++ *
++ * Notes: When creating the device, we can create
++ */
++
++static void
++colordCreateProfile (cups_array_t *profiles, /* I - Profiles array */
++ const char *printer_name, /* I - Printer name */
++ const char *qualifier, /* I - Profile qualifier */
++ const char *colorspace, /* I - Profile colorspace */
++ const char **format, /* I - Profile qualifier format */
++ const char *iccfile, /* I - ICC filename */
++ const char *scope) /* I - The scope of the profile, e.g.
++ 'normal', 'temp' or 'disk' */
++{
++ DBusMessage *message = NULL; /* D-Bus request */
++ DBusMessage *reply = NULL; /* D-Bus reply */
++ DBusMessageIter args; /* D-Bus method arguments */
++ DBusMessageIter dict; /* D-Bus method arguments */
++ DBusError error; /* D-Bus error */
++ char *idstr; /* Profile ID string */
++ size_t idstrlen; /* Profile ID allocated length */
++ const char *profile_path; /* Device object path */
++ char format_str[1024]; /* Qualifier format as a string */
++
++ /*
++ * Create the profile...
++ */
++
++ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
++ "/org/freedesktop/ColorManager",
++ "org.freedesktop.ColorManager",
++ "CreateProfile");
++
++ /* create a profile id */
++ idstrlen = strlen (printer_name) + 1 + strlen (qualifier) + 1;
++ idstr = malloc (idstrlen);
++ if (!idstr)
++ goto out;
++ snprintf (idstr, idstrlen, "%s-%s", printer_name, qualifier);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Using profile id of %s",
++ idstr);
++
++ dbus_message_iter_init_append(message, &args);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &idstr);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope);
++
++ /* mush the qualifier format into a simple string */
++ snprintf(format_str, sizeof(format_str), "%s.%s.%s",
++ format[0],
++ format[1],
++ format[2]);
++
++ /* set initial properties */
++ dbus_message_iter_open_container(&args,
++ DBUS_TYPE_ARRAY,
++ "{ss}",
++ &dict);
++ message_dict_add_strings(&dict, "Qualifier", qualifier);
++ message_dict_add_strings(&dict, "Format", format_str);
++ message_dict_add_strings(&dict, "Colorspace", colorspace);
++ if (iccfile != NULL)
++ message_dict_add_strings(&dict, "Filename", iccfile);
++ dbus_message_iter_close_container(&args, &dict);
++
++ /* send syncronous */
++ dbus_error_init(&error);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateProfile(%s,%s)",
++ idstr, scope);
++ reply = dbus_connection_send_with_reply_and_block(con,
++ message,
++ COLORD_DBUS_TIMEOUT,
++ &error);
++ if (reply == NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "failed to CreateProfile: %s:%s",
++ error.name, error.message);
++ dbus_error_free(&error);
++ goto out;
++ }
++
++ /* get reply data */
++ dbus_message_iter_init(reply, &args);
++ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "incorrect reply type");
++ goto out;
++ }
++ dbus_message_iter_get_basic(&args, &profile_path);
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "created profile %s",
++ profile_path);
++ cupsArrayAdd(profiles, strdup(profile_path));
++
++out:
++ if (message != NULL)
++ dbus_message_unref(message);
++ if (reply != NULL)
++ dbus_message_unref(reply);
++ free (idstr);
++}
++
++/*
++ * 'colordDeviceAddProfile()' - Assign a profile to a device.
++ */
++
++static void
++colordDeviceAddProfile (const char *device_path, /* I - Device object path */
++ const char *profile_path, /* I - Profile object path */
++ const char *relation) /* I - Device relation, either 'soft' or 'hard' */
++{
++ DBusMessage *message = NULL; /* D-Bus request */
++ DBusMessage *reply = NULL; /* D-Bus reply */
++ DBusMessageIter args; /* D-Bus method arguments */
++ DBusError error; /* D-Bus error */
++
++ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
++ device_path,
++ "org.freedesktop.ColorManager.Device",
++ "AddProfile");
++
++ /* send profile path as the argument */
++ dbus_message_iter_init_append(message, &args);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &relation);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &profile_path);
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "Calling %s:AddProfile(%s) [%s]",
++ device_path, profile_path, relation);
++
++ /* send syncronous */
++ dbus_error_init(&error);
++ reply = dbus_connection_send_with_reply_and_block(con,
++ message,
++ COLORD_DBUS_TIMEOUT,
++ &error);
++ if (reply == NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "failed to AddProfile: %s:%s",
++ error.name, error.message);
++ dbus_error_free(&error);
++ goto out;
++ }
++out:
++ if (message != NULL)
++ dbus_message_unref(message);
++ if (reply != NULL)
++ dbus_message_unref(reply);
++}
++
++/*
++ * 'colordCreateDevice()' - Create a device and register profiles.
++ */
++
++static void
++colordCreateDevice (cupsd_printer_t *p, /* I - Printer */
++ ppd_file_t *ppd, /* I - PPD file */
++ cups_array_t *profiles, /* I - Profiles array */
++ const char *colorspace, /* I - Device colorspace, e.g. 'rgb' */
++ char **format, /* I - Device qualifier format */
++ const char *relation, /* I - Profile relation, either 'soft' or 'hard' */
++ const char *scope) /* I - The scope of the device, e.g.
++ 'normal', 'temp' or 'disk' */
++{
++ DBusMessage *message = NULL; /* D-Bus request */
++ DBusMessage *reply = NULL; /* D-Bus reply */
++ DBusMessageIter args; /* D-Bus method arguments */
++ DBusMessageIter dict; /* D-Bus method arguments */
++ DBusError error; /* D-Bus error */
++ const char *device_path; /* Device object path */
++ const char *profile_path; /* Profile path */
++ char *default_profile_path = NULL;
++ /* Default profile path */
++ char device_id[1024]; /* Device ID as understood by colord */
++ char format_str[1024]; /* Qualifier format as a string */
++
++ /*
++ * Create the device...
++ */
++
++ snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
++ device_path = device_id;
++
++ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
++ "/org/freedesktop/ColorManager",
++ "org.freedesktop.ColorManager",
++ "CreateDevice");
++
++ dbus_message_iter_init_append(message, &args);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_path);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope);
++
++ /* mush the qualifier format into a simple string */
++ snprintf(format_str, sizeof(format_str), "%s.%s.%s",
++ format[0],
++ format[1],
++ format[2]);
++
++ /* set initial properties */
++ dbus_message_iter_open_container(&args,
++ DBUS_TYPE_ARRAY,
++ "{ss}",
++ &dict);
++ message_dict_add_strings(&dict, "Colorspace", colorspace);
++ message_dict_add_strings(&dict, "Mode", COLORD_MODE_PHYSICAL);
++ if (ppd->manufacturer != NULL)
++ message_dict_add_strings(&dict, "Vendor", ppd->manufacturer);
++ if (ppd->modelname != NULL)
++ message_dict_add_strings(&dict, "Model", ppd->modelname);
++ if (p->sanitized_device_uri != NULL)
++ message_dict_add_strings(&dict, "Serial", p->sanitized_device_uri);
++ message_dict_add_strings(&dict, "Format", format_str);
++ message_dict_add_strings(&dict, "Kind", COLORD_KIND_PRINTER);
++ dbus_message_iter_close_container(&args, &dict);
++
++ /* send syncronous */
++ dbus_error_init(&error);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateDevice(%s,%s)",
++ device_id, scope);
++ reply = dbus_connection_send_with_reply_and_block(con,
++ message,
++ COLORD_DBUS_TIMEOUT,
++ &error);
++ if (reply == NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "failed to CreateDevice: %s:%s",
++ error.name, error.message);
++ dbus_error_free(&error);
++ goto out;
++ }
++
++ /* get reply data */
++ dbus_message_iter_init(reply, &args);
++ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "incorrect reply type");
++ goto out;
++ }
++ dbus_message_iter_get_basic(&args, &device_path);
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "created device %s",
++ device_path);
++
++ /* add profiles */
++ for (profile_path = cupsArrayFirst(profiles);
++ profile_path;
++ profile_path = cupsArrayNext(profiles))
++ {
++ colordDeviceAddProfile (device_path, profile_path, relation);
++ }
++
++out:
++ free(default_profile_path);
++ if (message != NULL)
++ dbus_message_unref(message);
++ if (reply != NULL)
++ dbus_message_unref(reply);
++}
++
++/*
++ * 'colordFindDeviceById()' - Finds a device
++ */
++
++static char *
++colordFindDeviceById (const char *device_id) /* I - Device ID string */
++{
++ DBusMessage *message = NULL; /* D-Bus request */
++ DBusMessage *reply = NULL; /* D-Bus reply */
++ DBusMessageIter args; /* D-Bus method arguments */
++ DBusError error; /* D-Bus error */
++ const char *device_path_tmp; /* Device object path */
++ char *device_path = NULL; /* Device object path */
++
++ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
++ "/org/freedesktop/ColorManager",
++ "org.freedesktop.ColorManager",
++ "FindDeviceById");
++
++ dbus_message_iter_init_append(message, &args);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id);
++
++ /* send syncronous */
++ dbus_error_init(&error);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling FindDeviceById(%s)", device_id);
++ reply = dbus_connection_send_with_reply_and_block(con,
++ message,
++ COLORD_DBUS_TIMEOUT,
++ &error);
++ if (reply == NULL)
++ {
++ /* this can happen normally on start-up */
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "failed to DeleteDevice: %s:%s",
++ error.name, error.message);
++ dbus_error_free(&error);
++ goto out;
++ }
++
++ /* get reply data */
++ dbus_message_iter_init(reply, &args);
++ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "incorrect reply type");
++ goto out;
++ }
++ dbus_message_iter_get_basic(&args, &device_path_tmp);
++ if (device_path_tmp != NULL)
++ device_path = strdup (device_path_tmp);
++out:
++ if (message != NULL)
++ dbus_message_unref(message);
++ if (reply != NULL)
++ dbus_message_unref(reply);
++ return device_path;
++}
++
++/*
++ * 'colordDeleteDevice()' - Delete a device
++ */
++
++static void
++colordDeleteDevice (const char *device_id) /* I - Device ID string */
++{
++ DBusMessage *message = NULL; /* D-Bus request */
++ DBusMessage *reply = NULL; /* D-Bus reply */
++ DBusMessageIter args; /* D-Bus method arguments */
++ DBusError error; /* D-Bus error */
++ char *device_path; /* Device object path */
++
++ /*
++ * Find the device...
++ */
++
++ device_path = colordFindDeviceById (device_id);
++ if (device_path == NULL)
++ {
++ /* this can happen normally on start-up */
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "failed to find device: %s",
++ device_id);
++ goto out;
++ }
++
++ /*
++ * Delete the device...
++ */
++
++ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
++ "/org/freedesktop/ColorManager",
++ "org.freedesktop.ColorManager",
++ "DeleteDevice");
++
++ dbus_message_iter_init_append(message, &args);
++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id);
++
++ /* send syncronous */
++ dbus_error_init(&error);
++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling DeleteDevice(%s)", device_id);
++ reply = dbus_connection_send_with_reply_and_block(con,
++ message,
++ COLORD_DBUS_TIMEOUT,
++ &error);
++ if (reply == NULL)
++ {
++ /* this can happen normally on start-up */
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "failed to DeleteDevice: %s:%s",
++ error.name, error.message);
++ dbus_error_free(&error);
++ goto out;
++ }
++out:
++ free (device_path);
++ if (message != NULL)
++ dbus_message_unref(message);
++ if (reply != NULL)
++ dbus_message_unref(reply);
++}
++
++/*
++ * 'colordGetQualifierFormat()' - Get the qualifier format.
++ *
++ * Notes: Returns a value of "ColorSpace.MediaType.Resolution" by default
++ */
++
++char **
++colordGetQualifierFormat(ppd_file_t *ppd)
++{
++ char **format; /* Qualifier format tuple */
++ const char *tmp; /* Temporary string */
++ ppd_attr_t *attr; /* Profile attributes */
++
++ /* create 3-tuple */
++ format = calloc(3, sizeof(char*));
++
++ /* get 1st section */
++ tmp = "cupsICCQualifier1";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ if (attr != NULL)
++ tmp = attr->value;
++ else
++ {
++ tmp = "DefaultColorSpace";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ }
++ if (attr == NULL)
++ {
++ tmp = "DefaultColorModel";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ }
++ if (attr == NULL)
++ {
++ tmp = "";
++ }
++ if (strncmp(tmp, "Default", 7) == 0)
++ tmp += 7;
++ format[0] = strdup(tmp);
++
++ /* get 2nd section */
++ tmp = "cupsICCQualifier2";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ if (attr != NULL)
++ tmp = attr->value;
++ else
++ {
++ tmp = "DefaultMediaType";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ }
++ if (attr == NULL)
++ {
++ tmp = "";
++ }
++ if (strncmp(tmp, "Default", 7) == 0)
++ tmp += 7;
++ format[1] = strdup(tmp);
++
++ /* get 3rd section */
++ tmp = "cupsICCQualifier3";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ if (attr != NULL)
++ tmp = attr->value;
++ else
++ {
++ tmp = "DefaultResolution";
++ attr = ppdFindAttr(ppd, tmp, NULL);
++ }
++ if (attr == NULL)
++ {
++ tmp = "";
++ }
++ if (strncmp(tmp, "Default", 7) == 0)
++ tmp += 7;
++ format[2] = strdup(tmp);
++
++ return format;
++}
++
++/*
++ * 'colordRegisterPrinter()' - Register profiles for a printer.
++ */
++
++void
++colordRegisterPrinter(cupsd_printer_t *p) /* I - printer */
++{
++ char ppdfile[1024], /* PPD filename */
++ iccfile[1024]; /* ICC filename */
++ ppd_file_t *ppd; /* PPD file */
++ cups_array_t *profiles; /* Profile paths array */
++ const char *profile_key; /* Profile keyword */
++ ppd_attr_t *attr; /* Profile attributes */
++ const char *device_colorspace; /* Device colorspace */
++ char **format; /* Qualifier format tuple */
++ int i; /* Loop counter */
++
++ /*
++ * Do nothing for discovered printers as they will have local color
++ * correction
++ */
++
++ if (p->type & CUPS_PRINTER_DISCOVERED)
++ return;
++
++ /*
++ * Ensure we have a DBus connection
++ */
++
++ colordStart();
++ if (con == NULL)
++ return;
++
++ /*
++ * Try opening the PPD file for this printer...
++ */
++
++ snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
++ if ((ppd = ppdOpenFile(ppdfile)) == NULL)
++ {
++ cupsdLogMessage(CUPSD_LOG_DEBUG,
++ "cannot open %s",
++ ppdfile);
++ return;
++ }
++
++ /*
++ * Find out the qualifier format
++ */
++
++ format = colordGetQualifierFormat(ppd);
++
++ /*
++ * See if we have any embedded profiles...
++ */
++
++ profiles = cupsArrayNew3 (NULL, NULL, NULL, 0, NULL,
++ (cups_afree_func_t) free);
++ profile_key = "cupsICCProfile";
++ attr = ppdFindAttr(ppd, profile_key, NULL);
++ for (; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL))
++ if (attr->spec[0] && attr->value && attr->value[0])
++ {
++ if (attr->value[0] != '/')
++ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
++ attr->value);
++ else
++ strlcpy(iccfile, attr->value, sizeof(iccfile));
++
++ if (access(iccfile, 0))
++ {
++ cupsdLogMessage(CUPSD_LOG_WARN,
++ "no access to %s",
++ iccfile);
++ continue;
++ }
++
++ colordCreateProfile(profiles,
++ p->name,
++ attr->spec,
++ COLORD_SPACE_UNKNOWN,
++ (const char **)format,
++ iccfile,
++ COLORD_SCOPE_TEMP);
++ }
++
++ /*
++ * Add the grayscale profile first. We always have a grayscale profile.
++ */
++
++ colordCreateProfile(profiles,
++ p->name,
++ "Gray..",
++ COLORD_SPACE_GRAY,
++ (const char **)format,
++ NULL,
++ COLORD_SCOPE_TEMP);
++
++ /*
++ * Then add the RGB/CMYK/DeviceN color profile...
++ */
++
++ device_colorspace = "unknown";
++ switch (ppd->colorspace)
++ {
++ case PPD_CS_RGB :
++ case PPD_CS_CMY :
++ device_colorspace = COLORD_SPACE_RGB;
++ colordCreateProfile(profiles,
++ p->name,
++ "RGB..",
++ COLORD_SPACE_RGB,
++ (const char **)format,
++ NULL,
++ COLORD_SCOPE_TEMP);
++ break;
++ case PPD_CS_RGBK :
++ case PPD_CS_CMYK :
++ device_colorspace = COLORD_SPACE_CMYK;
++ colordCreateProfile(profiles,
++ p->name,
++ "CMYK..",
++ COLORD_SPACE_CMYK,
++ (const char **)format,
++ NULL,
++ COLORD_SCOPE_TEMP);
++ break;
++ case PPD_CS_GRAY :
++ device_colorspace = COLORD_SPACE_GRAY;
++ break;
++ case PPD_CS_N :
++ colordCreateProfile(profiles,
++ p->name,
++ "DeviceN..",
++ COLORD_SPACE_UNKNOWN,
++ (const char **)format,
++ NULL,
++ COLORD_SCOPE_TEMP);
++ break;
++ }
++
++ /*
++ * Register the device with colord.
++ */
++
++ cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"",
++ p->name);
++ colordCreateDevice (p,
++ ppd,
++ profiles,
++ device_colorspace,
++ format,
++ COLORD_RELATION_SOFT,
++ COLORD_SCOPE_TEMP);
++
++ /*
++ * Free any memory we used...
++ */
++
++ cupsArrayDelete(profiles);
++ for (i=0; i<3; i++)
++ free(format[i]);
++ free(format);
++
++ ppdClose(ppd);
++}
++
++/*
++ * 'colordUnregisterPrinter()' - Unregister profiles for a printer.
++ */
++
++void
++colordUnregisterPrinter(cupsd_printer_t *p) /* I - printer */
++{
++ char device_id[1024]; /* Device ID as understood by colord */
++
++ /*
++ * Ensure we have a DBus connection
++ */
++
++ colordStart();
++ if (con == NULL)
++ return;
++
++ /*
++ * Just delete the device itself, and leave the profiles registered
++ */
++
++ snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
++ colordDeleteDevice(device_id);
++}
++
++#endif /* HAVE_DBUS */
++
++/*
++ * End of "$Id$".
++ */
+diff --git a/scheduler/colord.h b/scheduler/colord.h
+new file mode 100644
+index 0000000..75bdd3b
+--- /dev/null
++++ b/scheduler/colord.h
+@@ -0,0 +1,41 @@
++/*
++ * "$Id$"
++ *
++ * colord integration for the CUPS scheduler.
++ *
++ * Copyright 2011 Red Hat, Inc.
++ *
++ * 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.
++ *
++ */
++
++void colordRegisterPrinter(cupsd_printer_t *p);
++void colordUnregisterPrinter(cupsd_printer_t *p);
++void colordStart(void);
++void colordStop(void);
++
++/*
++ * End of "$Id$".
++ */
+diff --git a/scheduler/ipp.c b/scheduler/ipp.c
+index b9903d1..b5af36f 100644
+--- a/scheduler/ipp.c
++++ b/scheduler/ipp.c
+@@ -2921,17 +2921,23 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
+
+ cupsdSetPrinterReasons(printer, "none");
+
+-#ifdef __APPLE__
+ /*
+ * (Re)register color profiles...
+ */
+
+ if (!RunUser)
+ {
++ cupsdCmsRegisterPrinter(printer);
++#ifdef __APPLE__
++ /*
++ * FIXME: ideally the ColorSync stuff would be moved to colorsync.c
++ * and the colorsyncRegisterProfiles() would be called from
++ * cupsdCmsRegisterPrinter() in printers.c
++ */
+ apple_unregister_profiles(printer);
+ apple_register_profiles(printer);
+- }
+ #endif /* __APPLE__ */
++ }
+ }
+
+ /*
+@@ -7028,11 +7034,17 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */
+ snprintf(filename, sizeof(filename), "%s/%s.data", CacheDir, printer->name);
+ unlink(filename);
+
+-#ifdef __APPLE__
+ /*
+ * Unregister color profiles...
+ */
+
++ cupsdCmsUnregisterPrinter(printer);
++#ifdef __APPLE__
++ /*
++ * FIXME: ideally the ColorSync stuff would be moved to colorsync.c
++ * and the colorsyncUnregisterPrinter() would be called from
++ * cupsdCmsUnregisterPrinter() in printers.c
++ */
+ apple_unregister_profiles(printer);
+ #endif /* __APPLE__ */
+
+diff --git a/scheduler/printers.c b/scheduler/printers.c
+index 6920801..e830499 100644
+--- a/scheduler/printers.c
++++ b/scheduler/printers.c
+@@ -80,6 +80,9 @@
+ # include <asl.h>
+ #endif /* __APPLE__ */
+
++#ifdef HAVE_DBUS
++# include "colord.h"
++#endif /* HAVE_DBUS */
+
+ /*
+ * Local functions...
+@@ -712,6 +715,53 @@ cupsdDeleteAllPrinters(void)
+ }
+ }
+
++/*
++ * 'cupsdCmsRegisterPrinter()' - Registers a printer and profiles with the CMS
++ */
++
++void
++cupsdCmsRegisterPrinter(cupsd_printer_t *p)
++{
++#if defined(HAVE_DBUS)
++ colordRegisterPrinter(p);
++#endif /* defined(HAVE_DBUS) */
++}
++
++/*
++ * 'cupsdCmsUnregisterPrinter()' - Unregisters a printer and profiles with the CMS
++ */
++
++void
++cupsdCmsUnregisterPrinter(cupsd_printer_t *p)
++{
++#if defined(HAVE_DBUS)
++ colordUnregisterPrinter(p);
++#endif /* defined(HAVE_DBUS) */
++}
++
++/*
++ * 'cupsdCmsStart()' - Starts the CMS
++ */
++
++void
++cupsdCmsStart(void)
++{
++#if defined(HAVE_DBUS)
++ colordStart();
++#endif /* defined(HAVE_DBUS) */
++}
++
++/*
++ * 'cupsdCmsStop()' - Stops the CMS
++ */
++
++void
++cupsdCmsStop(void)
++{
++#if defined(HAVE_DBUS)
++ colordStop();
++#endif /* defined(HAVE_DBUS) */
++}
+
+ /*
+ * 'cupsdDeletePrinter()' - Delete a printer from the system.
+@@ -752,6 +802,12 @@ cupsdDeletePrinter(
+ "Job stopped.");
+
+ /*
++ * Unregister profiles...
++ */
++
++ cupsdCmsUnregisterPrinter(p);
++
++ /*
+ * If this printer is the next for browsing, point to the next one...
+ */
+
+@@ -1418,6 +1474,12 @@ cupsdRenamePrinter(
+ }
+
+ /*
++ * Unregister profiles...
++ */
++
++ cupsdCmsUnregisterPrinter(p);
++
++ /*
+ * Rename the printer...
+ */
+
+@@ -2644,6 +2706,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
+ #endif /* __sgi */
+
+ /*
++ * Re-register profiles...
++ */
++
++ cupsdCmsUnregisterPrinter(p);
++ cupsdCmsRegisterPrinter(p);
++
++ /*
+ * Let the browse protocols reflect the change
+ */
+
+diff --git a/scheduler/printers.h b/scheduler/printers.h
+index 1751578..3820428 100644
+--- a/scheduler/printers.h
++++ b/scheduler/printers.h
+@@ -170,6 +170,10 @@ extern const char *cupsdValidateDest(const char *uri,
+ cups_ptype_t *dtype,
+ cupsd_printer_t **printer);
+ extern void cupsdWritePrintcap(void);
++extern void cupsdCmsRegisterPrinter(cupsd_printer_t *p);
++extern void cupsdCmsUnregisterPrinter(cupsd_printer_t *p);
++extern void cupsdCmsStart(void);
++extern void cupsdCmsStop(void);
+
+
+ /*
+--
+1.7.6.2
+
diff --git a/cups-logrotate.patch b/cups-logrotate.patch
new file mode 100644
index 0000000..a6485a9
--- /dev/null
+++ b/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 <stdarg.h>
+ #include <syslog.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
+
+
+ /*
+@@ -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/cups-lpd b/cups-lpd
new file mode 100644
index 0000000..2d9e197
--- /dev/null
+++ b/cups-lpd
@@ -0,0 +1,11 @@
+# default: off
+# description: Allow applications using the legacy lpd protocol to communicate with CUPS
+service printer
+{
+ disable = yes
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+}
diff --git a/cups-lpr-help.patch b/cups-lpr-help.patch
new file mode 100644
index 0000000..c42434d
--- /dev/null
+++ b/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 <cups/cups-private.h>
+
+
++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/cups-lspp.patch b/cups-lspp.patch
new file mode 100644
index 0000000..ab534f6
--- /dev/null
+++ b/cups-lspp.patch
@@ -0,0 +1,2811 @@
+diff -up cups-1.5b2/config.h.in.lspp cups-1.5b2/config.h.in
+--- cups-1.5b2/config.h.in.lspp 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b2/config.h.in 2011-05-31 18:29:01.357890200 +0200
+@@ -733,6 +733,12 @@
+
+ #undef HAVE_XPC
+
++/*
++ * Are we trying to meet LSPP requirements?
++ */
++
++#undef WITH_LSPP
++
+
+ #endif /* !_CUPS_CONFIG_H_ */
+
+diff -up cups-1.5b2/config-scripts/cups-lspp.m4.lspp cups-1.5b2/config-scripts/cups-lspp.m4
+--- cups-1.5b2/config-scripts/cups-lspp.m4.lspp 2011-05-31 18:29:01.357890200 +0200
++++ cups-1.5b2/config-scripts/cups-lspp.m4 2011-05-31 18:29:01.357890200 +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.5b2/configure.in.lspp cups-1.5b2/configure.in
+--- cups-1.5b2/configure.in.lspp 2010-11-20 02:03:46.000000000 +0100
++++ cups-1.5b2/configure.in 2011-05-31 18:29:01.357890200 +0200
+@@ -41,6 +41,8 @@ sinclude(config-scripts/cups-defaults.m4
+ sinclude(config-scripts/cups-pdf.m4)
+ sinclude(config-scripts/cups-scripting.m4)
+
++sinclude(config-scripts/cups-lspp.m4)
++
+ INSTALL_LANGUAGES=""
+ UNINSTALL_LANGUAGES=""
+ LANGFILES=""
+diff -up cups-1.5b2/data/Makefile.lspp cups-1.5b2/data/Makefile
+--- cups-1.5b2/data/Makefile.lspp 2011-05-12 07:21:56.000000000 +0200
++++ cups-1.5b2/data/Makefile 2011-05-31 18:29:01.358890188 +0200
+@@ -25,7 +25,11 @@ BANNERS = \
+ secret \
+ standard \
+ topsecret \
+- unclassified
++ unclassified \
++ selinux \
++ mls \
++ te
++
+
+ CHARSETS = \
+ utf-8
+diff -up cups-1.5b2/data/mls.lspp cups-1.5b2/data/mls
+--- cups-1.5b2/data/mls.lspp 2011-05-31 18:29:01.358890188 +0200
++++ cups-1.5b2/data/mls 2011-05-31 18:29:01.358890188 +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.5b2/data/selinux.lspp cups-1.5b2/data/selinux
+--- cups-1.5b2/data/selinux.lspp 2011-05-31 18:29:01.359890176 +0200
++++ cups-1.5b2/data/selinux 2011-05-31 18:29:01.359890176 +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.5b2/data/te.lspp cups-1.5b2/data/te
+--- cups-1.5b2/data/te.lspp 2011-05-31 18:29:01.359890176 +0200
++++ cups-1.5b2/data/te 2011-05-31 18:29:01.359890176 +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.5b2/filter/common.c.lspp cups-1.5b2/filter/common.c
+--- cups-1.5b2/filter/common.c.lspp 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b2/filter/common.c 2011-05-31 18:29:01.360890163 +0200
+@@ -30,6 +30,12 @@
+ * Include necessary headers...
+ */
+
++#include "config.h"
++#ifdef WITH_LSPP
++#define _GNU_SOURCE
++#include <string.h>
++#endif /* WITH_LSPP */
++
+ #include "common.h"
+ #include <locale.h>
+
+@@ -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.5b2/filter/pstops.c.lspp cups-1.5b2/filter/pstops.c
+--- cups-1.5b2/filter/pstops.c.lspp 2011-05-20 08:52:23.000000000 +0200
++++ cups-1.5b2/filter/pstops.c 2011-05-31 18:29:01.362890137 +0200
+@@ -3258,6 +3258,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 */
+
+
+ /*
+@@ -3280,6 +3292,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...
+ */
+@@ -3358,7 +3488,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.5b2/Makedefs.in.lspp cups-1.5b2/Makedefs.in
+--- cups-1.5b2/Makedefs.in.lspp 2011-05-31 18:29:01.295890975 +0200
++++ cups-1.5b2/Makedefs.in 2011-05-31 18:29:01.362890137 +0200
+@@ -157,7 +157,7 @@ LDFLAGS = -L../cgi-bin -L../cups -L../f
+ LEGACY_BACKENDS = @LEGACY_BACKENDS@
+ 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.5b2/scheduler/client.c.lspp cups-1.5b2/scheduler/client.c
+--- cups-1.5b2/scheduler/client.c.lspp 2011-05-31 18:29:01.327890576 +0200
++++ cups-1.5b2/scheduler/client.c 2011-05-31 18:29:01.364890113 +0200
+@@ -44,6 +44,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.
+ */
+
+ /*
+@@ -52,10 +53,17 @@
+
+ #include "cupsd.h"
+
++#define _GNU_SOURCE
+ #ifdef HAVE_TCPD_H
+ # include <tcpd.h>
+ #endif /* HAVE_TCPD_H */
+
++#ifdef WITH_LSPP
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#include <fcntl.h>
++#endif /* WITH_LSPP */
++
+
+ /*
+ * Local functions...
+@@ -352,6 +360,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, "cupsdAcceptClient: %d from %s (Domain)",
+@@ -712,6 +771,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;
+@@ -2138,6 +2204,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)
+@@ -4548,6 +4675,50 @@ make_certificate(cupsd_client_t *con) /*
+ #endif /* HAVE_SSL */
+
+
++#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.5b2/scheduler/client.h.lspp cups-1.5b2/scheduler/client.h
+--- cups-1.5b2/scheduler/client.h.lspp 2011-03-25 22:25:38.000000000 +0100
++++ cups-1.5b2/scheduler/client.h 2011-05-31 18:29:01.365890101 +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 <selinux/selinux.h>
++#endif /* WITH_LSPP */
++
+ /*
+ * HTTP client structure...
+ */
+@@ -61,6 +68,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)
+@@ -130,6 +141,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 */
+
+
+ /*
+diff -up cups-1.5b2/scheduler/conf.c.lspp cups-1.5b2/scheduler/conf.c
+--- cups-1.5b2/scheduler/conf.c.lspp 2011-05-31 18:29:01.212892013 +0200
++++ cups-1.5b2/scheduler/conf.c 2011-05-31 18:29:01.366890088 +0200
+@@ -31,6 +31,7 @@
+ * read_location() - Read a <Location path> definition.
+ * read_policy() - Read a <Policy name> definition.
+ * set_policy_defaults() - Set default policy values as needed.
++ * is_lspp_config() - Is the system configured for LSPP
+ */
+
+ /*
+@@ -56,6 +57,9 @@
+ # define INADDR_NONE 0xffffffff
+ #endif /* !INADDR_NONE */
+
++#ifdef WITH_LSPP
++# include <libaudit.h>
++#endif /* WITH_LSPP */
+
+ /*
+ * Configuration variable structure...
+@@ -173,6 +177,10 @@ static const cupsd_var_t variables[] =
+ # if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
+ { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME },
+ # endif /* HAVE_LIBSSL || HAVE_GNUTLS */
++#ifdef WITH_LSPP
++ { "AuditLog", &AuditLog, CUPSD_VARTYPE_INTEGER },
++ { "PerPageLabels", &PerPageLabels, CUPSD_VARTYPE_BOOLEAN },
++#endif /* WITH_LSPP */
+ #endif /* HAVE_SSL */
+ { "ServerName", &ServerName, CUPSD_VARTYPE_STRING },
+ { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME },
+@@ -434,6 +442,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 */
+
+
+ /*
+@@ -722,6 +733,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");
+
+@@ -1107,7 +1137,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...
+@@ -3765,6 +3807,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 <Policy name> definition.
+diff -up cups-1.5b2/scheduler/conf.h.lspp cups-1.5b2/scheduler/conf.h
+--- cups-1.5b2/scheduler/conf.h.lspp 2011-05-31 18:29:01.213892000 +0200
++++ cups-1.5b2/scheduler/conf.h 2011-05-31 18:29:01.380889905 +0200
+@@ -250,6 +250,12 @@ VAR char *ServerKey VALUE(NULL);
+ VAR int SSLOptions VALUE(CUPSD_SSL_NONE);
+ /* 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(DEFAULT_KEEPALIVE);
+@@ -261,6 +267,9 @@ VAR char *SystemGroupAuthKey VALUE(NULL
+ /* System group auth key */
+ #endif /* HAVE_AUTHORIZATION_H */
+
++#ifdef WITH_LSPP
++extern int is_lspp_config(void);
++#endif /* WITH_LSPP */
+
+ /*
+ * Prototypes...
+diff -up cups-1.5b2/scheduler/cupsd.h.lspp cups-1.5b2/scheduler/cupsd.h
+--- cups-1.5b2/scheduler/cupsd.h.lspp 2011-05-12 00:17:34.000000000 +0200
++++ cups-1.5b2/scheduler/cupsd.h 2011-05-31 18:29:01.381889893 +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 <unistd.h>
+ #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 <CoreFoundation/CoreFoundation.h>
+ #endif /* HAVE_CDSASSL */
+
+-
+ /*
+ * Some OS's don't have hstrerror(), most notably Solaris...
+ */
+diff -up cups-1.5b2/scheduler/ipp.c.lspp cups-1.5b2/scheduler/ipp.c
+--- cups-1.5b2/scheduler/ipp.c.lspp 2011-05-31 18:29:01.317890700 +0200
++++ cups-1.5b2/scheduler/ipp.c 2011-05-31 18:29:01.385889845 +0200
+@@ -41,6 +41,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.
+@@ -106,6 +107,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...
+ */
+@@ -131,6 +135,14 @@ extern int mbr_check_membership_by_id(uu
+ # endif /* HAVE_MEMBERSHIPPRIV_H */
+ #endif /* __APPLE__ */
+
++#ifdef WITH_LSPP
++#include <libaudit.h>
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#include <selinux/avc.h>
++#include <selinux/flask.h>
++#include <selinux/av_permissions.h>
++#endif /* WITH_LSPP */
+
+ /*
+ * Local functions...
+@@ -168,6 +180,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 ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
+ int quickcopy);
+@@ -1365,6 +1380,21 @@ add_job(cupsd_client_t *con, /* I - Cl
+ ipp_attribute_t *media_col, /* media-col attribute */
+ *media_margin; /* media-*-margin attribute */
+ ipp_t *unsup_col; /* media-col in unsupported response */
++#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))",
+@@ -1622,6 +1652,106 @@ add_job(cupsd_client_t *con, /* I - Cl
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+ "Untitled");
+
++#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,
+@@ -1630,6 +1760,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_IMPLICIT |
+ CUPS_PRINTER_REMOTE);
+ job->attrs = con->request;
+@@ -1835,6 +1991,29 @@ add_job(cupsd_client_t *con, /* I - Cl
+ attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
+ attr->values[1].string.text = _cupsStrRetain(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;
+
+@@ -1865,6 +2044,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,
+@@ -1883,6 +2065,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") &&
+@@ -1903,6 +2088,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) &&
+@@ -1943,8 +2131,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...
+@@ -4709,6 +4941,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.
+ */
+@@ -5346,6 +5683,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,
+@@ -5381,6 +5727,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...
+@@ -5475,6 +5897,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);
+@@ -7472,6 +7912,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...
+ */
+@@ -7825,6 +8281,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);
+
+@@ -12264,6 +12725,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.5b2/scheduler/job.c.lspp cups-1.5b2/scheduler/job.c
+--- cups-1.5b2/scheduler/job.c.lspp 2011-05-31 18:29:01.285891101 +0200
++++ cups-1.5b2/scheduler/job.c 2011-05-31 18:29:01.390889785 +0200
+@@ -64,6 +64,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...
+ */
+@@ -79,6 +82,14 @@
+ # endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
+ #endif /* __APPLE__ */
+
++#ifdef WITH_LSPP
++#include <libaudit.h>
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#include <selinux/avc.h>
++#include <selinux/flask.h>
++#include <selinux/av_permissions.h>
++#endif /* WITH_LSPP */
+
+ /*
+ * Design Notes for Job Management
+@@ -518,6 +529,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,
+@@ -1000,6 +1019,67 @@ cupsdContinueJob(cupsd_job_t *job) /* I
+ }
+ }
+
++#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",
+@@ -1716,6 +1796,20 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
+ goto error;
+ }
+
++#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);
+@@ -2104,6 +2198,14 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J
+ char filename[1024], /* Job control filename */
+ newfile[1024]; /* New 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",
+@@ -2123,6 +2225,76 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J
+ fchmod(cupsFileNumber(fp), 0600);
+ 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,
+@@ -3509,6 +3681,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...
+ */
+@@ -4143,6 +4327,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);
+
+@@ -4272,6 +4469,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.5b2/scheduler/job.h.lspp cups-1.5b2/scheduler/job.h
+--- cups-1.5b2/scheduler/job.h.lspp 2011-05-18 04:27:11.000000000 +0200
++++ cups-1.5b2/scheduler/job.h 2011-05-31 18:29:01.393889749 +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 <selinux/selinux.h>
++#endif /* WITH_LSPP */
++
+ /*
+ * Constants...
+ */
+@@ -76,6 +83,10 @@ struct cupsd_job_s /**** Job request *
+ void *profile; /* Security profile */
+ cups_array_t *history; /* Debug log history */
+ int progress; /* Printing progress */
++#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.5b2/scheduler/main.c.lspp cups-1.5b2/scheduler/main.c
+--- cups-1.5b2/scheduler/main.c.lspp 2011-05-31 18:29:01.251891525 +0200
++++ cups-1.5b2/scheduler/main.c 2011-05-31 18:29:01.394889737 +0200
+@@ -36,6 +36,8 @@
+ * usage() - Show scheduler usage.
+ */
+
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+ * Include necessary headers...
+ */
+@@ -69,6 +71,9 @@
+ # include <notify.h>
+ #endif /* HAVE_NOTIFY_H */
+
++#ifdef WITH_LSPP
++# include <libaudit.h>
++#endif /* WITH_LSPP */
+
+ /*
+ * Local functions...
+@@ -130,6 +135,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 */
+@@ -455,6 +463,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...
+ */
+@@ -1182,6 +1209,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.5b2/scheduler/printers.c.lspp cups-1.5b2/scheduler/printers.c
+--- cups-1.5b2/scheduler/printers.c.lspp 2011-05-31 18:29:01.321890651 +0200
++++ cups-1.5b2/scheduler/printers.c 2011-05-31 18:30:03.264116265 +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...
+ */
+@@ -81,6 +83,11 @@
+ # include "colord.h"
+ #endif /* HAVE_DBUS */
+
++#ifdef WITH_LSPP
++# include <libaudit.h>
++# include <selinux/context.h>
++#endif /* WITH_LSPP */
++
+ /*
+ * Local functions...
+ */
+@@ -2195,6 +2202,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
+ "username",
+ "password"
+ };
++#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,
+@@ -2332,6 +2346,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;
+@@ -5463,7 +5516,6 @@ write_irix_state(cupsd_printer_t *p) /*
+ }
+ #endif /* __sgi */
+
+-
+ /*
+ * 'write_xml_string()' - Write a string with XML escaping.
+ */
diff --git a/cups-multilib.patch b/cups-multilib.patch
new file mode 100644
index 0000000..3c6bc39
--- /dev/null
+++ b/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 gnutls's pkg-config script. This is a bit
++# of a cheat, but the cups-devel package requires gnutls-devel anyway.
++libdir=`pkg-config --variable=libdir gnutls`
++imagelibdir=`pkg-config --variable=libdir gnutls`
+ datarootdir=@datadir@
+ datadir=@datadir@
+ sysconfdir=@sysconfdir@
diff --git a/cups-no-export-ssllibs.patch b/cups-no-export-ssllibs.patch
new file mode 100644
index 0000000..9be3c81
--- /dev/null
+++ b/cups-no-export-ssllibs.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.5b1/config-scripts/cups-ssl.m4.no-export-ssllibs cups-1.5b1/config-scripts/cups-ssl.m4
+--- cups-1.5b1/config-scripts/cups-ssl.m4.no-export-ssllibs 2011-05-11 02:52:08.000000000 +0200
++++ cups-1.5b1/config-scripts/cups-ssl.m4 2011-05-23 17:47:27.000000000 +0200
+@@ -164,7 +164,7 @@ AC_SUBST(IPPALIASES)
+ AC_SUBST(SSLFLAGS)
+ AC_SUBST(SSLLIBS)
+
+-EXPORT_SSLLIBS="$SSLLIBS"
++EXPORT_SSLLIBS=""
+ AC_SUBST(EXPORT_SSLLIBS)
+
+
diff --git a/cups-no-gzip-man.patch b/cups-no-gzip-man.patch
new file mode 100644
index 0000000..6786c44
--- /dev/null
+++ b/cups-no-gzip-man.patch
@@ -0,0 +1,18 @@
+diff -up cups-1.5b1/config-scripts/cups-manpages.m4.no-gzip-man cups-1.5b1/config-scripts/cups-manpages.m4
+--- cups-1.5b1/config-scripts/cups-manpages.m4.no-gzip-man 2011-05-12 07:21:56.000000000 +0200
++++ cups-1.5b1/config-scripts/cups-manpages.m4 2011-05-23 17:25:50.000000000 +0200
+@@ -69,10 +69,10 @@ case "$uname" in
+ ;;
+ Linux* | GNU* | Darwin*)
+ # Linux, GNU Hurd, and Mac 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/cups-peercred.patch b/cups-peercred.patch
new file mode 100644
index 0000000..a106abb
--- /dev/null
+++ b/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 <grp.h>
+ #ifdef HAVE_SHADOW_H
diff --git a/cups-pid.patch b/cups-pid.patch
new file mode 100644
index 0000000..23ffd47
--- /dev/null
+++ b/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/cups-ps-command-filter.patch b/cups-ps-command-filter.patch
new file mode 100644
index 0000000..88cd18b
--- /dev/null
+++ b/cups-ps-command-filter.patch
@@ -0,0 +1,13 @@
+diff -up cups-1.5.0/cups/ppd-cache.c.ps-command-filter cups-1.5.0/cups/ppd-cache.c
+--- cups-1.5.0/cups/ppd-cache.c.ps-command-filter 2011-11-04 13:10:34.405729542 +0000
++++ cups-1.5.0/cups/ppd-cache.c 2011-11-04 13:11:58.502184096 +0000
+@@ -1272,7 +1272,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)
+
+ if (filter)
+ cupsArrayAdd(pc->filters,
+- "application/vnd.cups-command application/postscript 0 -");
++ "application/vnd.cups-command application/postscript 100 "
++ "commandtops");
+ }
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL)
diff --git a/cups-res_init.patch b/cups-res_init.patch
new file mode 100644
index 0000000..1dc110e
--- /dev/null
+++ b/cups-res_init.patch
@@ -0,0 +1,26 @@
+diff -up cups-1.5b1/cups/http-addr.c.res_init cups-1.5b1/cups/http-addr.c
+--- cups-1.5b1/cups/http-addr.c.res_init 2011-04-16 01:38:13.000000000 +0200
++++ cups-1.5b1/cups/http-addr.c 2011-05-24 15:56:50.000000000 +0200
+@@ -256,7 +256,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.5b1/cups/http-addrlist.c.res_init cups-1.5b1/cups/http-addrlist.c
+--- cups-1.5b1/cups/http-addrlist.c.res_init 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/cups/http-addrlist.c 2011-05-24 15:56:50.000000000 +0200
+@@ -386,7 +386,8 @@ httpAddrGetList(const char *hostname, /*
+
+ freeaddrinfo(results);
+ }
+- else if (error == EAI_FAIL)
++ else if (error == EAI_FAIL || error == EAI_AGAIN || error == EAI_NODATA ||
++ error == EAI_NONAME)
+ cg->need_res_init = 1;
+
+ #else
diff --git a/cups-ricoh-deviceid-oid.patch b/cups-ricoh-deviceid-oid.patch
new file mode 100644
index 0000000..c148f95
--- /dev/null
+++ b/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/cups-serial.patch b/cups-serial.patch
new file mode 100644
index 0000000..d17c9cb
--- /dev/null
+++ b/cups-serial.patch
@@ -0,0 +1,11 @@
+diff -up cups-1.5b1/backend/serial.c.serial cups-1.5b1/backend/serial.c
+--- cups-1.5b1/backend/serial.c.serial 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/backend/serial.c 2011-05-23 17:34:33.000000000 +0200
+@@ -75,6 +75,7 @@
+ #endif /* __APPLE__ */
+
+ #if defined(__linux) && defined(TIOCGSERIAL)
++# include <linux/types.h>
+ # include <linux/serial.h>
+ # include <linux/ioctl.h>
+ #endif /* __linux && TIOCGSERIAL */
diff --git a/cups-serverbin-compat.patch b/cups-serverbin-compat.patch
new file mode 100644
index 0000000..0ca72fd
--- /dev/null
+++ b/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/cups-snmp-quirks.patch b/cups-snmp-quirks.patch
new file mode 100644
index 0000000..fdc7cc5
--- /dev/null
+++ b/cups-snmp-quirks.patch
@@ -0,0 +1,115 @@
+diff -up cups-1.5b1/backend/snmp-supplies.c.snmp-quirks cups-1.5b1/backend/snmp-supplies.c
+--- cups-1.5b1/backend/snmp-supplies.c.snmp-quirks 2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/backend/snmp-supplies.c 2011-05-24 17:15:55.000000000 +0200
+@@ -47,6 +47,13 @@
+
+
+ /*
++ * Printer quirks...
++ */
++
++#define QUIRK_CAPACITY (1<<0)
++
++
++/*
+ * Local structures...
+ */
+
+@@ -66,6 +73,12 @@ typedef struct /**** Printer state ta
+ const char *keyword; /* IPP printer-state-reasons keyword */
+ } backend_state_t;
+
++typedef struct /**** Quirk names table ****/
++{
++ int bit; /* Quirk bit */
++ const char *keyword; /* cupsSNMPQuirks keyword */
++} quirk_name_t;
++
+
+ /*
+ * Local globals...
+@@ -77,6 +90,7 @@ static int current_state = -1;
+ static int charset = -1; /* Character set for supply names */
+ static int num_supplies = 0;
+ /* Number of supplies found */
++static int quirks = 0; /* Printer quirks */
+ static backend_supplies_t supplies[CUPS_MAX_SUPPLIES];
+ /* Supply information */
+ static int supply_state = -1;
+@@ -176,6 +190,15 @@ static const backend_state_t const suppl
+ { CUPS_TONER_EMPTY, "toner-empty-warning" }
+ };
+
++static const quirk_name_t const quirk_names[] =
++ {
++ /*
++ * The prtMarkerSuppliesLevel values are
++ * percentages, not levels relative to the
++ * stated capacity.
++ */
++ { QUIRK_CAPACITY, "capacity" }
++ };
+
+ /*
+ * Local functions...
+@@ -229,6 +252,9 @@ backendSNMPSupplies(
+
+ for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr))
+ {
++ if (quirks & QUIRK_CAPACITY)
++ supplies[i].max_capacity = 100;
++
+ if (supplies[i].max_capacity > 0)
+ percent = 100 * supplies[i].level / supplies[i].max_capacity;
+ else
+@@ -401,6 +427,7 @@ backend_init_supplies(
+ http_addr_t *addr) /* I - Printer address */
+ {
+ int i, /* Looping var */
++ len, /* Quirk name length */
+ type; /* Current marker type */
+ cups_file_t *cachefile; /* Cache file */
+ const char *cachedir; /* CUPS_CACHEDIR value */
+@@ -462,6 +489,7 @@ backend_init_supplies(
+ current_state = -1;
+ num_supplies = -1;
+ charset = -1;
++ quirks = 0;
+
+ memset(supplies, 0, sizeof(supplies));
+
+@@ -477,6 +505,34 @@ backend_init_supplies(
+ return;
+ }
+
++ if (ppd &&
++ (ppdattr = ppdFindAttr(ppd, "cupsSNMPQuirks", NULL)) != NULL &&
++ ppdattr->value)
++ {
++ ptr = ppdattr->value;
++ while (*ptr != '\0')
++ {
++ /*
++ * Match keyword against quirk_names table.
++ */
++
++ for (i = 0; i < sizeof (quirk_names) / sizeof (quirk_names[0]); i++)
++ {
++ len = strlen (quirk_names[i].keyword);
++ if (!strncmp (ptr, quirk_names[i].keyword, len) &&
++ (ptr[len] == '\0' || ptr[len] == ' '))
++ quirks |= quirk_names[i].bit;
++ }
++
++ /*
++ * Advance to next keyword.
++ */
++
++ ptr += strcspn (ptr, " ");
++ ptr += strspn (ptr, " ");
++ }
++ }
++
+ ppdClose(ppd);
+
+ /*
diff --git a/cups-str3382.patch b/cups-str3382.patch
new file mode 100644
index 0000000..2e8736d
--- /dev/null
+++ b/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 <io.h>
+ #else
+ # include <unistd.h>
++# include <sys/types.h>
+ #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/cups-str3921.patch b/cups-str3921.patch
new file mode 100644
index 0000000..d370e38
--- /dev/null
+++ b/cups-str3921.patch
@@ -0,0 +1,14 @@
+diff -up cups-1.5.0/scheduler/cups-driverd.cxx.str3921 cups-1.5.0/scheduler/cups-driverd.cxx
+--- cups-1.5.0/scheduler/cups-driverd.cxx.str3921 2011-06-08 22:19:11.000000000 +0100
++++ cups-1.5.0/scheduler/cups-driverd.cxx 2011-10-11 12:07:34.979538544 +0100
+@@ -1411,9 +1411,7 @@ load_drv(const char *filename, /* I -
+ * Add a dummy entry for the file...
+ */
+
+- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0,
+- "/%s", name);
+- add_ppd(name, uri, "", "", "", "", "", "", mtime, size, 0,
++ add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0,
+ PPD_TYPE_DRV, "drv");
+ ChangedPPD = 1;
+
diff --git a/cups-str3947.patch b/cups-str3947.patch
new file mode 100644
index 0000000..9bff194
--- /dev/null
+++ b/cups-str3947.patch
@@ -0,0 +1,26 @@
+diff -up cups-1.5.0/notifier/dbus.c.str3947 cups-1.5.0/notifier/dbus.c
+--- cups-1.5.0/notifier/dbus.c.str3947 2011-03-04 16:55:59.000000000 +0000
++++ cups-1.5.0/notifier/dbus.c 2011-09-28 10:42:56.298760622 +0100
+@@ -4,7 +4,7 @@
+ * D-Bus notifier for CUPS.
+ *
+ * Copyright 2008-2010 by Apple Inc.
+- * Copyright (C) 2007 Red Hat, Inc.
++ * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2007 Tim Waugh <twaugh@redhat.com>
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+@@ -423,10 +423,11 @@ main(int argc, /* I - Number of comm
+ p = printer_reasons;
+ for (i = 0; i < attr->num_values; i++)
+ {
+- strcpy(p, attr->values[i].string.text);
+- p += strlen(p);
+ if (i)
+ *p++ = ',';
++
++ strcpy(p, attr->values[i].string.text);
++ p += strlen(p);
+ }
+ dbus_message_iter_append_string(&iter, &printer_reasons);
+ }
diff --git a/cups-strict-ppd-line-length.patch b/cups-strict-ppd-line-length.patch
new file mode 100644
index 0000000..b2697ec
--- /dev/null
+++ b/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/cups-system-auth.patch b/cups-system-auth.patch
new file mode 100644
index 0000000..60117a9
--- /dev/null
+++ b/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/cups-systemd-socket.patch b/cups-systemd-socket.patch
new file mode 100644
index 0000000..8e5147d
--- /dev/null
+++ b/cups-systemd-socket.patch
@@ -0,0 +1,396 @@
+diff -up cups-1.5.0/config.h.in.systemd-socket cups-1.5.0/config.h.in
+--- cups-1.5.0/config.h.in.systemd-socket 2011-10-18 15:32:40.741672460 +0100
++++ cups-1.5.0/config.h.in 2011-10-18 15:32:40.843670530 +0100
+@@ -503,6 +503,13 @@
+
+
+ /*
++ * Do we have systemd support?
++ */
++
++#undef HAVE_SYSTEMD
++
++
++/*
+ * Various scripting languages...
+ */
+
+diff -up cups-1.5.0/config-scripts/cups-systemd.m4.systemd-socket cups-1.5.0/config-scripts/cups-systemd.m4
+--- cups-1.5.0/config-scripts/cups-systemd.m4.systemd-socket 2011-10-18 15:32:40.844670511 +0100
++++ cups-1.5.0/config-scripts/cups-systemd.m4 2011-10-18 15:33:16.861989058 +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.5.0/configure.in.systemd-socket cups-1.5.0/configure.in
+--- cups-1.5.0/configure.in.systemd-socket 2010-11-20 01:03:46.000000000 +0000
++++ cups-1.5.0/configure.in 2011-10-18 15:32:40.844670511 +0100
+@@ -37,6 +37,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-pdf.m4)
+ sinclude(config-scripts/cups-scripting.m4)
+@@ -71,6 +72,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-cupsd-conf.html
+ doc/help/standard.html
+diff -up cups-1.5.0/cups/usersys.c.systemd-socket cups-1.5.0/cups/usersys.c
+--- cups-1.5.0/cups/usersys.c.systemd-socket 2011-10-18 15:32:40.645674277 +0100
++++ cups-1.5.0/cups/usersys.c 2011-10-18 15:32:40.845670492 +0100
+@@ -770,7 +770,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.5.0/data/cups.path.in.systemd-socket cups-1.5.0/data/cups.path.in
+--- cups-1.5.0/data/cups.path.in.systemd-socket 2011-10-18 15:32:40.846670473 +0100
++++ cups-1.5.0/data/cups.path.in 2011-10-18 15:32:40.846670473 +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.5.0/data/cups.service.in.systemd-socket cups-1.5.0/data/cups.service.in
+--- cups-1.5.0/data/cups.service.in.systemd-socket 2011-10-18 15:32:40.846670473 +0100
++++ cups-1.5.0/data/cups.service.in 2011-10-18 15:32:40.846670473 +0100
+@@ -0,0 +1,9 @@
++[Unit]
++Description=CUPS Printing Service
++
++[Service]
++ExecStart=@sbindir@/cupsd -f
++
++[Install]
++Also=cups.socket cups.path
++WantedBy=printer.target
+diff -up cups-1.5.0/data/cups.socket.in.systemd-socket cups-1.5.0/data/cups.socket.in
+--- cups-1.5.0/data/cups.socket.in.systemd-socket 2011-10-18 15:32:40.847670454 +0100
++++ cups-1.5.0/data/cups.socket.in 2011-10-18 15:32:40.847670454 +0100
+@@ -0,0 +1,10 @@
++[Unit]
++Description=CUPS Printing Service Sockets
++
++[Socket]
++ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
++ListenStream=631
++BindIPv6Only=ipv6-only
++
++[Install]
++WantedBy=sockets.target
+diff -up cups-1.5.0/data/Makefile.systemd-socket cups-1.5.0/data/Makefile
+--- cups-1.5.0/data/Makefile.systemd-socket 2011-05-12 06:21:56.000000000 +0100
++++ cups-1.5.0/data/Makefile 2011-10-18 15:32:40.847670454 +0100
+@@ -112,6 +112,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
+
+
+ #
+@@ -159,6 +165,9 @@ uninstall:
+ -$(RMDIR) $(DATADIR)/charsets
+ -$(RMDIR) $(DATADIR)/banners
+ -$(RMDIR) $(DATADIR)
++ for file in $(SYSTEMD_UNITS); do \
++ $(RM) $(SYSTEMDUNITDIR)/$$file; \
++ done
+
+
+ #
+diff -up cups-1.5.0/Makedefs.in.systemd-socket cups-1.5.0/Makedefs.in
+--- cups-1.5.0/Makedefs.in.systemd-socket 2011-10-18 15:32:40.719672876 +0100
++++ cups-1.5.0/Makedefs.in 2011-10-18 15:32:40.848670435 +0100
+@@ -143,6 +143,7 @@ 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)
+@@ -151,6 +152,7 @@ FONTS = @FONTS@
+ IMGLIBS = @IMGLIBS@
+ IMGFILTERS = @IMGFILTERS@
+ LAUNCHDLIBS = @LAUNCHDLIBS@
++SDLIBS = @SDLIBS@
+ LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \
+ -L../scheduler @LDARCHFLAGS@ \
+ @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
+@@ -267,6 +269,7 @@ PAMFILE = @PAMFILE@
+
+ DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
+ DBUSDIR = @DBUSDIR@
++SYSTEMDUNITDIR = $(BUILDROOT)@systemdsystemunitdir@
+
+
+ #
+diff -up cups-1.5.0/scheduler/client.h.systemd-socket cups-1.5.0/scheduler/client.h
+--- cups-1.5.0/scheduler/client.h.systemd-socket 2011-03-25 21:25:38.000000000 +0000
++++ cups-1.5.0/scheduler/client.h 2011-10-18 15:32:40.848670435 +0100
+@@ -75,6 +75,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.5.0/scheduler/listen.c.systemd-socket cups-1.5.0/scheduler/listen.c
+--- cups-1.5.0/scheduler/listen.c.systemd-socket 2011-04-16 00:38:13.000000000 +0100
++++ cups-1.5.0/scheduler/listen.c 2011-10-18 15:32:40.849670416 +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.5.0/scheduler/main.c.systemd-socket cups-1.5.0/scheduler/main.c
+--- cups-1.5.0/scheduler/main.c.systemd-socket 2011-10-18 15:32:40.802671306 +0100
++++ cups-1.5.0/scheduler/main.c 2011-10-18 15:32:40.851670379 +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 <systemd/sd-daemon.h>
++#endif /* HAVE_SYSTEMD */
++
+ #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
+ # include <malloc.h>
+ #endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
+@@ -78,6 +84,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);
+@@ -537,6 +546,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...
+ */
+@@ -759,6 +775,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...
+ */
+@@ -1584,6 +1609,100 @@ 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.5.0/scheduler/Makefile.systemd-socket cups-1.5.0/scheduler/Makefile
+--- cups-1.5.0/scheduler/Makefile.systemd-socket 2011-10-18 15:32:40.817671022 +0100
++++ cups-1.5.0/scheduler/Makefile 2011-10-18 15:32:40.852670360 +0100
+@@ -382,7 +382,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 $@...
+@@ -390,7 +390,7 @@ cupsd-static: $(CUPSDOBJS) libcupsmime.a
+ $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
+ ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \
+ $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
+- $(LIBWRAP)
++ $(LIBWRAP) $(SDLIBS)
+
+
+ #
diff --git a/cups-uri-compat.patch b/cups-uri-compat.patch
new file mode 100644
index 0000000..2520a5b
--- /dev/null
+++ b/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/cups-usb-paperout.patch b/cups-usb-paperout.patch
new file mode 100644
index 0000000..f1f73f0
--- /dev/null
+++ b/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 <sys/select.h>
+
++#ifdef __linux
++#include <sys/ioctl.h>
++#include <linux/lp.h>
++#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/cups.cron b/cups.cron
new file mode 100755
index 0000000..72f91d8
--- /dev/null
+++ b/cups.cron
@@ -0,0 +1,8 @@
+#!/bin/sh
+for d in /var/spool/cups/tmp
+do
+ if [ -d "$d" ]; then
+ /usr/sbin/tmpwatch -f 720 "$d"
+ fi
+done
+exit 0
diff --git a/cups.logrotate b/cups.logrotate
new file mode 100644
index 0000000..773c70f
--- /dev/null
+++ b/cups.logrotate
@@ -0,0 +1,5 @@
+/var/log/cups/*_log {
+ missingok
+ notifempty
+ sharedscripts
+}
diff --git a/cups.spec b/cups.spec
new file mode 100644
index 0000000..867828c
--- /dev/null
+++ b/cups.spec
@@ -0,0 +1,2920 @@
+%global php_extdir %(php-config --extension-dir 2>/dev/null || echo %{_libdir}/php4)
+%global php_apiver %((echo 0; php -i 2>/dev/null | sed -n 's/^PHP API => //p') | tail -1)
+
+%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: Common Unix Printing System
+Name: cups
+Version: 1.5.0
+Release: 22%{?dist}
+License: GPLv2
+Group: System Environment/Daemons
+Source: http://ftp.easysw.com/pub/cups/%{version}/cups-%{version}-source.tar.bz2
+# Pixmap for desktop file
+Source2: cupsprinter.png
+# LSPP-required ps->pdf filter
+Source4: pstopdf
+# xinetd config file for cups-lpd service
+Source5: cups-lpd
+# Logrotate configuration
+Source6: cups.logrotate
+# Backend for NCP protocol
+Source7: ncp.backend
+# Cron-based tmpwatch for /var/spool/cups/tmp
+Source8: cups.cron
+# Filter and PPD for textonly printing
+Source9: textonly.filter
+Source10: textonly.ppd
+Source11: macros.cups
+Patch1: cups-no-gzip-man.patch
+Patch2: cups-system-auth.patch
+Patch3: cups-multilib.patch
+Patch4: cups-serial.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-getpass.patch
+Patch14: cups-driverd-timeout.patch
+Patch15: cups-strict-ppd-line-length.patch
+Patch16: cups-logrotate.patch
+Patch17: cups-usb-paperout.patch
+Patch18: cups-build.patch
+Patch19: cups-res_init.patch
+Patch20: cups-filter-debug.patch
+Patch21: cups-uri-compat.patch
+Patch22: cups-cups-get-classes.patch
+Patch23: cups-str3382.patch
+Patch24: cups-str3947.patch
+Patch25: cups-0755.patch
+Patch26: cups-snmp-quirks.patch
+Patch27: cups-hp-deviceid-oid.patch
+Patch28: cups-dnssd-deviceid.patch
+Patch29: cups-ricoh-deviceid-oid.patch
+
+Patch30: cups-avahi-1-config.patch
+Patch31: cups-avahi-2-backend.patch
+Patch32: cups-avahi-3-timeouts.patch
+Patch33: cups-avahi-4-poll.patch
+Patch34: cups-avahi-5-services.patch
+
+Patch35: cups-icc.patch
+Patch36: cups-systemd-socket.patch
+Patch37: cups-CVE-2011-2896.patch
+Patch38: cups-str3921.patch
+Patch39: cups-ps-command-filter.patch
+
+Patch100: cups-lspp.patch
+
+Epoch: 1
+Url: http://www.cups.org/
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Requires: /sbin/chkconfig /sbin/service
+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
+
+# Unconditionally obsolete LPRng so that upgrades work properly.
+Obsoletes: lpd <= 3.8.15-3, lpr <= 3.8.15-3, LPRng <= 3.8.15-3
+Provides: lpd = 3.8.15-4, lpr = 3.8.15-4, LPRng = 3.8.15-4
+
+Obsoletes: cupsddk < 1.2.3-7
+Provides: cupsddk = 1.2.3-7
+Obsoletes: cupsddk-drivers < 1.2.3-7
+Provides: cupsddk-drivers = 1.2.3-7
+
+# kdelibs conflict for bug #192585.
+Conflicts: kdelibs < 6:3.5.2-6
+
+BuildRequires: pam-devel pkgconfig
+BuildRequires: gnutls-devel libacl-devel
+BuildRequires: openldap-devel
+BuildRequires: make >= 1:3.80
+BuildRequires: php-devel, pcre-devel
+BuildRequires: libjpeg-devel
+BuildRequires: libpng-devel
+BuildRequires: libtiff-devel
+BuildRequires: krb5-devel
+BuildRequires: avahi-devel
+BuildRequires: poppler-utils
+BuildRequires: systemd-units, systemd-devel
+
+# Make sure we get postscriptdriver tags.
+BuildRequires: python-cups
+
+%if %lspp
+BuildRequires: libselinux-devel >= 1.23
+BuildRequires: audit-libs-devel >= 1.1
+%endif
+
+# -fstack-protector-all requires GCC 4.0.1
+BuildRequires: gcc >= 4.0.1
+
+BuildRequires: automake
+
+BuildRequires: dbus-devel >= 0.90
+Requires: dbus >= 0.90
+
+# Requires tmpwatch for the cron.daily script (bug #218901).
+Requires: tmpwatch
+
+# Requires /etc/tmpfiles.d (bug #656566)
+Requires: systemd-units >= 13
+Requires(post): systemd-units
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+Requires(post): systemd-sysv
+
+Requires: poppler-utils
+
+# We ship udev rules which use setfacl.
+Requires: udev
+Requires: acl
+
+# Make sure we have some filters for converting to raster format.
+Requires: ghostscript-cups
+
+# Make sure we register devices and profiles with colord.
+Requires: colord
+
+%package devel
+Summary: Common Unix Printing System - development environment
+Group: Development/Libraries
+License: LGPLv2
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+Requires: gnutls-devel
+Requires: krb5-devel
+Requires: zlib-devel
+Obsoletes: cupsddk-devel < 1.2.3-7
+Provides: cupsddk-devel = 1.2.3-7
+
+%package libs
+Summary: Common Unix Printing System - libraries
+Group: System Environment/Libraries
+License: LGPLv2
+
+%package lpd
+Summary: Common Unix Printing System - lpd emulation
+Group: System Environment/Daemons
+Requires: %{name} = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+Requires: xinetd
+
+%package php
+Summary: Common Unix Printing System - php module
+Group: Development/Languages
+Requires: %{name} = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Requires: php(zend-abi) = %{php_zend_api}
+Requires: php(api) = %{php_core_api}
+
+%package ipptool
+Summary: Common Unix Printing System - tool for performing IPP requests
+Group: System Environment/Daemons
+Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+
+%description
+The Common UNIX Printing System provides a portable printing layer for
+UNIX® operating systems. It has been developed by Easy Software Products
+to promote a standard printing solution for all UNIX vendors and users.
+CUPS provides the System V and Berkeley command-line interfaces.
+
+%description devel
+The Common UNIX 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
+The Common UNIX Printing System provides a portable printing layer for
+UNIX® operating systems. It has been developed by Easy Software Products
+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 lpd
+The Common UNIX Printing System provides a portable printing layer for
+UNIX® operating systems. This is the package that provides standard
+lpd emulation.
+
+%description php
+The Common UNIX Printing System provides a portable printing layer for
+UNIX® operating systems. This is the package that provides a PHP
+module.
+
+%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
+# Fix compilation of serial backend.
+%patch4 -p1 -b .serial
+# 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
+# More sophisticated implementation of cupsGetPassword than getpass.
+%patch13 -p1 -b .getpass
+# Increase driverd timeout to 70s to accommodate foomatic.
+%patch14 -p1 -b .driverd-timeout
+# Only enforce maximum PPD line length when in strict mode.
+%patch15 -p1 -b .strict-ppd-line-length
+# Re-open the log if it has been logrotated under us.
+%patch16 -p1 -b .logrotate
+# Support for errno==ENOSPACE-based USB paper-out reporting.
+%patch17 -p1 -b .usb-paperout
+# Simplify the DNSSD parts so they can build using the compat library.
+%patch18 -p1 -b .build
+# Re-initialise the resolver on failure in httpAddrGetList().
+%patch19 -p1 -b .res_init
+# Log extra debugging information if no filters are available.
+%patch20 -p1 -b .filter-debug
+# Allow the usb backend to understand old-style URI formats.
+%patch21 -p1 -b .uri-compat
+# Fix support for older CUPS servers in cupsGetDests.
+%patch22 -p1 -b .cups-get-classes
+# Fix temporary filename creation.
+%patch23 -p1 -b .str3382
+# Fixed string manipulation in the dbus notifier (STR #3947, bug #741833).
+%patch24 -p1 -b .str3947
+# Use mode 0755 for binaries and libraries where appropriate.
+%patch25 -p1 -b .0755
+# Handle SNMP supply level quirks (bug #581825).
+%patch26 -p1 -b .snmp-quirks
+# Add an SNMP query for HP's device ID OID (STR #3552).
+%patch27 -p1 -b .hp-deviceid-oid
+# Mark DNS-SD Device IDs that have been guessed at with "FZY:1;".
+%patch28 -p1 -b .dnssd-deviceid
+# Add an SNMP query for Ricoh's device ID OID (STR #3552).
+%patch29 -p1 -b .ricoh-deviceid-oid
+
+# Avahi support:
+# - discovery in the dnssd backend
+# - service announcement in the scheduler
+%patch30 -p1 -b .avahi-1-config
+%patch31 -p1 -b .avahi-2-backend
+%patch32 -p1 -b .avahi-3-timeouts
+%patch33 -p1 -b .avahi-4-poll
+%patch34 -p1 -b .avahi-5-services
+
+# ICC colord support.
+%patch35 -p1 -b .icc
+
+# Add support for systemd socket activation (patch from Lennart
+# Poettering).
+%patch36 -p1 -b .systemd-socket
+
+# Avoid GIF reader loop (CVE-2011-2896, STR #3914, bug #727800).
+%patch37 -p1 -b .CVE-2011-2896
+
+# Work around PPDs cache handling issue (bug #742989).
+%patch38 -p1 -b .str3921
+
+# Set the correct PostScript command filter for e.g. foomatic queues
+# (STR #3973).
+%patch39 -p1 -b .ps-command-filter
+
+%if %lspp
+# LSPP support.
+%patch100 -p1 -b .lspp
+%endif
+
+sed -i -e '1iMaxLogSize 0' conf/cupsd.conf.in
+
+cp %{SOURCE5} cups-lpd.real
+perl -pi -e "s,\@LIBDIR\@,%{_libdir},g" cups-lpd.real
+
+# Let's look at the compilation command lines.
+perl -pi -e "s,^.SILENT:,," Makedefs.in
+
+# Fix locale code for Norwegian (bug #520379).
+mv locale/cups_no.po locale/cups_nb.po
+
+f=CREDITS.txt
+mv "$f" "$f"~
+iconv -f MACINTOSH -t UTF-8 "$f"~ > "$f"
+rm "$f"~
+
+# Rebuild configure script for --enable-avahi.
+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-log-file-perm=0600 --enable-relro \
+ --with-pdftops=pdftops \
+ --with-dbusdir=%{_sysconfdir}/dbus-1 \
+ --with-php=/usr/bin/php-cgi --enable-avahi \
+ --enable-threads --enable-gnutls \
+ localedir=%{_datadir}/locale
+
+# If we got this far, all prerequisite libraries must be here.
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+make BUILDROOT=$RPM_BUILD_ROOT install
+
+# Serial backend needs to run as root (bug #212577).
+chmod 700 $RPM_BUILD_ROOT%{cups_serverbin}/backend/serial
+
+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}/xinetd.d $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily
+install -c -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_datadir}/pixmaps
+install -c -m 644 cups-lpd.real $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/cups-lpd
+install -c -m 644 %{SOURCE6} $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/cups
+install -c -m 755 %{SOURCE7} $RPM_BUILD_ROOT%{cups_serverbin}/backend/ncp
+install -c -m 755 %{SOURCE8} $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily/cups
+install -c -m 755 %{SOURCE9} $RPM_BUILD_ROOT%{cups_serverbin}/filter/textonly
+install -c -m 644 %{SOURCE10} $RPM_BUILD_ROOT%{_datadir}/cups/model/textonly.ppd
+
+# Ship pstopdf for LSPP systems to deal with malicious postscript
+%if %lspp
+install -c -m 755 %{SOURCE4} $RPM_BUILD_ROOT%{cups_serverbin}/filter
+%endif
+
+# Ship an rpm macro for where to put driver executables.
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/rpm/
+install -m 0644 %{SOURCE11} $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
+
+# This is %%ghost'ed, but needs to be created in %%install anyway.
+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
+
+# Put the php config bit into place
+%{__mkdir_p} %{buildroot}%{_sysconfdir}/php.d
+%{__cat} << __EOF__ > %{buildroot}%{_sysconfdir}/php.d/%{name}.ini
+; Enable %{name} extension module
+extension=phpcups.so
+__EOF__
+
+# install /etc/tmpfiles.d/cups.conf (bug #656566)
+mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/tmpfiles.d
+cat > ${RPM_BUILD_ROOT}%{_sysconfdir}/tmpfiles.d/cups.conf <<EOF
+d %{_localstatedir}/run/cups 0755 root lp -
+d %{_localstatedir}/run/cups/certs 0511 lp sys -
+EOF
+
+find %{buildroot} -type f -o -type l | sed '
+s:.*\('%{_datadir}'/\)\([^/_]\+\)\(.*\.po$\):%lang(\2) \1\2\3:
+/^%lang(C)/d
+/^\([^%].*\)/d
+' > %{name}.lang
+
+%post
+if [ $1 -eq 1 ] ; then
+ # Initial installation
+ /bin/systemctl enable cups.{service,socket,path} >/dev/null 2>&1 || :
+fi
+
+# Remove old-style certs directory; new-style is /var/run
+# (see bug #194581 for why this is necessary).
+/bin/rm -rf %{_sysconfdir}/cups/certs
+%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
+rm -f %{_localstatedir}/cache/cups/*.ipp %{_localstatedir}/cache/cups/*.cache
+exit 0
+
+%post libs -p /sbin/ldconfig
+
+%postun libs -p /sbin/ldconfig
+
+%preun
+if [ $1 -eq 0 ] ; then
+ # Package removal, not upgrade
+ /bin/systemctl --no-reload disable %{name}.path %{name}.socket %{name}.service >/dev/null 2>&1 || :
+ /bin/systemctl stop %{name}.path %{name}.socket %{name}.service >/dev/null 2>&1 || :
+%if %use_alternatives
+ /usr/sbin/alternatives --remove print %{_bindir}/lpr.cups
+%endif
+fi
+exit 0
+
+%postun
+/bin/systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 1 ]; then
+ # Package upgrade, not uninstall
+ /bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || :
+fi
+exit 0
+
+%triggerun -- %{name} < 1:1.5.0-22
+# This package is allowed to autostart; however, the upgrade trigger
+# in Fedora 16 final failed to actually do this. Do it now as a
+# one-off fix for bug #748841.
+/bin/systemctl --no-reload enable %{name}.{service,socket,path} >/dev/null 2>&1 || :
+
+%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 ../../../bin/smbspool %{cups_serverbin}/backend/smb || :
+exit 0
+
+%triggerun -- samba-client
+[ $2 = 0 ] || exit 0
+rm -f %{cups_serverbin}/backend/smb
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files -f %{name}.lang
+%defattr(-,root,root)
+%doc README.txt CREDITS.txt CHANGES.txt
+%attr(0660,root,lp) %dev(char,6,0) /lib/udev/devices/lp0
+%attr(0660,root,lp) %dev(char,6,1) /lib/udev/devices/lp1
+%attr(0660,root,lp) %dev(char,6,2) /lib/udev/devices/lp2
+%attr(0660,root,lp) %dev(char,6,3) /lib/udev/devices/lp3
+%dir %attr(0755,root,lp) %{_sysconfdir}/cups
+%dir %attr(0755,root,lp) /var/run/cups
+%dir %attr(0511,lp,sys) /var/run/cups/certs
+%config(noreplace) %{_sysconfdir}/tmpfiles.d/cups.conf
+%verify(not md5 size mtime) %config(noreplace) %attr(0640,root,lp) %{_sysconfdir}/cups/cupsd.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(0644,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/es
+%dir %{_datadir}/%{name}/www/eu
+%dir %{_datadir}/%{name}/www/ja
+%dir %{_datadir}/%{name}/www/pl
+%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/de/index.html
+%doc %{_datadir}/%{name}/www/es/index.html
+%doc %{_datadir}/%{name}/www/eu/index.html
+%doc %{_datadir}/%{name}/www/id/index.html
+%doc %{_datadir}/%{name}/www/it/index.html
+%doc %{_datadir}/%{name}/www/ja/index.html
+%doc %{_datadir}/%{name}/www/pl/index.html
+%doc %{_datadir}/%{name}/www/ru/index.html
+%{_unitdir}/%{name}.service
+%{_unitdir}/%{name}.socket
+%{_unitdir}/%{name}.path
+%{_bindir}/cupstestppd
+%{_bindir}/cupstestdsc
+%{_bindir}/cancel*
+%{_bindir}/lp*
+%{_bindir}/ppd*
+%dir %{cups_serverbin}
+%{cups_serverbin}/backend
+%{cups_serverbin}/cgi-bin
+%dir %{cups_serverbin}/daemon
+%{cups_serverbin}/daemon/cups-polld
+%{cups_serverbin}/daemon/cups-deviced
+%{cups_serverbin}/daemon/cups-driverd
+%{cups_serverbin}/daemon/cups-exec
+%{cups_serverbin}/notifier
+%{cups_serverbin}/filter
+%{cups_serverbin}/monitor
+%{cups_serverbin}/driver
+%{_mandir}/man1/cancel*
+%{_mandir}/man1/cupstest*
+%{_mandir}/man1/lp*
+%{_mandir}/man1/ppd*
+%{_mandir}/man[578]/*
+%{_sbindir}/*
+%dir %{_datadir}/cups
+%dir %{_datadir}/cups/banners
+%{_datadir}/cups/banners/*
+%{_datadir}/cups/charsets
+%{_datadir}/cups/data
+%{_datadir}/cups/fonts
+%{_datadir}/cups/model
+%dir %{_datadir}/cups/templates
+%{_datadir}/cups/templates/*.tmpl
+%{_datadir}/cups/templates/de/*.tmpl
+%{_datadir}/cups/templates/es/*.tmpl
+%{_datadir}/cups/templates/eu/*.tmpl
+%{_datadir}/cups/templates/id/*.tmpl
+%{_datadir}/cups/templates/it/*.tmpl
+%{_datadir}/cups/templates/ja/*.tmpl
+%{_datadir}/cups/templates/pl/*.tmpl
+%{_datadir}/cups/templates/ru/*.tmpl
+%{_datadir}/locale/*/*.po
+%{_datadir}/ppd
+%dir %attr(1770,root,lp) /var/spool/cups/tmp
+%dir %attr(0710,root,lp) /var/spool/cups
+%dir %attr(0755,lp,sys) /var/log/cups
+%{_datadir}/pixmaps/cupsprinter.png
+%{_sysconfdir}/cron.daily/cups
+%config(noreplace) %{_sysconfdir}/dbus-1/system.d/cups.conf
+%{_datadir}/cups/drv
+%{_datadir}/cups/examples
+%dir %{_datadir}/cups/mime
+%{_datadir}/cups/mime/mime.types
+%{_datadir}/cups/mime/mime.convs
+%dir %{_datadir}/cups/ppdc
+%{_datadir}/cups/ppdc/*.defs
+%{_datadir}/cups/ppdc/*.h
+
+%files libs
+%defattr(-,root,root)
+%doc LICENSE.txt
+%{_libdir}/*.so.*
+
+%files devel
+%defattr(-,root,root)
+%{_bindir}/cups-config
+%{_libdir}/*.so
+%{_includedir}/cups
+%{_mandir}/man1/cups-config.1*
+%{_sysconfdir}/rpm/macros.cups
+
+%files lpd
+%defattr(-,root,root)
+%config(noreplace) %{_sysconfdir}/xinetd.d/cups-lpd
+%dir %{cups_serverbin}
+%dir %{cups_serverbin}/daemon
+%{cups_serverbin}/daemon/cups-lpd
+
+%files php
+%defattr(-,root,root)
+%config(noreplace) %{_sysconfdir}/php.d/%{name}.ini
+%{php_extdir}/phpcups.so
+
+%files ipptool
+%defattr(-,root,root)
+%{_bindir}/ipptool
+%dir %{_datadir}/cups/ipptool
+%{_datadir}/cups/ipptool/create-printer-subscription.test
+%{_datadir}/cups/ipptool/get-completed-jobs.test
+%{_datadir}/cups/ipptool/get-jobs.test
+%{_datadir}/cups/ipptool/ipp-1.1.test
+%{_datadir}/cups/ipptool/ipp-2.0.test
+%{_datadir}/cups/ipptool/ipp-2.1.test
+%{_datadir}/cups/ipptool/testfile.jpg
+%{_datadir}/cups/ipptool/testfile.pdf
+%{_datadir}/cups/ipptool/testfile.ps
+%{_datadir}/cups/ipptool/testfile.txt
+%{_mandir}/man1/ipptool.1.gz
+
+%changelog
+* Fri Nov 11 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-22
+- Fixed trigger (bug #748841).
+
+* Wed Nov 9 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-21
+- Set correct systemd service default on upgrade, once updates are
+ applied (bug #748841).
+
+* Fri Nov 4 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-20
+- Set the correct PostScript command filter for e.g. foomatic queues
+ (STR #3973).
+
+* Mon Oct 31 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-19
+- Set correct systemd service default on upgrade (bug #748841).
+
+* Wed Oct 19 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.5.0-17
+- Use libsystemd-daemon instead of bundling sd-daemon.c.
+
+* Tue Oct 11 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.5.0-15
+- Fixed Timeouts array comparison function (Ubuntu #860691).
+
+* Wed Oct 5 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.5.0-13
+- Work around PPDs cache handling issue (bug #742989).
+
+* Tue Oct 4 2011 Tim Waugh <twaugh@redhat.com> 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 <rhughes@redhat.com> 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 <twaugh@redhat.com> 1:1.5.0-10
+- Fixed string manipulation in the dbus notifier (STR #3947, bug #741833).
+
+* Thu Sep 22 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-9
+- Fixed systemd socket activation support (bug #738709, bug #738710).
+
+* Wed Sep 14 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-8
+- Prevent libcups crash in cups-get-classes patch (bug #736698).
+
+* Thu Sep 1 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-7
+- Use PathExistsGlob instead of DirectoryNotEmpty in cups.path
+ (bug #734435).
+
+* Fri Aug 19 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.5.0-5
+- Avoid GIF reader loop (CVE-2011-2896, STR #3914, bug #727800).
+
+* Wed Aug 17 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-4
+- Enable systemd units by default (bug #731421).
+
+* Mon Aug 8 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-3
+- Updated avahi support to register sub-types.
+
+* Fri Aug 5 2011 Tim Waugh <twaugh@redhat.com> 1:1.5.0-2
+- Ported avahi support from 1.4.
+
+* Tue Jul 26 2011 Jiri Popelka <jpopelka@redhat.com> 1:1.5.0-1
+- 1.5.0
+
+* Wed Jul 20 2011 Tim Waugh <twaugh@redhat.com> 1:1.5-0.16.rc1
+- Don't delete job data files when restarted (STR #3880).
+
+* Fri Jul 15 2011 Tim Waugh <twaugh@redhat.com> 1:1.5-0.15.rc1
+- Ship an rpm macro for where to put driver executables.
+
+* Thu Jul 7 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.5-0.13.rc1
+- Make build log verbose enough to include compiler flags used.
+
+* Tue Jul 5 2011 Tim Waugh <twaugh@redhat.com> 1:1.5-0.12.rc1
+- Removed udev rules file as it is no longer necessary.
+
+* Tue Jul 5 2011 Tim Waugh <twaugh@redhat.com> 1:1.5-0.11.rc1
+- Add support for systemd socket activation (patch from Lennart
+ Poettering).
+
+* Wed Jun 29 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.5-0.9.rc1
+- Ship systemd service unit instead of SysV initscript (bug #690766).
+
+* Wed Jun 29 2011 Tim Waugh <twaugh@redhat.com> 1:1.5-0.8.rc1
+- Tag localization files correctly (bug #716421).
+
+* Wed Jun 15 2011 Jiri Popelka <jpopelka@redhat.com> 1:1.5-0.7.rc1
+- 1.5rc1
+
+* Sat Jun 04 2011 Richard Hughes <rhughes@redhat.com> 1:1.5-0.6.b2
+- Updated colord patch with fixes from Tim Waugh.
+
+* Tue May 31 2011 Jiri Popelka <jpopelka@redhat.com> 1:1.5-0.5.b2
+- enable LSPP support again
+
+* Tue May 31 2011 Richard Hughes <rhughes@redhat.com> 1:1.5-0.4.b2
+- Updated colord patch against 1.5 upstream and fixes from Tim Waugh.
+
+* Tue May 31 2011 Jiri Popelka <jpopelka@redhat.com> 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 <jpopelka@redhat.com> 1:1.5-0.2.b2
+- 1.5b2
+
+* Tue May 24 2011 Jiri Popelka <jpopelka@redhat.com> 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 <twaugh@redhat.com> 1:1.4.6-17
+- Package parallel port printer device nodes (bug #678804).
+
+* Tue May 17 2011 Richard Hughes <rhughes@redhat.com> 1:1.4.6-16
+- Updated colord patch from upstream review.
+
+* Fri Mar 25 2011 Jiri Popelka <jpopelka@redhat.com> 1:1.4.6-15
+- Polished patches according to results from static analysis of code (bug #690130).
+
+* Thu Mar 10 2011 Tim Waugh <twaugh@redhat.com> 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 <rhughes@redhat.com> 1:1.4.6-13
+- Updated colord patch.
+
+* Fri Feb 25 2011 Tim Waugh <twaugh@redhat.com> 1:1.4.6-12
+- Fixed build failure due to php_zend_api macro type.
+
+* Fri Feb 25 2011 Tim Waugh <twaugh@redhat.com> 1:1.4.6-11
+- Fixed dbus notifier support for job-state-changed.
+
+* Thu Feb 10 2011 Jiri Popelka <jpopelka@redhat.com> 1:1.4.6-10
+- Remove testing cups-usb-buffer-size.patch (bug #661814).
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1:1.4.6-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Tue Feb 01 2011 Jiri Popelka <jpopelka@redhat.com> 1:1.4.6-8
+- Use Till's patch to fix USB-Parallel adapter cable problem (bug #624564).
+
+* Tue Jan 25 2011 Tim Waugh <twaugh@redhat.com> 1:1.4.6-7
+- Some fixes for the AvahiClient callback (bug #672143).
+
+* Tue Jan 18 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.4.6-5
+- ICC colord support.
+
+* Wed Jan 12 2011 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.4.6-3
+- Build requires automake for avahi support.
+
+* Mon Jan 10 2011 Tim Waugh <twaugh@redhat.com> 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 <jpopelka@redhat.com> 1:1.4.6-1
+- 1.4.6.
+
+* Fri Dec 31 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.5-10
+- Some Avahi support fixes from Till Kamppeter.
+
+* Fri Dec 24 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.5-9
+- Native Avahi support for announcing printers on the network.
+
+* Wed Dec 22 2010 Tim Waugh <twaugh@redhat.com> 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 <jpopelka@redhat.com> 1:1.4.5-7
+- Call avc_init() only once to not leak file descriptors (bug #654075).
+
+* Thu Dec 9 2010 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 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 <twaugh@redhat.com>
+- /usr/sbin/cupsd should be mode 0755 (bug #546004).
+
+* Fri Dec 03 2010 Jiri Popelka <jpopelka@redhat.com> 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 <jpopelka@redhat.com> 1:1.4.5-3
+- BuildRequires python-cups instead of pycups.
+
+* Fri Nov 26 2010 Jiri Popelka <jpopelka@redhat.com> 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 <jpopelka@redhat.com> 1:1.4.5-1
+- 1.4.5.
+- No longer need CVE-2010-2941, str3608
+
+* Thu Nov 11 2010 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 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 <twaugh@redhat.com>
+- Fixed serverbin-compat patch to avoid misleading "filter not
+ available" messages (bug #633779).
+
+* Mon Aug 23 2010 Tim Waugh <twaugh@redhat.com>
+- Fixed SNMP quirks parsing.
+
+* Fri Aug 20 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.4-9
+- Use better upstream fix for STR #3608 (bug #606909).
+
+* Fri Aug 13 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.4-8
+- Specify udevadm trigger action in initscript (bug #623959).
+
+* Tue Aug 3 2010 Tim Waugh <twaugh@redhat.com>
+- Merged F-12 change:
+ - Use numeric addresses for interfaces unless HostNameLookups are
+ turned on (bug #583054).
+
+* Tue Jul 13 2010 Jiri Popelka <jpopelka@redhat.com> 1:1.4.4-7
+- Added restartlog to initscript usage output (bug #612996).
+
+* Mon Jul 12 2010 Jiri Popelka <jpopelka@redhat.com> 1:1.4.4-6
+- Moved LICENSE.txt to libs sub-package.
+
+* Mon Jun 28 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.4-5
+- Avoid empty notify-subscribed-event attributes (bug #606909,
+ STR #3608).
+
+* Thu Jun 24 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.4-4
+- Use gnutls again but disable threading (bug #607159).
+
+* Tue Jun 22 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.4-3
+- Rebuilt to keep correct package n-v-r ordering between releases.
+
+* Fri Jun 18 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.4-2
+- Re-enabled SSL support by using OpenSSL instead of gnutls.
+
+* Fri Jun 18 2010 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com>
+- Removed unapplied gnutls-gcrypt-threads patch. Fixed typos in
+ descriptions for lpd and php sub-packages.
+
+* Wed Jun 9 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.3-11
+- Use upstream method of handling SNMP quirks in PPDs (STR #3551,
+ bug #581825).
+
+* Tue Jun 01 2010 Jiri Popelka <jpopelka@redhat.com> 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 <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.4.3-8
+- Fixed Ricoh Device ID OID (STR #3552).
+
+* Tue May 11 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.3-7
+- Add an SNMP query for Ricoh's device ID OID (STR #3552).
+
+* Fri Apr 16 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.3-6
+- Mark DNS-SD Device IDs that have been guessed at with "FZY:1;".
+
+* Fri Apr 16 2010 Jiri Popelka <jpopelka@redhat.com> 1:1.4.3-5
+- Fixed str3541.patch
+
+* Tue Apr 13 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.3-4
+- Add an SNMP query for HP's device ID OID (STR #3552).
+
+* Tue Apr 13 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.3-3
+- Handle SNMP supply level quirks (bug #581825).
+
+* Wed Mar 31 2010 Tim Waugh <twaugh@redhat.com> 1:1.4.3-2
+- Another BrowsePoll fix: handle EAI_NODATA as well (bug #567353).
+
+* Wed Mar 31 2010 Jiri Popelka <jpopelka@redhat.com> 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 <jpopelka@redhat.com> 1:1.4.2-36
+- Fixed lpstat to adhere to -o option (bug #577901, STR #3541).
+
+* Wed Mar 10 2010 Jiri Popelka <jpopelka@redhat.com> 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 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 <jpopelka@redhat.com> 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 1:1.4.2-30
+- Re-initialize the resolver if getnameinfo() returns EAI_AGAIN
+ (bug #567353).
+
+* Mon Feb 15 2010 Jiri Popelka <jpopelka@redhat.com> 1:1.4.2-29
+- Improve cups-gnutls-gcrypt-threads.patch (#564841, STR #3461).
+
+* Thu Feb 4 2010 Tim Waugh <twaugh@redhat.com> - 1:1.4.2-28
+- Rebuild for postscriptdriver tags.
+
+* Fri Jan 22 2010 Tim Waugh <twaugh@redhat.com> - 1:1.4.2-27
+- Make sure we have some filters for converting to raster format.
+
+* Fri Jan 15 2010 Tim Waugh <twaugh@redhat.com> - 1:1.4.2-26
+- Reset status after successful ipp job (bug #548219, STR #3460).
+
+* Thu Jan 14 2010 Tim Waugh <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 1:1.4.2-19
+- Ensure proper thread-safety in gnutls's use of libgcrypt
+ (bug #544619).
+
+* Sat Dec 19 2009 Tim Waugh <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 1:1.4.2-17
+- Fixed invalid read in cupsAddDest (bug #537460).
+
+* Wed Dec 9 2009 Tim Waugh <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 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 <twaugh@redhat.com> - 1:1.4.2-13
+- The web interface prevented conflicting options from being adjusted
+ (bug #533426, STR #3439).
+
+* Thu Dec 3 2009 Tim Waugh <twaugh@redhat.com> - 1:1.4.2-12
+- Fixes for SNMP scanning with Lexmark printers (bug #542857, STR #3413).
+
+* Mon Nov 23 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.2-10
+- Undo last change as it was incorrect.
+
+* Mon Nov 23 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.2-9
+- Fixed small typos introduced in fix for bug #536741.
+
+* Fri Nov 20 2009 Jiri Popelka <jpopelka@redhat.com> 1:1.4.2-8
+- Do not translate russian links showing completed jobs
+ (bug #539354, STR #3422).
+
+* Thu Nov 19 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.2-7
+- Applied patch to fix CVE-2009-3553 (bug #530111, STR #3200).
+
+* Tue Nov 17 2009 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.4.2-4
+- Upstream fix for GNU TLS error handling bug (bug #537883, STR #3381).
+
+* Wed Nov 11 2009 Jiri Popelka <jpopelka@redhat.com> 1:1.4.2-3
+- Fixed lspp-patch to avoid memory leak (bug #536741).
+
+* Tue Nov 10 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.2-2
+- Added explicit version dependency on cups-libs to cups-lpd
+ (bug #502205).
+
+* Tue Nov 10 2009 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 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 <jpopelka@redhat.com> 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 <jpopelka@redhat.com> 1:1.4.1-12
+- Fix cups-lpd to create unique temporary data files (bug #529838).
+
+* Mon Oct 19 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.1-11
+- Fixed German translation (bug #529575, STR #3380).
+
+* Thu Oct 15 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.1-10
+- Don't ship pstoraster -- it is now provided by the ghostscript-cups
+ package.
+
+* Thu Oct 8 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.1-9
+- Fixed naming of 'Generic PostScript Printer' entry.
+
+* Wed Oct 7 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.1-8
+- Use upstream patch for STR #3356 (bug #526405).
+
+* Fri Oct 2 2009 Tim Waugh <twaugh@redhat.com> 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 <twaugh@redhat.com> 1:1.4.1-6
+- Don't use cached PPD for raw queue (bug #526405, STR #3356).
+
+* Wed Sep 23 2009 Jiri Popelka <jpopelka@redhat.com> 1:1.4.1-5
+- Fixed cups.init to be LSB compliant (bug #521641)
+
+* Mon Sep 21 2009 Jiri Popelka <jpopelka@redhat.com> 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 <tmraz@redhat.com> 1:1.4.1-3
+- Use password-auth common PAM configuration instead of system-auth
+ when available.
+
+* Tue Sep 15 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.1-2
+- Fixed 'service cups status' to check for correct subsys name
+ (bug #521641).
+
+* Mon Sep 14 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.1-1
+- 1.4.1.
+
+* Fri Sep 4 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.0-2
+- Fixed the dnssd backend so that it only reports devices once avahi
+ resolution has completed. This makes it report Device IDs
+ (bug #520858).
+- Fix locale code for Norwegian (bug #520379).
+
+* Fri Aug 28 2009 Tim Waugh <twaugh@redhat.com> 1:1.4.0-1
+- 1.4.0.
+
+* Thu Aug 27 2009 Warren Togami <wtogami@redhat.com> 1:1.4-0.rc1.21
+- rebuild
+
+* Wed Aug 26 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.20
+- Fixed admin.cgi crash when modifying a class (bug #519724,
+ STR #3312, patch from Jiri Popelka).
+
+* Wed Aug 26 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.19
+- Prevent infinite loop in cupsDoIORequest when processing HTTP
+ errors (bug #518065, bug #519663, STR #3311).
+- Fixed document-format-supported attribute when
+ application/octet-stream is enabled (bug #516507, STR #3308, patch
+ from Jiri Popelka).
+- Fixed buggy JobKillDelay handling fix (STR #3292).
+- Prevent infinite loop in ppdc (STR #3293).
+
+* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 1:1.4-0.rc1.17.1
+- rebuilt with new audit
+
+* Fri Aug 21 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.17
+- Removed 3-distribution symlink (bug #514244).
+
+* Tue Aug 18 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.16
+- Fixed JobKillDelay handling for cancelled jobs (bug #518026, STR
+ #3292).
+- Use 'exec' to invoke ghostscript in the pstoraster filter. This
+ allows the SIGTERM signal to reach the correct process, as well as
+ conserving memory (part of bug #518026).
+
+* Tue Aug 11 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.15
+- Avoid empty BrowseLocalProtocols setting (bug #516460, STR #3287).
+
+* Mon Aug 10 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.14
+- Fixed ppds.dat handling of drv files (bug #515027, STR #3279).
+- Fixed udev rules file to avoid DEVTYPE warning messages.
+- Fixed cupsGetNamedDest() so it does not fall back to the default
+ printer when a destination has been named (bug #516439, STR #3285).
+- Fixed MIME type rules for image/jpeg and image/x-bitmap
+ (bug #516438, STR #3284).
+- Clear out cache files on upgrade.
+- Require acl.
+
+* Thu Aug 6 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.13
+- Ship udev rules to allow libusb to access printer devices.
+- Fixed duplex test pages (bug #514898, STR #3277).
+
+* Wed Jul 29 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.12
+- Fixed Avahi support in the dnssd backend (bug #513888).
+- Fixed incorrect arguments to sigaction() in dnssd backend (STR #3272).
+- Cheaply restore compatibility with 1.1.x by having cups_get_sdests()
+ perform a CUPS_GET_CLASSES request if it is not sure it is talking
+ to CUPS 1.2 or later (bug #512866).
+- Prevent ipp backend looping with bad IPP devices (bug #476424,
+ STR #3262).
+- Fixed Device ID reporting in the usb backend (STR #3266).
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1:1.4-0.rc1.11.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Fri Jul 24 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.11
+- Tell udevd to replay printer add events in the initscript.
+
+* Wed Jul 15 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.10
+- Applied patch to prevent bad job control files crashing cupsd on
+ start-up (STR #3253, bug #509741).
+- Correctly handle CUPS-Get-PPDs requests for models with '+' in their
+ names (STR #3254, bug #509586).
+- Accept incorrect device URIs in the (non-libusb) usb backend for
+ compatibility with Fedora 11 before bug #507244 was fixed.
+- Applied patch to fix incorrect device URIs (STR #3259, bug #507244).
+- Applied patch to fix job-hold-until for remote queues (STR #3258,
+ bug #497376).
+
+* Mon Jul 13 2009 Remi Collet <Fedora@FamilleCollet.com> 1:1.4-0.rc1.9
+- add PHP ABI check
+- use php_extdir
+- add php configuration file (/etc/php.d/cups.ini)
+
+* Fri Jul 10 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.8
+- Build does not require aspell-devel (bug #510405).
+
+* Wed Jul 1 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.7
+- Fixed template problem preventing current printer option defaults
+ from being shown in the web interface (bug #506794, STR #3244).
+
+* Wed Jul 1 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.6
+- Fixed lpadmin for remote 1.3.x servers (bug #506977, STR #3231).
+
+* Tue Jun 23 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.5
+- Added more debugging output when constructing filter chain.
+
+* Thu Jun 18 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.4
+- More complete fix for STR #3229 (bug #506461).
+
+* Wed Jun 17 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.3
+- Don't use RPM_SOURCE_DIR macro.
+- Fixed add/modify-printer templates which had extra double-quote
+ characters, preventing the Continue button from appearing in certain
+ browsers (bug #506461, STR #3229).
+
+* Wed Jun 17 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.rc1.1
+- 1.4rc1. No longer need str3124, CVE-2009-0163, CVE-2009-0164,
+ str3197, missing-devices patches.
+- Disabled avahi patch for the time being. More work is needed to
+ port this to rc1.
+- Removed wbuffer patch as it is not needed (see STR #1968).
+
+* Fri May 15 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.18
+- More complete fix for STR #3197 (bug #500859).
+
+* Thu May 14 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.17
+- Prevent cupsd crash when handling IPP_TAG_DELETEATTR requests
+ (STR #3197, bug #500859).
+
+* Thu May 7 2009 Ville Skyttä <ville.skytta at iki.fi> - 1:1.4-0.b2.16
+- Avoid stripping binaries before rpmbuild creates the -debuginfo subpackage.
+
+* Sun Apr 26 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.15
+- Accept "Host: ::1" (bug #497393).
+- Accept Host: fields set to the ServerName value (bug #497301).
+- Specify that we want poppler's pdftops (not ghostscript) for the
+ pdftops wrapper when calling configure.
+
+* Fri Apr 17 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.14
+- Applied patch to fix CVE-2009-0163 (bug #490596).
+- Applied patch to fix CVE-2009-0164 (bug #490597).
+
+* Thu Apr 2 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.13
+- Don't verify MD5 sum, file size, or mtime for several config files:
+ cupsd.conf, client.conf, classes.conf, printers.conf, snmp.conf,
+ subscriptions.conf, lpoptions (bug #486287).
+
+* Mon Mar 23 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.12
+- If cups-polld gets EAI_AGAIN when looking up a hostname,
+ re-initialise the resolver (bug #490943).
+
+* Wed Mar 11 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.11
+- Bumped cupsddk n-v-r for obsoletes/provides, as cupsddk was rebuilt.
+
+* Tue Mar 10 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.10
+- Applied patch to fix ppd-natural-language attribute in PPD list
+ (STR #3124).
+
+* Mon Mar 9 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.9
+- Handle https:// device URIs (bug #478677, STR #3122).
+
+* Thu Mar 5 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.8
+- Updated to svn8404.
+
+* Wed Feb 25 2009 Tim Waugh <twaugh@redhat.com>
+- Added 'Should-Start: portreserve' to the initscript (part of bug #487250).
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1:1.4-0.b2.7.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Thu Feb 19 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.7
+- Prevent cups-deviced missing devices (STR #3108).
+- Actually drop the perl implementation of the dnssd backend and use
+ the avahi-aware one.
+
+* Thu Feb 12 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.6
+- Beginnings of avahi support. The dnssd backend should now work, but
+ the scheduler will not yet advertise DNS-SD services.
+- No longer require avahi-tools as the dnssd backend does not use the
+ command line tools any longer.
+- Load MIME type rules correctly (bug #426089, STR #3059).
+
+* Wed Jan 28 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.4
+- Fixed quotas (STR #3077, STR #3078).
+
+* Tue Jan 27 2009 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.3
+- Fixed default BrowseLocalProtocols (bug #481505).
+
+* Tue Dec 16 2008 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b2.2
+- 1.4b2.
+- No longer need CVE-2008-5183 patch.
+
+* Sat Dec 13 2008 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b1.6
+- Start cupsd at priority 25: after avahi-daemon but before haldaemon
+ (bug #468709).
+
+* Tue Dec 9 2008 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b1.5
+- Applied patch to fix RSS subscription limiting (bug #473901,
+ CVE-2008-5183).
+- Attempt to unbreak the fix for STR #2831 (bug #474742).
+
+* Sun Nov 30 2008 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b1.4
+- Own more directories (bug #473581).
+
+* Tue Nov 11 2008 Tim Waugh <twaugh@redhat.com> 1:1.4-0.b1.3
+- 1.4b1.
+- No longer need ext, includeifexists, foomatic-recommended,
+ getnameddest, str2101, str2536 patches.
+- Require poppler-utils at runtime and for build. No longer need
+ pdftops.conf.
+- Obsolete cupsddk.
+
+* Thu Oct 30 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.9-3
+- Fixed LSPP labels (bug #468442).
+
+* Tue Oct 21 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.9-2
+- Fixed textonly filter to send FF correctly.
+
+* Fri Oct 10 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.9-1
+- 1.3.9, including fixes for CVE-2008-3639 (STR #2918, bug #464710),
+ CVE-2008-3640 (STR #2919, bug #464713) and CVE-2008-3641 (STR #2911,
+ bug #464716).
+- No longer need str2892 or res_init patches.
+
+* Wed Sep 10 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.8-6
+- Backported patch for FatalErrors configuration directive
+ (bug #314941, STR #2536).
+
+* Thu Sep 4 2008 Tim Waugh <twaugh@redhat.com>
+- Use php-cgi for executing PHP scripts (bug #460898).
+
+* Wed Sep 3 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.8-5
+- The dnssd backend uses avahi-browse so require it (bug #458565).
+- New php sub-package (bug #428235).
+- cups-polld: reinit the resolver if we haven't yet resolved the
+ hostname (bug #354071).
+
+* Mon Aug 11 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.8-4
+- Better password prompting behaviour (bug #215133, STR #2101).
+
+* Tue Aug 5 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.8-3
+- Mark template files config(noreplace) for site-local modifications
+ (bug #441719).
+
+* Sun Aug 3 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.8-2
+- Applied patch to fix STR #2892 (bug #453610).
+
+* Mon Jul 28 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.8-1
+- 1.3.8.
+
+* Fri Jul 18 2008 Tim Waugh <twaugh@redhat.com>
+- Removed autoconf requirement by applying autoconf-generated changes
+ to patches that caused them. Affected patches: cups-lspp.
+
+* Tue Jul 15 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-13
+- CVE-2008-1373 patch is no longer needed (applied upstream).
+- Mark HTML files and templates config(noreplace) for site-local
+ modifications (bug #441719).
+- The cups-devel package requires zlib-devel (bug #455192).
+
+* Tue Jul 1 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-12
+- Fixed bug #447200 again.
+
+* Tue Jul 1 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-11
+- Use portreserve.
+
+* Tue Jun 24 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-10
+- Rebuilt for new gnutls.
+
+* Tue Jun 17 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-9
+- Don't overwrite the upstream snmp.conf file.
+
+* Tue Jun 17 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-8
+- Fixed bug #447200 again.
+
+* Tue Jun 17 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-7
+- Backported cupsGetNamedDest from 1.4 (bug #428086).
+
+* Tue Jun 3 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-6
+- Applied patch to fix STR #2750 (IPP authentication).
+
+* Fri May 30 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-5
+- Better fix for cupsdTimeoutJob LSPP configuration suggested by
+ Matt Anderson (bug #447200).
+
+* Thu May 29 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-4
+- Fix last fix (bug #447200).
+
+* Wed May 28 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-3
+- If cupsdTimeoutJob is called when the originating connection is still
+ known, pass that to the function so that copy_banner can get at it if
+ necessary (bug #447200).
+
+* Fri May 9 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-2
+- Applied patch to fix CVE-2008-1722 (integer overflow in image filter,
+ bug #441692, STR #2790).
+
+* Thu Apr 3 2008 Tim Waugh <twaugh@redhat.com>
+- Main package requires exactly-matching libs package.
+
+* Wed Apr 2 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.7-1
+- 1.3.7. No longer need str2715, str2727, or CVE-2008-0047 patches.
+
+* Thu Apr 1 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-9
+- Applied patch to fix CVE-2008-1373 (GIF overflow, bug #438303).
+- Applied patch to prevent heap-based buffer overflow in CUPS helper
+ program (bug #436153, CVE-2008-0047, STR #2729).
+
+* Thu Apr 1 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-8
+- Ship a few doc files (bug #438598).
+
+* Thu Mar 27 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-7
+- Don't ship broken symlink %%{_datadir}/cups/doc (bug #438598).
+
+* Mon Mar 17 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-6
+- Own %%{_datadir}/cups/www (bug #437742).
+
+* Thu Feb 28 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-5
+- Apply upstream fix for Adobe JPEG files (bug #166460, STR #2727).
+
+* Tue Feb 26 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-4
+- LSB header for initscript (bug #246897).
+- Move HTML-related files to main application directory so that the CUPS
+ web interface still works even with --excludedocs (bug #375631).
+
+* Tue Feb 26 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-3
+- Set MaxLogSize to 0 to prevent log rotation. Upstream default is 1Mb, but
+ we want logrotate to be in charge.
+
+* Sat Feb 23 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-2
+- Fix encoding of job-sheets option (bug #433753, STR #2715).
+
+* Wed Feb 20 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.6-1
+- 1.3.6.
+
+* Thu Feb 14 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.5-6
+- Include fixes from svn up to revision 7304. No longer need str2703 patch.
+ Build with --with-dbusdir.
+- Try out logrotate again (bug #432730).
+
+* Tue Feb 12 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.5-5
+- Fixed admin.cgi handling of DefaultAuthType (bug #432478, STR #2703).
+
+* Tue Feb 5 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.5-4
+- Fix compilation of SO_PEERCRED support.
+- Include fixes from svn up to revision 7287. No longer need str2650 or
+ str2664 patches.
+
+* Fri Feb 1 2008 Tim Waugh <twaugh@redhat.com>
+- Updated initscript for LSB exit codes and actions (bug #246897).
+
+* Thu Jan 24 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.5-3
+- Build requires autoconf.
+
+* Mon Jan 21 2008 Tim Waugh <twaugh@redhat.com> 1:1.3.5-2
+- Main package requires libs sub-package of the same release.
+
+* Thu Jan 10 2008 Tim Waugh <twaugh@redhat.com>
+- Apply patch to fix busy looping in the backends (bug #426653, STR #2664).
+
+* Wed Jan 9 2008 Tim Waugh <twaugh@redhat.com>
+- Apply patch to prevent overlong PPD lines from causing failures except
+ in strict mode (bug #405061). Needed for compatibility with older
+ versions of foomatic (e.g. Red Hat Enterprise Linux 3/4).
+- Applied upstream patch to fix cupsctl --remote-any (bug #421411, STR #2650).
+
+* Thu Jan 3 2008 Tim Waugh <twaugh@redhat.com>
+- Efficiency fix for pstoraster (bug #416871).
+
+* Tue Dec 18 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.5-1
+- 1.3.5.
+
+* Mon Dec 10 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.4-5
+- Rebuilt with higher release number.
+
+* Tue Dec 4 2007 Warren Togami <wtogami@redhat.com> 1:1.3.4-3
+- rebuild
+
+* Fri Nov 30 2007 Tim Waugh <twaugh@redhat.com>
+- CVE-2007-4045 patch is not necessarily because cupsd_client_t objects are
+ not moved in array operations, only pointers to them.
+
+* Tue Nov 27 2007 Tim Waugh <twaugh@redhat.com>
+- Updated to improved dnssd backend from Till Kamppeter.
+
+* Tue Nov 13 2007 Tim Waugh <twaugh@redhat.com>
+- Fixed CVE-2007-4045 patch; has no effect with shipped packages since they
+ are linked with gnutls.
+- LSPP cupsdSetString/ClearString fixes (bug #378451).
+
+* Wed Nov 7 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.4-2
+- Applied patch to fix CVE-2007-4045 (bug #250161).
+- Applied patch to fix CVE-2007-4352, CVE-2007-5392 and
+ CVE-2007-5393 (bug #345101).
+
+* Thu Nov 1 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.4-1
+- 1.3.4 (bug #361681).
+
+* Wed Oct 10 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.3-3
+- Use ppdev instead of libieee1284 for parallel port Device ID
+ retrieval (bug #311671). This avoids SELinux audit messages.
+
+* Tue Oct 9 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.3-2
+- Use libieee1284 for parallel port Device ID retrieval (bug #311671).
+
+* Fri Sep 28 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.3-1
+- 1.3.3.
+
+* Tue Sep 25 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.2-3
+- Don't strip foomatic recommended strings from make/model names.
+
+* Fri Sep 21 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.2-2
+- Write printcap when remote printers have timed out (bug #290831).
+
+* Wed Sep 19 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.2-1
+- Include Till Kamppeter's dnssd backend.
+- 1.3.2.
+- No longer need str2512 patches.
+
+* Tue Sep 18 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.1-3
+- Write printcap when a remote queue is deleted (bug #290831).
+
+* Tue Sep 18 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.1-2
+- Avoid writing printcap unnecessarily (bug #290831).
+
+* Mon Sep 17 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.1-1
+- 1.3.1.
+
+* Wed Aug 29 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.0-2
+- More specific license tag.
+
+* Mon Aug 13 2007 Tim Waugh <twaugh@redhat.com> 1:1.3.0-1
+- 1.3.0.
+
+* Tue Jul 31 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.rc2.2
+- Make cancel man page work properly with alternatives system (bug #249768).
+- Don't call aclocal even when we modify m4 files -- CUPS does not use
+ automake (bug #250251).
+
+* Tue Jul 31 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.rc2.1
+- Better buildroot tag.
+- Moved LSPP access check in add_job() to before allocation of the job
+ structure (bug #231522).
+- 1.3rc2. No longer need avahi patch.
+
+* Mon Jul 23 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.b1.5
+- Use kernel support for USB paper-out detection, when available
+ (bug #249213).
+
+* Fri Jul 20 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.b1.4
+- Better error checking in the LSPP patch (bug #231522).
+
+* Fri Jul 20 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.b1.3
+- Change initscript start level to 98, to start after avahi but before
+ haldaemon.
+- The devel sub-package requires krb5-devel.
+
+* Thu Jul 19 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.b1.2
+- Build requires avahi-compat-libdns_sd-devel. Applied patch to fix
+ build against avahi (bug #245824).
+- Build requires krb5-devel.
+
+* Wed Jul 18 2007 Tim Waugh <twaugh@redhat.com> 1:1.3-0.b1.1
+- 1.3b1. No longer need relro, directed-broadcast, af_unix-auth, or
+ str2109 patches.
+
+* Fri Jul 13 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.12-1
+- 1.2.12. No longer need adminutil or str2408 patches.
+
+* Mon Jul 9 2007 Tim Waugh <twaugh@redhat.com>
+- Another small improvement for the textonly filter (bug #244979).
+
+* Thu Jul 5 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.11-5
+- Support for page-ranges and accounting in the textonly filter (bug #244979).
+
+* Wed Jul 4 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.11-4
+- Better paper-out detection patch still (bug #246222).
+
+* Fri Jun 29 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.11-3
+- Applied patch to fix group handling in PPDs (bug #186231, STR #2408).
+
+* Wed Jun 27 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.11-2
+- Fixed _cupsAdminSetServerSettings() sharing/shared handling (bug #238057).
+
+* Mon Jun 25 2007 Tim Waugh <twaugh@redhat.com>
+- Fixed permissions on classes.conf in the file manifest (bug #245748).
+
+* Wed Jun 13 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.11-1
+- 1.2.11.
+
+* Tue Jun 12 2007 Tim Waugh <twaugh@redhat.com>
+- Make the initscript use start priority 56 (bug #213828).
+- Better paper-out detection patch (bug #241589).
+
+* Wed May 9 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-10
+* Revert paper-out detection for the moment.
+
+* Wed May 9 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-9
+- Applied fix for rotated PDFs (bug #236753, STR #2348).
+
+* Thu Apr 26 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-8
+- Initscript fixes (bug #237955).
+
+* Wed Apr 25 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-7
+- Until bug #236736 is fixed, work around the kernel usblp driver's
+ quirks so that we can detect paper-out conditions.
+
+* Tue Apr 10 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-6
+- Fixed 'cancel' man page (bug #234088).
+- Added empty subscriptions.conf file to make sure it gets the right
+ SELinux file context.
+
+* Wed Apr 4 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-5
+- Send D-BUS QueueChanged signal on printer state changes.
+
+* Tue Apr 3 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-4
+- Relay printer-state-message values in the IPP backend (STR #2109).
+
+* Mon Apr 2 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-3
+- Don't clear printer-state-reasons after job completion (STR #2323).
+
+* Thu Mar 29 2007 Tim Waugh <twaugh@redhat.com>
+- Small improvement for AF_UNIX auth patch.
+
+* Thu Mar 29 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-2
+- LSPP: Updated patch for line-wrapped labels (bug #228107).
+
+* Tue Mar 20 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.10-1
+- 1.2.10.
+
+* Tue Mar 20 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.9-2
+- Added %%{_datadir}/ppd for LSB (bug #232893).
+
+* Fri Mar 16 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.9-1
+- 1.2.9.
+
+* Fri Mar 9 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.8-5
+- Better UNIX domain sockets authentication patch after feedback from
+ Uli (bug #230613).
+
+* Thu Mar 8 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.8-4
+- Implemented SCM_CREDENTIALS authentication for UNIX domain sockets
+ (bug #230613).
+
+* Fri Mar 2 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.8-3
+- Updated LSPP patch (bug #229673).
+
+* Mon Feb 26 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.8-2
+- Applied fix for STR #2264 (bug #230116).
+
+* Wed Feb 14 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.8-1
+- 1.2.8.
+
+* Tue Feb 13 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.7-8
+- Removed logrotate config file and maxlogsize patch (bug #227369). Now
+ CUPS is in charge of rotating its own logs, and defaults to doing so once
+ they get to 1Mb in size.
+
+* Fri Jan 12 2007 Tim Waugh <twaugh@redhat.com> 1:1.2.7-7
+- Don't even reload CUPS when rotating logs (bug #215024).
+
+* Fri Dec 8 2006 Tim Waugh <twaugh@redhat.com>
+- Requires tmpwatch for the cron.daily script (bug #218901).
+
+* Thu Dec 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.7-6
+- Fixed If-Modified-Since: handling in libcups (bug #217556, STR #2133).
+- Fixed extra EOF in pstops output (bug #216154, STR #2111).
+- Use upstream patch for STR #2121.
+
+* Mon Nov 27 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.7-5
+- Better LSPP fix for bug #216855.
+
+* Thu Nov 23 2006 Tim Waugh <twaugh@redhat.com>
+- Use translated string for password prompt (STR #2121).
+
+* Wed Nov 22 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.7-4
+- Another LSPP fix (bug #216669).
+- Fixed LSPP SELinux check (bug #216855).
+- Increased PPD timeout in copy_model() (bug #216065).
+
+* Tue Nov 21 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.7-3
+- Run the serial backend as root (bug #212577).
+
+* Thu Nov 16 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.7-2
+- 1.2.7.
+
+* Tue Nov 14 2006 Tim Waugh <twaugh@redhat.com>
+- Fixed LogFilePerm.
+
+* Mon Nov 13 2006 Tim Waugh <twaugh@redhat.com>
+- Don't use getpass() (bug #215133).
+
+* Fri Nov 10 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.6-5
+- Reload, don't restart, when logrotating (bug #215023).
+
+* Wed Nov 8 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.6-4
+- Fixed pdftops.conf (bug #214611).
+
+* Mon Nov 6 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.6-3
+- 1.2.6.
+
+* Mon Nov 6 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.5-7
+- One more D-Bus signal fix (bug #212763).
+
+* Fri Nov 3 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.5-6
+- Restore missed JobQueuedRemote D-Bus signal in ipp backend (part of
+ bug #212763).
+
+* Thu Nov 2 2006 Tim Waugh <twaugh@redhat.com>
+- LSPP patch fix (bug #213498).
+
+* Wed Nov 1 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.5-5
+- Send QueueChanged D-Bus signal on all job state changes.
+
+* Tue Oct 31 2006 Tim Waugh <twaugh@redhat.com>
+- Added filter and PPD for text-only printer (bug #213030).
+
+* Mon Oct 30 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.5-4
+- Fixed support for /dev/ttyUSB devices (bug #212577, STR #2061).
+- Fixed parallel backend (bug #213021, STR #2056).
+
+* Tue Oct 26 2006 Tim Waugh <twaugh@redhat.com>
+- Ship a real lpoptions file to make sure it is world-readable (bug #203510).
+
+* Mon Oct 23 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.5-3
+- 1.2.5.
+
+* Tue Oct 17 2006 Tim Waugh <twaugh@redhat.com>
+- Feature-complete LSPP patch from Matt Anderson (bug #210542).
+
+* Thu Oct 5 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-9
+- adminutil.c: when writing 'BrowseAllow @LOCAL', add a comment about what
+ to change it to when using directed broadcasts from another subnet
+ (bug #204373).
+
+* Wed Oct 4 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-8
+- LSPP patch didn't get updated properly in 1:1.2.4-6. Use the right
+ patch this time (bug #208676). LSPP re-enabled.
+
+* Wed Oct 4 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-7
+- LSPP patch disabled, since it still causes cupsd to crash.
+
+* Wed Oct 4 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-6
+- Updated LSPP patch from Matt Anderson (bug #208676).
+
+* Tue Oct 3 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-5
+- Updated LSPP patch from Matt Anderson (bug #208676).
+
+* Sun Oct 01 2006 Jesse Keating <jkeating@redhat.com> - 1:1.2.4-4
+- rebuilt for unwind info generation, broken in gcc-4.1.1-21
+
+* Wed Sep 27 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-3
+- Add '--help' option to lpr command (bug #206380, STR #1989).
+
+* Fri Sep 22 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.4-2
+- 1.2.4 (bug #206763). No longer need str1968 patch.
+
+* Wed Sep 13 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.3-5
+- Fixed STR #1968 properly (bug #205619).
+
+* Tue Sep 12 2006 Tim Waugh <twaugh@redhat.com>
+- No longer need language patch.
+
+* Mon Sep 11 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.3-4
+- Applied upstream patch to fix STR #1968 (bug #205619).
+
+* Thu Sep 7 2006 Tim Waugh <twaugh@redhat.com>
+- %%ghost %%config(noreplace) /etc/cups/lpoptions (bug #59022).
+
+* Wed Aug 30 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.3-3
+- Don't overwrite snmp.c.
+- No longer need str1893 patch.
+
+* Wed Aug 30 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.3-2
+- 1.2.3. No longer need str1880 or str1881 patches.
+
+* Tue Aug 29 2006 Tim Waugh <twaugh@redhat.com>
+- Removed dest-cache patch.
+
+* Thu Aug 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-17
+- Fixed another LSPP patch problem (bug #203784).
+- Updated fix for STR #1881 from upstream.
+
+* Thu Aug 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-16
+- Fixed another LSPP patch problem noted by Erwin Rol.
+
+* Thu Aug 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-15
+- Fixed LSPP patch passing NULL to strcmp (bug #203784).
+
+* Mon Aug 21 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-14
+- Updated LSPP patch (bug #203376).
+
+* Fri Aug 18 2006 Jesse Keating <jkeating@redhat.com> - 1:1.2.2-13
+- rebuilt with latest binutils to pick up 64K -z commonpagesize on ppc*
+ (#203001)
+
+* Fri Aug 18 2006 Tim Waugh <twaugh@redhat.com>
+- Own notifier directory (bug #203085).
+
+* Thu Aug 17 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-12
+- Apply patch to fix STR #1880 (bug #200205).
+
+* Wed Aug 16 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-11
+- Use upstream patch to fix STR #1881.
+
+* Fri Aug 11 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-10
+- Remove 'Provides: LPRng = 3.8.15-3' (bug #148757).
+- Applied patch to fix STR #1893 (bug #201800).
+
+* Thu Aug 10 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-9
+- Try different fix for STR #1795/STR #1881 (bug #201167).
+
+* Sun Aug 6 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-8
+- Apply patch from STR #1881 for remote IPP printing (bug #201167).
+
+* Wed Aug 2 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-7
+- Updated LSPP patch from Matt Anderson.
+- Ship pstopdf filter for LSPP.
+
+* Fri Jul 28 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-6
+- Use replacement snmp.c from STR #1737 (bug #193093).
+- Re-enable LSPP; doesn't harm browsing after all.
+
+* Fri Jul 28 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-5
+- Disable LSPP for now, since it seems to break browsing somehow.
+
+* Mon Jul 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-4
+- Fixed package requirements (bug #199903).
+
+* Fri Jul 21 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-3
+- Apply Matt Anderson's LSPP patch.
+- Renumbered patches.
+
+* Thu Jul 20 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.2-2
+- 1.2.2.
+
+* Wed Jul 19 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-21
+- Sync with svn5754. Fixes bug #198987, bug #195532, bug #130118.
+
+* Tue Jul 18 2006 John (J5) Palmieri <johnp@redhat.com> - 1:1.2.1-20
+- Require a new version of D-Bus and rebuild
+
+* Fri Jul 14 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-19
+- Sync with svn5737. Fixes bug #192015.
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 1:1.2.1-18.1
+- rebuild
+
+* Fri Jul 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-18
+- Ship with an empty classes.conf file.
+
+* Tue Jul 4 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-17
+- Sync with svn5706.
+- No longer need localhost, str1740, str1758, str1736, str1776 patches.
+
+* Thu Jun 29 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-16
+- Bumped paps requirement.
+- Don't use texttopaps for application/* MIME types (bug #197214).
+
+* Thu Jun 29 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-15
+- Require paps and use it for printing text (bug #197214).
+
+* Thu Jun 15 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-14
+- Don't export in SSLLIBS to cups-config.
+
+* Thu Jun 15 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-13
+- Fixed cupsd network default printer crash (STR #1776).
+
+* Wed Jun 14 2006 Tomas Mraz <tmraz@redhat.com> - 1:1.2.1-12
+- rebuilt with new gnutls
+
+* Tue Jun 13 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-11
+- Remove certs directory in %%post, not %%postun.
+
+* Tue Jun 13 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-10
+- Remove old-style certs directory after upgrade (bug #194581).
+
+* Wed Jun 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-9
+- Prevent 'too many open files' error (STR #1736, bug #194368).
+
+* Wed Jun 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-8
+- Fix 'Allow from @IF(...)' (STR #1758, bug #187703).
+
+* Wed Jun 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-7
+- ServerBin compatibility patch (bug #194005).
+
+* Fri Jun 2 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-6
+- Applied upstream patch to fix STR #1740 (bug #192809).
+
+* Thu Jun 1 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-5
+- Fixed group ownerships again (bug #192880).
+
+* Thu Jun 1 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-4
+- Fixed 'service cups reload' not to give an error message.
+
+* Thu May 25 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-3
+- Fix 'localhost' fallback in httpAddrGetList() (bug #192628, STR #1723).
+
+* Mon May 22 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.1-2
+- 1.2.1.
+- Another STR #1705 fix (bug #192034).
+- Fixed devel package multilib conflict (bug #192664).
+
+* Mon May 22 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.0-7
+- Sync to svn5568. No longer need rpath patch.
+- Added a 'conflicts:' for kdelibs to prevent bug #192548.
+
+* Sat May 20 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.0-6
+- Sync to svn5555. No longer need str1670 or str1705 patches.
+
+* Fri May 19 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.0-5
+- Sync to svn5545.
+- Ship a driver directory.
+
+* Thu May 18 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.0-4
+- Disable back-channel data in the usb backend (STR #1705, bug #192034).
+- Fix for 'browsing stops on reload', STR #1670 (bug #191217).
+
+* Wed May 16 2006 Tim Waugh <twaugh@redhat.com>
+- Sync to svn5538.
+- Added 'restartlog' to initscript, for clearing out error_log. Useful
+ for problem diagnosis.
+- Initscript no longer needs to check for printconf-backend.
+
+* Tue May 16 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.0-3
+- Added image library build requirements.
+- The devel package requires gnutls-devel (bug #191908).
+
+* Mon May 8 2006 Tim Waugh <twaugh@redhat.com> 1:1.2.0-2
+- 1.2.0.
+
+* Fri May 5 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.5.rc3.4
+- Sync to svn5493.
+
+* Fri May 5 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.5.rc3.3
+- Sync to svn5491.
+
+* Fri Apr 28 2006 Tim Waugh <twaugh@redhat.com>
+- Sync to svn5470.
+- No longer need link, CAN-2005-0064, or no-propagate-ipp-port patches.
+- Switch to upstream PIE implementation (every single binary is PIE).
+- Extend relro to all binaries.
+- Better rpath patch.
+
+* Wed Apr 26 2006 Tim Waugh <twaugh@redhat.com>
+- No longer need backend, rcp, or ppdsdat patches.
+- Use configure switch for LogFilePerm default instead of patch.
+
+* Tue Apr 25 2006 Tim Waugh <twaugh@redhat.com>
+- Own /var/run/cups (bug #189561).
+- Sync from svn5460 to svn5462.
+
+* Tue Apr 25 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.5.rc3.2
+- Patch pdftops to understand 'includeifexists', and use that in the
+ pdftops.conf file (bug #189809).
+
+* Mon Apr 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.5.rc3.1
+- 1.2rc3.
+- Ship an snmp.conf.
+
+* Fri Apr 21 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.4.rc2.2
+- Updated to svn 5446.
+
+* Wed Apr 19 2006 Tim Waugh <twaugh@redhat.com>
+- Ignore .rpmnew and .rpmsave banner files.
+
+* Tue Apr 11 2006 Tim Waugh <twaugh@redhat.com>
+- Ship a /etc/cups/pdftops.conf file (bug #188583).
+
+* Fri Apr 7 2006 Tim Waugh <twaugh@redhat.com>
+- Build requires libacl-devel.
+
+* Fri Apr 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.4.rc2.1
+- 1.2rc2.
+
+* Fri Apr 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.9
+- Sync scheduler/* with svn 5383.
+
+* Fri Apr 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.8
+- No longer need openssl-devel.
+- Build with LDAP_DEPRECATED=1, to pick up declarations of ldap_init() etc.
+- Only warn about ACLs once (STR #1532).
+- Fix imagetops filter (STR #1533).
+- Sync pstops.c with svn 5382.
+
+* Thu Apr 6 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.7
+- Build requires openldap-devel.
+- Sync pstops.c with svn 5372.
+
+* Tue Apr 4 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.6
+- Tweak to allow 'usb:/dev/usb/lp0'-style URIs again.
+
+* Sun Apr 2 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.5
+- Backported svn 5365:5366 change for mutex-protected stringpool (STR #1530).
+
+* Sat Apr 1 2006 Tim Waugh <twaugh@redhat.com>
+- Fixed _cupsStrFree() (STR #1529).
+
+* Fri Mar 31 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.4
+- Fixed interaction with CUPS 1.1 servers (STR #1528).
+
+* Wed Mar 29 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.3
+- Fix group list of non-root backends (STR #1521, bug #186954).
+
+* Tue Mar 28 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.2
+- Fix lpq -h (STR#1515, bug #186686).
+
+* Mon Mar 27 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.1
+- Ship a printers.conf file, and a client.conf file. That way, they get
+ their SELinux file contexts set correctly.
+
+* Mon Mar 27 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.2.rc1.0
+- 1.2rc1.
+
+* Fri Mar 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.6
+- Add KDE compatibility symbols _ipp_add_attr/_ipp_free_attr to ipp.h, with
+ a comment saying why they shouldn't be used.
+
+* Fri Mar 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.5
+- Fix KDE compatibility symbols _ipp_add_attr/_ipp_free_attr.
+
+* Fri Mar 24 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.4
+- Update to svn snapshot.
+
+* Thu Mar 23 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.3
+- Update to svn snapshot. No longer need users or policy patches.
+
+* Fri Mar 17 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.2
+- Rebuilt.
+
+* Tue Mar 14 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.1
+- Build requires gnutls-devel.
+- Fixed default policy name.
+- Fixed 'set-allowed-users' in web UI.
+
+* Mon Mar 13 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b2.0
+- 1.2b2.
+- Use new CUPS_SERVERBIN location (/usr/lib/cups even on 64-bit hosts).
+
+* Fri Mar 10 2006 Tim Waugh <twaugh@redhat.com>
+- Fixed some permissions.
+
+* Fri Mar 10 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b1.1
+- Ship /etc/cups/ssl directory.
+
+* Thu Mar 9 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.1.b1.0
+- 1.2b1. No longer need devid patch.
+
+* Wed Mar 8 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn5238.2
+- Fixed 'device-id' attribute in GET_DEVICES requests (STR #1467).
+
+* Tue Mar 7 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn5238.1
+- New svn snapshot.
+- No longer need browse or raw patches.
+
+* Wed Mar 1 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn5137.1
+- Fixed raw printing.
+- Removed (unapplied) session printing patch.
+- Fixed browse info.
+
+* Thu Feb 23 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn5137.0
+- New svn snapshot.
+
+* Fri Feb 17 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn5102.0
+- New svn snapshot.
+- No longer need enabledisable patch.
+- Fixed double-free in scheduler/policy.c (STR #1428).
+
+* Fri Feb 10 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn5083.0
+- New svn snapshot.
+
+* Wed Jan 25 2006 Tim Waugh <twaugh@redhat.com> 1:1.2-0.0.svn4964.0
+- Use -fPIE not -fpie in PIE patch.
+- Fix link patch.
+- Patch in PIE instead of using --enable-pie, since that doesn't work.
+
+* Fri Jan 20 2006 Tim Waugh <twaugh@redhat.com>
+- 1.2 svn snapshot.
+- No longer need doclink, str1023, pdftops, sanity, lpstat, str1068,
+ sigchld, gcc34, gcc4, slow, CAN-2004-0888, CAN-2005-2097, finddest,
+ str1249, str1284, str1290, str1301, CVE-2005-3625,6,7 patches.
+- Removed autodetect-tag patch.
+
+* Tue Jan 17 2006 Tim Waugh <twaugh@redhat.com> 1:1.1.23-30
+- Include 'Autodetected' tag for better integration with autodetection tools.
+
+* Tue Jan 10 2006 Tim Waugh <twaugh@redhat.com> 1:1.1.23-29
+- Apply dest-cache-v2 patch (bug #175847).
+
+* Wed Jan 4 2006 Tim Waugh <twaugh@redhat.com> 1:1.1.23-28
+- Apply patch to fix CVE-2005-3625, CVE-2005-3626, CVE-2005-3627
+ (bug #176868).
+
+* Mon Dec 19 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-27
+- Link pdftops with -z relro.
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Thu Dec 01 2005 John (J5) Palmieri <johnp@redhat.com> - 1:1.1.23-26
+- rebuild for new dbus
+
+* Tue Nov 8 2005 Tomas Mraz <tmraz@redhat.com> 1:1.1.23-25
+- rebuilt with new openssl
+
+* Thu Oct 20 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-24
+- Build with -fstack-protector-all.
+
+* Sat Oct 15 2005 Florian La Roche <laroche@redhat.com> 1:1.1.23-23
+- link libcupsimage.so against libcups
+
+* Tue Oct 11 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-22
+- Apply patch to fix STR #1301 (bug #169979).
+
+* Thu Oct 6 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-21
+- Apply patch to fix STR #1290.
+
+* Wed Oct 5 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-20
+- Apply upstream patch for STR #1249.
+
+* Fri Sep 30 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-19
+- Use upstream patch for STR #1284.
+
+* Fri Sep 30 2005 Tomas Mraz <tmraz@redhat.com>
+- use include instead of pam_stack in pam config
+
+* Thu Sep 29 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-18
+- Raise IPP_MAX_VALUES to 100 (bug #164232). STR #1284.
+- Made FindDest better behaved in some instances (bug #164232). STR #1283.
+
+* Fri Sep 2 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-17
+- Fixed CAN-2005-2097 (bug #164510).
+
+* Thu Jun 16 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-16
+- Make DeletePrinterFromClass faster (bug #160620).
+
+* Thu Mar 31 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-15
+- Don't require exact dbus version, just minimum.
+
+* Thu Mar 10 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-14
+- Fixed up dbus patch so that it compiles.
+
+* Wed Mar 9 2005 John (J5) Palmieri <johnp@redhat.com>
+- Fix up dbus patch
+
+* Mon Mar 7 2005 John (J5) Palmieri <johnp@redhat.com> 1:1.1.23-13
+- Fixed up dbus patch to work with dbus 0.31
+
+* Tue Mar 1 2005 Tomas Mraz <tmraz@redhat.com> 1:1.1.23-12
+- rebuild for openssl-0.9.7e
+
+* Tue Feb 22 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-11
+- UTF-8-ify spec file (bug #149293).
+
+* Fri Feb 18 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-10
+- Fixed build with GCC 4.
+
+* Thu Feb 10 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-9
+- Back to old DBUS API since new DBUS isn't built yet.
+
+* Mon Feb 7 2005 Tim Waugh <twaugh@redhat.com>
+- Use upstream patch for STR #1068.
+- Apply patch to fix remainder of CAN-2004-0888 (bug #135378).
+
+* Wed Feb 2 2005 Tim Waugh <twaugh@redhat.com>
+- Applied patch to prevent occasional cupsd crash on reload (bug #146850).
+
+* Tue Feb 1 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-8
+- New DBUS API.
+
+* Tue Feb 1 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-7
+- Applied patch to prevent file descriptor confusion (STR #1068).
+
+* Fri Jan 28 2005 Tim Waugh <twaugh@redhat.com>
+- Build does not require XFree86-devel (bug #146397).
+
+* Thu Jan 27 2005 Tim Waugh <twaugh@redhat.com>
+- Corrected directory modes so that they reflect what cupsd sets them to.
+
+* Mon Jan 24 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-6
+- Build against new dbus.
+
+* Fri Jan 21 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-5
+- Use tmpwatch to remove unused files in the spool temporary directory
+ (bug #110026).
+
+* Thu Jan 20 2005 Tim Waugh <twaugh@redhat.com>
+- Use gzip's -n flag for the PPDs.
+
+* Thu Jan 20 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-4
+- Mark the initscript noreplace (bug #145629).
+
+* Wed Jan 19 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-3
+- Applied patch to fix CAN-2005-0064.
+
+* Thu Jan 6 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-2
+- Fixed patch from STR #1023.
+
+* Tue Jan 4 2005 Tim Waugh <twaugh@redhat.com> 1:1.1.23-1
+- 1.1.23.
+
+* Mon Dec 20 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.23-0.rc1.1
+- 1.1.23rc1.
+- No longer need ioctl, ref-before-use, str1023 or str1024 patches.
+
+* Fri Dec 17 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-6
+- Use upstream patches for bug #143086.
+
+* Thu Dec 16 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-5
+- Fixed STR #1023 (part of bug #143086).
+- Fixed STR #1024 (rest of bug #143086).
+
+* Thu Dec 9 2004 Tim Waugh <twaugh@redhat.com>
+- Not all files in the doc directory are pure documentation (bug #67337).
+
+* Thu Dec 9 2004 Tim Waugh <twaugh@redhat.com>
+- Fixed ioctl parameter size in usb backend. Spotted by David A. Marlin.
+
+* Fri Dec 3 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-4
+- Convert de and fr .tmpl files into UTF-8 (bug #136177).
+
+* Thu Dec 2 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-3
+- Fix ref-before-use bug in debug output (bug #141585).
+
+* Mon Nov 29 2004 Tim Waugh <twaugh@redhat.com>
+- Copied "ext" patch over from xpdf RPM package.
+
+* Mon Nov 22 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-2
+- Fixed cups-lpd file mode (bug #137325).
+- Convert all man pages to UTF-8 (bug #107118). Patch from Miloslav Trmac.
+
+* Mon Nov 8 2004 Tim Waugh <twaugh@redhat.com>
+- New lpd subpackage, from patch by Matthew Galgoci (bug #137325).
+
+* Tue Nov 2 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-1
+- 1.1.22.
+- No longer need ippfail, overread or str970 patches.
+
+* Tue Oct 26 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc2.1
+- Make cancel-cups(1) man page point to lp-cups(1) not lp(1) (bug #136973).
+- Use upstream patch for STR #953.
+- 1.1.22rc2.
+
+* Wed Oct 20 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc1.7
+- Prevent filters generating incorrect PS in locales where "," is the
+ decimal separator (bug #136102). Patch from STR #970.
+
+* Thu Oct 14 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc1.5
+- Fixed another typo in last patch!
+
+* Thu Oct 14 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc1.4
+- Fixed typo in last patch.
+
+* Thu Oct 14 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc1.3
+- Another attempt at fixing bug #135502.
+
+* Wed Oct 13 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc1.2
+- Fail better when receiving corrupt IPP responses (bug #135502).
+
+* Mon Oct 11 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.22-0.rc1.1
+- 1.1.22rc1.
+
+* Tue Oct 5 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-7
+- Set LogFilePerm 0600 in default config file.
+
+* Tue Oct 5 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-6
+- Apply patch to fix CAN-2004-0923 (bug #134601).
+
+* Mon Oct 4 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-5
+- Fixed reload logic (bug #134080).
+
+* Wed Sep 29 2004 Warren Togami <wtogami@redhat.com> 1:1.1.21-4
+- Remove .pdf from docs, fix links
+
+* Fri Sep 24 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-3
+- Write a pid file (bug #132987).
+
+* Thu Sep 23 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-2
+- 1.1.21.
+
+* Thu Sep 9 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc2.2
+- Updated DBUS patch (from Colin Walters).
+
+* Tue Aug 24 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc2.1
+- 1.1.21rc2.
+- No longer need state, reload-timeout or str743 patches.
+- httpnBase64 patch no longer applies; alternate method implemented
+ upstream.
+- Fix single byte overread in usersys.c (spotted by Colin Walters).
+
+* Wed Aug 18 2004 Tim Waugh <twaugh@redhat.com>
+- Applied httpnEncode64 patch from Colin Walters.
+
+* Sun Aug 15 2004 Tim Waugh <twaugh@redhat.com>
+- Session printing patch (Colin Walters). Disabled for now.
+
+* Sun Aug 15 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.9
+- Shorter reload timeout (Colin Walters).
+- Updated DBUS patch from Colin Walters.
+
+* Fri Aug 13 2004 Tim Waugh <twaugh@redhat.com>
+- Updated IPP backend IPP_PORT patch from Colin Walters.
+
+* Fri Aug 13 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.8
+- Preserve DBUS_SESSION_BUS_ADDRESS in environment (Colin Walters).
+- Fixed enabledisable patch.
+
+* Fri Aug 13 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.7
+- Bumped DBUS version to 0.22.
+
+* Fri Aug 6 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.6
+- Patch from Colin Walters to prevent IPP backend using non-standard
+ IPP port.
+
+* Sun Aug 1 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.5
+- Really bumped DBUS version.
+
+* Fri Jul 30 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.4
+- Bumped DBUS version.
+
+* Fri Jul 16 2004 Tim Waugh <twaugh@redhat.com>
+- Added version to LPRng obsoletes: tag (bug #128024).
+
+* Thu Jul 8 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.3
+- Updated DBUS patch.
+
+* Tue Jun 29 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.2
+- Apply patch from STR #743 (bug #114999).
+
+* Fri Jun 25 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-1.rc1.1
+- Fix permissions on logrotate script (bug #126426).
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri Jun 4 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-0.rc1.2
+- Build for dbus-0.21.
+- Fix SetPrinterState().
+
+* Thu Jun 3 2004 Tim Waugh <twaugh@redhat.com>
+- Use configure's --with-optim parameter instead of setting OPTIM at
+ make time (bug #125228).
+
+* Thu Jun 3 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.21-0.rc1.1
+- 1.1.21rc1.
+- No longer need str716, str718, authtype or encryption patches.
+
+* Wed Jun 2 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-15
+- Build on ppc and ppc64 again.
+
+* Wed Jun 2 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-14
+- ExcludeArch ppc, ppc64.
+- More D-BUS changes.
+
+* Tue Jun 1 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-13
+- Enable optimizations on ia64 again.
+
+* Thu May 27 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-12
+- D-BUS changes.
+
+* Wed May 26 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-11
+- Build requires make >= 3.80 (bug #124472).
+
+* Wed May 26 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-10
+- Finish fix for cupsenable/cupsdisable (bug #102490).
+- Fix MaxLogSize setting (bug #123003).
+
+* Tue May 25 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-9
+- Apply patches from CVS (authtype) to fix STR #434, STR #611, and as a
+ result STR #719. This fixes several problems including those noted in
+ bug #114999.
+
+* Mon May 24 2004 Tim Waugh <twaugh@redhat.com>
+- Use upstream patch for exit code fix for bug #110135 [STR 718].
+
+* Wed May 19 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-8
+- If cupsd fails to start, make it exit with an appropriate code so that
+ initlog notifies the user (bug #110135).
+
+* Thu May 13 2004 Tim Waugh <twaugh@redhat.com>
+- Fix cups/util.c:get_num_sdests() to use encryption when it is necessary
+ or requested (bug #118982).
+- Use upstream patch for the HTTP/1.1 Continue bug (from STR716).
+
+* Tue May 11 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-7
+- Fix non-conformance with HTTP/1.1, which caused failures when printing
+ to a Xerox Phaser 8200 via IPP (bug #122352).
+- Make lppasswd(1) PIE.
+- Rotate logs within cupsd (instead of relying on logrotate) if we start
+ to approach the filesystem file size limit (bug #123003).
+
+* Tue Apr 6 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-6
+- Fix pie patch (bug #120078).
+
+* Fri Apr 2 2004 Tim Waugh <twaugh@redhat.com>
+- Fix rcp patch for new system-config-printer name.
+
+* Tue Mar 02 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri Feb 6 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-4
+- Tracked D-BUS API changes.
+- Updated D-BUS configuration file.
+- Symlinks to avoid conflicting with bash builtins (bug #102490).
+
+* Thu Feb 5 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-3
+- Improved PIE patch.
+- Fixed compilation with GCC 3.4.
+
+* Thu Jan 29 2004 Tim Waugh <twaugh@redhat.com>
+- Don't ship cupsconfig now that nothing uses it.
+
+* Wed Jan 7 2004 Tim Waugh <twaugh@redhat.com> 1:1.1.20-2
+- Try harder to find a translated page for the web interface (bug #107619).
+- Added build_as_pie conditional to spec file to facilitate debugging.
+
+* Mon Dec 1 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.20-1
+- 1.1.20.
+- No longer need idefense, str226 patches.
+- Updated sanity patch.
+- The devel sub-package requires openssl-devel (bug #110772).
+
+* Wed Nov 26 2003 Thomas Woerner <twoerner@redhat.com> 1:1.1.19-16
+- removed -Wl,-rpath from cups-sharedlibs.m4 (replaced old no_rpath patch)
+
+* Tue Nov 25 2003 Thomas Woerner <twoerner@redhat.com> 1:1.1.19-15
+- no rpath in cups-config anymore
+
+* Thu Nov 20 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-14
+- Enable PIE for cupsd.
+
+* Fri Nov 14 2003 Tim Waugh <twaugh@redhat.com>
+- Don't ignore the file descriptor when ShutdownClient is called: it
+ might get closed before we next try to read it (bug #107787).
+
+* Tue Oct 14 2003 Tim Waugh <twaugh@redhat.com>
+- Removed busy-loop patch; 1.1.19 has its own fix for this.
+
+* Thu Oct 2 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-13
+- Apply patch from STR 226 to make CUPS reload better behaved (bug #101507).
+
+* Wed Sep 10 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-12
+- Prevent a libcups busy loop (bug #97958).
+
+* Thu Aug 14 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-11
+- Another attempt to fix bug #100984.
+
+* Wed Aug 13 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-10
+- Pass correct attributes-natural-language through even in the absence
+ of translations for that language (bug #100984).
+- Show compilation command lines.
+
+* Wed Jul 30 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-9
+- Prevent lpstat displaying garbage.
+
+* Mon Jul 21 2003 Tim Waugh <twaugh@redhat.com>
+- Mark mime.convs and mime.types as config files (bug #99461).
+
+* Mon Jun 23 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-8
+- Start cupsd before nfs server processes (bug #97767).
+
+* Tue Jun 17 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-7
+- Add some %%if %%use_dbus / %%endif's to make it compile without dbus
+ (bug #97397). Patch from Jos Vos.
+
+* Mon Jun 16 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-6
+- Don't busy loop in the client if the IPP port is in use by another
+ app (bug #97468).
+
+* Tue Jun 10 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-5
+- Mark pam.d/cups as config file not to be replaced (bug #92236).
+
+* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Tue Jun 3 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-3
+- Provide a version for LPRng (bug #92145).
+
+* Thu May 29 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-2
+- Obsolete LPRng now.
+
+* Tue May 27 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-1
+- 1.1.19. No longer need optparse patch.
+
+* Sat May 17 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-0.rc5.4
+- Ship configuration file for D-BUS.
+
+* Fri May 16 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-0.rc5.3
+- Rebuild for dbus-0.11 API changes.
+- Fix ownership in file manifest (bug #90840).
+
+* Wed May 14 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-0.rc5.2
+- Fix option parsing in lpq (bug #90823).
+
+* Tue May 13 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-0.rc5.1
+- 1.1.19rc5.
+
+* Thu May 8 2003 Tim Waugh <twaugh@redhat.com> 1:1.1.19-0.rc4.1
+- 1.1.19rc4. Ported initscript, idefense, ppdsdat, dbus patches.
+- No longer need error, sigchld patches.
+- Ship cupstestppd.
+
+* Thu Apr 24 2003 Tim Waugh <twaugh@redhat.com>
+- Mark banners as config files (bug #89069).
+
+* Sat Apr 12 2003 Havoc Pennington <hp@redhat.com> 1:1.1.18-4
+- adjust dbus patch - dbus_bus_get() sends the hello for you,
+ and there were a couple of memleaks
+- buildprereq dbus 0.9
+- rebuild for new dbus
+- hope it works, I'm ssh'd in with no way to test. ;-)
+
+* Thu Apr 10 2003 Tim Waugh <twaugh@redhat.com> 1.1.18-3
+- Get on D-BUS.
+
+* Fri Mar 28 2003 Tim Waugh <twaugh@redhat.com> 1.1.18-2
+- Fix translation in the init script (bug #87551).
+
+* Wed Mar 26 2003 Tim Waugh <twaugh@redhat.com> 1.1.18-1.1
+- Turn off optimization on ia64 until bug #87383 is fixed.
+
+* Wed Mar 26 2003 Tim Waugh <twaugh@redhat.com> 1.1.18-1
+- 1.1.18.
+- No longer need uninit patch.
+- Some parts of the iDefense and pdftops patches seem to have been
+ picked up, but not others.
+
+* Wed Feb 12 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-13
+- Don't set SIGCHLD to SIG_IGN when using wait4 (via pclose) (bug #84101).
+
+* Tue Feb 4 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-12
+- Fix cups-lpd (bug #83452).
+
+* Fri Jan 31 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-11
+- Build ppds.dat on first install.
+
+* Fri Jan 24 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-10
+- Add support for rebuilding ppds.dat without running the scheduler
+ proper (for bug #82500).
+
+* Wed Jan 22 2003 Tim Powers <timp@redhat.com> 1.1.17-9
+- rebuilt
+
+* Wed Jan 22 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-8
+- Warn against editing queues managed by redhat-config-printer
+ (bug #82267).
+
+* Wed Jan 22 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-7
+- Fix up error reporting in lpd backend.
+
+* Thu Jan 9 2003 Tim Waugh <twaugh@redhat.com> 1.1.17-6
+- Add epoch to internal requirements.
+- Make 'condrestart' return success exit code when daemon isn't running.
+
+* Tue Jan 7 2003 Nalin Dahyabhai <nalin@redhat.com> 1.1.17-5
+- Use pkg-config information to find SSL libraries.
+
+* Thu Dec 19 2002 Tim Waugh <twaugh@redhat.com> 1.1.17-4
+- Security fixes.
+- Make 'service cups reload' update the configuration first (bug #79953).
+
+* Tue Dec 10 2002 Tim Waugh <twaugh@redhat.com> 1.1.17-3
+- Fix cupsd startup hang (bug #79346).
+
+* Mon Dec 9 2002 Tim Waugh <twaugh@redhat.com> 1.1.17-2
+- Fix parallel backend behaviour when cancelling jobs.
+
+* Mon Dec 9 2002 Tim Waugh <twaugh@redhat.com> 1.1.17-1
+- 1.1.17.
+- No longer need libdir patch.
+- Fix logrotate script (bug #76791).
+
+* Wed Nov 20 2002 Tim Waugh <twaugh@redhat.com>
+- Build requires XFree86-devel (bug #78362).
+
+* Wed Nov 20 2002 Tim Waugh <twaugh@redhat.com>
+- 1.1.16.
+- Updated system-auth patch.
+- Add ncp backend script.
+
+* Wed Nov 13 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-15
+- Set alternatives priority to 40.
+
+* Mon Nov 11 2002 Nalin Dahyabhai <nalin@redhat.com> 1.1.15-14
+- Buildrequire pam-devel.
+- Patch default PAM config file to remove directory names from module paths,
+ allowing the configuration files to work equally well on multilib systems.
+- Patch default PAM config file to use system-auth, require the file at build-
+ time because that's what data/Makefile checks for.
+
+* Fri Nov 8 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-13
+- Use logrotate for log rotation (bug #76791).
+- No longer need cups.desktop, since redhat-config-printer handles it.
+
+* Thu Oct 17 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-12
+- Revert to libdir for CUPS_SERVERBIN.
+
+* Thu Oct 17 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-11
+- Use %%configure for multilib correctness.
+- Use libexec instead of lib for CUPS_SERVERBIN.
+- Ship translated man pages.
+- Remove unshipped files.
+- Fix file list permissions (bug #59021, bug #74738).
+- Fix messy initscript output (bug #65857).
+- Add 'reload' to initscript (bug #76114).
+
+* Fri Aug 30 2002 Bernhard Rosenkraenzer <bero@redhat.de> 1.1.15-10
+- Add generic postscript PPD file (#73061)
+
+* Mon Aug 19 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-9
+- Fix prefix in pstoraster (bug #69573).
+
+* Mon Aug 19 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-8
+- Disable cups-lpd by default (bug #71712).
+- No need for fread patch now that glibc is fixed.
+
+* Thu Aug 15 2002 Tim Waugh <twaugh@redhat.com> 1.1.15-7
+- Really add cups-lpd xinetd file (bug #63919).
+- Ship pstoraster (bug #69573).
+- Prevent fread from trying to read from beyond EOF (fixes a segfault
+ with new glibc).
+
+* Sat Aug 10 2002 Elliot Lee <sopwith@redhat.com> 1.1.15-6
+- rebuilt with gcc-3.2 (we hope)
+
+* Mon Aug 5 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.15-5
+- Add cups-lpd xinetd file (#63919)
+
+* Tue Jul 23 2002 Florian La Roche <Florian.LaRoche@redhat.de> 1.1.15-4
+- add a "exit 0" to postun script
+
+* Tue Jul 2 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.15-3
+- Add a symlink /usr/share/cups/doc -> /usr/share/doc/cups-devel-1.1.15
+ because some applications expect to find the cups docs in
+ /usr/share/cups/doc
+
+* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Fri Jun 21 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.15-1
+- 1.1.15-1
+- Fix up smb printing trigger (samba-client, not samba-clients)
+- Start cupsd earlier, apparently it needs to be running before samba
+ starts up for smb printing to work.
+
+* Thu May 23 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Tue May 7 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-17
+- Rebuild in current environment
+- [-16 never existed because of build system breakage]
+
+* Wed Apr 17 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-15
+- Fix bug #63387
+
+* Mon Apr 15 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-14
+- Fix dangling symlink created by samba-clients trigger
+
+* Wed Apr 10 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-13
+- Add desktop file and icon for CUPS configuration
+
+* Wed Apr 3 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-12
+- Support SMB printing (#62407)
+- Add HTML redirections to doc files to work around users mistaking
+ /usr/share/doc/cups-1.1.14 for the web frontend (#62405)
+
+* Tue Apr 2 2002 Bill Nottingham <notting@redhat.com> 1.1.14-11
+- fix subsys in initscript (#59206)
+- don't strip binaries
+
+* Mon Mar 11 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-10
+- Make initscript use killproc instead of killall
+
+* Fri Mar 8 2002 Bill Nottingham <notting@redhat.com> 1.1.14-9
+- use alternatives --initscript support
+
+* Mon Mar 4 2002 Bill Nottingham <notting@redhat.com> 1.1.14-8
+- use the right path for the lpc man page, duh
+
+* Thu Feb 28 2002 Bill Nottingham <notting@redhat.com> 1.1.14-7
+- lpc man page is alternative too
+- run ldconfig in -libs %%post/%%postun, not main
+- remove alternatives in %%preun
+
+* Wed Feb 27 2002 Bill Nottingham <notting@redhat.com> 1.1.14-6
+- don't source /etc/sysconfig/network in cups.init, we don't use any
+ values from it
+
+* Tue Feb 26 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-4
+- Fix bugs #60220 and #60352
+
+* Thu Feb 21 2002 Tim Powers <timp@redhat.com>
+- rebuild against correct version of openssl (0.9.6b)
+
+* Wed Feb 20 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-2
+- Add all man pages to alternatives (#59943)
+- Update to real 1.1.14
+
+* Tue Feb 12 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.14-1
+- Update to almost-1.1.14
+
+* Mon Feb 11 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.13-5
+- Move cups-config to cups-devel subpackage
+- Make alternatives usage a %%define to simplify builds for earlier
+ releases
+- Explicitly provide things we're supplying through alternatives
+ to shut up kdeutils dependencies
+
+* Tue Feb 5 2002 Tim Powers <timp@redhat.com>
+- shut the alternatives stuff up for good
+
+* Fri Feb 1 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.13-3
+- Fix alternatives stuff
+- Don't display error messages in %%post
+
+* Wed Jan 30 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.13-2
+- alternatives stuff
+
+* Tue Jan 29 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.13-1
+- 1.1.13
+- Add patch for koi8-{r,u} and iso8859-8 encodings (#59018)
+- Rename init scripts so we can safely "killall cupsd" from there
+
+* Sat Jan 26 2002 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.12-1
+- Initial (conflicting, since alternatives isn't there yet) packaging for
+ Red Hat Linux
+
+* Sat Jan 19 2002 Bernhard Rosenkraenzer <bero@redhat.com>
+- 1.1.12
+
+* Mon Nov 5 2001 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.10-3
+- Compress PPD files
+- Fix build with gcc 3.1
+- Fix init script
+
+* Tue Sep 4 2001 Bernhard Rosenkraenzer <bero@redhat.com> 1.1.10-2
+- Fix URL
+- Generate printcap
+- s/Copyright/License/g
+
+* Tue Sep 4 2001 Than Ngo <than@redhat.com> 1.1.10-1
+- update to 1.1.10-1 for ExtraBinge 7.2
+
+* Tue May 29 2001 Michael Stefaniuc <mstefani@redhat.com>
+- update to 1.1.8
+- changed cupsd.conf to generate /etc/printcap
+
+* Tue May 15 2001 Than Ngo <than@redhat.com>
+- update to 1.1.7, bugfixes
+
+* Thu Dec 14 2000 Than Ngo <than@redhat.com>
+- fixed package dependency with lpr and LPRng
+
+* Wed Oct 25 2000 Than Ngo <than@redhat.com>
+- remove man/cat
+
+* Tue Oct 24 2000 Than Ngo <than@redhat.com>
+- don't start cupsd service in level 0, fixed
+
+* Thu Oct 19 2000 Than Ngo <than@redhat.com>
+- update to 1.1.4
+- fix CUPS_DOCROOT (Bug #18717)
+
+* Fri Aug 11 2000 Than Ngo <than@redhat.de>
+- update to 1.1.2 (Bugfix release)
+
+* Fri Aug 4 2000 Than Ngo <than@redhat.de>
+- fix, cupsd read config file under /etc/cups (Bug #15432)
+- add missing cups filters
+
+* Wed Aug 2 2000 Tim Powers <timp@redhat.com>
+- rebuilt against libpng-1.0.8
+
+* Tue Aug 01 2000 Than Ngo <than@redhat.de>
+- fix permission, add missing ldconfig in %%post and %%postun (Bug #14963)
+
+* Sat Jul 29 2000 Bernhard Rosenkraenzer <bero@redhat.com>
+- 1.1.1 (this has some major bugfixes)
+- Fix a typo in initscript (it's $?, not ?$)
+- Fix /usr/etc vs. /etc trouble, don't insist on /usr/var (YUCK!)
+- Create the spool dir
+
+* Fri Jul 28 2000 Than Ngo <than@redhat.de>
+- fix unclean code for building against gcc-2.96
+- add missing restart function in startup script
+
+* Fri Jul 28 2000 Tim Powers <timp@redhat.com>
+- fixed initscript so that conrestart doesn't return 1 if the test fails
+
+* Mon Jul 24 2000 Prospector <prospector@redhat.com>
+- rebuilt
+
+* Wed Jul 19 2000 Than Ngo <than@redhat.de>
+- using service to fire them up
+- fix Prereq section
+
+* Mon Jul 17 2000 Tim Powers <timp@redhat.com>
+- added defattr to the devel package
+
+* Sun Jul 16 2000 Than Ngo <than@redhat.de>
+- add cups config files
+
+* Sat Jul 15 2000 Than Ngo <than@redhat.de>
+- update to 1.1 release
+- move back to /etc/rc.d/init.d
+- fix cupsd.init to work with /etc/init.d and /etc/rc.d/init.d
+- split cups
+
+* Wed Jul 12 2000 Than Ngo <than@redhat.de>
+- rebuilt
+
+* Thu Jul 06 2000 Tim Powers <timp@redhat.com>
+- fixed broken PreReq to now require /etc/init.d
+
+* Tue Jun 27 2000 Tim Powers <timp@redhat.com>
+- PreReq initscripts >= 5.20
+
+* Mon Jun 26 2000 Tim Powers <timp@redhat.com>
+- started changelog
+- fixed init.d script location
+- changed script in init.d quite a bit and made more like the rest of our
+ startup scripts
diff --git a/cupsprinter.png b/cupsprinter.png
new file mode 100644
index 0000000..324df1c
--- /dev/null
+++ b/cupsprinter.png
Binary files differ
diff --git a/macros.cups b/macros.cups
new file mode 100644
index 0000000..5b560d9
--- /dev/null
+++ b/macros.cups
@@ -0,0 +1 @@
+%_cups_serverbin %(/usr/bin/cups-config --serverbin)
diff --git a/ncp.backend b/ncp.backend
new file mode 100755
index 0000000..d57ada1
--- /dev/null
+++ b/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/pstopdf b/pstopdf
new file mode 100644
index 0000000..938efbe
--- /dev/null
+++ b/pstopdf
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# CUPS filter script for Ghostscript.
+#
+# Copyright 2001-2002 by Easy Software Products.
+# Copyright 2006 by Hewlett-Packard Development Company, L.P.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# Installation directories...
+prefix=/usr
+exec_prefix=${prefix}
+bindir=${exec_prefix}/bin
+
+# Set the library/font path...
+GS_FONTPATH="$CUPS_FONTPATH"
+export GS_FONTPATH
+
+# Options we use with Ghostscript...
+gsopts="-dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH "
+gsopts="$gsopts -dNOMEDIAATTRS -sDEVICE=pdfwrite -sstdout=%stderr"
+
+# See if we have a profile=n,n,n,n,n,n,n,n,n,n,n option...
+profile=""
+for option in $5; do
+ case $option in
+ profile=*)
+ profile="-scupsProfile=`echo $option | awk -F= '{print $2}'`"
+ ;;
+ esac
+done
+
+# See if we have a filename on the command-line...
+if test -z "$6"; then
+ ifile="-"
+else
+ ifile="$6"
+fi
+
+# Now run Ghostscript...
+$bindir/gs $gsopts -sOUTPUTFILE="%stdout" $profile $ifile
+
diff --git a/textonly.filter b/textonly.filter
new file mode 100755
index 0000000..504bc4d
--- /dev/null
+++ b/textonly.filter
@@ -0,0 +1,124 @@
+#!/bin/bash
+## Copyright (C) 2003-2006 Red Hat, Inc.
+## Copyright (C) 2003-2006 Tim Waugh <twaugh@redhat.com>
+## Changed on 2007/05/17, Opher Shachar, LADPC Ltd.
+## Added support for page-ranges option.
+## Added page accounting.
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+if [ $# == 0 ]; then
+ echo >&2 "ERROR: $0 job-id user title copies options [file]"
+ exit 1
+fi
+
+# Extract the papersize
+SENDFF=`grep '^\*DefaultSendFF' "$PPD" | cut -d\ -f2`
+COPIES=1
+if [ $# -ge 4 ]; then
+ COPIES="$4"
+fi
+
+if [ "$COPIES" -gt 1 ] && [ $# -lt 6 ]; then
+ unset TMPFILE
+ trap -- 'rm -f "$TMPFILE"' EXIT
+ TMPFILE=$(mktemp ${TMPDIR:-/tmp}/textonly.XXXXXX)
+ cat > "$TMPFILE"
+else
+ TMPFILE="$6"
+fi
+
+PR=${5#*page-ranges=}
+# Do options specify page-ranges?
+if [[ "$PR" != "$5" ]]; then
+ PR=${PR%% *}
+else
+ #unset PR
+ PR=1-999999
+fi
+
+if [[ "$PR" ]]; then
+ TMPFILE2=$(mktemp ${TMPDIR:-/tmp}/textonly2.XXXXXX)
+ pagenum=0
+ EOF=
+ {
+ while [[ "$PR" ]]; do
+ pl=${PR%%,*} ;# take first subrange
+ PR=${PR#$pl};PR=${PR#,} ;# remove from range list
+ pu=${pl#*-} ;# extract upper and lower
+ pl=${pl%-*} ;# pages of subrange
+ # Allows interpreting 0-5,3-10 as 1-5,6-10 rejects 5-1 or 1-
+ (( pagenum >= pl )) && pl=$(( pagenum + 1 ))
+ (( pl > pu )) && continue
+
+ # Loop reading pages until at or over lower page of subrange.
+ while read -d `echo -ne '\f'` -r; do
+ (( pagenum++ ))
+ (( pagenum == pl )) && break
+ done
+ # Did we reach lower page of subrange or EOF?
+ if (( pagenum < pl )); then
+ [[ ! "$REPLY" ]] && break ;# empty last page - we're done.
+ (( pagenum++ ))
+ EOF=y
+ fi
+ # Output page and report to page log
+ if (( pagenum == pl )); then
+ echo -n "${REPLY}" >>"$TMPFILE2"
+ # If EOF then page has no final FF
+ [[ ! "$EOF" ]] && echo -ne '\f' >>"$TMPFILE2"
+ echo "PAGE: $pagenum $COPIES" >&2
+ fi
+ [[ "$EOF" ]] && break
+ # Is the current subrange a single page?
+ (( pagenum == pu )) && continue
+ while read -d `echo -ne '\f'` -r; do
+ (( pagenum++ ))
+ echo -ne "${REPLY}\f" >>"$TMPFILE2"
+ echo "PAGE: $pagenum $COPIES" >&2
+ (( pagenum == pu )) && break
+ done
+ # Could be that we reached EOF before page boundry
+ if (( pagenum < pu )); then
+ if [[ "$REPLY" ]]; then
+ (( pagenum++ ))
+ echo -n "${REPLY}" >>"$TMPFILE2"
+ echo "PAGE: $pagenum $COPIES" >&2
+ fi
+ break
+ fi
+ done
+ } <"$TMPFILE"
+else
+ TMPFILE2="$TMPFILE"
+ pc=$(grep -co `echo -ne '\f'` "$TMPFILE2")
+ pc=$(( pc * $COPIES ))
+ echo "PAGE: $pc" >&2
+fi
+
+while [ "$COPIES" -gt 0 ]; do
+ # Just translate LF->CRLF at the moment, until the PPD has options added.
+ sed -e 's/$/'`echo -ne '\r'`'/g' "$TMPFILE2"
+
+ if [ "$SENDFF" == "True" ]
+ then
+ echo -ne '\f'
+ fi
+
+ COPIES=$(($COPIES - 1))
+done
+# Cleanup
+[[ "$TMPFILE" != "$TMPFILE2" ]] && rm -f "$TMPFILE2"
+exit 0
diff --git a/textonly.ppd b/textonly.ppd
new file mode 100644
index 0000000..89060bc
--- /dev/null
+++ b/textonly.ppd
@@ -0,0 +1,47 @@
+*PPD-Adobe: "4.3"
+*%
+*% Text-only printer definition
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "TEXTONLY.PPD"
+*Manufacturer: "Generic"
+*Product: "(Generic)"
+*cupsVersion: 1.0
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*cupsFilter: "text/plain 0 textonly"
+*ModelName: "Generic text-only printer"
+*ShortNickName: "Generic text-only printer"
+*NickName: "Generic text-only printer"
+*PSVersion: "(2017.000) 0"
+*LanguageLevel: "2"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "8"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 756"
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/Letter: "612 792"
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*OpenUI *SendFF: Boolean
+*DefaultSendFF: False
+*SendFF True/True: ""
+*SendFF False/False: ""
+*CloseUI: *SendFF