- up to 2.2.1; FC patches refresh auto/th/cups-2.2.1-1
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 8 Nov 2016 10:56:47 +0000 (11:56 +0100)
committerArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 8 Nov 2016 10:56:47 +0000 (11:56 +0100)
21 files changed:
cups-avahi-address.patch
cups-avahi-no-threaded.patch
cups-banners.patch [new file with mode: 0644]
cups-dnssd-deviceid.patch [new file with mode: 0644]
cups-driverd-timeout.patch [new file with mode: 0644]
cups-dymo-deviceid.patch [new file with mode: 0644]
cups-eggcups.patch [new file with mode: 0644]
cups-enum-all.patch [new file with mode: 0644]
cups-filter-debug.patch [new file with mode: 0644]
cups-freebind.patch [new file with mode: 0644]
cups-hp-deviceid-oid.patch [new file with mode: 0644]
cups-ipp-multifile.patch [new file with mode: 0644]
cups-logrotate.patch [new file with mode: 0644]
cups-lspp.patch [new file with mode: 0644]
cups-man_pages_linking.patch
cups-pid.patch [new file with mode: 0644]
cups-res_init.patch [new file with mode: 0644]
cups-ricoh-deviceid-oid.patch [new file with mode: 0644]
cups-systemd-socket.patch
cups-web-devices-timeout.patch [new file with mode: 0644]
cups.spec

index b731d8360dc52ec8e8881490de3bfbd7343c21de..b8090ea0cabd9a7e19aa3bb7cbf8b53fc3ff08b6 100644 (file)
@@ -1,7 +1,7 @@
-diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-support.c
---- cups-2.0rc1/cups/http-support.c.avahi-address      2014-08-28 17:37:22.000000000 +0200
-+++ cups-2.0rc1/cups/http-support.c    2014-09-12 15:31:45.062950696 +0200
-@@ -2342,7 +2342,7 @@ http_resolve_cb(
+diff -up cups-2.2b2/cups/http-support.c.avahi-address cups-2.2b2/cups/http-support.c
+--- cups-2.2b2/cups/http-support.c.avahi-address       2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/cups/http-support.c     2016-06-27 15:31:34.201361844 +0200
+@@ -2340,7 +2340,7 @@ http_resolve_cb(
      const char             *type,     /* I - Registration type */
      const char             *domain,   /* I - Domain (unused) */
      const char             *hostTarget,       /* I - Hostname */
@@ -10,7 +10,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
      uint16_t               port,      /* I - Port number */
      AvahiStringList        *txt,      /* I - TXT record */
      AvahiLookupResultFlags flags,     /* I - Lookup flags (unused) */
-@@ -2495,39 +2495,62 @@ http_resolve_cb(
+@@ -2493,39 +2493,62 @@ http_resolve_cb(
      * getting the IP address of the .local name and then do reverse-lookups...
      */
  
@@ -20,7 +20,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
 +    size_t addrlen;
 +    int error;
  
-     DEBUG_printf(("8http_resolve_cb: Looking up \"%s\".", hostTarget));
+     DEBUG_printf(("5http_resolve_cb: Looking up \"%s\".", hostTarget));
  
 -    snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port));
 -    if ((addrlist = httpAddrGetList(hostTarget, AF_UNSPEC, fqdn)) != NULL)
@@ -54,7 +54,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
  
 -        if (!error)
 -      {
--        DEBUG_printf(("8http_resolve_cb: Found \"%s\".", fqdn));
+-        DEBUG_printf(("5http_resolve_cb: Found \"%s\".", fqdn));
 +      if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn ||
 +          _cups_strcasecmp(hostptr, ".local"))
  
@@ -73,7 +73,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
 +
  #ifdef DEBUG
 -      else
--        DEBUG_printf(("8http_resolve_cb: \"%s\" did not resolve: %d",
+-        DEBUG_printf(("5http_resolve_cb: \"%s\" did not resolve: %d",
 -                      httpAddrString(&(addr->addr), fqdn, sizeof(fqdn)),
 -                      error));
 +      DEBUG_printf(("8http_resolve_cb: \"%s\" did not resolve: %d",
index 0a8ea6213239b60f4ca8cb942453bc1e284b6604..f81c71fe2898076209bf51ac7e46934c3f992477 100644 (file)
@@ -1,6 +1,6 @@
-diff -up cups-2.0.2/scheduler/avahi.c.KUoOri cups-2.0.2/scheduler/avahi.c
---- cups-2.0.2/scheduler/avahi.c.KUoOri        2015-02-10 13:47:38.620396709 +0100
-+++ cups-2.0.2/scheduler/avahi.c       2015-02-10 13:47:38.620396709 +0100
+diff -up cups-2.2b2/scheduler/avahi.c.avahi-no-threaded cups-2.2b2/scheduler/avahi.c
+--- cups-2.2b2/scheduler/avahi.c.avahi-no-threaded     2016-06-27 17:55:19.568728958 +0200
++++ cups-2.2b2/scheduler/avahi.c       2016-06-27 17:55:19.568728958 +0200
 @@ -0,0 +1,441 @@
 +/*
 + * "$Id$"
@@ -443,9 +443,9 @@ diff -up cups-2.0.2/scheduler/avahi.c.KUoOri cups-2.0.2/scheduler/avahi.c
 +/*
 + * End of "$Id$".
 + */
-diff -up cups-2.0.2/scheduler/avahi.h.KUoOri cups-2.0.2/scheduler/avahi.h
---- cups-2.0.2/scheduler/avahi.h.KUoOri        2015-02-10 13:47:38.620396709 +0100
-+++ cups-2.0.2/scheduler/avahi.h       2015-02-10 13:47:38.620396709 +0100
+diff -up cups-2.2b2/scheduler/avahi.h.avahi-no-threaded cups-2.2b2/scheduler/avahi.h
+--- cups-2.2b2/scheduler/avahi.h.avahi-no-threaded     2016-06-27 17:55:19.568728958 +0200
++++ cups-2.2b2/scheduler/avahi.h       2016-06-27 17:55:19.568728958 +0200
 @@ -0,0 +1,69 @@
 +/*
 + * "$Id$"
@@ -516,10 +516,10 @@ diff -up cups-2.0.2/scheduler/avahi.h.KUoOri cups-2.0.2/scheduler/avahi.h
 +/*
 + * End of "$Id$".
 + */
-diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
---- cups-2.0.2/scheduler/cupsd.h.KUoOri        2014-03-21 17:42:53.000000000 +0100
-+++ cups-2.0.2/scheduler/cupsd.h       2015-02-10 13:47:38.624396652 +0100
-@@ -119,6 +119,7 @@ extern const char *cups_hstrerror(int);
+diff -up cups-2.2b2/scheduler/cupsd.h.avahi-no-threaded cups-2.2b2/scheduler/cupsd.h
+--- cups-2.2b2/scheduler/cupsd.h.avahi-no-threaded     2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/cupsd.h       2016-06-27 17:57:45.476572827 +0200
+@@ -118,6 +118,7 @@ extern const char *cups_hstrerror(int);
  #include "colorman.h"
  #include "conf.h"
  #include "banners.h"
@@ -527,7 +527,7 @@ diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
  #include "dirsvc.h"
  #include "network.h"
  #include "subscriptions.h"
-@@ -139,6 +140,15 @@ extern const char *cups_hstrerror(int);
+@@ -138,6 +139,15 @@ extern const char *cups_hstrerror(int);
  
  typedef void (*cupsd_selfunc_t)(void *data);
  
@@ -543,21 +543,21 @@ diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
  
  /*
   * Globals...
-@@ -163,6 +173,10 @@ VAR int                   OnDemand        VALUE(0);
+@@ -162,6 +172,9 @@ VAR int                    OnDemand        VALUE(0);
                                        /* Launched on demand */
- #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ #endif /* HAVE_ONDEMAND */
  
 +#ifdef HAVE_AVAHI
 +VAR cups_array_t *Timeouts;           /* Timed callbacks for main loop */
 +#endif /* HAVE_AVAHI */
-+
  
  /*
   * Prototypes...
-@@ -226,6 +240,17 @@ extern void               cupsdStopSelect(void);
+@@ -224,3 +237,15 @@ extern void               cupsdStopSelect(void);
+ /* server.c */
  extern void           cupsdStartServer(void);
  extern void           cupsdStopServer(void);
++
 +#ifdef HAVE_AVAHI
 +extern void     cupsdInitTimeouts(void);
 +extern cupsd_timeout_t *cupsdAddTimeout (const struct timeval *tv,
@@ -569,13 +569,11 @@ diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
 +                                  const struct timeval *tv);
 +extern void     cupsdRemoveTimeout (cupsd_timeout_t *timeout);
 +#endif /* HAVE_AVAHI */
- /*
-  * End of "$Id: cupsd.h 11717 2014-03-21 16:42:53Z msweet $".
-diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
---- cups-2.0.2/scheduler/dirsvc.c.KUoOri       2015-01-30 17:16:12.000000000 +0100
-+++ cups-2.0.2/scheduler/dirsvc.c      2015-02-10 13:50:47.131728120 +0100
-@@ -195,7 +195,7 @@ cupsdStartBrowsing(void)
+\ No newline at end of file
+diff -up cups-2.2b2/scheduler/dirsvc.c.avahi-no-threaded cups-2.2b2/scheduler/dirsvc.c
+--- cups-2.2b2/scheduler/dirsvc.c.avahi-no-threaded    2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/dirsvc.c      2016-06-27 17:55:19.569728950 +0200
+@@ -193,7 +193,7 @@ cupsdStartBrowsing(void)
      cupsdUpdateDNSSDName();
  
  #  else /* HAVE_AVAHI */
@@ -584,7 +582,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      {
        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");
  
-@@ -206,7 +206,7 @@ cupsdStartBrowsing(void)
+@@ -204,7 +204,7 @@ cupsdStartBrowsing(void)
      {
        int error;                      /* Error code, if any */
  
@@ -593,7 +591,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  
        if (DNSSDClient == NULL)
        {
-@@ -217,11 +217,9 @@ cupsdStartBrowsing(void)
+@@ -215,11 +215,9 @@ cupsdStartBrowsing(void)
          if (FatalErrors & CUPSD_FATAL_BROWSE)
          cupsdEndProcess(getpid(), 0);
  
@@ -606,7 +604,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      }
  #  endif /* HAVE_DNSSD */
    }
-@@ -608,7 +606,7 @@ dnssdClientCallback(
+@@ -606,7 +604,7 @@ dnssdClientCallback(
          * Renew Avahi client...
          */
  
@@ -615,7 +613,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  
          if (!DNSSDClient)
          {
-@@ -672,13 +670,7 @@ dnssdDeregisterInstance(
+@@ -670,13 +668,7 @@ dnssdDeregisterInstance(
    DNSServiceRefDeallocate(*srv);
  
  #  else /* HAVE_AVAHI */
@@ -629,7 +627,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  #  endif /* HAVE_DNSSD */
  
    *srv = NULL;
-@@ -999,16 +991,10 @@ dnssdRegisterInstance(
+@@ -997,16 +989,10 @@ dnssdRegisterInstance(
    (void)commit;
  
  #  else /* HAVE_AVAHI */
@@ -646,7 +644,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
                      name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
      return (0);
-@@ -1123,9 +1109,6 @@ dnssdRegisterInstance(
+@@ -1121,9 +1107,6 @@ dnssdRegisterInstance(
        cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
                        name);
    }
@@ -656,7 +654,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  #  endif /* HAVE_DNSSD */
  
    if (error)
-@@ -1296,9 +1279,6 @@ dnssdStop(void)
+@@ -1294,9 +1277,6 @@ dnssdStop(void)
    DNSSDMaster = NULL;
  
  #  else /* HAVE_AVAHI */
@@ -666,7 +664,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
    if (DNSSDClient)
    {
      avahi_client_free(DNSSDClient);
-@@ -1307,7 +1287,7 @@ dnssdStop(void)
+@@ -1305,7 +1285,7 @@ dnssdStop(void)
  
    if (DNSSDMaster)
    {
@@ -675,10 +673,10 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      DNSSDMaster = NULL;
    }
  #  endif /* HAVE_DNSSD */
-diff -up cups-2.0.2/scheduler/dirsvc.h.KUoOri cups-2.0.2/scheduler/dirsvc.h
---- cups-2.0.2/scheduler/dirsvc.h.KUoOri       2013-05-29 13:51:34.000000000 +0200
-+++ cups-2.0.2/scheduler/dirsvc.h      2015-02-10 13:47:38.640396426 +0100
-@@ -51,7 +51,7 @@ VAR cups_array_t     *DNSSDPrinters  VALUE(NU
+diff -up cups-2.2b2/scheduler/dirsvc.h.avahi-no-threaded cups-2.2b2/scheduler/dirsvc.h
+--- cups-2.2b2/scheduler/dirsvc.h.avahi-no-threaded    2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/dirsvc.h      2016-06-27 17:55:19.569728950 +0200
+@@ -49,7 +49,7 @@ VAR cups_array_t     *DNSSDPrinters  VALUE(NU
  VAR DNSServiceRef     DNSSDMaster     VALUE(NULL);
                                        /* Master DNS-SD service reference */
  #  else /* HAVE_AVAHI */
@@ -687,21 +685,22 @@ diff -up cups-2.0.2/scheduler/dirsvc.h.KUoOri cups-2.0.2/scheduler/dirsvc.h
                                        /* Master polling interface for Avahi */
  VAR AvahiClient               *DNSSDClient    VALUE(NULL);
                                        /* Client information */
-diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
---- cups-2.0.2/scheduler/main.c.KUoOri 2015-02-10 13:40:24.295545063 +0100
-+++ cups-2.0.2/scheduler/main.c        2015-02-10 13:47:38.641396412 +0100
-@@ -129,6 +129,10 @@ main(int  argc,                           /* I - Number of comm
+diff -up cups-2.2b2/scheduler/main.c.avahi-no-threaded cups-2.2b2/scheduler/main.c
+--- cups-2.2b2/scheduler/main.c.avahi-no-threaded      2016-06-27 17:55:19.555729061 +0200
++++ cups-2.2b2/scheduler/main.c        2016-06-27 17:58:44.350106330 +0200
+@@ -131,7 +131,10 @@ main(int  argc,                           /* I - Number of comm
    int                 service_idle_exit;
                                        /* Idle exit on select timeout? */
- #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ #endif /* HAVE_ONDEMAND */
+-
 +#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
-@@ -577,6 +581,14 @@ main(int  argc,                           /* I - Number of comm
+  /*
+@@ -609,6 +612,14 @@ main(int  argc,                           /* I - Number of comm
  
    httpInitialize();
  
@@ -716,7 +715,7 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
    cupsdStartServer();
  
   /*
-@@ -883,6 +895,16 @@ main(int  argc,                           /* I - Number of comm
+@@ -930,6 +941,16 @@ main(int  argc,                           /* I - Number of comm
      }
  #endif /* __APPLE__ */
  
@@ -733,9 +732,9 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
  #ifndef __APPLE__
     /*
      * Update the network interfaces once a minute...
-@@ -1574,6 +1596,10 @@ select_timeout(int fds)                 /* I - Number
+@@ -1620,6 +1641,10 @@ select_timeout(int fds)                 /* I - Number
+   cupsd_client_t      *con;           /* Client information */
    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 */
@@ -744,7 +743,7 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
  
  
    cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: JobHistoryUpdate=%ld",
-@@ -1619,6 +1645,19 @@ select_timeout(int fds)                 /* I - Number
+@@ -1665,6 +1690,19 @@ select_timeout(int fds)                 /* I - Number
    }
  #endif /* __APPLE__ */
  
@@ -764,10 +763,10 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
   /*
    * Check whether we are accepting new connections...
    */
-diff -up cups-2.0.2/scheduler/Makefile.KUoOri cups-2.0.2/scheduler/Makefile
---- cups-2.0.2/scheduler/Makefile.KUoOri       2014-10-21 13:55:01.000000000 +0200
-+++ cups-2.0.2/scheduler/Makefile      2015-02-10 13:47:38.646396341 +0100
-@@ -17,6 +17,7 @@ include ../Makedefs
+diff -up cups-2.2b2/scheduler/Makefile.avahi-no-threaded cups-2.2b2/scheduler/Makefile
+--- cups-2.2b2/scheduler/Makefile.avahi-no-threaded    2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/Makefile      2016-06-27 17:55:19.569728950 +0200
+@@ -15,6 +15,7 @@ include ../Makedefs
  
  CUPSDOBJS =   \
                auth.o \
@@ -775,7 +774,7 @@ diff -up cups-2.0.2/scheduler/Makefile.KUoOri cups-2.0.2/scheduler/Makefile
                banners.o \
                cert.o \
                classes.o \
-@@ -40,7 +41,8 @@ CUPSDOBJS =  \
+@@ -38,7 +39,8 @@ CUPSDOBJS =  \
                server.o \
                statbuf.o \
                subscriptions.o \
@@ -785,9 +784,9 @@ diff -up cups-2.0.2/scheduler/Makefile.KUoOri cups-2.0.2/scheduler/Makefile
  LIBOBJS =     \
                filter.o \
                mime.o \
-diff -up cups-2.0.2/scheduler/timeout.c.KUoOri cups-2.0.2/scheduler/timeout.c
---- cups-2.0.2/scheduler/timeout.c.KUoOri      2015-02-10 13:47:38.646396341 +0100
-+++ cups-2.0.2/scheduler/timeout.c     2015-02-10 13:47:38.646396341 +0100
+diff -up cups-2.2b2/scheduler/timeout.c.avahi-no-threaded cups-2.2b2/scheduler/timeout.c
+--- cups-2.2b2/scheduler/timeout.c.avahi-no-threaded   2016-06-27 17:55:19.569728950 +0200
++++ cups-2.2b2/scheduler/timeout.c     2016-06-27 17:55:19.569728950 +0200
 @@ -0,0 +1,235 @@
 +/*
 + * "$Id$"
diff --git a/cups-banners.patch b/cups-banners.patch
new file mode 100644 (file)
index 0000000..aa19282
--- /dev/null
@@ -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-dnssd-deviceid.patch b/cups-dnssd-deviceid.patch
new file mode 100644 (file)
index 0000000..7bd2463
--- /dev/null
@@ -0,0 +1,38 @@
+diff -up cups-2.1.4/backend/dnssd.c.dnssd-deviceid cups-2.1.4/backend/dnssd.c
+--- cups-2.1.4/backend/dnssd.c.dnssd-deviceid  2016-06-15 14:36:19.922353606 +0200
++++ cups-2.1.4/backend/dnssd.c 2016-06-15 14:45:45.794966648 +0200
+@@ -1188,15 +1188,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)
+     {
+      /*
+@@ -1206,7 +1213,7 @@ query_callback(
+       memcpy(make_and_model, model, (size_t)(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 (file)
index 0000000..b7240a3
--- /dev/null
@@ -0,0 +1,21 @@
+diff -up cups-1.7b1/scheduler/ipp.c.driverd-timeout cups-1.7b1/scheduler/ipp.c
+--- cups-1.7b1/scheduler/ipp.c.driverd-timeout 2013-04-19 12:24:43.003841810 +0200
++++ cups-1.7b1/scheduler/ipp.c 2013-04-19 12:24:43.204839107 +0200
+@@ -4556,7 +4556,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;
+@@ -4576,7 +4576,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-dymo-deviceid.patch b/cups-dymo-deviceid.patch
new file mode 100644 (file)
index 0000000..cc2995d
--- /dev/null
@@ -0,0 +1,11 @@
+diff -up cups-1.6.2/ppdc/sample.drv.dymo-deviceid cups-1.6.2/ppdc/sample.drv
+--- cups-1.6.2/ppdc/sample.drv.dymo-deviceid   2013-06-18 16:57:02.110662953 +0100
++++ cups-1.6.2/ppdc/sample.drv 2013-06-18 16:58:56.513989117 +0100
+@@ -125,6 +125,7 @@ Version "1.5"
+ {
+   Manufacturer "Dymo"
+   ModelName "Label Printer"
++  Attribute "1284DeviceID" "" "MFG:DYMO;MDL:LabelWriter 400;"
+   Attribute NickName "" "Dymo Label Printer"
+   PCFileName "dymo.ppd"
+   DriverType label
diff --git a/cups-eggcups.patch b/cups-eggcups.patch
new file mode 100644 (file)
index 0000000..908f518
--- /dev/null
@@ -0,0 +1,130 @@
+diff -up cups-2.1b1/backend/ipp.c.eggcups cups-2.1b1/backend/ipp.c
+--- cups-2.1b1/backend/ipp.c.eggcups   2015-05-28 03:19:14.000000000 +0200
++++ cups-2.1b1/backend/ipp.c   2015-06-29 12:56:54.872807227 +0200
+@@ -149,6 +149,70 @@ static char               tmpfilename[1024] = "";
+ static char           mandatory_attrs[1024] = "";
+                                       /* cupsMandatory value */
++#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...
+@@ -1700,6 +1764,15 @@ main(int  argc,                         /* I - Number of comm
+       fprintf(stderr, "DEBUG: Print job accepted - job ID %d.\n", 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-2.1b1/backend/Makefile.eggcups cups-2.1b1/backend/Makefile
+--- cups-2.1b1/backend/Makefile.eggcups        2014-05-09 00:42:44.000000000 +0200
++++ cups-2.1b1/backend/Makefile        2015-06-29 12:54:55.753026774 +0200
+@@ -264,7 +264,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-2.1b1/scheduler/subscriptions.c.eggcups cups-2.1b1/scheduler/subscriptions.c
+--- cups-2.1b1/scheduler/subscriptions.c.eggcups       2014-02-06 19:33:34.000000000 +0100
++++ cups-2.1b1/scheduler/subscriptions.c       2015-06-29 12:54:55.753026774 +0200
+@@ -1293,13 +1293,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;
+@@ -1335,7 +1335,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-enum-all.patch b/cups-enum-all.patch
new file mode 100644 (file)
index 0000000..0ac3983
--- /dev/null
@@ -0,0 +1,17 @@
+diff -up cups-1.6.2/cups/dest.c.enum-all cups-1.6.2/cups/dest.c
+--- cups-1.6.2/cups/dest.c.enum-all    2013-06-04 10:58:36.169786250 +0100
++++ cups-1.6.2/cups/dest.c     2013-06-04 10:59:02.147900811 +0100
+@@ -2724,9 +2724,12 @@ cups_dnssd_browse_cb(
+       break;
+     case AVAHI_BROWSER_REMOVE:
+-    case AVAHI_BROWSER_ALL_FOR_NOW:
+     case AVAHI_BROWSER_CACHE_EXHAUSTED:
+         break;
++
++    case AVAHI_BROWSER_ALL_FOR_NOW:
++      avahi_simple_poll_quit(data->simple_poll);
++        break;
+   }
+ }
diff --git a/cups-filter-debug.patch b/cups-filter-debug.patch
new file mode 100644 (file)
index 0000000..96c82da
--- /dev/null
@@ -0,0 +1,32 @@
+diff -up cups-1.6b1/scheduler/job.c.filter-debug cups-1.6b1/scheduler/job.c
+--- cups-1.6b1/scheduler/job.c.filter-debug    2012-05-25 16:06:01.000000000 +0200
++++ cups-1.6b1/scheduler/job.c 2012-05-25 16:07:46.309259511 +0200
+@@ -625,10 +625,28 @@ cupsdContinueJob(cupsd_job_t *job)       /* I
+     if (!filters)
+     {
++      mime_filter_t *current;
++
+       cupsdLogJob(job, CUPSD_LOG_ERROR,
+                 "Unable to convert file %d to printable format.",
+                 job->current_file);
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++                "Required: %s/%s -> %s/%s",
++                job->filetypes[job->current_file]->super,
++                job->filetypes[job->current_file]->type,
++                job->printer->filetype->super,
++                job->printer->filetype->type);
++
++      for (current = (mime_filter_t *)cupsArrayFirst(MimeDatabase->srcs);
++         current;
++         current = (mime_filter_t *)cupsArrayNext(MimeDatabase->srcs))
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++                    "Available: %s/%s -> %s/%s (%s)",
++                    current->src->super, current->src->type,
++                    current->dst->super, current->dst->type,
++                    current->filter);
++
+       abort_message = "Aborting job because it cannot be printed.";
+       abort_state   = IPP_JOB_ABORTED;
diff --git a/cups-freebind.patch b/cups-freebind.patch
new file mode 100644 (file)
index 0000000..6d9ba43
--- /dev/null
@@ -0,0 +1,15 @@
+diff -up cups-2.0.2/cups/http-addr.c.freebind cups-2.0.2/cups/http-addr.c
+--- cups-2.0.2/cups/http-addr.c.freebind       2015-02-10 14:46:33.000000000 +0100
++++ cups-2.0.2/cups/http-addr.c        2015-02-10 14:50:35.074759141 +0100
+@@ -186,6 +186,10 @@ httpAddrListen(http_addr_t *addr, /* I -
+   val = 1;
+   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, CUPS_SOCAST &val, sizeof(val));
++#ifdef __linux
++  setsockopt(fd, IPPROTO_IP, IP_FREEBIND, CUPS_SOCAST &val, sizeof(val));
++#endif /* __linux */
++
+ #ifdef IPV6_V6ONLY
+   if (addr->addr.sa_family == AF_INET6)
+     setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, CUPS_SOCAST &val, sizeof(val));
+diff -up cups-2.0.2/scheduler/listen.c.freebind cups-2.0.2/scheduler/listen.c
diff --git a/cups-hp-deviceid-oid.patch b/cups-hp-deviceid-oid.patch
new file mode 100644 (file)
index 0000000..da5136a
--- /dev/null
@@ -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-ipp-multifile.patch b/cups-ipp-multifile.patch
new file mode 100644 (file)
index 0000000..beac7fa
--- /dev/null
@@ -0,0 +1,15 @@
+diff -up cups-1.7.0/backend/ipp.c.ipp-multifile cups-1.7.0/backend/ipp.c
+--- cups-1.7.0/backend/ipp.c.ipp-multifile     2013-10-24 15:52:00.745814354 +0100
++++ cups-1.7.0/backend/ipp.c   2013-10-24 15:53:46.463266724 +0100
+@@ -1758,7 +1758,10 @@ main(int  argc,                         /* I - Number of comm
+       ippAddBoolean(request, IPP_TAG_OPERATION, "last-document",
+                     (i + 1) >= num_files);
+-      if (document_format)
++      if (num_files > 1)
++        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
++                     "document-format", NULL, "application/octet-stream");
++      else if (document_format)
+         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
+                      "document-format", NULL, document_format);
diff --git a/cups-logrotate.patch b/cups-logrotate.patch
new file mode 100644 (file)
index 0000000..6b8eb8c
--- /dev/null
@@ -0,0 +1,63 @@
+diff -up cups-2.1b1/scheduler/log.c.logrotate cups-2.1b1/scheduler/log.c
+--- cups-2.1b1/scheduler/log.c.logrotate       2015-06-04 20:00:31.000000000 +0200
++++ cups-2.1b1/scheduler/log.c 2015-06-29 13:25:09.623350218 +0200
+@@ -26,6 +26,9 @@
+ #  include <systemd/sd-journal.h>
+ #endif /* HAVE_ASL_H */
+ #include <syslog.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
+ /*
+@@ -135,12 +138,10 @@ cupsdCheckLogFile(cups_file_t **lf,      /* I
+   }
+  /*
+-  * 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...
+@@ -254,6 +255,34 @@ cupsdCheckLogFile(cups_file_t **lf,       /* I
+      /*
+       * Change ownership and permissions of non-device logs...
+       */
++
++      fchown(cupsFileNumber(*lf), RunUser, Group);
++      fchmod(cupsFileNumber(*lf), LogFilePerm);
++    }
++  }
++
++ /*
++  * 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);
diff --git a/cups-lspp.patch b/cups-lspp.patch
new file mode 100644 (file)
index 0000000..93a3a49
--- /dev/null
@@ -0,0 +1,1997 @@
+diff -up cups-2.2b2/config.h.in.lspp cups-2.2b2/config.h.in
+--- cups-2.2b2/config.h.in.lspp        2016-06-27 17:39:48.075973879 +0200
++++ cups-2.2b2/config.h.in     2016-06-27 17:47:31.376356684 +0200
+@@ -737,4 +737,11 @@ static __inline int _cups_abs(int i) { r
+ #  endif /* __GNUC__ || __STDC_VERSION__ */
+ #endif /* !HAVE_ABS && !abs */
++/*
++ * Are we trying to meet LSPP requirements?
++ */
++
++#undef WITH_LSPP
++
++
+ #endif /* !_CUPS_CONFIG_H_ */
+diff -up cups-2.2b2/config-scripts/cups-lspp.m4.lspp cups-2.2b2/config-scripts/cups-lspp.m4
+--- cups-2.2b2/config-scripts/cups-lspp.m4.lspp        2016-06-27 17:39:48.076973871 +0200
++++ cups-2.2b2/config-scripts/cups-lspp.m4     2016-06-27 17:39:48.076973871 +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-2.2b2/configure.ac.lspp cups-2.2b2/configure.ac
+--- cups-2.2b2/configure.ac.lspp       2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/configure.ac    2016-06-27 17:39:48.076973871 +0200
+@@ -38,6 +38,8 @@ sinclude(config-scripts/cups-startup.m4)
+ sinclude(config-scripts/cups-defaults.m4)
+ sinclude(config-scripts/cups-scripting.m4)
++sinclude(config-scripts/cups-lspp.m4)
++
+ INSTALL_LANGUAGES=""
+ UNINSTALL_LANGUAGES=""
+ LANGFILES=""
+diff -up cups-2.2b2/filter/common.c.lspp cups-2.2b2/filter/common.c
+--- cups-2.2b2/filter/common.c.lspp    2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/filter/common.c 2016-06-27 17:39:48.076973871 +0200
+@@ -17,6 +17,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>
+@@ -299,6 +305,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 */
+  /*
+@@ -321,6 +339,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...
+   */
+@@ -401,7 +537,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-2.2b2/filter/pstops.c.lspp cups-2.2b2/filter/pstops.c
+--- cups-2.2b2/filter/pstops.c.lspp    2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/filter/pstops.c 2016-06-27 17:39:48.077973863 +0200
+@@ -3176,6 +3176,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 */
+  /*
+@@ -3198,6 +3210,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...
+   */
+@@ -3276,7 +3406,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-2.2b2/Makedefs.in.lspp cups-2.2b2/Makedefs.in
+--- cups-2.2b2/Makedefs.in.lspp        2016-06-27 17:39:48.045974117 +0200
++++ cups-2.2b2/Makedefs.in     2016-06-27 17:39:48.077973863 +0200
+@@ -143,7 +143,7 @@ LDFLAGS            =       -L../cgi-bin -L../cups -L../f
+                       @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
+ LINKCUPS      =       @LINKCUPS@ $(LIBGSSAPI) $(DNSSDLIBS) $(LIBZ)
+ LINKCUPSIMAGE =       @LINKCUPSIMAGE@
+-LIBS          =       $(LINKCUPS) $(COMMONLIBS)
++LIBS          =       $(LINKCUPS) $(COMMONLIBS) @LIBAUDIT@ @LIBSELINUX@
+ ONDEMANDFLAGS =       @ONDEMANDFLAGS@
+ ONDEMANDLIBS  =       @ONDEMANDLIBS@
+ OPTIM         =       @OPTIM@
+diff -up cups-2.2b2/scheduler/client.c.lspp cups-2.2b2/scheduler/client.c
+--- cups-2.2b2/scheduler/client.c.lspp 2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/client.c      2016-06-27 17:39:48.077973863 +0200
+@@ -22,12 +22,20 @@
+ #define _HTTP_NO_PRIVATE
+ #include "cupsd.h"
++#ifndef _GNU_SOURCE
++#define _GNU_SOURCE
++#endif /* !defined(_GNU_SOURCE) */
+ #ifdef __APPLE__
+ #  include <libproc.h>
+ #endif /* __APPLE__ */
+ #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 */
+ /*
+@@ -266,6 +274,59 @@ 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(httpGetFd(con->http), 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)
++      {
++        httpClose(con->http);
++        cupsdLogClient(con, CUPSD_LOG_ERROR,
++                     "Unable to determine client auid for client pid=%d",
++                     cr.pid);
++        free(con);
++        return;
++      }
++      cupsdLogClient(con, CUPSD_LOG_INFO,
++                   "peer's pid=%d, uid=%d, gid=%d, auid=%d",
++                   cr.pid, cr.uid, cr.gid, con->auid);
++    }
++    else
++    {
++      httpClose(con->http);
++      cupsdLogClient(con, CUPSD_LOG_ERROR, "getsockopt() failed");
++      free(con);
++      return; 
++    }
++
++   /*
++    * get the context of the peer connection
++    */
++    if (getpeercon(httpGetFd(con->http), &con->scon))
++    {
++      httpClose(con->http);
++      cupsdLogClient(con, CUPSD_LOG_ERROR, "getpeercon() failed");
++      free(con);
++      return; 
++    }
++
++    cupsdLogClient(con, CUPSD_LOG_INFO, "client context=%s", con->scon);
++  }
++  else
++  {
++    cupsdLogClient(con, CUPSD_LOG_DEBUG, "skipping getpeercon()");
++    cupsdSetString(&con->scon, UNKNOWN_SL);
++  }
++#endif /* WITH_LSPP */
++
+ #ifdef AF_LOCAL
+   if (httpAddrFamily(httpGetAddress(con->http)) == AF_LOCAL)
+   {
+@@ -560,6 +621,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_STATUS_CONTINUE;
+@@ -1924,6 +1992,73 @@ cupsdReadClient(cupsd_client_t *con)    /*
+             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_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++            cupsdCloseClient(con);
++            return;
++          }
++          clicon = context_new(con->scon);
++          tmpcon = context_new(spoolcon);
++          freecon(spoolcon);
++          if (!clicon || !tmpcon)
++          {
++            cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++            if (clicon)
++              context_free(clicon);
++            if (tmpcon)
++              context_free(tmpcon);
++            cupsdCloseClient(con);
++            return;
++          }
++          clirange = (char *) context_range_get(clicon);
++          if (clirange)
++          {
++            clirange = strdup(clirange);
++            if ((cliclearance = strtok(clirange, "-")) != NULL)
++            {
++              if (context_range_set(tmpcon, cliclearance) == -1)
++              {
++                cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++                free(clirange);
++                context_free(tmpcon);
++                context_free(clicon);
++                cupsdCloseClient(con);
++                return;
++              }
++            }
++            else
++            {
++              if (context_range_set(tmpcon, (context_range_get(clicon))) == -1)
++              {
++                cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++                free(clirange);
++                context_free(tmpcon);
++                context_free(clicon);
++                cupsdCloseClient(con);
++                return;
++              }
++            }
++            free(clirange);
++          }
++          if (setfilecon(con->filename, context_str(tmpcon)) == -1)
++          {
++            cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++            context_free(tmpcon);
++            context_free(clicon);
++            cupsdCloseClient(con);
++            return;
++          }
++          cupsdLogClient(con, CUPSD_LOG_DEBUG2, "%s set to %s", 
++                         con->filename, context_str(tmpcon));
++          context_free(tmpcon);
++          context_free(clicon);
++        }
++#endif /* WITH_LSPP */
++
+         if (httpGetState(con->http) != HTTP_STATE_POST_SEND)
+         {
+           if (!httpWait(con->http, 0))
+@@ -3456,6 +3591,49 @@ is_path_absolute(const char *path)      /* I
+   return (1);
+ }
++#ifdef WITH_LSPP
++/*
++ * 'client_pid_to_auid()' - Using the client's pid, read /proc and determine the loginuid.
++ */
++
++uid_t client_pid_to_auid(pid_t clipid)
++{
++  uid_t uid;
++  int len, in;
++  char buf[16] = {0};
++  char fname[32] = {0};
++
++
++ /*
++  * Hopefully this pid is still the one we are interested in.
++  */
++  snprintf(fname, 32, "/proc/%d/loginuid", clipid);
++  in = open(fname, O_NOFOLLOW|O_RDONLY);
++
++  if (in < 0)
++    return (uid_t) -1;
++
++  errno = 0;
++
++  do {
++    len = read(in, buf, sizeof(buf));
++  } while (len < 0 && errno == EINTR);
++
++  close(in);
++
++  if (len < 0 || len >= sizeof(buf))
++    return (uid_t) -1;
++
++  errno = 0;
++  buf[len] = 0;
++  uid = strtol(buf, 0, 10);
++
++  if (errno != 0)
++    return (uid_t) -1;
++  else
++    return uid;
++}
++#endif /* WITH_LSPP */
+ /*
+  * 'pipe_command()' - Pipe the output of a command to the remote client.
+diff -up cups-2.2b2/scheduler/client.h.lspp cups-2.2b2/scheduler/client.h
+--- cups-2.2b2/scheduler/client.h.lspp 2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/client.h      2016-06-27 17:39:48.077973863 +0200
+@@ -16,6 +16,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...
+  */
+@@ -65,6 +72,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)
+@@ -138,6 +149,9 @@ extern void        cupsdStartListening(void);
+ extern void   cupsdStopListening(void);
+ extern void   cupsdUpdateCGI(void);
+ extern void   cupsdWriteClient(cupsd_client_t *con);
++#ifdef WITH_LSPP
++extern uid_t  client_pid_to_auid(pid_t clipid);
++#endif /* WITH_LSPP */
+ #ifdef HAVE_SSL
+ extern int    cupsdEndTLS(cupsd_client_t *con);
+diff -up cups-2.2b2/scheduler/conf.c.lspp cups-2.2b2/scheduler/conf.c
+--- cups-2.2b2/scheduler/conf.c.lspp   2016-06-27 17:39:48.072973903 +0200
++++ cups-2.2b2/scheduler/conf.c        2016-06-27 17:39:48.078973855 +0200
+@@ -40,6 +40,9 @@
+ #  define INADDR_NONE 0xffffffff
+ #endif /* !INADDR_NONE */
++#ifdef WITH_LSPP
++#  include <libaudit.h>
++#endif /* WITH_LSPP */
+ /*
+  * Configuration variable structure...
+@@ -131,6 +134,10 @@ static const cupsd_var_t  cupsd_vars[] =
+   { "ServerName",             &ServerName,            CUPSD_VARTYPE_STRING },
+   { "StrictConformance",      &StrictConformance,     CUPSD_VARTYPE_BOOLEAN },
+   { "Timeout",                        &Timeout,               CUPSD_VARTYPE_TIME },
++#ifdef WITH_LSPP
++  { "AuditLog",                       &AuditLog,              CUPSD_VARTYPE_INTEGER },
++  { "PerPageLabels",          &PerPageLabels,         CUPSD_VARTYPE_BOOLEAN },
++#endif /* WITH_LSPP */
+   { "WebInterface",           &WebInterface,          CUPSD_VARTYPE_BOOLEAN }
+ };
+ static const cupsd_var_t      cupsfiles_vars[] =
+@@ -577,6 +584,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 */
+  /*
+@@ -931,6 +941,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");
+@@ -1350,7 +1379,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...
+@@ -3827,6 +3868,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-2.2b2/scheduler/conf.h.lspp cups-2.2b2/scheduler/conf.h
+--- cups-2.2b2/scheduler/conf.h.lspp   2016-06-27 17:39:48.078973855 +0200
++++ cups-2.2b2/scheduler/conf.h        2016-06-27 17:44:46.370632333 +0200
+@@ -248,6 +248,13 @@ VAR char          *ServerKeychain         VALUE(NULL);
+                                       /* Keychain holding cert + key */
+ #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_ONDEMAND
+ VAR int                       IdleExitTimeout         VALUE(60);
+                                       /* Time after which an idle cupsd will exit */
+@@ -266,6 +273,9 @@ VAR int                    HaveServerCreds         VALUE(0);
+ VAR gss_cred_id_t     ServerCreds;    /* Server's GSS credentials */
+ #endif /* HAVE_GSSAPI */
++#ifdef WITH_LSPP
++extern int            is_lspp_config(void);
++#endif /* WITH_LSPP */
+ /*
+  * Prototypes...
+diff -up cups-2.2b2/scheduler/cupsd.h.lspp cups-2.2b2/scheduler/cupsd.h
+--- cups-2.2b2/scheduler/cupsd.h.lspp  2016-06-27 17:39:48.064973966 +0200
++++ cups-2.2b2/scheduler/cupsd.h       2016-06-27 17:39:48.078973855 +0200
+@@ -11,6 +11,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.
+@@ -36,13 +38,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-2.2b2/scheduler/ipp.c.lspp cups-2.2b2/scheduler/ipp.c
+--- cups-2.2b2/scheduler/ipp.c.lspp    2016-06-27 17:39:48.028974252 +0200
++++ cups-2.2b2/scheduler/ipp.c 2016-06-27 17:39:48.080973839 +0200
+@@ -14,6 +14,9 @@
+  * 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,6 +40,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...
+@@ -61,6 +72,9 @@ static void  cancel_all_jobs(cupsd_client
+ static void   cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
+ static void   cancel_subscription(cupsd_client_t *con, int id);
+ static int    check_rss_recipient(const char *recipient);
++#ifdef WITH_LSPP
++static int    check_context(cupsd_client_t *con, cupsd_job_t *job);
++#endif /* WITH_LSPP */
+ static int    check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
+ static void   close_job(cupsd_client_t *con, ipp_attribute_t *uri);
+ static void   copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
+@@ -1248,6 +1262,21 @@ add_job(cupsd_client_t  *con,           /* I - Cl
+     "time-at-creation",
+     "time-at-processing"
+   };
++#ifdef WITH_LSPP
++  char                *audit_message;         /* Audit message string */
++  char                *printerfile;           /* device file pointed to by the printer */
++  char                *userheader = NULL;     /* User supplied job-sheets[0] */
++  char                *userfooter = NULL;     /* User supplied job-sheets[1] */
++  int         override = 0;           /* Was a banner overrode on a job */
++  security_id_t       clisid;                 /* SELinux SID for the client */
++  security_id_t       psid;                   /* SELinux SID for the printer */
++  context_t   printercon;             /* Printer's context string */
++  struct stat printerstat;            /* Printer's stat buffer */
++  security_context_t  devcon;         /* Printer's SELinux context */
++  struct avc_entry_ref        avcref;         /* Pointer to the access vector cache */
++  security_class_t    tclass;         /* Object class for the SELinux check */
++  access_vector_t     avr;            /* Access method being requested */
++#endif /* WITH_LSPP */
+   cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
+@@ -1559,6 +1588,106 @@ add_job(cupsd_client_t  *con,          /* I - Cl
+     return (NULL);
+   }
++#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 int 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,
+@@ -1567,6 +1696,32 @@ add_job(cupsd_client_t  *con,           /* I - Cl
+     return (NULL);
+   }
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++   /*
++    * duplicate the security context and auid of the connection into the job structure
++    */
++    job->scon = strdup(con->scon);
++    job->auid = con->auid;
++
++   /* 
++    * add the security context to the request so that on a restart the security
++    * attributes will be able to be restored
++    */
++    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "security-context", 
++               NULL, job->scon);
++  }
++  else
++  {
++   /*
++    * Fill in the security context of the job as unlabeled
++    */
++    cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: setting context of job to %s", UNKNOWN_SL);
++    cupsdSetString(&job->scon, UNKNOWN_SL);
++  }
++#endif /* WITH_LSPP */
++
+   job->dtype   = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
+   job->attrs   = con->request;
+   job->dirty   = 1;
+@@ -1756,6 +1911,29 @@ add_job(cupsd_client_t  *con,           /* I - Cl
+       ippSetString(job->attrs, &attr, 0, printer->job_sheets[0]);
+       ippSetString(job->attrs, &attr, 1, printer->job_sheets[1]);
+     }
++#ifdef WITH_LSPP
++    else
++    {
++     /*
++      * The option was present, so capture the user supplied strings
++      */
++      userheader = strdup(attr->values[0].string.text);
++
++      if (attr->num_values > 1)
++        userfooter = strdup(attr->values[1].string.text);
++
++      if (Classification != NULL && (strcmp(userheader, Classification) == 0)
++          && userfooter &&(strcmp(userfooter, Classification) == 0))
++      {
++       /*
++        * Since both values are Classification, the user is not trying to Override
++        */
++        free(userheader);
++        if (userfooter) free(userfooter);
++        userheader = userfooter = NULL;
++      }
++    }
++#endif /* WITH_LSPP */
+     job->job_sheets = attr;
+@@ -1786,6 +1964,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,
+@@ -1804,6 +1985,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") &&
+@@ -1824,6 +2008,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) &&
+@@ -1864,8 +2051,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...
+@@ -3619,6 +3850,128 @@ 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)
++  {
++    cupsdLogJob(job, CUPSD_LOG_ERROR,
++              "Error while determining SELinux enforcement");
++    return -1;
++  }
++  cupsdLogJob(job, CUPSD_LOG_DEBUG,
++            "check_context: client context %s job context %s",
++            con->scon, job->scon);
++
++
++ /*
++  * Initialize the avc engine...
++  */
++
++  static int avc_initialized = 0;
++  if (! avc_initialized++)
++  {
++    if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init");
++      return -1;
++    } 
++  } 
++  if (avc_context_to_sid(con->scon, &clisid) != 0)
++  {
++    cupsdLogJob(job, 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)
++  {
++    cupsdLogJob(job, 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)
++  {
++    cupsdLogJob(job, 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)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++                "check_context: Unable to get spoolfile context");
++      return -1;
++    }
++    if (avc_context_to_sid(spoolfilecon, &filesid) != 0)
++    {
++      cupsdLogJob(job, 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)
++    {
++      cupsdLogJob(job, CUPSD_LOG_INFO,
++                "check_context: SELinux denied access to the spool file");
++      return 0;
++    }
++    cupsdLogJob(job, CUPSD_LOG_INFO,
++              "check_context: SELinux allowed access to the spool file");
++    return 1;
++  }
++  else
++    if (enforcing == 0)
++      cupsdLogJob(job, CUPSD_LOG_INFO,
++                "check_context: allowing operation due to permissive mode");
++    else
++      cupsdLogJob(job, 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.
+  */
+@@ -4075,6 +4428,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,
+@@ -4110,6 +4472,85 @@ 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)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++                "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);
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++                "copy_banner: Unable to get the SELinux contexts");
++      job->num_files --;
++      return (0);
++    }
++    jobrange = (char *) context_range_get(jobcon);
++    if (jobrange)
++    {
++      jobrange = strdup(jobrange);
++      if ((jobclearance = strtok(jobrange, "-")) != NULL)
++      {
++      if (context_range_set(tmpcon, jobclearance) == -1)
++      {
++        cupsdLogJob(job, 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)
++      {
++        cupsdLogJob(job, 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)
++    {
++      cupsdLogJob(job, 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);
++    }
++    cupsdLogJob(job, 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...
+@@ -4204,6 +4645,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);
+@@ -6389,6 +6848,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...
+   */
+@@ -6786,6 +7261,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);
+@@ -11415,6 +11895,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-2.2b2/scheduler/job.c.lspp cups-2.2b2/scheduler/job.c
+--- cups-2.2b2/scheduler/job.c.lspp    2016-06-27 17:39:48.041974149 +0200
++++ cups-2.2b2/scheduler/job.c 2016-06-27 17:39:48.081973831 +0200
+@@ -11,6 +11,9 @@
+  * 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...
+  */
+@@ -26,6 +29,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
+@@ -546,6 +557,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,
+@@ -1082,6 +1101,67 @@ cupsdContinueJob(cupsd_job_t *job)      /* I
+   if (final_content_type[0])
+     envp[envc ++] = final_content_type;
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++    if (!job->scon || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++    {
++      if (AuditLog != -1)
++      {
++        audit_message = NULL;
++        cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s",
++                        job->id, job->auid, job->username, job->printer->name, title);
++        audit_log_user_message(AuditLog, AUDIT_USER_UNLABELED_EXPORT, audit_message,
++                               ServerName, NULL, NULL, 1);
++        cupsdClearString(&audit_message);
++      }
++    }
++    else 
++    {
++      jobcon = context_new(job->scon);
++
++      if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME)) == NULL)
++        label_template = strdup(Classification);
++      else if (attr->num_values > 1 &&
++               strcmp(attr->values[1].string.text, "none") != 0)
++        label_template = strdup(attr->values[1].string.text);
++      else
++        label_template = strdup(attr->values[0].string.text);
++
++      if (_cups_strcasecmp(label_template, MLS_CONFIG) == 0)
++        mls_label = context_range_get(jobcon);
++      else if (_cups_strcasecmp(label_template, TE_CONFIG) == 0)
++        mls_label = context_type_get(jobcon);
++      else if (_cups_strcasecmp(label_template, SELINUX_CONFIG) == 0)
++        mls_label = context_str(jobcon);
++      else
++        mls_label = label_template;
++
++      if (mls_label && (PerPageLabels || banner_page))
++      {
++        snprintf(classification, sizeof(classification), "CLASSIFICATION=LSPP:%s", mls_label);
++        envp[envc ++] = classification;
++      }
++
++      if ((AuditLog != -1) && !banner_page)
++      {
++        audit_message = NULL;
++        cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s"
++                        " obj=%s label=%s", job->id, job->auid, job->username,
++                        job->printer->name, title, job->scon, mls_label?mls_label:"none");
++        audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++                               ServerName, NULL, NULL, 1);
++        cupsdClearString(&audit_message);
++      }
++      context_free(jobcon);
++      free(label_template);
++    }
++  }
++  else
++   /*
++    * Fall through to the non-LSPP behavior
++    */
++#endif /* WITH_LSPP */
+   if (Classification && !banner_page)
+   {
+     if ((attr = ippFindAttribute(job->attrs, "job-sheets",
+@@ -1905,6 +1985,22 @@ cupsdLoadJob(cupsd_job_t *job)          /* I - J
+       ippSetString(job->attrs, &job->reasons, 0, "none");
+   }
++#ifdef WITH_LSPP
++  if ((attr = ippFindAttribute(job->attrs, "security-context", IPP_TAG_NAME)) != NULL)
++    cupsdSetString(&job->scon, attr->values[0].string.text);
++  else if (is_lspp_config())
++  {
++   /*
++    * There was no security context so delete the job
++    */
++    cupsdLogJob(job, CUPSD_LOG_ERROR,
++              "Missing or bad security-context attribute "
++              "in control file \"%s\"!",
++              jobfile);
++    goto error;
++  }
++#endif /* WITH_LSPP */
++
+   job->impressions = ippFindAttribute(job->attrs, "job-impressions-completed", IPP_TAG_INTEGER);
+   job->sheets      = ippFindAttribute(job->attrs, "job-media-sheets-completed", IPP_TAG_INTEGER);
+   job->job_sheets  = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
+@@ -2318,6 +2414,14 @@ cupsdSaveJob(cupsd_job_t *job)          /* I - J
+ {
+   char                filename[1024];         /* Job control filename */
+   cups_file_t *fp;                    /* Job file */
++#ifdef WITH_LSPP
++  security_context_t  spoolcon;       /* context of the job control file */
++  context_t           jobcon;         /* contex_t container for job->scon */
++  context_t           tmpcon;         /* Temp context to swap the level */
++  char                        *jobclearance;  /* SELinux low end clearance */
++  const char          *jobrange;      /* SELinux sensitivity range */
++  char                        *jobrange_copy; /* SELinux sensitivity range */
++#endif /* WITH_LSPP */
+   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
+@@ -2340,6 +2444,78 @@ cupsdSaveJob(cupsd_job_t *job)          /* I - J
+   fchown(cupsFileNumber(fp), RunUser, Group);
++#ifdef WITH_LSPP
++  if (job->scon && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++  {
++    if (getfilecon(filename, &spoolcon) == -1)
++    {
++      cupsdLogJob(job, 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);
++      cupsdLogJob(job, 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)
++      {
++        cupsdLogJob(job, 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)
++      {
++        cupsdLogJob(job, 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)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++                "Unable to set context of job control file \"%s\" - %s.",
++                filename, strerror(errno));
++      context_free(tmpcon);
++      context_free(jobcon);
++      return;
++    }
++    cupsdLogJob(job, CUPSD_LOG_DEBUG2, "New spool file context=%s",
++               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,
+@@ -3919,6 +4095,19 @@ 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"))
++      {
++        cupsdLogJob(job, CUPSD_LOG_DEBUG,
++                  "Ignoring page-label option due to LSPP mode");
++        continue;
++      }
++#endif /* WITH_LSPP */
++
+      /*
+       * Otherwise add them to the list...
+       */
+@@ -4680,6 +4869,18 @@ start_job(cupsd_job_t     *job,         /* I -
+           cupsd_printer_t *printer)   /* I - Printer to print job */
+ {
+   const char  *filename;              /* Support filename */
++#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 */
+   ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
+                                                  "job-cancel-after",
+                                                  IPP_TAG_INTEGER);
+@@ -4856,6 +5057,113 @@ 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)
++    {
++      cupsdLogJob(job, CUPSD_LOG_DEBUG,
++                "Attempting to check access on printer device %s",
++                printerfile);
++      if (lstat(printerfile, &printerstat) < 0)
++      {
++      if (errno != ENOENT)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++                    "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
++      {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++                  "StartJob: Printer is not a character device or "
++                  "regular file");
++      cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++      return ;
++      }
++      static int 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)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++                  "Unable to determine the SELinux sid for the job");
++        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++        return ;
++      }
++      if (getfilecon(printerfile, &devcon) == -1)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++                  "Unable to get the SELinux context of %s",
++                  printerfile);
++        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++        return ;
++      }
++      printercon = context_new(devcon);
++      cupsdLogJob(job, CUPSD_LOG_DEBUG,
++                "Printer context %s client context %s",
++                context_str(printercon), job->scon);
++      context_free(printercon);
++
++      if (avc_context_to_sid(devcon, &psid) != 0)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++                  "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-2.2b2/scheduler/job.h.lspp cups-2.2b2/scheduler/job.h
+--- cups-2.2b2/scheduler/job.h.lspp    2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/job.h 2016-06-27 17:39:48.081973831 +0200
+@@ -11,6 +11,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...
+  */
+@@ -88,6 +95,10 @@ struct cupsd_job_s                  /**** Job request *
+   int                 progress;       /* Printing progress */
+   int                 num_keywords;   /* Number of PPD keywords */
+   cups_option_t               *keywords;      /* PPD keywords */
++#ifdef WITH_LSPP
++  security_context_t  scon;           /* Security context of job */
++  uid_t                       auid;           /* Audit loginuid for this job */
++#endif /* WITH_LSPP */
+ };
+ typedef struct cupsd_joblog_s         /**** Job log message ****/
+diff -up cups-2.2b2/scheduler/main.c.lspp cups-2.2b2/scheduler/main.c
+--- cups-2.2b2/scheduler/main.c.lspp   2016-06-27 17:39:48.064973966 +0200
++++ cups-2.2b2/scheduler/main.c        2016-06-27 17:39:48.081973831 +0200
+@@ -56,6 +56,9 @@
+ #  include <sys/param.h>
+ #endif /* HAVE_SYS_PARAM_H */
++#ifdef WITH_LSPP
++#  include <libaudit.h>
++#endif /* WITH_LSPP */
+ /*
+  * Local functions...
+@@ -122,6 +125,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 __APPLE__
+   int                 use_sysman = 1; /* Use system management functions? */
+ #else
+@@ -505,6 +511,25 @@ main(int  argc,                           /* I - Number of comm
+     exit(errno);
+   }
++#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...
+   */
+@@ -1205,6 +1230,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-2.2b2/scheduler/printers.c.lspp cups-2.2b2/scheduler/printers.c
+--- cups-2.2b2/scheduler/printers.c.lspp       2016-06-27 17:39:48.013974372 +0200
++++ cups-2.2b2/scheduler/printers.c    2016-06-27 17:39:48.082973823 +0200
+@@ -11,6 +11,8 @@
+  * file is missing or damaged, see the license at "http://www.cups.org/".
+  */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+  * Include necessary headers...
+  */
+@@ -35,6 +37,10 @@
+ #  include <asl.h>
+ #endif /* __APPLE__ */
++#ifdef WITH_LSPP
++#  include <libaudit.h>
++#  include <selinux/context.h>
++#endif /* WITH_LSPP */
+ /*
+  * Local functions...
+@@ -2191,6 +2197,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
+   ipp_attribute_t *attr;              /* Attribute data */
+   char                *name,                  /* Current user/group name */
+               *filter;                /* Current filter */
++#ifdef WITH_LSPP
++  char                *audit_message;         /* Audit message string */
++  char                *printerfile;           /* Path to a local printer dev */
++  char                *rangestr;              /* Printer's range if its available */
++  security_context_t  devcon;         /* Printer SELinux context */
++  context_t   printercon;             /* context_t for the printer */
++#endif /* WITH_LSPP */
+   DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
+@@ -2318,6 +2331,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;
index 983c62955567ea0e6b6c86fc135e70dc59a12b6b..57d497307d3d4994fc230ed982c41e7b45acbf51 100644 (file)
@@ -22,7 +22,7 @@
 @@ -69,10 +69,10 @@
                ;;
        Linux* | GNU* | Darwin*)
-               # Linux, GNU Hurd, and OS X
+               # Linux, GNU Hurd, and macOS
 -              MAN1EXT=1.gz
 -              MAN5EXT=5.gz
 -              MAN7EXT=7.gz
diff --git a/cups-pid.patch b/cups-pid.patch
new file mode 100644 (file)
index 0000000..23ffd47
--- /dev/null
@@ -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-res_init.patch b/cups-res_init.patch
new file mode 100644 (file)
index 0000000..3866521
--- /dev/null
@@ -0,0 +1,26 @@
+diff -up cups-1.7b1/cups/http-addr.c.res_init cups-1.7b1/cups/http-addr.c
+--- cups-1.7b1/cups/http-addr.c.res_init       2013-03-20 19:14:10.000000000 +0100
++++ cups-1.7b1/cups/http-addr.c        2013-04-19 12:01:36.927512159 +0200
+@@ -319,7 +319,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.7b1/cups/http-addrlist.c.res_init cups-1.7b1/cups/http-addrlist.c
+--- cups-1.7b1/cups/http-addrlist.c.res_init   2013-04-19 12:01:36.930512119 +0200
++++ cups-1.7b1/cups/http-addrlist.c    2013-04-19 12:03:13.769229554 +0200
+@@ -581,7 +581,8 @@ httpAddrGetList(const char *hostname,      /*
+     }
+     else
+     {
+-      if (error == EAI_FAIL)
++      if (error == EAI_FAIL || error == EAI_AGAIN || error == EAI_NODATA ||
++          error == EAI_NONAME)
+         cg->need_res_init = 1;
+       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerror(error), 0);
diff --git a/cups-ricoh-deviceid-oid.patch b/cups-ricoh-deviceid-oid.patch
new file mode 100644 (file)
index 0000000..c148f95
--- /dev/null
@@ -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,
index 03c21b8219da7bd8580bee23f4e2f96d4a20be73..c6c3506956762a71e33747fd2083c5ac2bbcd3c9 100644 (file)
@@ -1,9 +1,9 @@
-diff -up cups-2.0.2/scheduler/main.c.ustTJg cups-2.0.2/scheduler/main.c
---- cups-2.0.2/scheduler/main.c.ustTJg 2015-02-10 13:40:24.121547526 +0100
-+++ cups-2.0.2/scheduler/main.c        2015-02-10 13:40:24.295545063 +0100
-@@ -658,8 +658,15 @@ main(int  argc,                           /* I - Number of comm
+diff -up cups-2.2b2/scheduler/main.c.systemd-socket cups-2.2b2/scheduler/main.c
+--- cups-2.2b2/scheduler/main.c.systemd-socket 2016-06-27 15:12:24.930881404 +0200
++++ cups-2.2b2/scheduler/main.c        2016-06-27 15:19:38.118234985 +0200
+@@ -690,8 +690,15 @@ main(int  argc,                           /* I - Number of comm
  
- #if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ #if defined(HAVE_ONDEMAND)
    if (OnDemand)
 +  {
      cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started on demand.");
@@ -15,12 +15,12 @@ diff -up cups-2.0.2/scheduler/main.c.ustTJg cups-2.0.2/scheduler/main.c
 +               (unsigned long) getpid());
 +# endif /* HAVE_SYSTEMD */
 +  } else
- #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ #endif /* HAVE_ONDEMAND */
    if (fg)
      cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in foreground.");
-diff -up cups-2.0.2/scheduler/org.cups.cupsd.path.in.ustTJg cups-2.0.2/scheduler/org.cups.cupsd.path.in
---- cups-2.0.2/scheduler/org.cups.cupsd.path.in.ustTJg 2014-03-21 15:50:24.000000000 +0100
-+++ cups-2.0.2/scheduler/org.cups.cupsd.path.in        2015-02-10 13:40:24.295545063 +0100
+diff -up cups-2.2b2/scheduler/org.cups.cupsd.path.in.systemd-socket cups-2.2b2/scheduler/org.cups.cupsd.path.in
+--- cups-2.2b2/scheduler/org.cups.cupsd.path.in.systemd-socket 2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/org.cups.cupsd.path.in        2016-06-27 15:12:24.930881404 +0200
 @@ -2,7 +2,7 @@
  Description=CUPS Scheduler
  
@@ -30,9 +30,9 @@ diff -up cups-2.0.2/scheduler/org.cups.cupsd.path.in.ustTJg cups-2.0.2/scheduler
  
  [Install]
  WantedBy=multi-user.target
-diff -up cups-2.0.2/scheduler/org.cups.cupsd.service.in.ustTJg cups-2.0.2/scheduler/org.cups.cupsd.service.in
---- cups-2.0.2/scheduler/org.cups.cupsd.service.in.ustTJg      2014-10-21 13:55:01.000000000 +0200
-+++ cups-2.0.2/scheduler/org.cups.cupsd.service.in     2015-02-10 13:40:24.296545049 +0100
+diff -up cups-2.2b2/scheduler/org.cups.cupsd.service.in.systemd-socket cups-2.2b2/scheduler/org.cups.cupsd.service.in
+--- cups-2.2b2/scheduler/org.cups.cupsd.service.in.systemd-socket      2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/org.cups.cupsd.service.in     2016-06-27 15:12:24.930881404 +0200
 @@ -1,10 +1,11 @@
  [Unit]
  Description=CUPS Scheduler
diff --git a/cups-web-devices-timeout.patch b/cups-web-devices-timeout.patch
new file mode 100644 (file)
index 0000000..fa3a320
--- /dev/null
@@ -0,0 +1,19 @@
+diff -up cups-1.7rc1/cgi-bin/admin.c.web-devices-timeout cups-1.7rc1/cgi-bin/admin.c
+--- cups-1.7rc1/cgi-bin/admin.c.web-devices-timeout    2013-05-29 12:51:34.000000000 +0100
++++ cups-1.7rc1/cgi-bin/admin.c        2013-08-16 16:01:17.308264287 +0100
+@@ -1019,13 +1019,13 @@ do_am_printer(http_t *http,            /* I - HTTP
+     }
+    /*
+-    * Scan for devices for up to 30 seconds...
++    * Scan for devices for up to 10 seconds...
+     */
+     fputs("DEBUG: Getting list of devices...\n", stderr);
+     current_device = 0;
+-    if (cupsGetDevices(http, 5, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
++    if (cupsGetDevices(http, 10, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
+                        (cups_device_cb_t)choose_device_cb,
+                      (void *)title) == IPP_OK)
+     {
index 3dfd1b9480bb216ee327fc2f130625a3a15d60a4..b8244b93a48f87f6be3a2dd58b2e3507d440b6fe 100644 (file)
--- a/cups.spec
+++ b/cups.spec
 Summary(pl.UTF-8):     Ogólny system druku dla Uniksa
 Summary(pt_BR.UTF-8):  Sistema Unix de Impressão
 Name:          cups
-Version:       2.1.4
-Release:       2
+Version:       2.2.1
+Release:       1
 Epoch:         1
 License:       LGPL v2 (libraries), GPL v2 (the rest)
 Group:         Applications/Printing
-Source0:       https://github.com/apple/cups/archive/release-%{version}.tar.gz
-# Source0-md5: 5a9b778799f3d43f8be9c3b7ac69d012
+Source0:       https://github.com/apple/cups/releases/download/v%{version}/%{name}-%{version}-source.tar.gz
+# Source0-md5: a94da2a1e9dbdccb4f3836a38a431931
 Source1:       %{name}.init
 Source2:       %{name}.pamd
 Source3:       %{name}.logrotate
@@ -43,6 +43,22 @@ Patch18:     %{name}-final-content-type.patch
 # avahi patches from fedora
 Patch100:      %{name}-avahi-address.patch
 Patch101:      %{name}-avahi-no-threaded.patch
+Patch102:      cups-banners.patch
+Patch103:      cups-pid.patch
+Patch104:      cups-eggcups.patch
+Patch105:      cups-driverd-timeout.patch
+Patch106:      cups-logrotate.patch
+Patch107:      cups-res_init.patch
+Patch108:      cups-filter-debug.patch
+Patch109:      cups-hp-deviceid-oid.patch
+Patch110:      cups-dnssd-deviceid.patch
+Patch111:      cups-ricoh-deviceid-oid.patch
+Patch112:      cups-enum-all.patch
+Patch113:      cups-dymo-deviceid.patch
+Patch114:      cups-freebind.patch
+Patch115:      cups-ipp-multifile.patch
+Patch116:      cups-web-devices-timeout.patch
+Patch117:      cups-lspp.patch
 URL:           http://www.cups.org/
 BuildRequires: acl-devel
 BuildRequires: autoconf >= 2.60
@@ -232,7 +248,7 @@ LPD compatibility support for CUPS print server.
 Wsparcie dla LPD w serwerze wydruków CUPS.
 
 %prep
-%setup -q -n %{name}-release-%{version}
+%setup -q
 %patch0 -p1
 %patch2 -p1
 %patch3 -p1
@@ -257,6 +273,23 @@ Wsparcie dla LPD w serwerze wydruków CUPS.
 %patch101 -p1
 %endif
 
+%patch102 -p1
+%patch103 -p1
+%patch104 -p1
+%patch105 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+
 %build
 %{__aclocal} -I config-scripts
 %{__autoconf}
@@ -415,7 +448,6 @@ fi
 %attr(600,root,lp) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/%{name}/snmp.conf
 %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/security/blacklist.cups
 %dir %attr(700,root,lp) %{_sysconfdir}/%{name}/ssl
-%dir %{_sysconfdir}/%{name}/interfaces
 %dir %attr(755,root,lp) %{_sysconfdir}/%{name}/ppd
 %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/logrotate.d/%{name}
 %attr(755,root,root) %{_bindir}/cupstestppd
This page took 0.888196 seconds and 4 git commands to generate.