diff options
| -rw-r--r-- | abs/extra-testing/cups/PKGBUILD | 105 | ||||
| -rwxr-xr-x | abs/extra-testing/cups/cups | 38 | ||||
| -rw-r--r-- | abs/extra-testing/cups/cups-1.3.7-peercred.patch | 11 | ||||
| -rw-r--r-- | abs/extra-testing/cups/cups-avahi.patch | 1089 | ||||
| -rw-r--r-- | abs/extra-testing/cups/cups.install | 11 | ||||
| -rw-r--r-- | abs/extra-testing/cups/cups.logrotate | 8 | ||||
| -rw-r--r-- | abs/extra-testing/cups/cups.pam | 3 | ||||
| -rw-r--r-- | abs/extra-testing/cups/fix-infinite-usb-loop.patch | 35 | 
8 files changed, 1300 insertions, 0 deletions
| diff --git a/abs/extra-testing/cups/PKGBUILD b/abs/extra-testing/cups/PKGBUILD new file mode 100644 index 0000000..e1f13b7 --- /dev/null +++ b/abs/extra-testing/cups/PKGBUILD @@ -0,0 +1,105 @@ +# $Id: PKGBUILD 82848 2010-06-18 06:18:19Z andyrtr $ +# Maintainer: Andreas Radke <andyrtr@archlinux.org> + +pkgbase="cups" +pkgname=('libcups' 'cups') +pkgver=1.4.4 +pkgrel=1 +arch=('i686' 'x86_64') +license=('GPL') +url="http://www.cups.org/" +makedepends=('libtiff>=3.9.2-2' 'libpng>=1.4.0'  'acl' 'openslp' 'pam' 'xdg-utils' 'heimdal>=1.3.1' 'gnutls>=2.8.3' 'poppler>=0.12.3' +             'xinetd' 'gzip' 'autoconf' 'php' 'libusb' 'dbus-core' 'avahi'  'hicolor-icon-theme') +source=(ftp://ftp.easysw.com/pub/cups/${pkgver}/cups-${pkgver}-source.tar.bz2 +	cups-avahi.patch +        cups cups.logrotate cups.pam) +#options=('!emptydirs') +md5sums=('8776403ad60fea9e85eab9c04d88560d' +         '3388dbe3fc20f16f37912e60a8ec46bc' +         '5c85b7d8d2ddd02c2c64955cebbf55ea' +         'f861b18f4446c43918c8643dcbbd7f6d' +         '96f82c38f3f540b53f3e5144900acf17') + +build() { +  cd ${srcdir}/${pkgbase}-${pkgver} +  # Avahi support in the dnssd backend. patch from Fedora +  patch -Np1 -i ${srcdir}/cups-avahi.patch || return 1 +  # Rebuild configure script for --enable-avahi. +  aclocal -I config-scripts +  autoconf -I config-scripts +  ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \ +     --with-logdir=/var/log/cups -with-docdir=/usr/share/cups/doc \ +     --with-cups-user=daemon --with-cups-group=lp --enable-pam=yes \ +     --disable-ldap --libdir=/usr/lib --enable-raw-printing \ +     --enable-dbus --with-dbusdir=/etc/dbus-1 --enable-ssl=yes --enable-gnutls --disable-threads --enable-dnssd\ +     --with-php=/usr/bin/php-cgi --with-pdftops=pdftops --with-optim="$CFLAGS" +  make || return 1 +} + +package_libcups() { +pkgdesc="The CUPS Printing System - client libraries and headers" +depends=('gnutls>=2.8.3' 'libtiff>=3.9.2-2' 'libpng>=1.4.0' 'heimdal>=1.3.1') +optdepends=('avahi: for the "dnssd" CUPS backend') + + +  cd ${srcdir}/${pkgbase}-${pkgver} +  make BUILDROOT=${pkgdir} install-headers install-libs || return 1 +  # put this into the libs pkg to make other software find the libs(no pkg-config file included) +  mkdir -p ${pkgdir}/usr/bin +  install -m755 ${srcdir}/${pkgbase}-${pkgver}/cups-config ${pkgdir}/usr/bin/cups-config +} + +package_cups() { +pkgdesc="The CUPS Printing System - deamon package" +install=cups.install +backup=(etc/cups/cupsd.conf +        etc/cups/mime.convs +        etc/cups/mime.types +        etc/cups/snmp.conf +        etc/cups/printers.conf +        etc/cups/classes.conf +        etc/cups/client.conf +        etc/cups/subscriptions.conf +        etc/dbus-1/system.d/cups.conf +        etc/logrotate.d/cups +        etc/pam.d/cups +        etc/xinetd.d/cups-lpd) +depends=('acl' 'openslp' 'pam' "libcups>=${pkgver}" 'xdg-utils' 'poppler>=0.12.3' 'libusb' 'dbus-core' 'hicolor-icon-theme') +optdepends=('php: for included phpcups.so module') + +  cd ${srcdir}/${pkgbase}-${pkgver} +  make BUILDROOT=${pkgdir} install-data install-exec || return 1 + +  # this one we ship in the libcups pkg +  rm -f ${pkgdir}/usr/bin/cups-config + +  # kill the sysv stuff +  rm -rf ${pkgdir}/etc/rc*.d +  rm -rf ${pkgdir}/etc/init.d +  install -D -m755 ../cups ${pkgdir}/etc/rc.d/cups +  install -D -m644 ../cups.logrotate ${pkgdir}/etc/logrotate.d/cups +  install -D -m644 ../cups.pam ${pkgdir}/etc/pam.d/cups +   +  # fix perms on /var/spool and /etc +  chmod 755 ${pkgdir}/var/spool +  chmod 755 ${pkgdir}/etc + +  # install ssl directory where to store the certs, solves some samba issues +  install -dm700 -g lp ${pkgdir}/etc/cups/ssl +  install -dm511 -g lp ${pkgdir}/var/run/cups/certs  + +  # install some more configuration files that will get filled by cupsd +  touch ${pkgdir}/etc/cups/printers.conf +  touch ${pkgdir}/etc/cups/classes.conf +  touch ${pkgdir}/etc/cups/client.conf +  echo "# see 'man client.conf'" >> ${pkgdir}/etc/cups/client.conf +  echo "ServerName /var/run/cups/cups.sock #  alternative: ServerName hostname-or-ip-address[:port] of a remote server" >> ${pkgdir}/etc/cups/client.conf +  touch ${pkgdir}/etc/cups/subscriptions.conf  +  chgrp lp ${pkgdir}/etc/cups/{printers.conf,classes.conf,client.conf,subscriptions.conf} +   +  # fix .desktop file +  sed -i 's|^Exec=htmlview http://localhost:631/|Exec=xdg-open http://localhost:631/|g' ${pkgdir}/usr/share/applications/cups.desktop +   +  # compress some driver files, adopted from Fedora +  find ${pkgdir}/usr/share/cups/model -name "*.ppd" | xargs gzip -n9f +} diff --git a/abs/extra-testing/cups/cups b/abs/extra-testing/cups/cups new file mode 100755 index 0000000..4afaf5a --- /dev/null +++ b/abs/extra-testing/cups/cups @@ -0,0 +1,38 @@ +#!/bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions + +PID=`pidof -o %PPID /usr/sbin/cupsd` +case "$1" in +  start) +    stat_busy "Starting CUPS Daemon" +    [ -z "$PID" ] && /usr/sbin/cupsd +    if [ $? -gt 0 ]; then +      stat_fail +    else +      echo $(pidof -o %PPID -x /usr/sbin/cupsd) > /var/run/cups.pid +      add_daemon cups +      stat_done +    fi +    ;; +  stop) +    stat_busy "Stopping CUPS Daemon" +    [ ! -z "$PID" ]  && kill $PID &> /dev/null +    if [ $? -gt 0 ]; then +      stat_fail +    else +      rm /var/run/cups.pid +      rm_daemon cups +      stat_done +    fi +    ;; +  restart) +    $0 stop +    sleep 1 +    $0 start +    ;; +  *) +    echo "usage: $0 {start|stop|restart}"   +esac +exit 0 diff --git a/abs/extra-testing/cups/cups-1.3.7-peercred.patch b/abs/extra-testing/cups/cups-1.3.7-peercred.patch new file mode 100644 index 0000000..eda2c93 --- /dev/null +++ b/abs/extra-testing/cups/cups-1.3.7-peercred.patch @@ -0,0 +1,11 @@ +diff -Naur cups-1.3.7/scheduler/auth.c cups-1.3.7.new/scheduler/auth.c +--- cups-1.3.7/scheduler/auth.c	2008-03-20 21:58:16.000000000 +0100 ++++ cups-1.3.7.new/scheduler/auth.c	2008-06-09 14:53:45.535194741 +0200 +@@ -54,6 +54,7 @@ +  * Include necessary headers... +  */ +  ++#define _GNU_SOURCE + #include "cupsd.h" + #include <grp.h> + #ifdef HAVE_SHADOW_H diff --git a/abs/extra-testing/cups/cups-avahi.patch b/abs/extra-testing/cups/cups-avahi.patch new file mode 100644 index 0000000..01fcb1a --- /dev/null +++ b/abs/extra-testing/cups/cups-avahi.patch @@ -0,0 +1,1089 @@ +diff -up cups-1.4.0/backend/dnssd.c.avahi cups-1.4.0/backend/dnssd.c +--- cups-1.4.0/backend/dnssd.c.avahi	2009-08-07 23:27:12.000000000 +0100 ++++ cups-1.4.0/backend/dnssd.c	2009-09-04 14:57:04.730388833 +0100 +@@ -22,6 +22,7 @@ +  *   exec_backend()          - Execute the backend that corresponds to the +  *                             resolved service name. +  *   get_device()            - Create or update a device. ++*    find_device() +  *   query_callback()        - Process query data. +  *   sigterm_handler()       - Handle termination signals... +  *   unquote()               - Unquote a name string. +@@ -33,7 +34,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 */ +  +  + /* +@@ -52,7 +64,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 */ +@@ -64,6 +81,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... +@@ -77,6 +108,7 @@ static int		job_canceled = 0; +  * Local functions... +  */ +  ++#ifdef HAVE_DNSSD + static void		browse_callback(DNSServiceRef sdRef, + 			                DNSServiceFlags flags, + 				        uint32_t interfaceIndex, +@@ -92,12 +124,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, +@@ -106,9 +132,111 @@ 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 */ ++ ++ ++/* ++ * cups_txt_records_t access functions ++ */ ++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; ++} ++ ++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. +@@ -119,6 +247,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 */ +@@ -130,12 +265,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 */ +@@ -194,6 +328,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 ("ERROR: Unable to create avahi client"); ++    return (1); ++  } ++ ++  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"); +@@ -245,6 +422,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... +@@ -252,6 +430,9 @@ main(int  argc,				/* I - Number of comm +  +   while (!job_canceled) +   { ++    int announce = 0; ++ ++#ifdef HAVE_DNSSD +     FD_ZERO(&input); +     FD_SET(fd, &input); +  +@@ -271,11 +452,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 */ +@@ -285,6 +490,7 @@ main(int  argc,				/* I - Number of comm +                best = NULL, count = 0; +            device; + 	   device = (cups_device_t *)cupsArrayNext(devices)) ++#ifdef HAVE_DNSSD +         if (!device->ref && !device->sent) + 	{ + 	 /* +@@ -313,14 +519,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; +@@ -372,6 +587,7 @@ main(int  argc,				/* I - Number of comm +  * 'browse_callback()' - Browse devices. +  */ +  ++#ifdef HAVE_DNSSD + static void + browse_callback( +     DNSServiceRef       sdRef,		/* I - Service reference */ +@@ -405,12 +621,14 @@ browse_callback( +  +   get_device((cups_array_t *)context, serviceName, regtype, replyDomain); + } ++#endif /* HAVE_DNSSD */ +  +  + /* +  * 'browse_local_callback()' - Browse local devices. +  */ +  ++#ifdef HAVE_DNSSD + static void + browse_local_callback( +     DNSServiceRef       sdRef,		/* I - Service reference */ +@@ -456,6 +674,7 @@ browse_local_callback( + 	  device->fullName); +   device->sent = 1; + } ++#endif /* HAVE_DNSSD */ +  +  + /* +@@ -528,6 +747,32 @@ exec_backend(char **argv)		/* I - Comman +   exit(CUPS_BACKEND_STOP); + } +  ++static int ++device_type (const char *regtype) ++{ ++#ifdef HAVE_AVAHI ++  if (!strcmp(regtype, "_ipp._tcp") || ++      !strcmp(regtype, "_ipp-tls._tcp")) ++    return (CUPS_DEVICE_IPP); ++  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.") || ++      !strcmp(regtype, "_ipp-tls._tcp.")) ++    return (CUPS_DEVICE_IPP); ++  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. +@@ -550,18 +795,7 @@ get_device(cups_array_t *devices,	/* I - +   */ +  +   key.name = (char *)serviceName; +- +-  if (!strcmp(regtype, "_ipp._tcp.") || +-      !strcmp(regtype, "_ipp-tls._tcp.")) +-    key.type = CUPS_DEVICE_IPP; +-  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; +@@ -581,8 +815,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); +       } +@@ -602,6 +842,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); +  +@@ -609,7 +852,13 @@ 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); +@@ -620,6 +869,7 @@ get_device(cups_array_t *devices,	/* I - +  * 'query_callback()' - Process query data. +  */ +  ++#ifdef HAVE_DNSSD + static void + query_callback( +     DNSServiceRef       sdRef,		/* I - Service reference */ +@@ -639,7 +889,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\", " +@@ -673,84 +923,212 @@ query_callback( +   if ((ptr = strstr(name, "._")) != NULL) +     *ptr = '\0'; +  +-  if (strstr(fullName, "_ipp._tcp.") || +-      strstr(fullName, "_ipp-tls._tcp.")) +-    dkey.type = CUPS_DEVICE_IPP; +-  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 ++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); ++  } ++} ++ ++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); ++} ++ ++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; +  +-  for (device = cupsArrayFind(devices, &dkey); ++  case AVAHI_BROWSER_REMOVE: ++  case AVAHI_BROWSER_ALL_FOR_NOW: ++  case AVAHI_BROWSER_CACHE_EXHAUSTED: ++    break; ++  }   ++} ++#endif /* HAVE_AVAHI */ ++ ++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 (strcasecmp(device->name, dkey.name) || +-        strcasecmp(device->domain, dkey.domain)) ++    if (strcasecmp(device->name, dkey->name) || ++        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; ++	char *key; ++	char *value; +  +-        for (ptr = key; data < datanext && *data != '='; data ++) +-	  *ptr++ = *data; +-	*ptr = '\0'; +- +-	if (data < datanext && *data == '=') +-	{ +-	  data ++; +- +-	  if (data < datanext) +-	    memcpy(value, data, datanext - data); +-	  value[datanext - data] = '\0'; +-	} +-	else +-	  continue; ++	if (parse_txt_record_pair (txt)) ++	  goto next; +  ++	key = txt->key; ++	value = txt->value; +         if (!strncasecmp(key, "usb_", 4)) + 	{ + 	 /* +@@ -805,6 +1183,10 @@ query_callback( + 	  if (device->type == CUPS_DEVICE_PRINTER) + 	    device->sent = 1; + 	} ++ ++      next: ++	if (next_txt_record (txt) == NULL) ++	  break; +       } +  +       if (device->device_id) +@@ -854,11 +1236,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.4.0/config.h.in.avahi cups-1.4.0/config.h.in +--- cups-1.4.0/config.h.in.avahi	2009-06-10 16:51:21.000000000 +0100 ++++ cups-1.4.0/config.h.in	2009-09-04 14:57:04.733388405 +0100 +@@ -336,6 +336,13 @@ +  +  + /* ++ * Do we have Avahi for DNS Service Discovery? ++ */ ++ ++#undef HAVE_AVAHI ++ ++ ++/* +  * Do we have <sys/ioctl.h>? +  */ +  +diff -up cups-1.4.0/config-scripts/cups-dnssd.m4.avahi cups-1.4.0/config-scripts/cups-dnssd.m4 +--- cups-1.4.0/config-scripts/cups-dnssd.m4.avahi	2009-02-10 17:05:35.000000000 +0000 ++++ cups-1.4.0/config-scripts/cups-dnssd.m4	2009-09-04 14:57:04.731388902 +0100 +@@ -27,6 +27,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 -up cups-1.4.0/cups/http-support.c.avahi cups-1.4.0/cups/http-support.c +--- cups-1.4.0/cups/http-support.c.avahi	2009-06-12 01:21:58.000000000 +0100 ++++ cups-1.4.0/cups/http-support.c	2009-09-04 14:57:04.736398674 +0100 +@@ -55,6 +55,11 @@ + #  include <dns_sd.h> + #  include <poll.h> + #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 */ +  +  + /* +@@ -121,6 +126,24 @@ static void		resolve_callback(DNSService + 					 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 +@@ -1349,15 +1372,26 @@ _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 +     DNSServiceRef	ref,		/* DNS-SD master service reference */ + 			domainref,	/* DNS-SD service reference for domain */ + 			localref;	/* DNS-SD service reference for .local */ +     int			domainsent = 0;	/* Send the domain resolve? */ +-    char		*regtype,	/* Pointer to type in hostname */ +-			*domain;	/* Pointer to domain in hostname */ +     _http_uribuf_t	uribuf;		/* URI buffer */ +     struct pollfd	polldata;	/* Polling data */ ++#else /* HAVE_AVAHI */ ++    AvahiSimplePoll	*simple_poll; ++    AvahiClient		*client; ++    int			error; ++    struct ++    { ++      AvahiSimplePoll	*poll; ++      _http_uribuf_t	uribuf; ++    } user_data; ++#endif /* HAVE_DNSSD */ +  +  +     if (logit) +@@ -1395,8 +1429,13 @@ _httpResolveURI( +     if (domain) +       *domain++ = '\0'; +  ++#ifdef HAVE_DNSSD +     uribuf.buffer  = resolved_uri; +     uribuf.bufsize = resolved_size; ++#else ++    user_data.uribuf.buffer = resolved_uri; ++    user_data.uribuf.bufsize = resolved_size; ++#endif +  +     resolved_uri[0] = '\0'; +  +@@ -1411,6 +1450,7 @@ _httpResolveURI( +  +     uri = NULL; +  ++#ifdef HAVE_DNSSD +     if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError) +     { +       localref = ref; +@@ -1486,6 +1526,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 (logit) +     { +@@ -1497,13 +1567,13 @@ _httpResolveURI( +       fputs("STATE: -connecting-to-device\n", stderr); +     } +  +-#else ++#else /* HAVE_DNSSD || HAVE_AVAHI */ +    /* +     * No DNS-SD support... +     */ +  +     uri = NULL; +-#endif /* HAVE_DNSSD */ ++#endif /* HAVE_DNSSD || HAVE_AVAHI */ +  +     if (logit && !uri) +       _cupsLangPuts(stderr, _("Unable to find printer!\n")); +@@ -1708,6 +1778,105 @@ resolve_callback( + } + #endif /* HAVE_DNSSD */ +  ++#ifdef HAVE_AVAHI ++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); ++} ++ ++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 8705 2009-06-12 00:21:58Z mike $". + diff --git a/abs/extra-testing/cups/cups.install b/abs/extra-testing/cups/cups.install new file mode 100644 index 0000000..97fda5a --- /dev/null +++ b/abs/extra-testing/cups/cups.install @@ -0,0 +1,11 @@ +post_install() { +  xdg-icon-resource forceupdate --theme hicolor 2> /dev/null +} + +post_upgrade() { +  post_install +} + +post_remove() { +  post_install +} diff --git a/abs/extra-testing/cups/cups.logrotate b/abs/extra-testing/cups/cups.logrotate new file mode 100644 index 0000000..9c49bbd --- /dev/null +++ b/abs/extra-testing/cups/cups.logrotate @@ -0,0 +1,8 @@ +/var/log/cups/*log { +   missingok +   notifempty +   delaycompress +   postrotate +      /bin/kill -HUP `cat /var/run/cups.pid 2>/dev/null` 2>/dev/null || true +   endscript +} diff --git a/abs/extra-testing/cups/cups.pam b/abs/extra-testing/cups/cups.pam new file mode 100644 index 0000000..53724d1 --- /dev/null +++ b/abs/extra-testing/cups/cups.pam @@ -0,0 +1,3 @@ +auth		required	pam_unix.so +account		required	pam_unix.so +session		required	pam_unix.so diff --git a/abs/extra-testing/cups/fix-infinite-usb-loop.patch b/abs/extra-testing/cups/fix-infinite-usb-loop.patch new file mode 100644 index 0000000..bad179e --- /dev/null +++ b/abs/extra-testing/cups/fix-infinite-usb-loop.patch @@ -0,0 +1,35 @@ +diff -urNad cups-1.4.0~/backend/usb-libusb.c cups-1.4.0/backend/usb-libusb.c +--- cups-1.4.0~/backend/usb-libusb.c	2009-08-08 00:24:14.000000000 +0200 ++++ cups-1.4.0/backend/usb-libusb.c	2009-09-02 16:37:31.000000000 +0200 +@@ -158,7 +158,7 @@ +  +     while (poll(pfds, 2, -1) > 0) +     { +-      if (pfds[0].revents & POLLIN) ++      if (pfds[0].revents & (POLLIN + POLLHUP)) +       { + 	if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0) + 	{ +@@ -179,7 +179,12 @@ +       } +  +       if (pfds[1].revents & POLLIN) +-        tbytes += side_cb(printer, print_fd); ++      { ++        if ((bytes = side_cb(printer, print_fd)) < 0) ++	  pfds[1].events = 0;		/* Filter has gone away... */ ++	else ++          tbytes += bytes; ++      } +     } +   } +  +@@ -747,7 +752,7 @@ +   if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) +   { +     _cupsLangPuts(stderr, _("WARNING: Failed to read side-channel request!\n")); +-    return (0); ++    return (-1); +   } +  +   switch (command)  | 
