New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please introduce support for installing systemd units #3917

Closed
michaelrsweet opened this Issue Aug 9, 2011 · 30 comments

Comments

Projects
None yet
1 participant
@michaelrsweet
Copy link
Collaborator

michaelrsweet commented Aug 9, 2011

Version: 2.0-feature
CUPS.org User: mgorny

Modern Linux distros start using systemd 1 as their init system. One of the key points of systemd is to move service unit files upstream instead of supplying it on per-distro basis.

That's why we'd like to request that CUPS would (optionally) be able to install those units. These are a few small files without additional deps.

The systemd author has prepared a patch for it and described it well 2 but I don't see the systemd support mentioned anywhere on bugzie, so I'm attaching it here.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Aug 9, 2011

CUPS.org User: mike

OK, before we can accept this large of a patch, I'll need you to print, sign, and mail two copies of the CUPS Contributor Agreement, available here:

http://www.cups.org/AppleContributorAgreement_2011-03-10.pdf

Once we get the agreement in place I'll work on integrating the changes into the next feature release, and probably revamp the existing launchd support so that both launchd and systemd share a common set of entry points in cupsd.

Thanks!

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Aug 29, 2011

CUPS.org User: mike

Ping

Are you planning on/looking into signing the CUPS Contributor Agreement, or should I close this bug?

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Aug 29, 2011

CUPS.org User: mgorny

I am trying to reach the patch author. I don't think there's really a point in me signing this if I'm just the one reporting the request.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Aug 29, 2011

CUPS.org User: mike

Agreed, and thanks for getting back to me.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 10, 2011

CUPS.org User: mike

See STR #3955 concerning an IPv6 regression with this change; need to add the BindIPv6Only keyword for the IPv6 listener...

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 12, 2011

CUPS.org User: twaugh.redhat

There were several other problems with this patch, which I now believe are ironed out. (The previous lack of any substantial testing, as well as issues involving the contributor agreement, were the reasons I had not submitted this patch before...)

I'll attach the current revision of this patch, which now seems to be working well.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 12, 2011

CUPS.org User: twaugh.redhat

Oh, I think I'm still waiting for a reply from Lennart about the license. I'll prod him again.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 18, 2011

CUPS.org User: twaugh.redhat

Patch attached. This patch does not introduce any source files, just data files, one function and some calls to it.

As a result it's hard to know where to put license information concerning the patch. I've spoken to Lennart and he is happy for the code to be licensed for CUPS as follows:

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Dec 9, 2011

CUPS.org User: mgorny

I think it'd be a good idea to add cups-lpd@.service there as well.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Apr 20, 2012

CUPS.org User: mgorny

Tim, please note that the attached patch has a little bug. When you pass --with-systemdsystemunitdir= yet libsystemd-daemon check fails to find libsystemd-daemon, SYSTEMD_UNITS is set but systemdsystemunitdir is not substituted. Thus, the unit files are installed into the root directory.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Jan 3, 2014

CUPS.org User: odyx

Hi Michael,

what is the status of the integration of this patch? It would be quite interesting to have this blessed by you for a more confident integration in the various distributions.

Cheers, OdyX

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Jan 4, 2014

CUPS.org User: mike

Didier,

I think we have a good patch from Tim we can incorporate. I'm taking care of some other infrastructure changes in cupsd now, and once that is done I will work on integrating this.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Jan 23, 2014

CUPS.org User: till.kamppeter

Does the supplied patch support starting cupsd on-demand?

On

http://0pointer.de/blog/projects/socket-activation2.html

there is a patch which starts cupsd on-demand:

http://0pointer.de/public/cups-0001-systemd-add-systemd-socket-activation-and-unit-files.patch

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Feb 14, 2014

CUPS.org User: mike

Till,

We'll make sure to have cupsd launch on demand via systemd.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Feb 23, 2014

CUPS.org User: odyx

@michael: cool!

While integrating this patch into Debian's cups, I've come to use the Gentoo variant, which has the benefit of detecting systemd's usage at runtime, not only build-time.

Patch is attached.

Cheers, OdyX

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 19, 2014

CUPS.org User: odyx

Hi again Mike,
While polishing the systemd integration for Debian including full socket-activation, I've come up with a patch generating a systemd.socket-compatible file on configuration changes from the webinterface, patch attached.

The "good way" to handle that would be for CUPS to stop bind interfaces by itself when run under systemd (and let cups.socket be the only piece binding sockets for cups), but that would have been a quite more extensive patch.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 19, 2014

CUPS.org User: mike

Didier,

What we do on OS X is to have launchd handle the domain socket and listening on localhost, and then have cupsd handle the external interfaces when printer sharing is enabled. We specifically avoid writing a new plist for launchd because it will cause launchd to stop cupsd to make the change...

I don't know whether this is an issue for systemd (systemd documentation is horrible) but I'd like to retain the same approach we used for launchd since it ensures that basic functionality/connectivity is always available to cupsd.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 19, 2014

CUPS.org User: mike

Didier,

In reviewing the patches, it looks like you have systemd listening for the old CUPS Browse (UDP) packets? That isn't something we'd want to continue listing since cupsd doesn't handle them.

I'm also not sure about the addition to the cupsd_listener_t structure but will do some testing to see if it is even necessary (it isn't for launchd).

The path should be a file that cupsd creates when it needs to keep running - the presence of "d" files is not sufficient.

Finally, I don't think we'll want to extend cupsAdminSetServerSettings at all. There are other ways the config file gets updated so those changes really don't have systemd reflecting the cupsd configuration at all...

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 21, 2014

CUPS.org User: mike

OK, changes are now in TOT and in the Git mirror. Source changes thus far are attached, although the patch reflects a lot of restructuring work to get all of the cupsd startup stuff simplified and in one place - probably easier to clone/pull from the Git mirror.

I've called the service "org.cups.cupsd" since at some point I think I'll add an org.cups.cups-lpd service as well - this mirrors what we've done for OS X and launchd, and eliminates the dependency on xinetd for LPD server support.

I also renamed the LaunchdTimeout directive to IdleExitTimeout, which defaults to 60 seconds. If there is no client activity within the timeout interval then we idle exit cupsd.

The socket file lists the loopback addresses as well as the domain socket. The path file looks for /var/cache/cups/org.cups.cupsd, which is created by cupsd if there are pending jobs or shared printers.

Unfortunately, at least on my Fedora 19 VM, the launch-on-demand works fine until cupsd idle exits... Then I have to run "sudo systemctl start org.cups.cupsd" to get things going again. (I did replace the original CUPS packages on Fedora, disabled the old cups service, and did a daemon-reload)

Would appreciate some more testing on this to make sure it works well for everyone, and perhaps yield a solution to the service not staying started...

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 28, 2014

CUPS.org User: mike

OK, after rebooting for a software update, idle-exit seems to be working properly, so maybe it was just a state thing with the old cups names going away and the org.cups.cupsd name coming in?

Anyways, seems to be working. Please file new bugs if you have any problems with the code in the Git mirror.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 28, 2014

"cups-systemd.patch":

From 1db0a48375836c7e93ac30649007c2391be8b3b2 Mon Sep 17 00:00:00 2001
From: Lennart Poettering lennart@poettering.net
Date: Mon, 4 Jul 2011 01:37:01 +0200
Subject: [PATCH] systemd: add systemd socket activation and unit files

On newer Linux machines systemd supports launchd-style socket
activation. This patch adds support for this mechanism and also adds
systemd unit files as appropriate to hook this up with systemd.

This includes an MIT-licensed drop-in file that implements the most
basic interfaces needed to get the file descriptors from systemd. Most
of the systemd and Linux-specific code compiles to NOPs on other
systems.

Three triggers to start CUPS are defined: a) if new printer hardware is
plugged in, b) when a client accesses the CUPS socket and c) when a

## spool file resides in /var/spool/cups.

 Makedefs.in                    |    2 +
 config-scripts/cups-systemd.m4 |   25 ++
 configure.in                   |    4 +
 data/Makefile                  |    9 +
 data/cups.path.in              |    8 +
 data/cups.service.in           |    9 +
 data/cups.socket.in            |    9 +
 scheduler/Makefile             |    9 +
 scheduler/main.c               |  107 ++++++++
 scheduler/sd-daemon.c          |  520 ++++++++++++++++++++++++++++++++++++++++
 scheduler/sd-daemon.h          |  277 +++++++++++++++++++++
 11 files changed, 979 insertions(+), 0 deletions(-)
 create mode 100644 config-scripts/cups-systemd.m4
 create mode 100644 data/cups.path.in
 create mode 100644 data/cups.service.in
 create mode 100644 data/cups.socket.in
 create mode 100644 scheduler/sd-daemon.c
 create mode 100644 scheduler/sd-daemon.h

diff --git a/Makedefs.in b/Makedefs.in
index 654eea4..02c43b6 100644
--- a/Makedefs.in
+++ b/Makedefs.in
@@ -143,6 +143,7 @@ CXXFLAGS    =   @CPPFLAGS@ @CXXFLAGS@
 CXXLIBS        =   @CXXLIBS@
 DBUS_NOTIFIER  =   @DBUS_NOTIFIER@
 DBUS_NOTIFIERLIBS =    @DBUS_NOTIFIERLIBS@
+SYSTEMD_UNITS   =       @SYSTEMD_UNITS@
 DNSSD_BACKEND  =   @DNSSD_BACKEND@
 DSOFLAGS   =   -L../cups @DSOFLAGS@
 DSOLIBS        =   @DSOLIBS@ $(COMMONLIBS)
@@ -267,6 +268,7 @@ PAMFILE     =   @PAMFILE@

 DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
 DBUSDIR        =   @DBUSDIR@
+SYSTEMDUNITDIR  =       $(BUILDROOT)@systemdsystemunitdir@

 #
diff --git a/config-scripts/cups-systemd.m4 b/config-scripts/cups-systemd.m4
new file mode 100644
index 0000000..fead8a9
--- /dev/null
+++ b/config-scripts/cups-systemd.m4
@@ -0,0 +1,25 @@
+dnl
+dnl "$Id$"
+dnl
+dnl   systemd stuff for CUPS.
+
+dnl Find whether systemd is available
+
+AC_ARG_WITH([systemdsystemunitdir],
-        AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
-        [], [with_systemdsystemunitdir=$($PKGCONFIG --variable=systemdsystemunitdir systemd)])
  +if test "x$with_systemdsystemunitdir" != xno; then
-        AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
  +fi
  +
  +if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then
-        SYSTEMD_UNITS="cups.service cups.socket cups.path"
  +else
-        SYSTEMD_UNITS=""
  +fi
  +
  +AC_SUBST(SYSTEMD_UNITS)
  +
  +dnl
  +dnl "$Id$"
  +dnl
  diff --git a/configure.in b/configure.in
  index 560f4f8..b0c19a9 100644
  --- a/configure.in
  +++ b/configure.in
  @@ -37,6 +37,7 @@ sinclude(config-scripts/cups-pam.m4)
  sinclude(config-scripts/cups-largefile.m4)
  sinclude(config-scripts/cups-dnssd.m4)
  sinclude(config-scripts/cups-launchd.m4)
  +sinclude(config-scripts/cups-systemd.m4)
  sinclude(config-scripts/cups-defaults.m4)
  sinclude(config-scripts/cups-pdf.m4)
  sinclude(config-scripts/cups-scripting.m4)
  @@ -71,6 +72,9 @@ AC_OUTPUT(Makedefs
    conf/snmp.conf
    cups-config
    data/testprint
-          data/cups.service
-          data/cups.socket
-          data/cups.path
    desktop/cups.desktop
    doc/help/ref-cupsd-conf.html
    doc/help/standard.html
  diff --git a/data/Makefile b/data/Makefile
  index b9de21a..cccab85 100644
  --- a/data/Makefile
  +++ b/data/Makefile
  @@ -112,6 +112,12 @@ install-data:
      $(INSTALL_DATA) $$file $(DATADIR)/ppdc; \
  done
  $(INSTALL_DIR) -m 755 $(DATADIR)/profiles
-   if test "x$(SYSTEMD_UNITS)" != "x" ; then \
-       $(INSTALL_DIR) -m 755 $(SYSTEMDUNITDIR); \
-       for file in $(SYSTEMD_UNITS); do \
-           $(INSTALL_DATA) $$file $(SYSTEMDUNITDIR); \
-       done; \
-   fi
  
  #
  @@ -159,6 +165,9 @@ uninstall:
  -$(RMDIR) $(DATADIR)/charsets
  -$(RMDIR) $(DATADIR)/banners
  -$(RMDIR) $(DATADIR)
-   for file in $(SYSTEMD_UNITS); do \
-       $(RM) $(SYSTEMDUNITDIR)/$$file; \
-   done
  
  #
  diff --git a/data/cups.path.in b/data/cups.path.in
  new file mode 100644
  index 0000000..c99e39b
  --- /dev/null
  +++ b/data/cups.path.in
  @@ -0,0 +1,8 @@
  +[Unit]
  +Description=CUPS Printer Service Spool
  +
  +[Path]
  +DirectoryNotEmpty=@CUPS_REQUESTS@
  +
  +[Install]
  +WantedBy=multi-user.target
  diff --git a/data/cups.service.in b/data/cups.service.in
  new file mode 100644
  index 0000000..007d0e6
  --- /dev/null
  +++ b/data/cups.service.in
  @@ -0,0 +1,9 @@
  +[Unit]
  +Description=CUPS Printing Service
  +
  +[Service]
  +ExecStart=@sbindir@/cupsd -f
  +
  +[Install]
  +Also=cups.socket cups.path
  +WantedBy=printer.target
  diff --git a/data/cups.socket.in b/data/cups.socket.in
  new file mode 100644
  index 0000000..b940096
  --- /dev/null
  +++ b/data/cups.socket.in
  @@ -0,0 +1,9 @@
  +[Unit]
  +Description=CUPS Printing Service Sockets
  +
  +[Socket]
  +ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
  +ListenStream=631
  +
  +[Install]
  +WantedBy=sockets.target
  diff --git a/scheduler/Makefile b/scheduler/Makefile
  index 3c7da8e..05152a6 100644
  --- a/scheduler/Makefile
  +++ b/scheduler/Makefile
  @@ -39,6 +39,7 @@ CUPSDOBJS =   \
      server.o \
      statbuf.o \
      subscriptions.o \
- 
    sd-daemon.o \
  sysman.o

  
  LIBOBJS =  \
        filter.o \
  @@ -568,6 +569,14 @@ sloc:
  
  #
  +# Update sd-daemon.[ch] drop-in file from upstream git
  +#
  +
  +update-systemd:
-   curl http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c > sd-daemon.c
-   curl http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h > sd-daemon.h
  +
  +#
  # Dependencies...
  #

diff --git a/scheduler/main.c b/scheduler/main.c
index baaa3a1..5a4b8e1 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -26,6 +26,8 @@
-   launchd_checkin()     - Check-in with launchd and collect the listening
-                           fds.
-   launchd_checkout()    - Update the launchd KeepAlive file as needed.
  - \*   systemd_checkin()     - Check-in with systemd and collect the
  - \*                           listening fds.
-   parent_handler()      - Catch USR1/CHLD signals...
-   process_children()    - Process all dead children...
-   select_timeout()      - Calculate the select timeout value.
  @@ -62,6 +64,8 @@
  #  endif /\* !LAUNCH_JOBKEY_SERVICEIPC _/
  #endif /_ HAVE_LAUNCH_H */

+#include "sd-daemon.h"
+
 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
 #  include <malloc.h>
 #endif /\* HAVE_MALLOC_H && HAVE_MALLINFO _/
@@ -78,6 +82,7 @@
 static void        launchd_checkin(void);
 static void        launchd_checkout(void);
 #endif /_ HAVE_LAUNCHD _/
+static void        systemd_checkin(void);
 static void        parent_handler(int sig);
 static void        process_children(void);
 static void        sigchld_handler(int sig);
@@ -520,6 +525,11 @@ main(int  argc,                /_ I - Number of command-line args _/
 #endif /_ HAVE_LAUNCHD */

  /*
-  \* If we were started by systemd get the listen sockets file descriptors...
-  */
-  systemd_checkin();
  +
- /*
  - Startup the server...
    */

@@ -731,6 +741,12 @@ main(int  argc,                /\* I - Number of command-line args _/
 #endif /_ HAVE_LAUNCHD */

    /*
-        \* If we were started by systemd get the listen sockets file descriptors...
-        */
  +
-        systemd_checkin();
  +
-       /*
       \* Startup the server...
       */

@@ -1535,6 +1551,97 @@ launchd_checkout(void)
 }
 #endif /\* HAVE_LAUNCHD */

+static void
+systemd_checkin(void)
+{
-  int n, fd;
  +
-  n = sd_listen_fds(1);
-  if (n < 0)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-           "systemd_checkin: Failed to acquire sockets from systemd - %s",
-           strerror(-n));
-    exit(EXIT_FAILURE);
-    return;
-  }
  +
-  if (n == 0)
-    return;
  +
-  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
-  {
-    http_addr_t addr;
-    socklen_t addrlen;
-    int r;
-    cupsd_listener_t *lis;
-    char s[256];
  +
-    r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1);
-    if (r < 0) {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-             "systemd_checkin: Unable to verify socket type - %s",
-             strerror(-r));
-      continue;
-    }
  +
-    if (!r) {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-             "systemd_checkin: Socket not of the right type");
-      continue;
-    }
  +
-    if (getsockname(fd, (struct sockaddr*) &addr, &addrlen))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-             "systemd_checkin: Unable to get local address - %s",
-             strerror(errno));
-      continue;
-    }
  +
-     /*
-    \* Try to match the systemd socket address to one of the listeners...
-    */
  +
-    for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
-       lis;
-       lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
-      if (httpAddrEqual(&lis->address, &addr))
-      break;
  +
-    if (lis)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "systemd_checkin: Matched existing listener %s with fd %d...",
-                      httpAddrString(&(lis->address), s, sizeof(s)), fd);
-    }
-    else
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "systemd_checkin: Adding new listener %s with fd %d...",
-                      httpAddrString(&addr, s, sizeof(s)), fd);
  +
-      if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
-      {
-        cupsdLogMessage(CUPSD_LOG_ERROR,
-                        "systemd_checkin: Unable to allocate listener - "
-                        "%s.", strerror(errno));
-        exit(EXIT_FAILURE);
-      }
  +
-      cupsArrayAdd(Listeners, lis);
  +
-      memcpy(&lis->address, &addr, sizeof(lis->address));
-    }
  +
-    lis->fd = fd;
  +
  +#  ifdef HAVE_SSL
-    if (_httpAddrPort(&(lis->address)) == 443)
-      lis->encryption = HTTP_ENCRYPT_ALWAYS;
  +#  endif /\* HAVE_SSL */
-  }
  +}
  
  /*
  - 'parent_handler()' - Catch USR1/CHLD signals...
    diff --git a/scheduler/sd-daemon.c b/scheduler/sd-daemon.c
    new file mode 100644
    index 0000000..a2ec74c
    --- /dev/null
    +++ b/scheduler/sd-daemon.c
    @@ -0,0 +1,520 @@
    +/_-_\- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -_-_/
    +
    +/***
-  Copyright 2010 Lennart Poettering
  +
-  Permission is hereby granted, free of charge, to any person
-  obtaining a copy of this software and associated documentation files
-  (the "Software"), to deal in the Software without restriction,
-  including without limitation the rights to use, copy, modify, merge,
-  publish, distribute, sublicense, and/or sell copies of the Software,
-  and to permit persons to whom the Software is furnished to do so,
-  subject to the following conditions:
  +
-  The above copyright notice and this permission notice shall be
-  included in all copies or substantial portions of the Software.
  +
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  SOFTWARE.
  +***/
  +
  +#ifndef _GNU_SOURCE
  +#define _GNU_SOURCE
  +#endif
  +
  +#include <sys/types.h>
  +#include <sys/stat.h>
  +#include <sys/socket.h>
  +#include <sys/un.h>
  +#include <sys/fcntl.h>
  +#include <netinet/in.h>
  +#include <stdlib.h>
  +#include <errno.h>
  +#include <unistd.h>
  +#include <string.h>
  +#include <stdarg.h>
  +#include <stdio.h>
  +#include <stddef.h>
  +#include <limits.h>
  +
  +#if defined(__linux__)
  +#include <mqueue.h>
  +#endif
  +
  +#include "sd-daemon.h"
  +
  +#if (**GNUC** >= 4) && !defined(SD_EXPORT_SYMBOLS)
  +#define _sd_hidden_ **attribute** ((visibility("hidden")))
  +#else
  +#define _sd_hidden_
  +#endif
  +
  +_sd_hidden_ int sd_listen_fds(int unset_environment) {
  +
  +#if defined(DISABLE_SYSTEMD) || !defined(**linux**)
-        return 0;
  +#else
-        int r, fd;
-        const char *e;
-        char *p = NULL;
-        unsigned long l;
  +
-        if (!(e = getenv("LISTEN_PID"))) {
-                r = 0;
-                goto finish;
-        }
  +
-        errno = 0;
-        l = strtoul(e, &p, 10);
  +
-        if (errno != 0) {
-                r = -errno;
-                goto finish;
-        }
  +
-        if (!p || *p || l <= 0) {
-                r = -EINVAL;
-                goto finish;
-        }
  +
-        /\* Is this for us? */
-        if (getpid() != (pid_t) l) {
-                r = 0;
-                goto finish;
-        }
  +
-        if (!(e = getenv("LISTEN_FDS"))) {
-                r = 0;
-                goto finish;
-        }
  +
-        errno = 0;
-        l = strtoul(e, &p, 10);
  +
-        if (errno != 0) {
-                r = -errno;
-                goto finish;
-        }
  +
-        if (!p || *p) {
-                r = -EINVAL;
-                goto finish;
-        }
  +
-        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
-                int flags;
  +
-                if ((flags = fcntl(fd, F_GETFD)) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
  +
-                if (flags & FD_CLOEXEC)
-                        continue;
  +
-                if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-        }
  +
-        r = (int) l;
  +
  +finish:
-        if (unset_environment) {
-                unsetenv("LISTEN_PID");
-                unsetenv("LISTEN_FDS");
-        }
  +
-        return r;
  +#endif
  +}
  +
  +_sd_hidden_ int sd_is_fifo(int fd, const char *path) {
-        struct stat st_fd;
  +
-        if (fd < 0)
-                return -EINVAL;
  +
-        memset(&st_fd, 0, sizeof(st_fd));
-        if (fstat(fd, &st_fd) < 0)
-                return -errno;
  +
-        if (!S_ISFIFO(st_fd.st_mode))
-                return 0;
  +
-        if (path) {
-                struct stat st_path;
  +
-                memset(&st_path, 0, sizeof(st_path));
-                if (stat(path, &st_path) < 0) {
  +
-                        if (errno == ENOENT || errno == ENOTDIR)
-                                return 0;
  +
-                        return -errno;
-                }
  +
-                return
-                        st_path.st_dev == st_fd.st_dev &&
-                        st_path.st_ino == st_fd.st_ino;
-        }
  +
-        return 1;
  +}
  +
  +_sd_hidden_ int sd_is_special(int fd, const char *path) {
-        struct stat st_fd;
  +
-        if (fd < 0)
-                return -EINVAL;
  +
-        if (fstat(fd, &st_fd) < 0)
-                return -errno;
  +
-        if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode))
-                return 0;
  +
-        if (path) {
-                struct stat st_path;
  +
-                if (stat(path, &st_path) < 0) {
  +
-                        if (errno == ENOENT || errno == ENOTDIR)
-                                return 0;
  +
-                        return -errno;
-                }
  +
-                if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode))
-                        return
-                                st_path.st_dev == st_fd.st_dev &&
-                                st_path.st_ino == st_fd.st_ino;
-                else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode))
-                        return st_path.st_rdev == st_fd.st_rdev;
-                else
-                        return 0;
-        }
  +
-        return 1;
  +}
  +
  +static int sd_is_socket_internal(int fd, int type, int listening) {
-        struct stat st_fd;
  +
-        if (fd < 0 || type < 0)
-                return -EINVAL;
  +
-        if (fstat(fd, &st_fd) < 0)
-                return -errno;
  +
-        if (!S_ISSOCK(st_fd.st_mode))
-                return 0;
  +
-        if (type != 0) {
-                int other_type = 0;
-                socklen_t l = sizeof(other_type);
  +
-                if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0)
-                        return -errno;
  +
-                if (l != sizeof(other_type))
-                        return -EINVAL;
  +
-                if (other_type != type)
-                        return 0;
-        }
  +
-        if (listening >= 0) {
-                int accepting = 0;
-                socklen_t l = sizeof(accepting);
  +
-                if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0)
-                        return -errno;
  +
-                if (l != sizeof(accepting))
-                        return -EINVAL;
  +
-                if (!accepting != !listening)
-                        return 0;
-        }
  +
-        return 1;
  +}
  +
  +union sockaddr_union {
-        struct sockaddr sa;
-        struct sockaddr_in in4;
-        struct sockaddr_in6 in6;
-        struct sockaddr_un un;
-        struct sockaddr_storage storage;
  +};
  +
  +_sd_hidden_ int sd_is_socket(int fd, int family, int type, int listening) {
-        int r;
  +
-        if (family < 0)
-                return -EINVAL;
  +
-        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
-                return r;
  +
-        if (family > 0) {
-                union sockaddr_union sockaddr;
-                socklen_t l;
  +
-                memset(&sockaddr, 0, sizeof(sockaddr));
-                l = sizeof(sockaddr);
  +
-                if (getsockname(fd, &sockaddr.sa, &l) < 0)
-                        return -errno;
  +
-                if (l < sizeof(sa_family_t))
-                        return -EINVAL;
  +
-                return sockaddr.sa.sa_family == family;
-        }
  +
-        return 1;
  +}
  +
  +_sd_hidden_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
-        union sockaddr_union sockaddr;
-        socklen_t l;
-        int r;
  +
-        if (family != 0 && family != AF_INET && family != AF_INET6)
-                return -EINVAL;
  +
-        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
-                return r;
  +
-        memset(&sockaddr, 0, sizeof(sockaddr));
-        l = sizeof(sockaddr);
  +
-        if (getsockname(fd, &sockaddr.sa, &l) < 0)
-                return -errno;
  +
-        if (l < sizeof(sa_family_t))
-                return -EINVAL;
  +
-        if (sockaddr.sa.sa_family != AF_INET &&
-            sockaddr.sa.sa_family != AF_INET6)
-                return 0;
  +
-        if (family > 0)
-                if (sockaddr.sa.sa_family != family)
-                        return 0;
  +
-        if (port > 0) {
-                if (sockaddr.sa.sa_family == AF_INET) {
-                        if (l < sizeof(struct sockaddr_in))
-                                return -EINVAL;
  +
-                        return htons(port) == sockaddr.in4.sin_port;
-                } else {
-                        if (l < sizeof(struct sockaddr_in6))
-                                return -EINVAL;
  +
-                        return htons(port) == sockaddr.in6.sin6_port;
-                }
-        }
  +
-        return 1;
  +}
  +
  +_sd_hidden_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
-        union sockaddr_union sockaddr;
-        socklen_t l;
-        int r;
  +
-        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
-                return r;
  +
-        memset(&sockaddr, 0, sizeof(sockaddr));
-        l = sizeof(sockaddr);
  +
-        if (getsockname(fd, &sockaddr.sa, &l) < 0)
-                return -errno;
  +
-        if (l < sizeof(sa_family_t))
-                return -EINVAL;
  +
-        if (sockaddr.sa.sa_family != AF_UNIX)
-                return 0;
  +
-        if (path) {
-                if (length <= 0)
-                        length = strlen(path);
  +
-                if (length <= 0)
-                        /\* Unnamed socket */
-                        return l == offsetof(struct sockaddr_un, sun_path);
  +
-                if (path[0])
-                        /\* Normal path socket */
-                        return
-                                (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) &&
-                                memcmp(path, sockaddr.un.sun_path, length+1) == 0;
-                else
-                        /\* Abstract namespace socket */
-                        return
-                                (l == offsetof(struct sockaddr_un, sun_path) + length) &&
-                                memcmp(path, sockaddr.un.sun_path, length) == 0;
-        }
  +
-        return 1;
  +}
  +
  +_sd_hidden_ int sd_is_mq(int fd, const char *path) {
  +#if !defined(**linux**)
-        return 0;
  +#else
-        struct mq_attr attr;
  +
-        if (fd < 0)
-                return -EINVAL;
  +
-        if (mq_getattr(fd, &attr) < 0)
-                return -errno;
  +
-        if (path) {
-                char fpath[PATH_MAX];
-                struct stat a, b;
  +
-                if (path[0] != '/')
-                        return -EINVAL;
  +
-                if (fstat(fd, &a) < 0)
-                        return -errno;
  +
-                strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12);
-                fpath[sizeof(fpath)-1] = 0;
  +
-                if (stat(fpath, &b) < 0)
-                        return -errno;
  +
-                if (a.st_dev != b.st_dev ||
-                    a.st_ino != b.st_ino)
-                        return 0;
-        }
  +
-        return 1;
  +#endif
  +}
  +
  +_sd_hidden_ int sd_notify(int unset_environment, const char *state) {
  +#if defined(DISABLE_SYSTEMD) || !defined(**linux**) || !defined(SOCK_CLOEXEC)
-        return 0;
  +#else
-        int fd = -1, r;
-        struct msghdr msghdr;
-        struct iovec iovec;
-        union sockaddr_union sockaddr;
-        const char *e;
  +
-        if (!state) {
-                r = -EINVAL;
-                goto finish;
-        }
  +
-        if (!(e = getenv("NOTIFY_SOCKET")))
-                return 0;
  +
-        /\* Must be an abstract socket, or an absolute path */
-        if ((e[0] != '@' && e[0] != '/') || e[1] == 0) {
-                r = -EINVAL;
-                goto finish;
-        }
  +
-        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
-                r = -errno;
-                goto finish;
-        }
  +
-        memset(&sockaddr, 0, sizeof(sockaddr));
-        sockaddr.sa.sa_family = AF_UNIX;
-        strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path));
  +
-        if (sockaddr.un.sun_path[0] == '@')
-                sockaddr.un.sun_path[0] = 0;
  +
-        memset(&iovec, 0, sizeof(iovec));
-        iovec.iov_base = (char*) state;
-        iovec.iov_len = strlen(state);
  +
-        memset(&msghdr, 0, sizeof(msghdr));
-        msghdr.msg_name = &sockaddr;
-        msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
  +
-        if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
-                msghdr.msg_namelen = sizeof(struct sockaddr_un);
  +
-        msghdr.msg_iov = &iovec;
-        msghdr.msg_iovlen = 1;
  +
-        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
-                r = -errno;
-                goto finish;
-        }
  +
-        r = 1;
  +
  +finish:
-        if (unset_environment)
-                unsetenv("NOTIFY_SOCKET");
  +
-        if (fd >= 0)
-                close(fd);
  +
-        return r;
  +#endif
  +}
  +
  +_sd_hidden_ int sd_notifyf(int unset_environment, const char *format, ...) {
  +#if defined(DISABLE_SYSTEMD) || !defined(**linux**)
-        return 0;
  +#else
-        va_list ap;
-        char *p = NULL;
-        int r;
  +
-        va_start(ap, format);
-        r = vasprintf(&p, format, ap);
-        va_end(ap);
  +
-        if (r < 0 || !p)
-                return -ENOMEM;
  +
-        r = sd_notify(unset_environment, p);
-        free(p);
  +
-        return r;
  +#endif
  +}
  +
  +_sd_hidden_ int sd_booted(void) {
  +#if defined(DISABLE_SYSTEMD) || !defined(**linux**)
-        return 0;
  +#else
  +
-        struct stat a, b;
  +
-        /\* We simply test whether the systemd cgroup hierarchy is
-         \* mounted */
  +
-        if (lstat("/sys/fs/cgroup", &a) < 0)
-                return 0;
  +
-        if (lstat("/sys/fs/cgroup/systemd", &b) < 0)
-                return 0;
  +
-        return a.st_dev != b.st_dev;
  +#endif
  +}
  diff --git a/scheduler/sd-daemon.h b/scheduler/sd-daemon.h
  new file mode 100644
  index 0000000..46dc7fd
  --- /dev/null
  +++ b/scheduler/sd-daemon.h
  @@ -0,0 +1,277 @@
  +/_-_\- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -_-_/
  +
  +#ifndef foosddaemonhfoo
  +#define foosddaemonhfoo
  +
  +/***
-  Copyright 2010 Lennart Poettering
  +
-  Permission is hereby granted, free of charge, to any person
-  obtaining a copy of this software and associated documentation files
-  (the "Software"), to deal in the Software without restriction,
-  including without limitation the rights to use, copy, modify, merge,
-  publish, distribute, sublicense, and/or sell copies of the Software,
-  and to permit persons to whom the Software is furnished to do so,
-  subject to the following conditions:
  +
-  The above copyright notice and this permission notice shall be
-  included in all copies or substantial portions of the Software.
  +
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  SOFTWARE.
  +**_/
  +
  +#include <sys/types.h>
  +#include <inttypes.h>
  +
  +#ifdef __cplusplus
  +extern "C" {
  +#endif
  +
  +/_
-  Reference implementation of a few systemd related interfaces for
-  writing daemons. These interfaces are trivial to implement. To
-  simplify porting we provide this reference implementation.
-  Applications are welcome to reimplement the algorithms described
-  here if they do not want to include these two source files.
  +
-  The following functionality is provided:
  +
-  - Support for logging with log levels on stderr
-  - File descriptor passing for socket-based activation
-  - Daemon startup and status notification
-  - Detection of systemd boots
  +
-  You may compile this with -DDISABLE_SYSTEMD to disable systemd
-  support. This makes all those calls NOPs that are directly related to
-  systemd (i.e. only sd_is_xxx() will stay useful).
  +
-  Since this is drop-in code we don't want any of our symbols to be
-  exported in any case. Hence we declare hidden visibility for all of
-  them.
  +
-  You may find an up-to-date version of these source files online:
  +
-  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
-  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
  +
-  This should compile on non-Linux systems, too, but with the
-  exception of the sd_is_xxx() calls all functions will become NOPs.
  +
-  See sd-daemon(7) for more information.
  +_/
  +
  +#ifndef _sd_printf_attr_
  +#if **GNUC** >= 4
  +#define _sd_printf_attr_(a,b) **attribute** ((format (printf, a, b)))
  +#else
  +#define _sd_printf_attr_(a,b)
  +#endif
  +#endif
  +
  +/_
-  Log levels for usage on stderr:
  +
-          fprintf(stderr, SD_NOTICE "Hello World!\n");
  +
-  This is similar to printk() usage in the kernel.
  +_/
  +#define SD_EMERG   "<0>"  /_ system is unusable _/
  +#define SD_ALERT   "<1>"  /_ action must be taken immediately _/
  +#define SD_CRIT    "<2>"  /_ critical conditions _/
  +#define SD_ERR     "<3>"  /_ error conditions _/
  +#define SD_WARNING "<4>"  /_ warning conditions _/
  +#define SD_NOTICE  "<5>"  /_ normal but significant condition _/
  +#define SD_INFO    "<6>"  /_ informational _/
  +#define SD_DEBUG   "<7>"  /_ debug-level messages _/
  +
  +/_ The first passed file descriptor is fd 3 _/
  +#define SD_LISTEN_FDS_START 3
  +
  +/_
-  Returns how many file descriptors have been passed, or a negative
-  errno code on failure. Optionally, removes the $LISTEN_FDS and
-  $LISTEN_PID file descriptors from the environment (recommended, but
-  problematic in threaded environments). If r is the return value of
-  this function you'll find the file descriptors passed as fds
-  SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
-  errno style error code on failure. This function call ensures that
-  the FD_CLOEXEC flag is set for the passed file descriptors, to make
-  sure they are not passed on to child processes. If FD_CLOEXEC shall
-  not be set, the caller needs to unset it after this call for all file
-  descriptors that are used.
  +
-  See sd_listen_fds(3) for more information.
  +_/
  +int sd_listen_fds(int unset_environment);
  +
  +/_
-  Helper call for identifying a passed file descriptor. Returns 1 if
-  the file descriptor is a FIFO in the file system stored under the
-  specified path, 0 otherwise. If path is NULL a path name check will
-  not be done and the call only verifies if the file descriptor
-  refers to a FIFO. Returns a negative errno style error code on
-  failure.
  +
-  See sd_is_fifo(3) for more information.
  +_/
  +int sd_is_fifo(int fd, const char *path);
  +
  +/_
-  Helper call for identifying a passed file descriptor. Returns 1 if
-  the file descriptor is a special character device on the file
-  system stored under the specified path, 0 otherwise.
-  If path is NULL a path name check will not be done and the call
-  only verifies if the file descriptor refers to a special character.
-  Returns a negative errno style error code on failure.
  +
-  See sd_is_special(3) for more information.
  +_/
  +int sd_is_special(int fd, const char *path);
  +
  +/_
-  Helper call for identifying a passed file descriptor. Returns 1 if
-  the file descriptor is a socket of the specified family (AF_INET,
-  ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
-  family is 0 a socket family check will not be done. If type is 0 a
-  socket type check will not be done and the call only verifies if
-  the file descriptor refers to a socket. If listening is > 0 it is
-  verified that the socket is in listening mode. (i.e. listen() has
-  been called) If listening is == 0 it is verified that the socket is
-  not in listening mode. If listening is < 0 no listening mode check
-  is done. Returns a negative errno style error code on failure.
  +
-  See sd_is_socket(3) for more information.
  +_/
  +int sd_is_socket(int fd, int family, int type, int listening);
  +
  +/_
-  Helper call for identifying a passed file descriptor. Returns 1 if
-  the file descriptor is an Internet socket, of the specified family
-  (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
-  SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
-  check is not done. If type is 0 a socket type check will not be
-  done. If port is 0 a socket port check will not be done. The
-  listening flag is used the same way as in sd_is_socket(). Returns a
-  negative errno style error code on failure.
  +
-  See sd_is_socket_inet(3) for more information.
  +_/
  +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
  +
  +/_
-  Helper call for identifying a passed file descriptor. Returns 1 if
-  the file descriptor is an AF_UNIX socket of the specified type
-  (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
-  a socket type check will not be done. If path is NULL a socket path
-  check will not be done. For normal AF_UNIX sockets set length to
-  0. For abstract namespace sockets set length to the length of the
-  socket name (including the initial 0 byte), and pass the full
-  socket path in path (including the initial 0 byte). The listening
-  flag is used the same way as in sd_is_socket(). Returns a negative
-  errno style error code on failure.
  +
-  See sd_is_socket_unix(3) for more information.
  +_/
  +int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length);
  +
  +/_
-  Helper call for identifying a passed file descriptor. Returns 1 if
-  the file descriptor is a POSIX Message Queue of the specified name,
-  0 otherwise. If path is NULL a message queue name check is not
-  done. Returns a negative errno style error code on failure.
  +_/
  +int sd_is_mq(int fd, const char *path);
  +
  +/_
-  Informs systemd about changed daemon state. This takes a number of
-  newline separated environment-style variable assignments in a
-  string. The following variables are known:
  +
-     READY=1      Tells systemd that daemon startup is finished (only
-                  relevant for services of Type=notify). The passed
-                  argument is a boolean "1" or "0". Since there is
-                  little value in signaling non-readiness the only
-                  value daemons should send is "READY=1".
  +
-     STATUS=...   Passes a single-line status string back to systemd
-                  that describes the daemon state. This is free-from
-                  and can be used for various purposes: general state
-                  feedback, fsck-like programs could pass completion
-                  percentages and failing programs could pass a human
-                  readable error message. Example: "STATUS=Completed
-                  66% of file system check..."
  +
-     ERRNO=...    If a daemon fails, the errno-style error code,
-                  formatted as string. Example: "ERRNO=2" for ENOENT.
  +
-     BUSERROR=... If a daemon fails, the D-Bus error-style error
-                  code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
  +
-     MAINPID=...  The main pid of a daemon, in case systemd did not
-                  fork off the process itself. Example: "MAINPID=4711"
  +
-  Daemons can choose to send additional variables. However, it is
-  recommended to prefix variable names not listed above with X_.
  +
-  Returns a negative errno-style error code on failure. Returns > 0
-  if systemd could be notified, 0 if it couldn't possibly because
-  systemd is not running.
  +
-  Example: When a daemon finished starting up, it could issue this
-  call to notify systemd about it:
  +
-     sd_notify(0, "READY=1");
  +
-  See sd_notifyf() for more complete examples.
  +
-  See sd_notify(3) for more information.
  +_/
  +int sd_notify(int unset_environment, const char *state);
  +
  +/_
-  Similar to sd_notify() but takes a format string.
  +
-  Example 1: A daemon could send the following after initialization:
  +
-     sd_notifyf(0, "READY=1\n"
-                   "STATUS=Processing requests...\n"
-                   "MAINPID=%lu",
-                   (unsigned long) getpid());
  +
-  Example 2: A daemon could send the following shortly before
-  exiting, on failure:
  +
-     sd_notifyf(0, "STATUS=Failed to start up: %s\n"
-                   "ERRNO=%i",
-                   strerror(errno),
-                   errno);
  +
-  See sd_notifyf(3) for more information.
  +_/
  +int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3);
  +
  +/_
-  Returns > 0 if the system was booted with systemd. Returns < 0 on
-  error. Returns 0 if the system was not booted with systemd. Note
-  that all of the functions above handle non-systemd boots just
-  fine. You should NOT protect them with a call to this function. Also
-  note that this function checks whether the system, not the user
-  session is controlled by systemd. However the functions above work
-  for both user and system services.
  +
-  See sd_booted(3) for more information.
  +*/
  +int sd_booted(void);
  +
  +#ifdef __cplusplus
  +}
  +#endif
  +
  +#endif
  -- 
  1.7.6
@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 28, 2014

"cups-systemd-socket.patch":

diff -up cups-1.5.0/config.h.in.systemd-socket cups-1.5.0/config.h.in
--- cups-1.5.0/config.h.in.systemd-socket   2011-10-18 15:32:40.741672460 +0100
+++ cups-1.5.0/config.h.in  2011-10-18 15:32:40.843670530 +0100
@@ -503,6 +503,13 @@

 /*
- \* Do we have systemd support?
- _/
  +
  +#undef HAVE_SYSTEMD
  +
  +
  +/_
  - Various scripting languages...
    */

diff -up cups-1.5.0/config-scripts/cups-systemd.m4.systemd-socket cups-1.5.0/config-scripts/cups-systemd.m4
--- cups-1.5.0/config-scripts/cups-systemd.m4.systemd-socket    2011-10-18 15:32:40.844670511 +0100
+++ cups-1.5.0/config-scripts/cups-systemd.m4   2011-10-18 15:33:16.861989058 +0100
@@ -0,0 +1,36 @@
+dnl
+dnl "$Id$"
+dnl
+dnl   systemd stuff for CUPS.
+
+dnl Find whether systemd is available
+
+SDLIBS=""
+AC_ARG_WITH([systemdsystemunitdir],
-        AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
-        [], [with_systemdsystemunitdir=$($PKGCONFIG --variable=systemdsystemunitdir systemd)])
  +if test "x$with_systemdsystemunitdir" != xno; then
-        AC_MSG_CHECKING(for libsystemd-daemon)
-        if $PKGCONFIG --exists libsystemd-daemon; then
-       AC_MSG_RESULT(yes)
-           SDCFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
-           SDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
-       AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
-       AC_DEFINE(HAVE_SYSTEMD)
-   else
-       AC_MSG_RESULT(no)
-   fi
  +fi
  +
  +if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then
-        SYSTEMD_UNITS="cups.service cups.socket cups.path"
  +else
-        SYSTEMD_UNITS=""
  +fi
  +
  +AC_SUBST(SYSTEMD_UNITS)
  +AC_SUBST(SDLIBS)
  +
  +dnl
  +dnl "$Id$"
  +dnl
  diff -up cups-1.5.0/configure.in.systemd-socket cups-1.5.0/configure.in
  --- cups-1.5.0/configure.in.systemd-socket  2010-11-20 01:03:46.000000000 +0000
  +++ cups-1.5.0/configure.in 2011-10-18 15:32:40.844670511 +0100
  @@ -37,6 +37,7 @@ sinclude(config-scripts/cups-pam.m4)
  sinclude(config-scripts/cups-largefile.m4)
  sinclude(config-scripts/cups-dnssd.m4)
  sinclude(config-scripts/cups-launchd.m4)
  +sinclude(config-scripts/cups-systemd.m4)
  sinclude(config-scripts/cups-defaults.m4)
  sinclude(config-scripts/cups-pdf.m4)
  sinclude(config-scripts/cups-scripting.m4)
  @@ -71,6 +72,9 @@ AC_OUTPUT(Makedefs
    conf/snmp.conf
    cups-config
    data/testprint
-          data/cups.service
-          data/cups.socket
- 
       data/cups.path
  
  
    desktop/cups.desktop
    doc/help/ref-cupsd-conf.html
    doc/help/standard.html
  diff -up cups-1.5.0/cups/usersys.c.systemd-socket cups-1.5.0/cups/usersys.c
  --- cups-1.5.0/cups/usersys.c.systemd-socket    2011-10-18 15:32:40.645674277 +0100
  +++ cups-1.5.0/cups/usersys.c   2011-10-18 15:32:40.845670492 +0100
  @@ -770,7 +770,7 @@ cups_read_client_conf(
   struct stat    sockinfo;       /\* Domain socket information */
  
   if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&
-   (sockinfo.st_mode & S_IRWXO) == S_IRWXO)
-   (sockinfo.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))
     cups_server = CUPS_DEFAULT_DOMAINSOCKET;
   else
  #endif /\* CUPS_DEFAULT_DOMAINSOCKET _/
  diff -up cups-1.5.0/data/cups.path.in.systemd-socket cups-1.5.0/data/cups.path.in
  --- cups-1.5.0/data/cups.path.in.systemd-socket 2011-10-18 15:32:40.846670473 +0100
  +++ cups-1.5.0/data/cups.path.in    2011-10-18 15:32:40.846670473 +0100
  @@ -0,0 +1,8 @@
  +[Unit]
  +Description=CUPS Printer Service Spool
  +
  +[Path]
  +PathExistsGlob=@CUPS_REQUESTS@/d_
  +
  +[Install]
  +WantedBy=multi-user.target
  diff -up cups-1.5.0/data/cups.service.in.systemd-socket cups-1.5.0/data/cups.service.in
  --- cups-1.5.0/data/cups.service.in.systemd-socket  2011-10-18 15:32:40.846670473 +0100
  +++ cups-1.5.0/data/cups.service.in 2011-10-18 15:32:40.846670473 +0100
  @@ -0,0 +1,9 @@
  +[Unit]
  +Description=CUPS Printing Service
  +
  +[Service]
  +ExecStart=@sbindir@/cupsd -f
  +
  +[Install]
  +Also=cups.socket cups.path
  +WantedBy=printer.target
  diff -up cups-1.5.0/data/cups.socket.in.systemd-socket cups-1.5.0/data/cups.socket.in
  --- cups-1.5.0/data/cups.socket.in.systemd-socket   2011-10-18 15:32:40.847670454 +0100
  +++ cups-1.5.0/data/cups.socket.in  2011-10-18 15:32:40.847670454 +0100
  @@ -0,0 +1,10 @@
  +[Unit]
  +Description=CUPS Printing Service Sockets
  +
  +[Socket]
  +ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
  +ListenStream=631
  +BindIPv6Only=ipv6-only
  +
  +[Install]
  +WantedBy=sockets.target
  diff -up cups-1.5.0/data/Makefile.systemd-socket cups-1.5.0/data/Makefile
  --- cups-1.5.0/data/Makefile.systemd-socket 2011-05-12 06:21:56.000000000 +0100
  +++ cups-1.5.0/data/Makefile    2011-10-18 15:32:40.847670454 +0100
  @@ -112,6 +112,12 @@ install-data:
      $(INSTALL_DATA) $$file $(DATADIR)/ppdc; \
  done
  $(INSTALL_DIR) -m 755 $(DATADIR)/profiles
-   if test "x$(SYSTEMD_UNITS)" != "x" ; then \
-       $(INSTALL_DIR) -m 755 $(SYSTEMDUNITDIR); \
-       for file in $(SYSTEMD_UNITS); do \
-           $(INSTALL_DATA) $$file $(SYSTEMDUNITDIR); \
-       done; \
-   fi
  
  #
  @@ -159,6 +165,9 @@ uninstall:
  -$(RMDIR) $(DATADIR)/charsets
  -$(RMDIR) $(DATADIR)/banners
  -$(RMDIR) $(DATADIR)
-   for file in $(SYSTEMD_UNITS); do \
-       $(RM) $(SYSTEMDUNITDIR)/$$file; \
-   done
  
  #
  diff -up cups-1.5.0/Makedefs.in.systemd-socket cups-1.5.0/Makedefs.in
  --- cups-1.5.0/Makedefs.in.systemd-socket   2011-10-18 15:32:40.719672876 +0100
  +++ cups-1.5.0/Makedefs.in  2011-10-18 15:32:40.848670435 +0100
  @@ -143,6 +143,7 @@ CXXFLAGS    =   @CPPFLAGS@ @CXXFLAGS@
  CXXLIBS        =   @CXXLIBS@
  DBUS_NOTIFIER  =   @DBUS_NOTIFIER@
  DBUS_NOTIFIERLIBS =    @DBUS_NOTIFIERLIBS@
  +SYSTEMD_UNITS   =       @SYSTEMD_UNITS@
  DNSSD_BACKEND  =   @DNSSD_BACKEND@
  DSOFLAGS   =   -L../cups @DSOFLAGS@
  DSOLIBS        =   @DSOLIBS@ $(COMMONLIBS)
  @@ -151,6 +152,7 @@ FONTS       =   @FONTS@
  IMGLIBS        =   @IMGLIBS@
  IMGFILTERS =   @IMGFILTERS@
  LAUNCHDLIBS    =   @LAUNCHDLIBS@
  +SDLIBS     =   @SDLIBS@
  LDFLAGS        =   -L../cgi-bin -L../cups -L../filter -L../ppdc \
            -L../scheduler @LDARCHFLAGS@ \
            @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
  @@ -267,6 +269,7 @@ PAMFILE     =   @PAMFILE@
  
  DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
  DBUSDIR        =   @DBUSDIR@
  +SYSTEMDUNITDIR  =       $(BUILDROOT)@systemdsystemunitdir@
  
  #
  diff -up cups-1.5.0/scheduler/client.h.systemd-socket cups-1.5.0/scheduler/client.h
  --- cups-1.5.0/scheduler/client.h.systemd-socket    2011-03-25 21:25:38.000000000 +0000
  +++ cups-1.5.0/scheduler/client.h   2011-10-18 15:32:40.848670435 +0100
  @@ -75,6 +75,9 @@ typedef struct
  int          fd;     /\* File descriptor for this server _/
  http_addr_t      address;    /_ Bind address of socket _/
  http_encryption_t    encryption; /_ To encrypt or not to encrypt... */
  +#ifdef HAVE_SYSTEMD
-  int          is_systemd; /\* Is this a systemd socket? _/
  +#endif /_ HAVE_SYSTEMD */
  } cupsd_listener_t;

diff -up cups-1.5.0/scheduler/listen.c.systemd-socket cups-1.5.0/scheduler/listen.c
--- cups-1.5.0/scheduler/listen.c.systemd-socket    2011-04-16 00:38:13.000000000 +0100
+++ cups-1.5.0/scheduler/listen.c   2011-10-18 15:32:40.849670416 +0100
@@ -401,7 +401,11 @@ cupsdStopListening(void)
        lis;
        lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
   {
-    if (lis->fd != -1)
-    if (lis->fd != -1
  +#ifdef HAVE_SYSTEMD
-        && !lis->is_systemd
  +#endif /\* HAVE_SYSTEMD */
-        )
   {
  #ifdef WIN32
       closesocket(lis->fd);
  diff -up cups-1.5.0/scheduler/main.c.systemd-socket cups-1.5.0/scheduler/main.c
  --- cups-1.5.0/scheduler/main.c.systemd-socket  2011-10-18 15:32:40.802671306 +0100
  +++ cups-1.5.0/scheduler/main.c 2011-10-18 15:32:40.851670379 +0100
  @@ -26,6 +26,8 @@
  -   launchd_checkin()     - Check-in with launchd and collect the listening
  -                           fds.
  -   launchd_checkout()    - Update the launchd KeepAlive file as needed.
- \*   systemd_checkin()     - Check-in with systemd and collect the
- \*                           listening fds.
  -   parent_handler()      - Catch USR1/CHLD signals...
  -   process_children()    - Process all dead children...
  -   select_timeout()      - Calculate the select timeout value.
    @@ -62,6 +64,10 @@
    #  endif /\* !LAUNCH_JOBKEY_SERVICEIPC _/
    #endif /_ HAVE_LAUNCH_H */

+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif /\* HAVE_SYSTEMD _/
+
 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
 #  include <malloc.h>
 #endif /_ HAVE_MALLOC_H && HAVE_MALLINFO _/
@@ -78,6 +84,9 @@
 static void        launchd_checkin(void);
 static void        launchd_checkout(void);
 #endif /_ HAVE_LAUNCHD _/
+#ifdef HAVE_SYSTEMD
+static void        systemd_checkin(void);
+#endif /_ HAVE_SYSTEMD _/
 static void        parent_handler(int sig);
 static void        process_children(void);
 static void        sigchld_handler(int sig);
@@ -537,6 +546,13 @@ main(int  argc,                /_ I - Number of comm
   }
 #endif /\* HAVE_LAUNCHD */

+#ifdef HAVE_SYSTEMD
- /*
-  \* If we were started by systemd get the listen sockets file descriptors...
-  */
-  systemd_checkin();
  +#endif /\* HAVE_SYSTEMD _/
  +
  /_
  - Startup the server...
    _/
    @@ -759,6 +775,15 @@ main(int  argc,                /_ I - Number of comm
    }
    #endif /\* HAVE_LAUNCHD */

+#ifdef HAVE_SYSTEMD
-       /*
-   \* If we were started by systemd get the listen sockets file
-   \* descriptors...
-        */
  +
-        systemd_checkin();
  +#endif /\* HAVE_SYSTEMD _/
  +
      /_
       \* Startup the server...
       _/
  @@ -1584,6 +1609,100 @@ launchd_checkout(void)
  }
  #endif /_ HAVE_LAUNCHD */

+#ifdef HAVE_SYSTEMD
+static void
+systemd_checkin(void)
+{
-  int n, fd;
  +
-  n = sd_listen_fds(0);
-  if (n < 0)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR,
-           "systemd_checkin: Failed to acquire sockets from systemd - %s",
-           strerror(-n));
-    exit(EXIT_FAILURE);
-    return;
-  }
  +
-  if (n == 0)
-    return;
  +
-  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
-  {
-    http_addr_t addr;
-    socklen_t addrlen = sizeof (addr);
-    int r;
-    cupsd_listener_t *lis;
-    char s[256];
  +
-    r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1);
-    if (r < 0) {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-             "systemd_checkin: Unable to verify socket type - %s",
-             strerror(-r));
-      continue;
-    }
  +
-    if (!r) {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-             "systemd_checkin: Socket not of the right type");
-      continue;
-    }
  +
-    if (getsockname(fd, (struct sockaddr*) &addr, &addrlen))
-    {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-             "systemd_checkin: Unable to get local address - %s",
-             strerror(errno));
-      continue;
-    }
  +
-     /*
-    \* Try to match the systemd socket address to one of the listeners...
-    */
  +
-    for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
-       lis;
-       lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
-      if (httpAddrEqual(&lis->address, &addr))
-      break;
  +
-    if (lis)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "systemd_checkin: Matched existing listener %s with fd %d...",
-                      httpAddrString(&(lis->address), s, sizeof(s)), fd);
-    }
-    else
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "systemd_checkin: Adding new listener %s with fd %d...",
-                      httpAddrString(&addr, s, sizeof(s)), fd);
  +
-      if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
-      {
-        cupsdLogMessage(CUPSD_LOG_ERROR,
-                        "systemd_checkin: Unable to allocate listener - "
-                        "%s.", strerror(errno));
-        exit(EXIT_FAILURE);
-      }
  +
-      cupsArrayAdd(Listeners, lis);
  +
-      memcpy(&lis->address, &addr, sizeof(lis->address));
-    }
  +
-    lis->fd = fd;
-    lis->is_systemd = 1;
  +
  +#  ifdef HAVE_SSL
-    if (_httpAddrPort(&(lis->address)) == 443)
-      lis->encryption = HTTP_ENCRYPT_ALWAYS;
  +#  endif /\* HAVE_SSL */
-  }
  +}
  +#endif /\* HAVE_SYSTEMD */
  
  /*
  - 'parent_handler()' - Catch USR1/CHLD signals...
    diff -up cups-1.5.0/scheduler/Makefile.systemd-socket cups-1.5.0/scheduler/Makefile
    --- cups-1.5.0/scheduler/Makefile.systemd-socket    2011-10-18 15:32:40.817671022 +0100
    +++ cups-1.5.0/scheduler/Makefile   2011-10-18 15:32:40.852670360 +0100
    @@ -382,7 +382,7 @@ cupsd:  $(CUPSDOBJS) $(LIBCUPSMIME) ../cu
    $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime \
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
    $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \
-       $(LIBGSSAPI) $(LIBWRAP)
-
    $(LIBGSSAPI) $(LIBWRAP) $(SDLIBS)
  
  
  cupsd-static:  $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
    echo Linking $@...
  @@ -390,7 +390,7 @@ cupsd-static:   $(CUPSDOBJS) libcupsmime.a
      $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
      ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \
      $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
-       $(LIBWRAP)
- 
    $(LIBWRAP) $(SDLIBS)
  
  
  #
@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 28, 2014

"systemd-optional-socket-activation.patch":

Description: systemd socket activation support.
This variation of the patch is Gentoo's and features the runtime
detection of systemd, to have cups continue to work without systemd
enabled. It has been slightly amended (mostly whitespace fixes) to
bring it as close as possible to Fedora's.
.
Original description:
Subject: [PATCH] systemd: add systemd socket activation and unit files
.
On newer Linux machines systemd supports launchd-style socket
activation. This patch adds support for this mechanism and also adds
systemd unit files as appropriate to hook this up with systemd.
.
This includes an MIT-licensed drop-in file that implements the most
basic interfaces needed to get the file descriptors from systemd. Most
of the systemd and Linux-specific code compiles to NOPs on other
systems.
.
Three triggers to start CUPS are defined: a) if new printer hardware is
plugged in, b) when a client accesses the CUPS socket and c) when a
spool file resides in /var/spool/cups.
Origin: http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-print/cups/files/cups-1.5.0-systemd-socket-2.patch?view=markup
Origin: http://pkgs.fedoraproject.org/cgit/cups.git/tree/cups-systemd-socket.patch?id=7048cf473bca56b13d3c2f140fd749d561490784
From: Lennart Poettering lennart@poettering.net
Author: Lennart Poettering lennart@poettering.net
Last-Update: 2014-02-18
--- a/config.h.in
+++ b/config.h.in
@@ -451,6 +451,13 @@

/*

  • * Do we have systemd support?
  • /
    +
    +#undef HAVE_SYSTEMD
    +
    +
    +/
    • Various scripting languages...
      */

--- /dev/null
+++ b/config-scripts/cups-systemd.m4
@@ -0,0 +1,36 @@
+dnl
+dnl "$Id$"
+dnl
+dnl systemd stuff for CUPS.
+
+dnl Find whether systemd is available
+
+SDLIBS=""
+AC_ARG_WITH([systemdsystemunitdir],

  •    AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
    
  •    [], [with_systemdsystemunitdir=$($PKGCONFIG --variable=systemdsystemunitdir systemd)])
    
    +if test "x$with_systemdsystemunitdir" != xno; then
  •    AC_MSG_CHECKING(for libsystemd-daemon)
    
  •    AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
    
  •    if $PKGCONFIG --exists libsystemd-daemon; then
    
  •   AC_MSG_RESULT(yes)
    
  •       SDCFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
    
  •       SDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
    
  •   AC_DEFINE(HAVE_SYSTEMD)
    
  • else
  •   AC_MSG_RESULT(no)
    
  • fi
    +fi

+if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then

  •    SYSTEMD_UNITS="cups.service cups.socket cups.path"
    
    +else
  •    SYSTEMD_UNITS=""
    
    +fi
    +
    +AC_SUBST(SYSTEMD_UNITS)
    +AC_SUBST(SDLIBS)
    +
    +dnl
    +dnl "$Id$"
    +dnl
    --- a/configure.in
    +++ b/configure.in
    @@ -33,6 +33,7 @@
    sinclude(config-scripts/cups-largefile.m4)
    sinclude(config-scripts/cups-dnssd.m4)
    sinclude(config-scripts/cups-launchd.m4)
    +sinclude(config-scripts/cups-systemd.m4)
    sinclude(config-scripts/cups-defaults.m4)
    sinclude(config-scripts/cups-scripting.m4)

@@ -67,6 +68,9 @@
conf/snmp.conf
cups-config
data/testprint

  • data/cups.service
    
  • data/cups.socket
    
  • data/cups.path
    

    desktop/cups.desktop
    doc/help/ref-cups-files-conf.html
    doc/help/ref-cupsd-conf.html
    --- a/cups/usersys.c
    +++ b/cups/usersys.c
    @@ -1045,7 +1045,7 @@
    struct stat sockinfo; /* Domain socket information */

    if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&

  • (sockinfo.st_mode & S_IRWXO) == S_IRWXO)

  • (sockinfo.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))
    cups_server = CUPS_DEFAULT_DOMAINSOCKET;
    else
    #endif /* CUPS_DEFAULT_DOMAINSOCKET _/
    --- /dev/null
    +++ b/data/cups.path.in
    @@ -0,0 +1,8 @@
    +[Unit]
    +Description=CUPS Printer Service Spool

+[Path]
+PathExistsGlob=@CUPS_REQUESTS@/d_
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+++ b/data/cups.service.in
@@ -0,0 +1,10 @@
+[Unit]
+Description=CUPS Printing Service
+
+[Service]
+ExecStart=@sbindir@/cupsd -f
+PrivateTmp=true
+
+[Install]
+Also=cups.socket cups.path
+WantedBy=printer.target
--- /dev/null
+++ b/data/cups.socket.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=CUPS Printing Service Sockets
+
+[Socket]
+ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
+ListenStream=631
+ListenDatagram=0.0.0.0:631
+BindIPv6Only=ipv6-only
+
+[Install]
+WantedBy=sockets.target
--- a/data/Makefile
+++ b/data/Makefile
@@ -100,6 +100,12 @@
$(INSTALL_DATA) $$file $(DATADIR)/ppdc;
done
$(INSTALL_DIR) -m 755 $(DATADIR)/profiles

  • if test "x$(SYSTEMD_UNITS)" != "x" ; then \
  •   $(INSTALL_DIR) -m 755 $(SYSTEMDUNITDIR); \
    
  •   for file in $(SYSTEMD_UNITS); do \
    
  •       $(INSTALL_DATA) $$file $(SYSTEMDUNITDIR); \
    
  •   done; \
    
  • fi

@@ -143,6 +149,9 @@
-$(RMDIR) $(DATADIR)/data
-$(RMDIR) $(DATADIR)/banners
-$(RMDIR) $(DATADIR)

  • for file in $(SYSTEMD_UNITS); do \
  •   $(RM) $(SYSTEMDUNITDIR)/$$file; \
    
  • done

--- a/Makedefs.in
+++ b/Makedefs.in
@@ -134,6 +134,7 @@
CXXLIBS = @CXXLIBS@
DBUS_NOTIFIER = @DBUS_NOTIFIER@
DBUS_NOTIFIERLIBS = @DBUS_NOTIFIERLIBS@
+SYSTEMD_UNITS = @SYSTEMD_UNITS@
DNSSD_BACKEND = @DNSSD_BACKEND@
DSOFLAGS = -L../cups @DSOFLAGS@
DSOLIBS = @DSOLIBS@ $(COMMONLIBS)
@@ -141,6 +142,7 @@
IPPFIND_BIN = @IPPFIND_BIN@
IPPFIND_MAN = @IPPFIND_MAN@
LAUNCHDLIBS = @LAUNCHDLIBS@
+SDLIBS = @SDLIBS@
LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc
-L../scheduler @LDARCHFLAGS@
@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
@@ -232,6 +234,7 @@

DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
DBUSDIR = @DBUSDIR@
+SYSTEMDUNITDIR = $(BUILDROOT)@systemdsystemunitdir@

--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -79,6 +79,9 @@
int fd; /* File descriptor for this server /
http_addr_t address; /
Bind address of socket /
http_encryption_t encryption; /
To encrypt or not to encrypt... */
+#ifdef HAVE_SYSTEMD

  • int is_systemd; /* Is this a systemd socket? /
    +#endif /
    HAVE_SYSTEMD */
    } cupsd_listener_t;

--- a/scheduler/listen.c
+++ b/scheduler/listen.c
@@ -401,7 +401,11 @@
lis;
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
{

  • if (lis->fd != -1)
  • if (lis->fd != -1
    +#ifdef HAVE_SYSTEMD
  •    && !lis->is_systemd
    
    +#endif /* HAVE_SYSTEMD */
  •    )
    
    {
    #ifdef WIN32
    closesocket(lis->fd);
    --- a/scheduler/main.c
    +++ b/scheduler/main.c
    @@ -26,6 +26,8 @@
    • launchd_checkin() - Check-in with launchd and collect the listening
    •                       fds.
      
    • launchd_checkout() - Update the launchd KeepAlive file as needed.
  • * systemd_checkin() - Check-in with systemd and collect the
  • * listening fds.
    • parent_handler() - Catch USR1/CHLD signals...
    • process_children() - Process all dead children...
    • select_timeout() - Calculate the select timeout value.
      @@ -62,6 +64,10 @@

    endif /* !LAUNCH_JOBKEY_SERVICEIPC _/

    #endif /_ HAVE_LAUNCH_H */

+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif /* HAVE_SYSTEMD _/
+
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)

include <malloc.h>

#endif /_ HAVE_MALLOC_H && HAVE_MALLINFO /
@@ -83,6 +89,9 @@
static void launchd_checkin(void);
static void launchd_checkout(void);
#endif /
HAVE_LAUNCHD /
+#ifdef HAVE_SYSTEMD
+static int systemd_checkin(void);
+#endif /
HAVE_SYSTEMD /
static void parent_handler(int sig);
static void process_children(void);
static void sigchld_handler(int sig);
@@ -568,6 +577,14 @@
}
#endif /
HAVE_LAUNCHD */

+#ifdef HAVE_SYSTEMD

  • /*
  • * If we were started by systemd get the listen sockets file descriptors...
  • */
  • if (systemd_checkin() < 0)
  • exit(EXIT_FAILURE);
    +#endif /* HAVE_SYSTEMD _/

/_

  • Startup the server...
    /
    @@ -764,6 +781,16 @@
    }
    #endif /
    HAVE_LAUNCHD */

+#ifdef HAVE_SYSTEMD

  •   /*
    
  • * If we were started by systemd get the listen sockets file
  • * descriptors...
  •    */
    
  •    if (systemd_checkin() < 0)
    
  •      exit(EXIT_FAILURE);
    
    +#endif /* HAVE_SYSTEMD /
    +
    /

    * Startup the server...
    /
    @@ -1523,6 +1550,104 @@
    }
    #endif /
    HAVE_LAUNCHD */

+#ifdef HAVE_SYSTEMD
+static int
+systemd_checkin(void)
+{

  • int n, fd;
  • n = sd_listen_fds(0);
  • if (n < 0)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •       "systemd_checkin: Failed to acquire sockets from systemd - %s"
    
  •       " -- skipping systemd activation",
    
  •       strerror(-n));
    
  • return (1);
  • }
  • if (n == 0)
  • return (0);
  • for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
  • {
  • http_addr_t addr;
  • socklen_t addrlen = sizeof (addr);
  • int r;
  • cupsd_listener_t *lis;
  • char s[256];
  • r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1);
  • if (r < 0)
  • {
  •  cupsdLogMessage(CUPSD_LOG_ERROR,
    
  •         "systemd_checkin: Unable to verify socket type - %s",
    
  •         strerror(-r));
    
  •  continue;
    
  • }
  • if (!r)
  • {
  •  cupsdLogMessage(CUPSD_LOG_ERROR,
    
  •         "systemd_checkin: Socket not of the right type");
    
  •  continue;
    
  • }
  • if (getsockname(fd, (struct sockaddr*) &addr, &addrlen))
  • {
  •  cupsdLogMessage(CUPSD_LOG_ERROR,
    
  •         "systemd_checkin: Unable to get local address - %s",
    
  •         strerror(errno));
    
  •  continue;
    
  • }
  • /*
  • * Try to match the systemd socket address to one of the listeners...
  • */
  • for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
  •   lis;
    
  •   lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
    
  •  if (httpAddrEqual(&lis->address, &addr))
    
  • break;
  • if (lis)
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG,
    
  •                  "systemd_checkin: Matched existing listener %s with fd %d...",
    
  •                  httpAddrString(&(lis->address), s, sizeof(s)), fd);
    
  • }
  • else
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG,
    
  •                  "systemd_checkin: Adding new listener %s with fd %d...",
    
  •                  httpAddrString(&addr, s, sizeof(s)), fd);
    
  •  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    
  •  {
    
  •    cupsdLogMessage(CUPSD_LOG_ERROR,
    
  •                    "systemd_checkin: Unable to allocate listener - "
    
  •                    "%s.", strerror(errno));
    
  •    return (-ENOMEM);
    
  •  }
    
  •  cupsArrayAdd(Listeners, lis);
    
  •  memcpy(&lis->address, &addr, sizeof(lis->address));
    
  • }
  • lis->fd = fd;
  • lis->is_systemd = 1;

+# ifdef HAVE_SSL

  • if (_httpAddrPort(&(lis->address)) == 443)
  •  lis->encryption = HTTP_ENCRYPT_ALWAYS;
    
    +# endif /* HAVE_SSL */
  • }
  • return (0);
    +}
    +#endif /* HAVE_SYSTEMD */

/*

  • 'parent_handler()' - Catch USR1/CHLD signals...
    --- a/scheduler/Makefile
    +++ b/scheduler/Makefile
    @@ -383,7 +383,7 @@
    $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS)
    $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \

  •   $(LIBGSSAPI) $(LIBWRAP)
    
  •   $(LIBGSSAPI) $(LIBWRAP) $(SDLIBS)
    

    cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
    echo Linking $@...
    @@ -391,7 +391,7 @@
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS)
    ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER)
    $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \

  •   $(LIBWRAP)
    
  •   $(LIBWRAP)  $(SDLIBS)
    

    tls.o: tls-darwin.c tls-gnutls.c tls-openssl.c

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 28, 2014

"cupsd-write-systemd-Port.patch":

Description: When using the webinterface to widen or shrink the range of
IPs that cupsd will listen to, also write systemd-compatible socket
unit configuration.
.
When this file is written by the scheduler, also reload the systemd
daemon and let systemd restart the cups.socket. This makes sure that
systemd is always the owner of the ports and enables socket activation
through all the ports that cupsd listens to.
.
This is enabled throught the cupsd-listen.conf symlink to
/etc/cups/cupsd-systemd-listen.conf in the
/etc/systemd/system/cups.socket.d/ directory.
Author: Didier Raboud odyx@debian.org
Bug-Debian: https://bugs.debian.org/740382
Last-Update: 2014-03-05
--- a/cups/adminutil.c
+++ b/cups/adminutil.c
@@ -1209,6 +1209,8 @@
cups_option_t cupsd_settings, / New settings /
*setting; /
Current setting _/
_cups_globals_t *cg = cupsGlobals(); / Global data */

  • char tempfiled[1024]; /* Temporary new cupsd-systemd-listen.conf */
  • cups_file_t systemdlistenconf; / cupsd-systemd-listen.conf file */

/*
@@ -1403,6 +1405,23 @@
}

/*

  • * Create a temporary file for the new cupsd-systemd-listen.conf...
  • */
  • if ((systemdlistenconf = cupsTempFile2(tempfiled, sizeof(tempfiled))) == NULL)
  • {
  • _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
  • return (0);
  • }
  • cupsFilePuts(systemdlistenconf,"[Socket]\n");
  • cupsFilePuts(systemdlistenconf,"# This file was generated by CUPS and WILL be deleted or overwritten by it!\n");
  • cupsFilePuts(systemdlistenconf,"# It has to be kept in sync with the Port and Listen stanzas in /etc/cups/cupsd.conf\n");
  • cupsFilePuts(systemdlistenconf,"# It is by default symlinked as cups-listen.conf in the\n");
  • cupsFilePuts(systemdlistenconf,"# /etc/systemd/system/cups.socket.d/ directory. Remove the symlink\n");
  • cupsFilePuts(systemdlistenconf,"# and write your own file there if you don't want this. See systemd.socket(5).\n");
  • /*
    • Copy the old file to the new, making changes along the way...
      */

@@ -1448,12 +1467,24 @@
{
cupsFilePuts(temp, "# Allow remote access\n");
cupsFilePrintf(temp, "Port %d\n", server_port);
+

  • /\* Let systemd's socket configuration listen on all port numbers */
    
  • cupsFilePuts(systemdlistenconf,   "# Allow remote access\n");
    
  • cupsFilePrintf(systemdlistenconf, "# Matches 'Port %d' from cupsd.conf.\n",ippPort());
    
  • cupsFilePrintf(systemdlistenconf, "ListenStream=0.0.0.0:%d\n", server_port);
    
  • cupsFilePrintf(systemdlistenconf, "ListenStream=[::]:%d\n", server_port);
    

    }
    else
    {
    cupsFilePuts(temp, "# Only listen for connections from the local "
    "machine.\n");
    cupsFilePrintf(temp, "Listen localhost:%d\n", server_port);
    +

  • /\* Let systemd's socket configuration listen only on local IP addresses */
    
  • cupsFilePuts(systemdlistenconf,   "# Only listen for connections from the local machine.\n");
    
  • cupsFilePrintf(systemdlistenconf, "# Matches 'Listen localhost:%d' from cupsd.conf.\n",ippPort());
    
  • cupsFilePrintf(systemdlistenconf, "ListenStream=127.0.0.1:%d\n", server_port);
    
  • cupsFilePrintf(systemdlistenconf, "ListenStream=[::1]:%d\n", server_port);
    

    }

    #ifdef CUPS_DEFAULT_DOMAINSOCKET
    @@ -1805,12 +1836,24 @@
    {
    cupsFilePuts(temp, "# Allow remote access\n");
    cupsFilePrintf(temp, "Port %d\n", ippPort());
    +

  •  /\* Let systemd's socket configuration listen on all port numbers */
    
  •  cupsFilePuts(systemdlistenconf,   "# Allow remote access\n");
    
  •  cupsFilePrintf(systemdlistenconf, "# Matches 'Port %d' from cupsd.conf.\n",ippPort());
    
  •  cupsFilePrintf(systemdlistenconf, "ListenStream=0.0.0.0:%d\n", ippPort());
    
  •  cupsFilePrintf(systemdlistenconf, "ListenStream=[::]:%d\n", ippPort());
    

    }
    else
    {
    cupsFilePuts(temp,
    "# Only listen for connections from the local machine.\n");
    cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort());
    +

  •  /\* Let systemd's socket configuration listen only on local IP addresses */
    
  •  cupsFilePuts(systemdlistenconf,   "# Only listen for connections from the local machine.\n");
    
  •  cupsFilePrintf(systemdlistenconf, "# Matches 'Listen localhost:%d' from cupsd.conf.\n",ippPort());
    
  •  cupsFilePrintf(systemdlistenconf, "ListenStream=127.0.0.1:%d\n", ippPort());
    
  •  cupsFilePrintf(systemdlistenconf, "ListenStream=[::1]:%d\n", ippPort());
    

    }

    #ifdef CUPS_DEFAULT_DOMAINSOCKET
    @@ -1947,6 +1990,16 @@

    cupsFileClose(cupsd);
    cupsFileClose(temp);

  • cupsFileClose(systemdlistenconf);

  • /*
  • * Upload the systemd configuration file to the server...
  • */
  • status = cupsPutFile(http, "/admin/conf/cupsd-systemd-listen.conf", tempfiled);
  • if (status == HTTP_STATUS_CREATED)
  • {

/*

  • Upload the configuration file to the server...
    @@ -2015,6 +2068,7 @@
    else
    cupsFreeOptions(cupsd_num_settings, cupsd_settings);
  • }
    /*
  • Remote our temp files and return...
    */
    @@ -2023,6 +2077,7 @@
    unlink(cupsdconf);

unlink(tempfile);

  • unlink(tempfiled);

return (status == HTTP_STATUS_CREATED);
}
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1768,10 +1768,10 @@
* Validate the resource name...
*/

  •        if (strcmp(con->uri, "/admin/conf/cupsd.conf"))
    
  •        if (strcmp(con->uri, "/admin/conf/cupsd.conf") && strcmp(con->uri, "/admin/conf/cupsd-systemd-listen.conf"))
    {
     /*
    
  •     \* PUT can only be done to the cupsd.conf file...
    
  •     * PUT can only be done to the cupsd.conf and cupsd-systemd-listen.conf files...
      */
    
      cupsdLogMessage(CUPSD_LOG_ERROR,
    

    @@ -3468,6 +3468,7 @@
    out; / Output file /
    char buffer[16384]; /
    Copy buffer /
    ssize_t bytes; /
    Number of bytes */

  • char conffile; / Configuration file */

/*
@@ -3482,17 +3483,30 @@
}

/*

  • * Determine which configuration file we're writing
  • */
  • if (strcmp(con->uri, "/admin/conf/cupsd.conf") == 0)
  • {
  • conffile = ConfigurationFile;
  • }
  • else if(strcmp(con->uri, "/admin/conf/cupsd-systemd-listen.conf") == 0)
  • {
  • conffile = SystemdConfigurationFile;
  • }
  • /*
    • Open the new config file...
      */
  • if ((out = cupsdCreateConfFile(ConfigurationFile, ConfigFilePerm)) == NULL)
  • if ((out = cupsdCreateConfFile(conffile, ConfigFilePerm)) == NULL)
    {
    cupsFileClose(in);
    return (HTTP_SERVER_ERROR);
    }

cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file "%s"...",

  •              ConfigurationFile);
    
  •              conffile);
    

    /*

    • Copy from the request to the new config file...
      @@ -3503,12 +3517,12 @@
      {
      cupsdLogMessage(CUPSD_LOG_ERROR,
      "Unable to copy to config file "%s": %s",
  •             ConfigurationFile, strerror(errno));
    
  •             conffile, strerror(errno));
    

    cupsFileClose(in);
    cupsFileClose(out);

  •  snprintf(filename, sizeof(filename), "%s.N", ConfigurationFile);
    
  •  snprintf(filename, sizeof(filename), "%s.N", conffile);
    

    cupsdUnlinkOrRemoveFile(filename);

    return (HTTP_SERVER_ERROR);
    @@ -3520,7 +3534,7 @@

    cupsFileClose(in);

  • if (cupsdCloseCreatedConfFile(out, ConfigurationFile))

  • if (cupsdCloseCreatedConfFile(out, conffile))
    return (HTTP_SERVER_ERROR);

/*
@@ -3534,8 +3548,15 @@

  • Set the NeedReload flag...
    */
  • NeedReload = RELOAD_CUPSD;
  • ReloadTime = time(NULL);
  • if(conffile == ConfigurationFile)
  • {
  • NeedReload = RELOAD_CUPSD;
  • ReloadTime = time(NULL);
  • }
  • else if(conffile == SystemdConfigurationFile)
  • {
  • NeedSystemdReload = 1;
  • }

/*

  • Return that the file was created successfully...
    --- a/scheduler/conf.h
    +++ b/scheduler/conf.h
    @@ -100,6 +100,8 @@
    /* cupsd.conf file to use /
    *CupsFilesFile VALUE(NULL),
    /
    cups-files.conf file to use */

  •       *SystemdConfigurationFile       VALUE(NULL),
    
  •               /* cupsd-systemd-listen.conf file to use */
        *ServerName     VALUE(NULL),
                /* FQDN for server */
        *ServerAdmin        VALUE(NULL),
    

    --- a/scheduler/main.c
    +++ b/scheduler/main.c
    @@ -352,6 +352,9 @@
    if (!ConfigurationFile)
    cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");

  • if (!SystemdConfigurationFile)

  • cupsdSetString(&SystemdConfigurationFile, CUPS_SERVERROOT "/cupsd-systemd-listen.conf");

if (!CupsFilesFile)
{
char filename, / Copy of cupsd.conf filename */
@@ -811,6 +814,15 @@

#ifdef HAVE_SYSTEMD
/*

  •    \* If systemd is the init system, reload the systemd configuration
    
  •    */
    
  •    if (NeedSystemdReload) {
    
  •      cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsd changed the systemd sockets, reload systemd and restart cups.socket");
    
  •      system("test -d /run/systemd/system -a -x /bin/systemctl && /bin/systemctl --system daemon-reload && /bin/systemctl restart cups.socket");
    
  •      NeedSystemdReload = 0;
    
  •    }
    
  •   /*
    
    • If we were started by systemd get the listen sockets file
    • descriptors...
      /
      --- a/scheduler/cupsd.h
      +++ b/scheduler/cupsd.h
      @@ -155,6 +155,8 @@
      /
      Time of reload request... /
      VAR int NeedReload VALUE(RELOAD_ALL),
      /
      Need to load configuration? */
  •       NeedSystemdReload   VALUE(0),
    
  •               /\* Need to reload systemd? _/
        DoingShutdown   VALUE(0);
                /_ Shutting down the scheduler? */
    
    VAR void *DefaultProfile VALUE(0);
@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Mar 28, 2014

"str3917.patch":

Index: configure.ac

--- configure.ac (revision 0)
+++ configure.ac (revision 11729)
@@ -0,0 +1,99 @@
+dnl
+dnl "$Id$"
+dnl
+dnl Configuration script for CUPS.
+dnl
+dnl Copyright 2007-2014 by Apple Inc.
+dnl Copyright 1997-2007 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Apple Inc. and are protected by Federal copyright
+dnl law. Distribution and use rights are outlined in the file "LICENSE.txt"
+dnl which should have been included with this file. If this file is
+dnl file is missing or damaged, see the license at "http://www.cups.org/".
+dnl
+
+AC_INIT(cups/cups.h)
+
+sinclude(config-scripts/cups-opsys.m4)
+sinclude(config-scripts/cups-common.m4)
+sinclude(config-scripts/cups-directories.m4)
+sinclude(config-scripts/cups-manpages.m4)
+
+sinclude(config-scripts/cups-sharedlibs.m4)
+sinclude(config-scripts/cups-libtool.m4)
+sinclude(config-scripts/cups-compiler.m4)
+
+sinclude(config-scripts/cups-network.m4)
+sinclude(config-scripts/cups-poll.m4)
+sinclude(config-scripts/cups-gssapi.m4)
+sinclude(config-scripts/cups-threads.m4)
+sinclude(config-scripts/cups-ssl.m4)
+sinclude(config-scripts/cups-pam.m4)
+sinclude(config-scripts/cups-largefile.m4)
+sinclude(config-scripts/cups-dnssd.m4)
+sinclude(config-scripts/cups-startup.m4)
+sinclude(config-scripts/cups-defaults.m4)
+sinclude(config-scripts/cups-scripting.m4)
+
+INSTALL_LANGUAGES=""
+UNINSTALL_LANGUAGES=""
+LANGFILES=""
+if test "x$LANGUAGES" != x; then

  • INSTALL_LANGUAGES="install-languages"
  • UNINSTALL_LANGUAGES="uninstall-languages"
  • for lang in $LANGUAGES; do
  •   if test -f doc/$lang/index.html.in; then
    
  •       LANGFILES="$LANGFILES doc/$lang/index.html"
    
  •   fi
    
  •   if test -f templates/$lang/header.tmpl.in; then
    
  •       LANGFILES="$LANGFILES templates/$lang/header.tmpl"
    
  •   fi
    
  • done
    +elif test "x$CUPS_BUNDLEDIR" != x; then
  • INSTALL_LANGUAGES="install-langbundle"
  • UNINSTALL_LANGUAGES="uninstall-langbundle"
    +fi

+AC_SUBST(INSTALL_LANGUAGES)
+AC_SUBST(UNINSTALL_LANGUAGES)
+
+AC_OUTPUT(Makedefs

  • conf/cups-files.conf
    
  • conf/cupsd.conf
    
  • conf/mime.convs
    
  • conf/pam.std
    
  • conf/snmp.conf
    
  • cups-config
    
  • data/testprint
    
  • desktop/cups.desktop
    
  • doc/help/ref-cups-files-conf.html
    
  • doc/help/ref-cupsd-conf.html
    
  • doc/index.html
    
  • man/client.conf.man
    
  • man/cups-deviced.man
    
  • man/cups-driverd.man
    
  • man/cups-files.conf.man
    
  • man/cups-lpd.man
    
  • man/cups-snmp.man
    
  • man/cupsaddsmb.man
    
  • man/cupsd.conf.man
    
  • man/cupsd.man
    
  • man/lpoptions.man
    
  • scheduler/cups-lpd.xinetd
    
  • scheduler/cups.sh
    
  • scheduler/cups.xml
    
  • scheduler/org.cups.cups-lpd.plist
    
  • scheduler/org.cups.cupsd.path
    
  • scheduler/org.cups.cupsd.service
    
  • scheduler/org.cups.cupsd.socket
    
  • templates/header.tmpl
    
  •      packaging/cups.list
    
  • $LANGFILES)
    
    +chmod +x cups-config
    +
    +dnl
    +dnl End of "$Id$".
    +dnl

Property changes on: configure.ac


Added: svn:keywords

-0,0 +1

+Id
\ No newline at end of property
Added: svn:eol-style

-0,0 +1

+native
\ No newline at end of property

Index: Makedefs.in

--- Makedefs.in (revision 11714)
+++ Makedefs.in (working copy)
@@ -3,7 +3,7 @@

Common makefile definitions for CUPS.

-# Copyright 2007-2013 by Apple Inc.
+# Copyright 2007-2014 by Apple Inc.

Copyright 1997-2007 by Easy Software Products, all rights reserved.

These coded instructions, statements, and computer programs are the

@@ -121,9 +121,9 @@

ALL_CFLAGS = -I.. -D_CUPS_SOURCE $(CFLAGS) $(SSLFLAGS) \

  •       @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
    
  •       @LARGEFILE@ @PTHREAD_FLAGS@ $(ONDEMANDFLAGS) $(OPTIONS)
    

    ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS) \

  •       @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
    
  •       @LARGEFILE@ @PTHREAD_FLAGS@ $(ONDEMANDFLAGS) $(OPTIONS)
    

    ARCHFLAGS = @ARCHFLAGS@
    ARFLAGS = @ARFLAGS@
    BACKLIBS = @BACKLIBS@
    @@ -140,13 +140,14 @@
    DNSSDLIBS = @DNSSDLIBS@
    IPPFIND_BIN = @IPPFIND_BIN@
    IPPFIND_MAN = @IPPFIND_MAN@
    -LAUNCHDLIBS = @LAUNCHDLIBS@
    LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc
    -L../scheduler @LDARCHFLAGS@
    @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
    LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(DNSSDLIBS) $(LIBZ)
    LINKCUPSIMAGE = @LINKCUPSIMAGE@
    LIBS = $(LINKCUPS) $(COMMONLIBS)
    +ONDEMANDFLAGS = @ONDEMANDFLAGS@
    +ONDEMANDLIBS = @ONDEMANDLIBS@
    OPTIM = @Optim@
    OPTIONS =
    PAMLIBS = @PAMLIBS@
    @@ -200,8 +201,6 @@
    DOCDIR = $(BUILDROOT)@CUPS_DOCROOT@
    ICONDIR = @ICONDIR@
    INCLUDEDIR = $(BUILDROOT)$(includedir)
    -INITDIR = @INITDIR@
    -INITDDIR = @INITDDIR@
    LIBDIR = $(BUILDROOT)$(libdir)
    LOCALEDIR = $(BUILDROOT)@CUPS_LOCALEDIR@
    LOGDIR = $(BUILDROOT)@CUPS_LOGDIR@
    @@ -216,10 +215,7 @@
    SBINDIR = $(BUILDROOT)@sbindir@
    SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@
    SERVERROOT = $(BUILDROOT)@CUPS_SERVERROOT@
    -SMFMANIFESTDIR = @SMFMANIFESTDIR@
    STATEDIR = $(BUILDROOT)@CUPS_STATEDIR@
    -USBQUIRKS = @USBQUIRKS@
    -XINETD = @xinetd@

    MAN1EXT = @MAN1EXT@
    MAN5EXT = @MAN5EXT@
    @@ -230,10 +226,17 @@
    PAMDIR = @PAMDIR@
    PAMFILE = @PAMFILE@

-DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
DBUSDIR = @DBUSDIR@
+INITDIR = @INITDIR@
+INITDDIR = @INITDDIR@
+LAUNCHD_DIR = @LAUNCHD_DIR@
+SMFMANIFESTDIR = @SMFMANIFESTDIR@
+SYSTEMD_DIR = @SYSTEMD_DIR@
+XINETD = @xinetd@

+USBQUIRKS = @USBQUIRKS@

Rules...

Index: packaging/cups.spec.in

--- packaging/cups.spec.in (revision 11714)
+++ packaging/cups.spec.in (working copy)
@@ -38,6 +38,10 @@
%{?_with_static: %define _static --enable-static}
%{!?_with_static: %define _static --disable-static}

+%{!?_with_systemd: %{!?_without_systemd: %define _with_systemd --with-systemd}}
+%{?_with_systemd: %define _systemd --enable-systemd}
+%{!?_with_systemd: %define _systemd --disable-systemd}
+
Summary: CUPS
Name: cups
Version: @CUPS_VERSION@
@@ -65,6 +69,10 @@
BuildRequires: libusbx-devel
%endif

+%if %{?_with_systemd:1}%{!?_with_systemd:0}
+BuildRequires: systemd-devel
+%endif
+

Use buildroot so as not to disturb the version already installed

BuildRoot: /tmp/%{name}-root

@@ -118,6 +126,7 @@
rm -rf $RPM_BUILD_ROOT

make BUILDROOT=$RPM_BUILD_ROOT install
+rm -rf $RPM_BUILD_ROOT/usr/share/cups/banners $RPM_BUILD_ROOT/usr/share/cups/data

%post
/sbin/chkconfig --add cups
@@ -169,28 +178,19 @@
%dir /etc/pam.d
/etc/pam.d/*

-# RC dirs are a pain under Linux... Uncomment the appropriate ones if you
-# don't use Red Hat or Mandrake...
+%if %{?_with_systemd:1}%{!?_with_systemd:0}
+# SystemD
+/usr/lib/systemd/system/*

+%else
+# Legacy init support on Linux
/etc/init.d/*
/etc/rc0.d/*
/etc/rc2.d/*
/etc/rc3.d/*
/etc/rc5.d/*
+%endif

-# OLD RedHat/Mandrake
-#/etc/rc.d/init.d/*
-#/etc/rc.d/rc0.d/*
-#/etc/rc.d/rc2.d/*
-#/etc/rc.d/rc3.d/*

-#/etc/rc.d/rc5.d/*

-#/sbin/rc.d/*
-#/sbin/rc.d/rc0.d/*
-#/sbin/rc.d/rc2.d/*
-#/sbin/rc.d/rc3.d/*

-#/sbin/rc.d/rc5.d/*

/usr/bin/cancel
/usr/bin/cupstestdsc
/usr/bin/cupstestppd
@@ -227,10 +227,6 @@

/usr/sbin/*
%dir /usr/share/cups
-%dir /usr/share/cups/banners
-/usr/share/cups/banners/*
-%dir /usr/share/cups/data
-/usr/share/cups/data/*
%dir /usr/share/cups/drv
/usr/share/cups/drv/*
%dir /usr/share/cups/ipptool
@@ -269,18 +265,18 @@
%dir /usr/share/doc/cups/images
/usr/share/doc/cups/images/*

-%dir /usr/share/doc/cups/ca
-/usr/share/doc/cups/ca/*
-%dir /usr/share/doc/cups/cs
-/usr/share/doc/cups/cs/*
-%dir /usr/share/doc/cups/es
-/usr/share/doc/cups/es/*
-%dir /usr/share/doc/cups/fr
-/usr/share/doc/cups/fr/*
-%dir /usr/share/doc/cups/ja
-/usr/share/doc/cups/ja/*
-%dir /usr/share/doc/cups/ru
-/usr/share/doc/cups/ru/*
+#%dir /usr/share/doc/cups/ca
+#/usr/share/doc/cups/ca/*
+#%dir /usr/share/doc/cups/cs
+#/usr/share/doc/cups/cs/*
+#%dir /usr/share/doc/cups/es
+#/usr/share/doc/cups/es/*
+#%dir /usr/share/doc/cups/fr
+#/usr/share/doc/cups/fr/*
+#%dir /usr/share/doc/cups/ja
+#/usr/share/doc/cups/ja/*
+#%dir /usr/share/doc/cups/ru
+#/usr/share/doc/cups/ru/*

%dir /usr/share/locale/ca
/usr/share/locale/ca/cups_ca.po
@@ -290,6 +286,8 @@
/usr/share/locale/es/cups_es.po
%dir /usr/share/locale/fr
/usr/share/locale/fr/cups_fr.po
+%dir /usr/share/locale/it
+/usr/share/locale/it/cups_it.po
%dir /usr/share/locale/ja
/usr/share/locale/ja/cups_ja.po
%dir /usr/share/locale/ru

Index: config-scripts/cups-startup.m4

--- config-scripts/cups-startup.m4 (revision 0)
+++ config-scripts/cups-startup.m4 (revision 11729)
@@ -0,0 +1,176 @@
+dnl
+dnl "$Id$"
+dnl
+dnl Launch-on-demand/startup stuff for CUPS.
+dnl
+dnl Copyright 2007-2014 by Apple Inc.
+dnl Copyright 1997-2005 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Apple Inc. and are protected by Federal copyright
+dnl law. Distribution and use rights are outlined in the file "LICENSE.txt"
+dnl which should have been included with this file. If this file is
+dnl file is missing or damaged, see the license at "http://www.cups.org/".
+dnl
+
+ONDEMANDFLAGS=""
+ONDEMANDLIBS=""
+AC_SUBST(ONDEMANDFLAGS)
+AC_SUBST(ONDEMANDLIBS)
+
+dnl Launchd is used on OS X/Darwin...
+AC_ARG_ENABLE(launchd, [ --disable-launchd disable launchd support])
+LAUNCHD_DIR=""
+AC_SUBST(LAUNCHD_DIR)
+
+if test x$enable_launchd != xno; then

  • AC_CHECK_FUNC(launch_msg, AC_DEFINE(HAVE_LAUNCHD))
  • if test $uversion -ge 140; then
  •   AC_CHECK_FUNC(launch_activate_socket, [
    
  •       AC_DEFINE(HAVE_LAUNCHD)
    
  •       AC_DEFINE(HAVE_LAUNCH_ACTIVATE_SOCKET)])
    
  • fi
  • AC_CHECK_HEADER(launch.h, AC_DEFINE(HAVE_LAUNCH_H))
  • case "$uname" in
  •   Darwin*)
    
  •       # Darwin, MacOS X
    
  •       LAUNCHD_DIR="/System/Library/LaunchDaemons/org.cups.cupsd.plist"
    
  •       # liblaunch is already part of libSystem
    
  •       ;;
    
  •   *)
    
  •       # All others; this test will need to be updated
    
  •       ;;
    
  • esac
    +fi

+dnl Systemd is used on Linux...
+AC_ARG_ENABLE(systemd, [ --disable-systemd disable systemd support])
+AC_ARG_WITH(systemd, [ --with-systemd set directory for systemd service files],

  •    SYSTEMD_DIR="$withval", SYSTEMD_DIR="")
    
    +AC_SUBST(SYSTEMD_DIR)
    +
    +if test x$enable_systemd != xno; then
  • if test "x$PKGCONFIG" = x; then
  •       if test x$enable_systemd = xyes; then
    
  •           AC_MSG_ERROR(Need pkg-config to enable systemd support.)
    
  •            fi
    
  •    else
    
  •       AC_MSG_CHECKING(for libsystemd-daemon)
    
  •            if $PKGCONFIG --exists libsystemd-daemon; then
    
  •                    AC_MSG_RESULT(yes)
    
  •                    ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
    
  •                    ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
    
  •                    AC_DEFINE(HAVE_SYSTEMD)
    
  •       if test "x$SYSTEMD_DIR" = x; then
    
  •               SYSTEMD_DIR="`$PKGCONFIG --variable=systemdsystemunitdir systemd`"
    
  •                    fi
    
  •            else
    
  •                    AC_MSG_RESULT(no)
    
  •            fi
    
  •    fi
    
    +fi
    +
    +dnl Solaris uses smf
    +SMFMANIFESTDIR=""
    +AC_SUBST(SMFMANIFESTDIR)
    +AC_ARG_WITH(smfmanifestdir, [ --with-smfmanifestdir set path for Solaris SMF manifest],SMFMANIFESTDIR="$withval")
    +
    +dnl Use init on other platforms...
    +AC_ARG_WITH(rcdir, [ --with-rcdir set path for rc scripts],rcdir="$withval",rcdir="")
    +AC_ARG_WITH(rclevels, [ --with-rclevels set run levels for rc scripts],rclevels="$withval",rclevels="2 3 5")
    +AC_ARG_WITH(rcstart, [ --with-rcstart set start number for rc scripts],rcstart="$withval",rcstart="")
    +AC_ARG_WITH(rcstop, [ --with-rcstop set stop number for rc scripts],rcstop="$withval",rcstop="")
    +
    +if test x$rcdir = x; then
  • if test x$LAUNCHD_DIR = x -a x$SYSTEMD_DIR = x -a x$SMFMANIFESTDIR = x; then
  •            # Fall back on "init", the original service startup interface...
    
  •            if test -d /sbin/init.d; then
    
  •                    # SuSE
    
  •                    rcdir="/sbin/init.d"
    
  •            elif test -d /etc/init.d; then
    
  •                    # Others
    
  •                    rcdir="/etc"
    
  •            else
    
  •                    # RedHat, NetBSD
    
  •                    rcdir="/etc/rc.d"
    
  •            fi
    
  •    else
    
  •       rcdir="no"
    
  • fi
    +fi

+if test "x$rcstart" = x; then

  • case "$uname" in
  •       Linux | GNU | GNU/k_BSD_)
    
  •               # Linux
    
  •                    rcstart="81"
    
  •                   ;;
    
  •   SunOS*)
    
  •       # Solaris
    
  •                    rcstart="81"
    
  •       ;;
    
  •            *)
    
  •                    # Others
    
  •                    rcstart="99"
    
  •                    ;;
    
  • esac
    +fi

+if test "x$rcstop" = x; then

  • case "$uname" in
  •       Linux | GNU | GNU/k_BSD_)
    
  •               # Linux
    
  •                    rcstop="36"
    
  •                   ;;
    
  •            *)
    
  •                    # Others
    
  •                    rcstop="00"
    
  •                    ;;
    
  • esac
    +fi

+INITDIR=""
+INITDDIR=""
+RCLEVELS="$rclevels"
+RCSTART="$rcstart"
+RCSTOP="$rcstop"
+AC_SUBST(INITDIR)
+AC_SUBST(INITDDIR)
+AC_SUBST(RCLEVELS)
+AC_SUBST(RCSTART)
+AC_SUBST(RCSTOP)
+
+if test "x$rcdir" != xno; then

  • if test "x$rclevels" = x; then
  •   INITDDIR="$rcdir"
    
  • else
  •   INITDIR="$rcdir"
    
  • fi
    +fi

+dnl Xinetd support...
+AC_ARG_WITH(xinetd, [ --with-xinetd set path for xinetd config files],xinetd="$withval",xinetd="")
+XINETD=""
+AC_SUBST(XINETD)
+
+if test "x$xinetd" = x; then

  • if test ! -x /sbin/launchd; then
  •            for dir in /etc/xinetd.d /usr/local/etc/xinetd.d; do
    
  •                    if test -d $dir; then
    
  •                            XINETD="$dir"
    
  •                            break
    
  •                    fi
    
  •            done
    
  •    fi
    
    +elif test "x$xinet" != xno; then
  • XINETD="$xinetd"
    +fi

+dnl
+dnl End of "$Id$".
+dnl

Property changes on: config-scripts/cups-startup.m4


Added: svn:keywords

-0,0 +1

+Id
\ No newline at end of property
Added: svn:eol-style

-0,0 +1

+native
\ No newline at end of property

Index: config-scripts/cups-network.m4

--- config-scripts/cups-network.m4 (revision 11714)
+++ config-scripts/cups-network.m4 (working copy)
@@ -1,16 +1,16 @@
dnl
dnl "$Id$"
dnl
-dnl Networking stuff for CUPS.
+dnl Networking stuff for CUPS.
dnl
-dnl Copyright 2007-2011 by Apple Inc.
-dnl Copyright 1997-2005 by Easy Software Products, all rights reserved.
+dnl Copyright 2007-2014 by Apple Inc.
+dnl Copyright 1997-2005 by Easy Software Products, all rights reserved.
dnl
-dnl These coded instructions, statements, and computer programs are the
-dnl property of Apple Inc. and are protected by Federal copyright
-dnl law. Distribution and use rights are outlined in the file "LICENSE.txt"
-dnl which should have been included with this file. If this file is
-dnl file is missing or damaged, see the license at "http://www.cups.org/".
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Apple Inc. and are protected by Federal copyright
+dnl law. Distribution and use rights are outlined in the file "LICENSE.txt"
+dnl which should have been included with this file. If this file is
+dnl file is missing or damaged, see the license at "http://www.cups.org/".
dnl

AC_CHECK_HEADER(resolv.h,AC_DEFINE(HAVE_RESOLV_H))
@@ -66,9 +66,6 @@
AC_SUBST(CUPS_DEFAULT_DOMAINSOCKET)
AC_SUBST(CUPS_LISTEN_DOMAINSOCKET)

-AC_CHECK_HEADERS(AppleTalk/at_proto.h,AC_DEFINE(HAVE_APPLETALK_AT_PROTO_H),,

- [#include <netat/appletalk.h>])

dnl
dnl End of "$Id$".
dnl

Index: config-scripts/cups-directories.m4

--- config-scripts/cups-directories.m4 (revision 11714)
+++ config-scripts/cups-directories.m4 (working copy)
@@ -3,7 +3,7 @@
dnl
dnl Directory stuff for CUPS.
dnl
-dnl Copyright 2007-2013 by Apple Inc.
+dnl Copyright 2007-2014 by Apple Inc.
dnl Copyright 1997-2007 by Easy Software Products, all rights reserved.
dnl
dnl These coded instructions, statements, and computer programs are the
@@ -121,104 +121,6 @@
AC_SUBST(privateinclude)
AC_SUBST(PRIVATEINCLUDE)

-dnl Setup init.d locations...
-AC_ARG_WITH(rcdir, [ --with-rcdir set path for rc scripts],rcdir="$withval",rcdir="")
-AC_ARG_WITH(rclevels, [ --with-rclevels set run levels for rc scripts],rclevels="$withval",rclevels="2 3 5")
-AC_ARG_WITH(rcstart, [ --with-rcstart set start number for rc scripts],rcstart="$withval",rcstart="99")
-AC_ARG_WITH(rcstop, [ --with-rcstop set stop number for rc scripts],rcstop="$withval",rcstop="00")

-AC_ARG_WITH(smfmanifestdir, [ --with-smfmanifestdir set path for Solaris SMF manifest],smfmanifestdir="$withval",smfmanifestdir="")

-INITDIR=""
-INITDDIR=""
-RCLEVELS="$rclevels"
-RCSTART="$rcstart"
-RCSTOP="$rcstop"

-SMFMANIFESTDIR=""

-if test x$rcdir = x; then

  • case "$uname" in
  •   Darwin*)
    
  •       # Darwin and MacOS X...
    
  •       if test -x /sbin/launchd; then
    
  •           INITDDIR="/System/Library/LaunchDaemons"
    
  •       else
    
  •           INITDDIR="/System/Library/StartupItems/PrintingServices"
    
  •       fi
    

- ;;

  •   FreeBSD\* | OpenBSD\* | MirBSD\* | ekkoBSD*)
    
  •       # FreeBSD and OpenBSD
    

- ;;

  •   Linux | GNU | GNU/k_BSD_)
    
  •       # Linux/HURD seems to choose an init.d directory at random...
    
  •       if test -d /sbin/init.d; then
    
  •           # SuSE
    
  •           INITDIR="/sbin/init.d"
    
  •       else
    
  •           if test -d /etc/init.d; then
    
  •               # Others
    
  •               INITDIR="/etc"
    
  •           else
    
  •               # RedHat
    
  •               INITDIR="/etc/rc.d"
    
  •           fi
    
  •       fi
    
  •       RCSTART="81"
    
  •       RCSTOP="36"
    

- ;;

  •   NetBSD*)
    
  •       # NetBSD
    
  •       INITDDIR="/etc/rc.d"
    

- ;;

  •   SunOS*)
    
  •       # Solaris
    
  •       if test "x$smfmanifestdir" != x; then
    
  •           SMFMANIFESTDIR=$smfmanifestdir
    
  •       else
    
  •           INITDIR="/etc"
    
  •           RCSTART="81"
    
  •       fi
    

- ;;

  •   *)
    
  •       INITDIR="/etc"
    

- ;;

  • esac
    -elif test "x$rcdir" != xno; then
  • if test "x$rclevels" = x; then
  •   INITDDIR="$rcdir"
    
  • else
  •   INITDIR="$rcdir"
    
  • fi
    -fi

-AC_SUBST(INITDIR)
-AC_SUBST(INITDDIR)
-AC_SUBST(RCLEVELS)
-AC_SUBST(RCSTART)
-AC_SUBST(RCSTOP)
-AC_SUBST(SMFMANIFESTDIR)

-dnl Xinetd support...
-AC_ARG_WITH(xinetd, [ --with-xinetd set path for xinetd config files],XINETD="$withval",XINETD="")

-if test "x$XINETD" = x -a ! -x /sbin/launchd; then

  • for dir in /private/etc/xinetd.d /etc/xinetd.d /usr/local/etc/xinetd.d; do
  •   if test -d $dir; then
    
  •       XINETD="$dir"
    
  •       break
    
  •   fi
    
  • done
    -elif test "x$XINETD" = xno; then
  • XINETD=""
    -fi

-AC_SUBST(XINETD)

dnl LPD sharing support...
AC_ARG_WITH(lpdconfig, [ --with-lpdconfig set URI for LPD config file],
LPDCONFIG="$withval", LPDCONFIG="")
Index: config-scripts/cups-launchd.m4

--- config-scripts/cups-launchd.m4 (revision 11714)
+++ config-scripts/cups-launchd.m4 (working copy)
@@ -1,48 +0,0 @@
-dnl
-dnl "$Id$"
-dnl
-dnl launchd stuff for CUPS.
-dnl
-dnl Copyright 2007-2014 by Apple Inc.
-dnl Copyright 1997-2005 by Easy Software Products, all rights reserved.
-dnl
-dnl These coded instructions, statements, and computer programs are the
-dnl property of Apple Inc. and are protected by Federal copyright
-dnl law. Distribution and use rights are outlined in the file "LICENSE.txt"
-dnl which should have been included with this file. If this file is
-dnl file is missing or damaged, see the license at "http://www.cups.org/".
-dnl

-AC_ARG_ENABLE(launchd, [ --disable-launchd disable launchd support])

-DEFAULT_LAUNCHD_CONF=""
-LAUNCHDLIBS=""

-if test x$enable_launchd != xno; then

  • AC_CHECK_FUNC(launch_msg, AC_DEFINE(HAVE_LAUNCHD))
  • if test $uversion -ge 140; then
  •   AC_CHECK_FUNC(launch_activate_socket, [
    
  •       AC_DEFINE(HAVE_LAUNCHD)
    
  •       AC_DEFINE(HAVE_LAUNCH_ACTIVATE_SOCKET)])
    
  • fi

- AC_CHECK_HEADER(launch.h, AC_DEFINE(HAVE_LAUNCH_H))

  • case "$uname" in
  •   Darwin*)
    
  •       # Darwin, MacOS X
    
  •       DEFAULT_LAUNCHD_CONF="/System/Library/LaunchDaemons/org.cups.cupsd.plist"
    
  •       # liblaunch is already part of libSystem
    
  •       ;;
    
  •   *)
    
  •       # All others; this test will need to be updated
    
  •       ;;
    
  • esac
    -fi

-AC_SUBST(DEFAULT_LAUNCHD_CONF)
-AC_SUBST(LAUNCHDLIBS)

-dnl
-dnl End of "$Id$".
-dnl
Index: configure.in

--- configure.in (revision 11714)
+++ configure.in (working copy)
@@ -1,96 +0,0 @@
-dnl
-dnl "$Id$"
-dnl
-dnl Configuration script for CUPS.
-dnl
-dnl Copyright 2007-2012 by Apple Inc.
-dnl Copyright 1997-2007 by Easy Software Products, all rights reserved.
-dnl
-dnl These coded instructions, statements, and computer programs are the
-dnl property of Apple Inc. and are protected by Federal copyright
-dnl law. Distribution and use rights are outlined in the file "LICENSE.txt"
-dnl which should have been included with this file. If this file is
-dnl file is missing or damaged, see the license at "http://www.cups.org/".
-dnl

-AC_INIT(cups/cups.h)

-sinclude(config-scripts/cups-opsys.m4)
-sinclude(config-scripts/cups-common.m4)
-sinclude(config-scripts/cups-directories.m4)
-sinclude(config-scripts/cups-manpages.m4)

-sinclude(config-scripts/cups-sharedlibs.m4)
-sinclude(config-scripts/cups-libtool.m4)
-sinclude(config-scripts/cups-compiler.m4)

-sinclude(config-scripts/cups-network.m4)
-sinclude(config-scripts/cups-poll.m4)
-sinclude(config-scripts/cups-gssapi.m4)
-sinclude(config-scripts/cups-threads.m4)
-sinclude(config-scripts/cups-ssl.m4)
-sinclude(config-scripts/cups-pam.m4)
-sinclude(config-scripts/cups-largefile.m4)
-sinclude(config-scripts/cups-dnssd.m4)
-sinclude(config-scripts/cups-launchd.m4)
-sinclude(config-scripts/cups-defaults.m4)
-sinclude(config-scripts/cups-scripting.m4)

-INSTALL_LANGUAGES=""
-UNINSTALL_LANGUAGES=""
-LANGFILES=""
-if test "x$LANGUAGES" != x; then

  • INSTALL_LANGUAGES="install-languages"
  • UNINSTALL_LANGUAGES="uninstall-languages"
  • for lang in $LANGUAGES; do
  •   if test -f doc/$lang/index.html.in; then
    
  •       LANGFILES="$LANGFILES doc/$lang/index.html"
    

- fi

  •   if test -f templates/$lang/header.tmpl.in; then
    
  •       LANGFILES="$LANGFILES templates/$lang/header.tmpl"
    
  •   fi
    
  • done
    -elif test "x$CUPS_BUNDLEDIR" != x; then
  • INSTALL_LANGUAGES="install-langbundle"
  • UNINSTALL_LANGUAGES="uninstall-langbundle"
    -fi

-AC_SUBST(INSTALL_LANGUAGES)
-AC_SUBST(UNINSTALL_LANGUAGES)

-AC_OUTPUT(Makedefs

  • conf/cups-files.conf
    
  • conf/cupsd.conf
    
  • conf/mime.convs
    
  • conf/pam.std
    
  • conf/snmp.conf
    
  • cups-config
    
  • data/testprint
    
  • desktop/cups.desktop
    
  • doc/help/ref-cups-files-conf.html
    
  • doc/help/ref-cupsd-conf.html
    
  • doc/index.html
    
  • man/client.conf.man
    
  • man/cups-deviced.man
    
  • man/cups-driverd.man
    
  • man/cups-files.conf.man
    
  • man/cups-lpd.man
    
  • man/cups-snmp.man
    
  • man/cupsaddsmb.man
    
  • man/cupsd.conf.man
    
  • man/cupsd.man
    
  • man/lpoptions.man
    
  • scheduler/cups-lpd.xinetd
    
  • scheduler/cups.sh
    
  • scheduler/cups.xml
    
  • scheduler/org.cups.cups-lpd.plist
    
  • templates/header.tmpl
    
  •      packaging/cups.list
    

- $LANGFILES)

-chmod +x cups-config

-dnl
-dnl End of "$Id$".
-dnl

Index: CHANGES.txt

--- CHANGES.txt (revision 11714)
+++ CHANGES.txt (working copy)
@@ -1,4 +1,4 @@
-CHANGES.txt - 2.0b1 - 2014-03-04
+CHANGES.txt - 2.0b1 - 2014-03-21


CHANGES IN CUPS V2.0b1
@@ -11,6 +11,7 @@
- Dropped support for AIX, HP-UX, and OSF/1 (aka Digital UNIX)
- Adopted Linux man page conventions and updated all man pages
(STR #4372)

  •    - Added systemd support (STR #3282)
    
    • Added support for re-sending a job as a raster file if a higher-level
      format such as PDF fails (rdar://problem/15583721)
    • Added support for regular expression matching in the MIME type rules
      Index: config.h.in

      --- config.h.in (revision 11714)
      +++ config.h.in (working copy)
      @@ -458,6 +458,13 @@

    /*

  • * Do we have systemd support?

  • /
    +
    +#undef HAVE_SYSTEMD
    +
    +
    +/

    • Various scripting languages...
      */

Index: scheduler/org.cups.cupsd.service.in

--- scheduler/org.cups.cupsd.service.in (revision 0)
+++ scheduler/org.cups.cupsd.service.in (revision 11729)
@@ -0,0 +1,10 @@
+[Unit]
+Description=CUPS Scheduler
+
+[Service]
+ExecStart=@sbindir@/cupsd -l
+Type=simple
+
+[Install]
+Also=org.cups.cupsd.socket org.cups.cupsd.path
+WantedBy=printer.target

Property changes on: scheduler/org.cups.cupsd.service.in


Added: svn:keywords

-0,0 +1

+Id
\ No newline at end of property
Added: svn:eol-style

-0,0 +1

+native
\ No newline at end of property

Index: scheduler/org.cups.cupsd.socket.in

--- scheduler/org.cups.cupsd.socket.in (revision 0)
+++ scheduler/org.cups.cupsd.socket.in (revision 11729)
@@ -0,0 +1,12 @@
+[Unit]
+Description=CUPS Scheduler
+
+[Socket]
+ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
+ListenStream=[::1]:631
+ListenStream=127.0.0.1:631
+BindIPv6Only=ipv6-only
+ReusePort=true
+
+[Install]
+WantedBy=sockets.target

Property changes on: scheduler/org.cups.cupsd.socket.in


Added: svn:keywords

-0,0 +1

+Id
\ No newline at end of property
Added: svn:eol-style

-0,0 +1

+native
\ No newline at end of property

Index: scheduler/org.cups.cupsd.path.in

--- scheduler/org.cups.cupsd.path.in (revision 0)
+++ scheduler/org.cups.cupsd.path.in (revision 11729)
@@ -0,0 +1,8 @@
+[Unit]
+Description=CUPS Scheduler
+
+[Path]
+PathExists=@CUPS_CACHEDIR@/org.cups.cupsd
+
+[Install]
+WantedBy=multi-user.target

Property changes on: scheduler/org.cups.cupsd.path.in


Added: svn:keywords

-0,0 +1

+Id
\ No newline at end of property
Added: svn:eol-style

-0,0 +1

+native
\ No newline at end of property

Index: scheduler/conf.c

--- scheduler/conf.c (revision 11714)
+++ scheduler/conf.c (working copy)
@@ -85,13 +85,16 @@
#ifdef HAVE_GSSAPI
{ "GSSServiceName", &GSSServiceName, CUPSD_VARTYPE_STRING },
#endif /* HAVE_GSSAPI */
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)

  • { "IdleExitTimeout", &IdleExitTimeout, CUPSD_VARTYPE_TIME },
    +#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
    { "JobKillDelay", &JobKillDelay, CUPSD_VARTYPE_TIME },
    { "JobRetryLimit", &JobRetryLimit, CUPSD_VARTYPE_INTEGER },
    { "JobRetryInterval", &JobRetryInterval, CUPSD_VARTYPE_TIME },
    { "KeepAliveTimeout", &KeepAliveTimeout, CUPSD_VARTYPE_TIME },
    { "KeepAlive", &KeepAlive, CUPSD_VARTYPE_BOOLEAN },
    #ifdef HAVE_LAUNCHD
  • { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_TIME },
  • { "LaunchdTimeout", &IdleExitTimeout, CUPSD_VARTYPE_TIME },
    #endif /* HAVE_LAUNCHD */
    { "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER },
    { "ListenBackLog", &ListenBackLog, CUPSD_VARTYPE_INTEGER },
    @@ -752,9 +755,9 @@
    DefaultLeaseDuration = 86400;
    MaxLeaseDuration = 0;

-#ifdef HAVE_LAUNCHD

  • LaunchdTimeout = 60;
    -#endif /* HAVE_LAUNCHD */
    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
  • IdleExitTimeout = 60;
    +#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */

/*

  • Setup environment variables...
    Index: scheduler/conf.h

    --- scheduler/conf.h (revision 11714)
    +++ scheduler/conf.h (working copy)
    @@ -243,10 +243,10 @@
    /* Keychain holding cert + key /
    #endif /
    HAVE_SSL */

-#ifdef HAVE_LAUNCHD
-VAR int LaunchdTimeout VALUE(60);
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+VAR int IdleExitTimeout VALUE(60);
/* Time after which an idle cupsd will exit /
-#endif /
HAVE_LAUNCHD /
+#endif /
HAVE_LAUNCHD || HAVE_SYSTEMD */

#ifdef HAVE_AUTHORIZATION_H
VAR char *SystemGroupAuthKey VALUE(NULL);

Index: scheduler/Makefile

--- scheduler/Makefile (revision 11714)
+++ scheduler/Makefile (working copy)
@@ -184,22 +184,29 @@
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc0.d;
$(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc0.d/K$(RCSTOP)cups;
fi

  • if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \

  •   $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \
    
  •   if test "$(INITDDIR)" = "/System/Library/LaunchDaemons"; then \
    
  •       echo Installing LaunchDaemons configuration files...; \
    
  •       $(INSTALL_DATA) org.cups.cupsd.plist $(BUILDROOT)$(DEFAULT_LAUNCHD_CONF); \
    
  •       $(INSTALL_DATA) org.cups.cups-lpd.plist $(BUILDROOT)/System/Library/LaunchDaemons; \
    
  •   else \
    
  •       echo Installing RC script...; \
    
  •       $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/cups; \
    
  •   fi \
    
  • if test "x$(INITDDIR)" != x; then \

  •   echo Installing init script...; \
    
  •   $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDDIR); \
    
  •   $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR); \
    

    fi

  • if test "x$(LAUNCHD_DIR)" != x; then \

  •   echo Installing launchd configuration files...; \
    
  •   $(INSTALL_DIR) $(BUILDROOT)$(LAUNCHD_DIR); \
    
  •   $(INSTALL_DATA) org.cups.cupsd.plist $(BUILDROOT)$(LAUNCHD_DIR); \
    
  •   $(INSTALL_DATA) org.cups.cups-lpd.plist $(BUILDROOT)$(LAUNCHD_DIR); \
    
  • fi
    if test "x$(SMFMANIFESTDIR)" != x; then
    echo Installing SMF manifest in $(SMFMANIFESTDIR)...;
    $(INSTALL_DIR) $(BUILDROOT)/$(SMFMANIFESTDIR);
    $(INSTALL_SCRIPT) cups.xml $(BUILDROOT)$(SMFMANIFESTDIR)/cups.xml;
    fi

  • if test "x$(SYSTEMD_DIR)" != x; then \

  •   echo Installing systemd configuration files...; \
    
  •   $(INSTALL_DIR) $(BUILDROOT)$(SYSTEMD_DIR); \
    
  •   $(INSTALL_DATA) org.cups.cupsd.path $(BUILDROOT)$(SYSTEMD_DIR); \
    
  •   $(INSTALL_DATA) org.cups.cupsd.service $(BUILDROOT)$(SYSTEMD_DIR); \
    
  •   $(INSTALL_DATA) org.cups.cupsd.socket $(BUILDROOT)$(SYSTEMD_DIR); \
    
  • fi
    if test "x$(XINETD)" != x; then
    echo Installing xinetd configuration file for cups-lpd...;
    $(INSTALL_DIR) -m 755 $(BUILDROOT)$(XINETD);
    @@ -282,7 +289,6 @@
    $(RM) $(SERVERBIN)/daemon/cups-driverd
    $(RM) $(SERVERBIN)/daemon/cups-exec
    $(RM) $(SERVERBIN)/daemon/cups-lpd

  • $(RM) $(BUILDROOT)/System/Library/Printers/Libraries/convert
    -$(RMDIR) $(STATEDIR)/certs
    -$(RMDIR) $(STATEDIR)
    -$(RMDIR) $(SERVERROOT)/ppd
    @@ -304,8 +310,8 @@
    -$(RMDIR) $(LIBDIR)
    $(RM) $(INCLUDEDIR)/cups/mime.h
    -$(RMDIR) $(INCLUDEDIR)/cups

  • echo Uninstalling startup script...
    if test "x$(INITDIR)" != x; then \

  •   echo Uninstalling init scripts...; \
    $(RM) $(BUILDROOT)$(INITDIR)/init.d/cups; \
    $(RMDIR) $(BUILDROOT)$(INITDIR)/init.d; \
    $(RM)  $(BUILDROOT)$(INITDIR)/rc0.d/K00cups; \
    

    @@ -317,23 +323,24 @@
    $(RM) $(BUILDROOT)$(INITDIR)/rc5.d/S99cups;
    $(RMDIR) $(BUILDROOT)$(INITDIR)/rc5.d;
    fi

  • if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \

  •   if test "$(INITDDIR)" = "/System/Library/StartupItems/PrintingServices"; then \
    
  •       $(RM) $(BUILDROOT)$(INITDDIR)/PrintingServices; \
    
  •       $(RM) $(BUILDROOT)$(INITDDIR)/StartupParameters.plist; \
    
  •       $(RM) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj/Localizable.strings; \
    
  •       $(RMDIR) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj; \
    
  •   elif test "$(INITDDIR)" = "/System/Library/LaunchDaemons"; then \
    
  •       $(RM) $(BUILDROOT)$(INITDDIR)/org.cups.cupsd.plist; \
    
  •       $(RM) $(BUILDROOT)$(INITDDIR)/org.cups.cups-lpd.plist; \
    
  •       $(RMDIR) $(BUILDROOT)/System/Library/StartupItems/PrintingServices; \
    
  •   else \
    
  •       $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDDIR)/cups; \
    
  •   fi \
    
  • if test "x$(INITDDIR)" != x; then \

  •   echo Uninstalling startup script...; \
    
  •   $(RM) $(BUILDROOT)$(INITDDIR)/cups.sh; \
    $(RMDIR) $(BUILDROOT)$(INITDDIR); \
    

    fi

  • if test "x$LAUNCHD_DIR" != x; then \

  •   echo Uninstalling launchd files...; \
    
  •   $(RM) $(BUILDROOT)$(LAUNCHD_DIR)/org.cups.cupsd.plist; \
    
  •   $(RM) $(BUILDROOT)$(LAUNCHD_DIR)/org.cups.cups-lpd.plist; \
    
  • fi

  • if test "x$SYSTEMD_DIR" != x; then \

  •   echo Uninstalling systemd files...; \
    
  •   $(RM) $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cupsd.path; \
    
  •   $(RM) $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cupsd.service; \
    
  •   $(RM) $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cupsd.socket; \
    
  • fi
    if test "x$(SMFMANIFESTDIR)" != x; then \

  •   echo Uninstalling SMF manifest in $(SMFMANIFESTDIR)...;\
    
  •   echo Uninstalling SMF manifest file...;\
    $(RM) $(BUILDROOT)$(SMFMANIFESTDIR)/cups.xml; \
    

    fi
    if test "x$(XINETD)" != x; then
    @@ -372,16 +379,16 @@
    echo Linking $@...
    $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \

  •   $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \
    
  •   $(LIBGSSAPI) $(LIBWRAP)
    
  •   $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(ONDEMANDLIBS) \
    
  •            $(DNSSDLIBS) $(LIBS) $(LIBGSSAPI) $(LIBWRAP)
    

    cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
    echo Linking $@...
    $(CC) $(LDFLAGS) -o cupsd-static $(CUPSDOBJS) libcupsmime.a
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS)
    ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \

  •   $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
    
  •   $(LIBWRAP)
    
  •   $(LIBMALLOC) $(SERVERLIBS) $(ONDEMANDLIBS) $(DNSSDLIBS) \
    
  •            $(LIBGSSAPI) $(LIBWRAP)
    

    Index: scheduler/client.h

    --- scheduler/client.h (revision 11714)
    +++ scheduler/client.h (working copy)
    @@ -3,7 +3,7 @@
    *

    • Client definitions for the CUPS scheduler.
      *
  • * Copyright 2007-2013 by Apple Inc.

  • * Copyright 2007-2014 by Apple Inc.

    • Copyright 1997-2007 by Easy Software Products, all rights reserved.
      *
    • These coded instructions, statements, and computer programs are the
      @@ -81,6 +81,9 @@
      int fd; /* File descriptor for this server /
      http_addr_t address; /
      Bind address of socket /
      http_encryption_t encryption; /
      To encrypt or not to encrypt... */
      +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
  • int on_demand; /* Is this a socket from launchd/systemd? /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */
    } cupsd_listener_t;

Index: scheduler/listen.c

--- scheduler/listen.c (revision 11714)
+++ scheduler/listen.c (working copy)
@@ -3,7 +3,7 @@
*

  • Server listening routines for the CUPS scheduler.
    *
    • * Copyright 2007-2013 by Apple Inc.
    • * Copyright 2007-2014 by Apple Inc.
  • Copyright 1997-2006 by Easy Software Products, all rights reserved.
    *
  • These coded instructions, statements, and computer programs are the
    @@ -274,16 +274,25 @@
    lis;
    lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
    {
    +#ifdef HAVE_SYSTEMD
    • if (lis->fd != -1 && !lis->on_demand)
    •  httpAddrClose(&(lis->address), lis->fd);
      
      +#elif defined(HAVE_LAUNCHD)
      if (lis->fd != -1)
      {
      -#ifdef HAVE_LAUNCH_H
    •  httpAddrClose(NULL, lis->fd);
      
    •  if (lis->on_demand)
      
    •    httpAddrClose(NULL, lis->fd);
      
    •  else
      
    •    httpAddrClose(&(lis->address), lis->fd);
      
    • }
    #else
    • if (lis->fd != -1)
      httpAddrClose(&(lis->address), lis->fd);
      -#endif /* HAVE_LAUNCH /
      +#endif /
      HAVE_SYSTEMD */
  •  lis->fd = -1;
    
  • }
  • lis->fd = -1;
    }
    }

Index: scheduler/cupsd.h

--- scheduler/cupsd.h (revision 11714)
+++ scheduler/cupsd.h (working copy)
@@ -158,10 +158,10 @@
VAR void DefaultProfile VALUE(0);
/
Default security profile */

-#ifdef HAVE_LAUNCH_H
-VAR int Launchd VALUE(0);

  •               /\* Running from launchd _/
    

    -#endif /_ HAVE_LAUNCH_H */
    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
    +VAR int OnDemand VALUE(0);

  •               /* Launched on demand */
    

    +#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */

    /*

    Index: scheduler/main.c

    --- scheduler/main.c (revision 11714)
    +++ scheduler/main.c (working copy)
    @@ -34,6 +34,12 @@

    endif /* HAVE_LAUNCH_ACTIVATE_SOCKET */

    #endif /* HAVE_LAUNCH_H */

+#ifdef HAVE_SYSTEMD
+# include <systemd/sd-daemon.h>
+# define CUPS_KEEPALIVE CUPS_CACHEDIR "/org.cups.cupsd"

  •               /\* Name of the systemd path file _/
    
    +#endif /_ HAVE_SYSTEMD _/
    +
    #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)

    include <malloc.h>

    #endif /_ HAVE_MALLOC_H && HAVE_MALLINFO */
    @@ -51,16 +61,16 @@
    • Local functions...
      */

-#ifdef HAVE_LAUNCHD
-static void launchd_checkin(void);
-static void launchd_checkout(void);
-#endif /* HAVE_LAUNCHD /
static void parent_handler(int sig);
static void process_children(void);
static void sigchld_handler(int sig);
static void sighup_handler(int sig);
static void sigterm_handler(int sig);
static long select_timeout(int fds);
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+static void service_checkin(void);
+static void service_checkout(void);
+#endif /
HAVE_LAUNCHD || HAVE_SYSTEMD */
static void usage(int status) attribute((noreturn));

@@ -114,10 +124,10 @@
#else
time_t netif_time = 0; /* Time since last network update /
#endif /
APPLE */
-#if HAVE_LAUNCHD

  • int launchd_idle_exit;
    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
  • int service_idle_exit;
    /* Idle exit on select timeout? /
    -#endif /
    HAVE_LAUNCHD /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */

#ifdef HAVE_GETEUID
@@ -141,8 +151,8 @@
#ifdef HAVE_LAUNCHD
if (getenv("CUPSD_LAUNCHD"))
{

  • Launchd = 1;
  • fg = 1;
  • OnDemand = 1;
  • fg = 1;
    }
    #endif /* HAVE_LAUNCHD */

@@ -219,15 +229,15 @@
usage(0);
break;

  •      case 'l' : /\* Started by launchd... */
    

    -#ifdef HAVE_LAUNCHD

  •     Launchd = 1;
    
  •     fg      = 1;
    
  •      case 'l' : /\* Started by launchd/systemd... */
    

    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)

  •     OnDemand = 1;
    
  •     fg       = 1;
    

    #else

  •     _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
    
  •     _cupsLangPuts(stderr, _("cupsd: On-demand support not compiled "
                              "in, running in normal mode."));
           fg = 0;
    

    -#endif /* HAVE_LAUNCHD /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */
    break;

       case 'p' : /* Stop immediately for profiling */
    

    @@ -531,17 +541,18 @@

    cupsdCleanFiles(CacheDir, "*.ipp");

-#if HAVE_LAUNCHD

  • if (Launchd)
    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
  • if (OnDemand)
    {
    /*
  • * If we were started by launchd get the listen sockets file descriptors...
  • * If we were started on demand by launchd or systemd get the listen sockets
    • file descriptors...
      */
  • launchd_checkin();
  • launchd_checkout();
  • service_checkin();
  • service_checkout();
    }
    -#endif /* HAVE_LAUNCHD /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */

/*

  • Startup the server...
    @@ -628,18 +639,15 @@
  • Send server-started event...
    */

-#ifdef HAVE_LAUNCHD

  • if (Launchd)
  • cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
  •              "Scheduler started via launchd.");
    
    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
  • if (OnDemand)
  • cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started on demand.");
    else
    -#endif /* HAVE_LAUNCHD /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */
    if (fg)
  • cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
  •              "Scheduler started in foreground.");
    
  • cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in foreground.");
    else
  • cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
  •              "Scheduler started in background.");
    
  • cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in background.");

/*

  • Start any pending print jobs...
    @@ -718,18 +726,18 @@
    break;
    }

-#if HAVE_LAUNCHD

  • if (Launchd)
    +#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)

  • if (OnDemand)
    {
    /*

  • \* If we were started by launchd, get the listen socket file
    
  • * If we were started by launchd or systemd, get the listen socket file
    
    • descriptors...
      */
  • launchd_checkin();
    
  • launchd_checkout();
    
  • service_checkin();
    
  • service_checkout();
    

    }
    -#endif /* HAVE_LAUNCHD /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */

    /*
     * Startup the server...
    

    @@ -760,23 +768,23 @@
    if ((timeout = select_timeout(fds)) > 1 && LastEvent)
    timeout = 1;

-#if HAVE_LAUNCHD
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*
* If no other work is scheduled and we're being controlled by
* launchd then timeout after 'LaunchdTimeout' seconds of
* inactivity...
*/

  • if (timeout == 86400 && Launchd && LaunchdTimeout &&

  • if (timeout == 86400 && OnDemand && IdleExitTimeout &&
    !cupsArrayCount(ActiveJobs) &&
    (!Browsing || !BrowseLocalProtocols || !cupsArrayCount(Printers)))
    {

  •  timeout      = LaunchdTimeout;
    
  •  launchd_idle_exit = 1;
    
  •  timeout      = IdleExitTimeout;
    
  •  service_idle_exit = 1;
    

    }
    else

  •  launchd_idle_exit = 0;
    

    -#endif /* HAVE_LAUNCHD */

  •  service_idle_exit = 0;
    

    +#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */

    if ((fds = cupsdDoSelect(timeout)) < 0)
    {
    @@ -873,13 +881,13 @@
    }
    #endif /* !APPLE */

-#if HAVE_LAUNCHD
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*
* If no other work was scheduled and we're being controlled by launchd
* then timeout after 'LaunchdTimeout' seconds of inactivity...
*/

  • if (!fds && launchd_idle_exit)
  • if (!fds && service_idle_exit)
    {
    cupsdLogMessage(CUPSD_LOG_INFO,
    "Printer sharing is off and there are no jobs pending, "
    @@ -887,7 +895,7 @@
    stop_scheduler = 1;
    break;
    }
    -#endif /* HAVE_LAUNCHD /
    +#endif /
    HAVE_LAUNCHD || HAVE_SYSTEMD */

/*

  • Resume listening for new connections as needed...
    @@ -941,8 +949,7 @@

    • Process pending data in the input buffer...
      */
  •  // TODO: Use httpGetReady()
    
  •  if (con->http->used)
    
  •  if (httpGetReady(con->http))
    

    {
    cupsdReadClient(con);
    continue;
    @@ -952,13 +959,10 @@

    • Check the activity and close old clients...
      */
  •  // TODO: Use httpGetActivity()
    

    activity = current_time - Timeout;

  •  if (con->http->activity < activity && !con->pipe_pid)
    
  •  if (httpGetActivity(con->http) < activity && !con->pipe_pid)
    

    {

  •    cupsdLogMessage(CUPSD_LOG_DEBUG,
    
  •               "Closing client %d after %d seconds of inactivity...",
    
  •               con->number, Timeout);
    
  •    cupsdLogMessage(CUPSD_LOG_DEBUG, "Closing client %d after %d seconds of inactivity.", con->number, Timeout);
    
     cupsdCloseClient(con);
     continue;
    

    @@ -1095,14 +1099,14 @@

    cupsdStopServer();

-#ifdef HAVE_LAUNCHD
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*

  • * Update the launchd KeepAlive file as needed...
    • Update the keep-alive file as needed...
      */
  • if (Launchd)
  • launchd_checkout();
    -#endif /* HAVE_LAUNCHD */
  • if (OnDemand)
  • service_checkout();
    +#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */

/*

  • Stop all jobs...
    @@ -1292,279 +1296,7 @@
    }

-#ifdef HAVE_LAUNCHD
/*

  • * 'launchd_checkin()' - Check-in with launchd and collect the listening fds.

- */

-static void
-launchd_checkin(void)
-{
-# ifdef HAVE_LAUNCH_ACTIVATE_SOCKET

  • int error; /* Check-in error, if any */
  • size_t i, /* Looping var */
  •       count;      /\* Number of listeners */
    
  • int ld_sockets; / Listener sockets */
  • cupsd_listener_t lis; / Listeners array */
  • http_addr_t addr; /* Address variable */
  • socklen_t addrlen; /* Length of address */

- char s[256]; /* String addresss */

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid());

  • /*
  • * Check-in with launchd...

- */

  • if ((error = launch_activate_socket("Listeners", &ld_sockets, &count)) != 0)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Unable to get listener sockets: %s", strerror(error));
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */

- }

  • /*
  • * Try to match the launchd sockets to the cupsd listeners...

- */

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: %d listeners.", (int)count);

  • for (i = 0; i < count; i ++)
  • {
  • /*
  • * Get the launchd socket address...

- */

- addrlen = sizeof(addr);

  • if (getsockname(ld_sockets[i], (struct sockaddr *)&addr, &addrlen))
  • {
  •  cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
    
  •  continue;
    

- }

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: Listener #%d at fd %d, "%s".", (int)i + 1, ld_sockets[i], httpAddrString(&addr, s, sizeof(s)));

  • for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
  • lis;
  • lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
  •  if (httpAddrEqual(&lis->address, &addr))
    

- break;

  • /*
  • * Add a new listener if there's no match...

- */

  • if (lis)
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
    
  • }
  • else
  • {

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));

  •  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    
  •  {
    
  • cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Unable to allocate listener: %s", strerror(errno));
  • exit(EXIT_FAILURE);

- }

- cupsArrayAdd(Listeners, lis);

  •  memcpy(&lis->address, &addr, sizeof(lis->address));
    

- }

- lis->fd = ld_sockets[i];

-# ifdef HAVE_SSL

  • if (httpAddrPort(&(lis->address)) == 443)
  •  lis->encryption = HTTP_ENCRYPT_ALWAYS;
    
    -# endif /* HAVE_SSL */

- }

-# else

  • size_t i, /* Looping var */
  •       count;      /\* Number of listeners */
    
  • launch_data_t ld_msg, /* Launch data message */
  •       ld_resp,    /\* Launch data response */
    
  •       ld_array,   /\* Launch data array */
    
  •       ld_sockets, /\* Launch data sockets dictionary */
    
  •       tmp;        /\* Launch data */
    
  • cupsd_listener_t lis; / Listeners array */
  • http_addr_t addr; /* Address variable */
  • socklen_t addrlen; /* Length of address */
  • int fd; /* File descriptor */

- char s[256]; /* String addresss */

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid());

  • /*
  • * Check-in with launchd...

- */

  • ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
  • if ((ld_resp = launch_msg(ld_msg)) == NULL)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •       "launchd_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
    
  •       "\") IPC failure");
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */

- }

  • if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
  • {
  • errno = launch_data_get_errno(ld_resp);
  • cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Check-in failed: %s",
  •                strerror(errno));
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */

- }

  • /*
  • * Get the sockets dictionary...

- */

  • if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
  •      == NULL)
    
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •                "launchd_checkin: No sockets found to answer requests on.");
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */

- }

  • /*
  • * Get the array of listener sockets...

- */

  • if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •                "launchd_checkin: No sockets found to answer requests on.");
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */

- }

  • /*
  • * Add listening fd(s) to the Listener array...

- */

  • if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
  • {

- count = launch_data_array_get_count(ld_array);

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: %d listeners.", (int)count);

  • for (i = 0; i < count; i ++)
  • {
  • /*
    
  •  \* Get the launchd file descriptor and address...
    

- */

  •  if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
    
  •  {
    
  • fd = launch_data_get_fd(tmp);

- addrlen = sizeof(addr);

  • if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
    
  • continue;
    

- }

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: Listener #%d at fd %d, "%s".", (int)i + 1, fd, httpAddrString(&addr, s, sizeof(s)));

  •   /*
    
  • * Try to match the launchd socket address to one of the listeners...

- */

  • for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
  •    lis;
    
  •    lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
    
  • if (httpAddrEqual(&lis->address, &addr))
    

- break;

  •   /*
    
  • * Add a new listener If there's no match...

- */

  • if (lis)
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
    
  • }
  • else
  • {

- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));

  • if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    
  • {
    
  •   cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Unable to allocate listener: %s.", strerror(errno));
    
  •   exit(EXIT_FAILURE);
    

- }

- cupsArrayAdd(Listeners, lis);

  • memcpy(&lis->address, &addr, sizeof(lis->address));
    

- }

- lis->fd = fd;

-# ifdef HAVE_SSL

  • if (httpAddrPort(&(lis->address)) == 443)
  • lis->encryption = HTTP_ENCRYPT_ALWAYS;
    
    -# endif /* HAVE_SSL */
  •  }
    
  • }

- }

  • launch_data_free(ld_msg);
  • launch_data_free(ld_resp);
    -# endif /* HAVE_LAUNCH_ACTIVATE_SOCKET _/
    -}

-/_

  • * 'launchd_checkout()' - Update the launchd KeepAlive file as needed.

- */

-static void
-launchd_checkout(void)
-{

- int fd; /* File descriptor */

  • /*
  • * Create or remove the launchd KeepAlive file based on whether
  • * there are active jobs, polling, browsing for remote printers or
  • * shared printers to advertise...

- */

  • if (cupsArrayCount(ActiveJobs) ||
  •  (Browsing && BrowseLocalProtocols && cupsArrayCount(Printers)))
    
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG,
  •                "Creating launchd keepalive file \"" CUPS_KEEPALIVE
    

- ""...");

  • if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0)
  •  close(fd);
    
  • }
  • else
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG,
  •                "Removing launchd keepalive file \"" CUPS_KEEPALIVE
    

- ""...");

  • unlink(CUPS_KEEPALIVE);
  • }
    -}
    -#endif /* HAVE_LAUNCHD _/

-/_

  • 'parent_handler()' - Catch USR1/CHLD signals...
    */

@@ -1838,11 +1570,10 @@

  • processed; if so, the timeout should be 0...
    */
  • // TODO: Use httpGetReady()
    for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
    con;
    con = (cupsd_client_t *)cupsArrayNext(Clients))
  • if (con->http->used > 0)
  • if (httpGetReady(con->http))
    return (0);

/*
@@ -1893,13 +1624,12 @@

  • Check the activity and close old clients...
    */
  • // TODO: Use httpGetActivity()
    for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
    con;
    con = (cupsd_client_t *)cupsArrayNext(Clients))
  • if ((con->http->activity + Timeout) < timeout)
  • if ((httpGetActivity(con->http) + Timeout) < timeout)
    {
  •  timeout = con->http->activity + Timeout;
    
  •  timeout = httpGetActivity(con->http) + Timeout;
    
    why = "timeout a client connection";
    }

@@ -2063,7 +1793,358 @@
}

+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*

  • * 'service_checkin()' - Check-in with launchd and collect the listening fds.
  • */
    +
    +static void
    +service_checkin(void)
    +{
    +# ifdef HAVE_LAUNCH_ACTIVATE_SOCKET
  • int error; /* Check-in error, if any */
  • size_t i, /* Looping var */
  •       count;      /\* Number of listeners */
    
  • int ld_sockets; / Listener sockets */
  • cupsd_listener_t lis; / Listeners array */
  • http_addr_t addr; /* Address variable */
  • socklen_t addrlen; /* Length of address */
  • char s[256]; /* String addresss */
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: pid=%d", (int)getpid());
  • /*
  • * Check-in with launchd...
  • */
  • if ((error = launch_activate_socket("Listeners", &ld_sockets, &count)) != 0)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get listener sockets: %s", strerror(error));
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */
  • }
  • /*
  • * Try to match the launchd sockets to the cupsd listeners...
  • */
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: %d listeners.", (int)count);
  • for (i = 0; i < count; i ++)
  • {
  • /*
  • * Get the launchd socket address...
  • */
  • addrlen = sizeof(addr);
  • if (getsockname(ld_sockets[i], (struct sockaddr *)&addr, &addrlen))
  • {
  •  cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
    
  •  continue;
    
  • }
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Listener #%d at fd %d, "%s".", (int)i + 1, ld_sockets[i], httpAddrString(&addr, s, sizeof(s)));
  • for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
  • lis;
  • lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
  •  if (httpAddrEqual(&lis->address, &addr))
    
  • break;
  • /*
  • * Add a new listener if there's no match...
  • */
  • if (lis)
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
    
  • }
  • else
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));
    
  •  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    
  •  {
    
  • cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to allocate listener: %s", strerror(errno));
  • exit(EXIT_FAILURE);
  •  }
    
  •  cupsArrayAdd(Listeners, lis);
    
  •  memcpy(&lis->address, &addr, sizeof(lis->address));
    
  • }
  • lis->fd = ld_sockets[i];
  • lis->on_demand = 1;

+# ifdef HAVE_SSL

  • if (httpAddrPort(&(lis->address)) == 443)
  •  lis->encryption = HTTP_ENCRYPT_ALWAYS;
    
    +# endif /* HAVE_SSL */
  • }

+# elif defined(HAVE_LAUNCHD)

  • size_t i, /* Looping var */
  •       count;      /\* Number of listeners */
    
  • launch_data_t ld_msg, /* Launch data message */
  •       ld_resp,    /\* Launch data response */
    
  •       ld_array,   /\* Launch data array */
    
  •       ld_sockets, /\* Launch data sockets dictionary */
    
  •       tmp;        /\* Launch data */
    
  • cupsd_listener_t lis; / Listeners array */
  • http_addr_t addr; /* Address variable */
  • socklen_t addrlen; /* Length of address */
  • int fd; /* File descriptor */
  • char s[256]; /* String addresss */
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: pid=%d", (int)getpid());
  • /*
  • * Check-in with launchd...
  • */
  • ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
  • if ((ld_resp = launch_msg(ld_msg)) == NULL)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •       "service_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
    
  •       "\") IPC failure");
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */
  • }
  • if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
  • {
  • errno = launch_data_get_errno(ld_resp);
  • cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Check-in failed: %s",
  •                strerror(errno));
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */
  • }
  • /*
  • * Get the sockets dictionary...
  • */
  • if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
  •      == NULL)
    
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •                "service_checkin: No sockets found to answer requests on.");
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */
  • }
  • /*
  • * Get the array of listener sockets...
  • */
  • if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR,
  •                "service_checkin: No sockets found to answer requests on.");
    
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */
  • }
  • /*
  • * Add listening fd(s) to the Listener array...
  • */
  • if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
  • {
  • count = launch_data_array_get_count(ld_array);
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: %d listeners.", (int)count);
  • for (i = 0; i < count; i ++)
  • {
  • /*
    
  •  \* Get the launchd file descriptor and address...
    
  •  */
    
  •  if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
    
  •  {
    
  • fd = launch_data_get_fd(tmp);
  • addrlen = sizeof(addr);
  • if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
    
  • continue;
    
  • }
  •    cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Listener #%d at fd %d, \"%s\".", (int)i + 1, fd, httpAddrString(&addr, s, sizeof(s)));
    
  •   /*
    
  • * Try to match the launchd socket address to one of the listeners...
  • */
  • for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
  •    lis;
    
  •    lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
    
  • if (httpAddrEqual(&lis->address, &addr))
    
  •   break;
    
  •   /*
    
  • * Add a new listener If there's no match...
  • */
  • if (lis)
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
    
  • }
  • else
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));
    
  • if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    
  • {
    
  •   cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to allocate listener: %s.", strerror(errno));
    
  •   exit(EXIT_FAILURE);
    
  • }
    
  • cupsArrayAdd(Listeners, lis);
    
  • memcpy(&lis->address, &addr, sizeof(lis->address));
    
  • }
  • lis->fd = fd;
  •    lis->on_demand = 1;
    
    +# ifdef HAVE_SSL
  • if (httpAddrPort(&(lis->address)) == 443)
  • lis->encryption = HTTP_ENCRYPT_ALWAYS;
    
    +# endif /* HAVE_SSL */
  •  }
    
  • }
  • }
  • launch_data_free(ld_msg);
  • launch_data_free(ld_resp);

+# else /* HAVE_SYSTEMD */

  • int i, /* Looping var */
  •       count;      /\* Number of listeners */
    
  • cupsd_listener_t lis; / Listeners array */
  • http_addr_t addr; /* Address variable */
  • socklen_t addrlen; /* Length of address */
  • char s[256]; /* String addresss */
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: pid=%d", (int)getpid());
  • /*
  • * Check-in with systemd...
  • */
  • if ((count = sd_listen_fds(0)) < 0)
  • {
  • cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get listener sockets: %s", strerror(-count));
  • exit(EXIT_FAILURE);
  • return; /* anti-compiler-warning */
  • }
  • /*
  • * Try to match the systemd sockets to the cupsd listeners...
  • */
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: %d listeners.", count);
  • for (i = 0; i < count; i ++)
  • {
  • /*
  • * Get the launchd socket address...
  • */
  • addrlen = sizeof(addr);
  • if (getsockname(SD_LISTEN_FDS_START + i, (struct sockaddr *)&addr, &addrlen))
  • {
  •  cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
    
  •  continue;
    
  • }
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Listener #%d at fd %d, "%s".", (int)i + 1, SD_LISTEN_FDS_START + i, httpAddrString(&addr, s, sizeof(s)));
  • for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
  • lis;
  • lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
  •  if (httpAddrEqual(&lis->address, &addr))
    
  • break;
  • /*
  • * Add a new listener if there's no match...
  • */
  • if (lis)
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
    
  • }
  • else
  • {
  •  cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));
    
  •  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    
  •  {
    
  • cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to allocate listener: %s", strerror(errno));
  • exit(EXIT_FAILURE);
  •  }
    
  •  cupsArrayAdd(Listeners, lis);
    
  •  memcpy(&lis->address, &addr, sizeof(lis->address));
    
  • }
  • lis->fd = SD_LISTEN_FDS_START + i;
  • lis->on_demand = 1;

+# ifdef HAVE_SSL

  • if (httpAddrPort(&(lis->address)) == 443)
  •  lis->encryption = HTTP_ENCRYPT_ALWAYS;
    
    +# endif /* HAVE_SSL */
  • }
    +# endif /* HAVE_LAUNCH_ACTIVATE_SOCKET _/
    +}

+/_

  • * 'service_checkout()' - Update the CUPS_KEEPALIVE file as needed.
  • */
    +
    +static void
    +service_checkout(void)
    +{
  • int fd; /* File descriptor */
  • /*
  • * Create or remove the systemd path file based on whether there are active
  • * jobs or shared printers to advertise...
  • */
  • if (cupsArrayCount(ActiveJobs) ||
  •  (Browsing && BrowseLocalProtocols && cupsArrayCount(Printers)))
    
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating keep-alive file "" CUPS_KEEPALIVE "".");
  • if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0)
  •  close(fd);
    
  • }
  • else
  • {
  • cupsdLogMessage(CUPSD_LOG_DEBUG, "Removing keep-alive file "" CUPS_KEEPALIVE "".");
  • unlink(CUPS_KEEPALIVE);
  • }
    +}
    +#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD _/

+/_

  • 'usage()' - Show scheduler usage.
    */

@@ -2080,7 +2161,7 @@
_cupsLangPuts(fp, _(" -F Run in the foreground but "
"detach from console."));
_cupsLangPuts(fp, _(" -h Show this usage message."));

  • _cupsLangPuts(fp, _(" -l Run cupsd from launchd(8)."));
  • _cupsLangPuts(fp, _(" -l Run cupsd on demand."));
    _cupsLangPuts(fp, _(" -t Test the configuration "
    "file."));

Index: scheduler

--- scheduler (revision 11714)
+++ scheduler (working copy)

Property changes on: scheduler


Modified: svn:ignore

-15,6 +15,9

libcupsmime.so
libcupsmime.so.1
org.cups.cups-lpd.plist
+org.cups.cupsd.path
+org.cups.cupsd.service
+org.cups.cupsd.socket
testlpd
testmime
testspeed

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Sep 25, 2014

CUPS.org User: jpopelka

Mar 21, 2014 Michael Sweet wrote:

I've called the service "org.cups.cupsd" since at some point
I think I'll add an org.cups.cups-lpd service as well -
this mirrors what we've done for OS X and launchd,
and eliminates the dependency on xinetd for LPD server support.

FYI: this is how it looks like in Fedora:
http://pkgs.fedoraproject.org/cgit/cups.git/tree/cups-lpd.socket
http://pkgs.fedoraproject.org/cgit/cups.git/tree/cups-lpd@.service
https://bugzilla.redhat.com/show_bug.cgi?id=884641

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 2, 2014

CUPS.org User: mike

Jiri,

If you can file a new bug with the proposed files, I can get them added to the 2.0.1 update.

Thanks!

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 17, 2014

CUPS.org User: roukoswarf

I've called the service "org.cups.cupsd" since at some point

This naming is rather unfortunate, for a number of reasons:
Many systems who currently have cups services use a different naming, which this has broken a few systems during the update from 1.7.5 where the central service was cups.service, requiring changes of any related scripts or documentation.

Secondly, the name is horrible to type, especially in non-OSX land where service names need to be typed out, only secondary services intended to be tied to other services seem to commonly use this naming scheme, not a primary install-able service file.

I'm sorry for the rant, but I don't think many will be happy with this change from the naming we use in every other service, and have used for cups in the past.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 17, 2014

CUPS.org User: mike

I'll comment here, but the bug is closed and we have no plans of changing this.

On all other platforms that support on-demand launch of cupsd and cups-lpd, we have (from day one) used org.cups.cupsd and org.cups.cups-lpd, and recommended those names for anyone implementing a new on-demand method. This was not used for the original Linux systemd support for some reason, but now that it is part of CUPS we are following this standard naming convention.

As for being "horrible to type", most users (including admins) will never need to. Unlike other services, you don't actually need to stop and start cupsd when installing new drivers, print queues, etc.

If you are updating CUPS itself you are probably updating via a package which will handle stopping, disabling, then enabling and starting each of the systemd files. If you are updating CUPS via source, then you are still faced with running 6 commands before and 6 commands after installation in order to properly update the systemd configuration (bleh!), so at that point I fail to see how saving 10 characters per command matters. (And once we add cups-lpd support (STR #4493) you'll have an additional 4 commands to run before and after.)

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator

michaelrsweet commented Oct 17, 2014

CUPS.org User: jsmeix.suse

Only FYI an addendum regarding
"running 6 commands before and 6 commands after"
and "additional 4 commands to run before and after":

I am thinking about some kind of main switch
to switch off and on "the whole CUPS thing".

See
https://bugzilla.opensuse.org/show_bug.cgi?id=864894
what I mean with "main switch".

Summary:

Assume for "the whole CUPS thing" there are those unit files
(don't care about the actual names - it is only an example here):
cupsd.service
cupsd.socket
cupsd.path
cups-lpd.socket
cups-browsed.service
cups-browsed.socket

For example to completely switch off "the whole CUPS thing"
one may have to do (depending on what is actually active):

systemctl stop cupsd.service

systemctl stop cupsd.socket

systemctl stop cupsd.path

systemctl stop cups-lpd.socket

systemctl stop cups-browsed.service

systemctl stop cups-browsed.socket

I am thinking about a "main switch" unit file e.g. named
cups.service
so that only one single command

systemctl stop cups.service

is needed for "the whole CUPS thing" (also for start/enable/disable).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment