summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2014-03-21 16:42:53 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2014-03-21 16:42:53 +0000
commit1720786e61396c74c14b561e11b22c9c045898c6 (patch)
treef65d9faacf8650c3f395e60a141cc0b579d1e5ec
parentf2b8078bd6129eb05e81a9bb07a2d7a295d5422e (diff)
downloadcups-1720786e61396c74c14b561e11b22c9c045898c6.tar.gz
Add systemd support to cupsd (STR #3282)
git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@11717 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--CHANGES.txt3
-rw-r--r--config-scripts/cups-directories.m496
-rw-r--r--config-scripts/cups-ondemand.m476
-rw-r--r--config-scripts/cups-startup.m4176
-rw-r--r--config.h.in7
-rw-r--r--configure.ac2
-rw-r--r--scheduler/Makefile40
-rw-r--r--scheduler/client.c2
-rw-r--r--scheduler/client.h5
-rw-r--r--scheduler/conf.c11
-rw-r--r--scheduler/conf.h6
-rw-r--r--scheduler/cupsd.h8
-rw-r--r--scheduler/listen.c21
-rw-r--r--scheduler/main.c746
-rw-r--r--scheduler/org.cups.cupsd.socket.in1
-rw-r--r--xcode/CUPS.xcodeproj/project.pbxproj18
16 files changed, 668 insertions, 550 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 7d9cdeeca..98730973d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -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 @@ CHANGES IN CUPS V2.0b1
- 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
diff --git a/config-scripts/cups-directories.m4 b/config-scripts/cups-directories.m4
index f4227506f..40a17038a 100644
--- a/config-scripts/cups-directories.m4
+++ b/config-scripts/cups-directories.m4
@@ -121,102 +121,6 @@ fi
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/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="")
diff --git a/config-scripts/cups-ondemand.m4 b/config-scripts/cups-ondemand.m4
deleted file mode 100644
index b1ea1a3ff..000000000
--- a/config-scripts/cups-ondemand.m4
+++ /dev/null
@@ -1,76 +0,0 @@
-dnl
-dnl "$Id$"
-dnl
-dnl Launch-on-demand 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
-dnl End of "$Id$".
-dnl
diff --git a/config-scripts/cups-startup.m4 b/config-scripts/cups-startup.m4
new file mode 100644
index 000000000..dcb13d2dd
--- /dev/null
+++ b/config-scripts/cups-startup.m4
@@ -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
diff --git a/config.h.in b/config.h.in
index 1b2df157e..f673a395b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -458,6 +458,13 @@
/*
+ * Do we have systemd support?
+ */
+
+#undef HAVE_SYSTEMD
+
+
+/*
* Various scripting languages...
*/
diff --git a/configure.ac b/configure.ac
index cf97de7ff..5ee8e8ba7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,7 +32,7 @@ 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-ondemand.m4)
+sinclude(config-scripts/cups-startup.m4)
sinclude(config-scripts/cups-defaults.m4)
sinclude(config-scripts/cups-scripting.m4)
diff --git a/scheduler/Makefile b/scheduler/Makefile
index 4d8393d63..9fb318a84 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -289,7 +289,6 @@ uninstall:
$(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
@@ -311,8 +310,8 @@ uninstall:
-$(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; \
@@ -324,23 +323,24 @@ uninstall:
$(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 \
@@ -379,16 +379,16 @@ cupsd: $(CUPSDOBJS) $(LIBCUPSMIME) ../cups/$(LIBCUPS)
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)
#
diff --git a/scheduler/client.c b/scheduler/client.c
index b7a3c798d..b6a93082e 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -2516,7 +2516,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
bytes = (ssize_t)(sizeof(con->header) - (size_t)con->header_used);
- if (!con->pipe_pid && bytes > httpGetRemaining(con->http))
+ if (!con->pipe_pid && bytes > (ssize_t)httpGetRemaining(con->http))
{
/*
* Limit GET bytes to original size of file (STR #3265)...
diff --git a/scheduler/client.h b/scheduler/client.h
index 6217eac9c..afe8d3ac3 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -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 @@ 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... */
+#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;
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 1e82b2295..97eedc768 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -85,13 +85,16 @@ static const cupsd_var_t cupsd_vars[] =
#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 @@ cupsdReadConfiguration(void)
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...
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 6b43d66c5..3cc8acb5e 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -243,10 +243,10 @@ VAR char *ServerKeychain VALUE(NULL);
/* 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);
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index d0f8fb5c4..3885305a7 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -158,10 +158,10 @@ VAR int NeedReload VALUE(RELOAD_ALL),
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 */
/*
diff --git a/scheduler/listen.c b/scheduler/listen.c
index 7ef4a3c92..6fe34c90e 100644
--- a/scheduler/listen.c
+++ b/scheduler/listen.c
@@ -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 @@ cupsdStopListening(void)
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;
}
}
diff --git a/scheduler/main.c b/scheduler/main.c
index f847e275c..555b6d6d8 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -34,6 +34,11 @@ extern int launch_activate_socket(const char *name, int **fds, size_t *cnt);
# endif /* HAVE_LAUNCH_ACTIVATE_SOCKET */
#endif /* HAVE_LAUNCH_H */
+#ifdef HAVE_SYSTEMD
+# 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 +56,16 @@ extern int launch_activate_socket(const char *name, int **fds, size_t *cnt);
* 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 +119,10 @@ main(int argc, /* I - Number of command-line args */
#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 +146,8 @@ main(int argc, /* I - Number of command-line args */
#ifdef HAVE_LAUNCHD
if (getenv("CUPSD_LAUNCHD"))
{
- Launchd = 1;
- fg = 1;
+ OnDemand = 1;
+ fg = 1;
}
#endif /* HAVE_LAUNCHD */
@@ -219,15 +224,15 @@ main(int argc, /* I - Number of command-line args */
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 +536,18 @@ main(int argc, /* I - Number of command-line args */
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 +634,15 @@ main(int argc, /* I - Number of command-line args */
* 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 +721,18 @@ main(int argc, /* I - Number of command-line args */
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 +763,23 @@ main(int argc, /* I - Number of command-line args */
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 +876,13 @@ main(int argc, /* I - Number of command-line args */
}
#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 +890,7 @@ main(int argc, /* I - Number of command-line args */
stop_scheduler = 1;
break;
}
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
/*
* Resume listening for new connections as needed...
@@ -941,8 +944,7 @@ main(int argc, /* I - Number of command-line args */
* Process pending data in the input buffer...
*/
- // TODO: Use httpGetReady()
- if (con->http->used)
+ if (httpGetReady(con->http))
{
cupsdReadClient(con);
continue;
@@ -952,13 +954,10 @@ main(int argc, /* I - Number of command-line args */
* 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 +1094,14 @@ main(int argc, /* I - Number of command-line args */
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,278 +1291,6 @@ cupsdSetStringf(char **s, /* O - New string */
}
-#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 +1565,10 @@ select_timeout(int fds) /* I - Number of descriptors returned */
* 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 +1619,12 @@ select_timeout(int fds) /* I - Number of descriptors returned */
* 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,6 +1788,357 @@ sigterm_handler(int sig) /* I - Signal number */
}
+#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(error));
+ 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 +2156,7 @@ usage(int status) /* O - Exit status */
_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."));
diff --git a/scheduler/org.cups.cupsd.socket.in b/scheduler/org.cups.cupsd.socket.in
index c705c3762..cd98aa56e 100644
--- a/scheduler/org.cups.cupsd.socket.in
+++ b/scheduler/org.cups.cupsd.socket.in
@@ -6,6 +6,7 @@ ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
ListenStream=[::1]:631
ListenStream=127.0.0.1:631
BindIPv6Only=ipv6-only
+ReusePort=true
[Install]
WantedBy=sockets.target
diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj
index 7e099b4a8..b417bd855 100644
--- a/xcode/CUPS.xcodeproj/project.pbxproj
+++ b/xcode/CUPS.xcodeproj/project.pbxproj
@@ -1359,7 +1359,7 @@
72E65BA818DC799B00097E89 /* cups-dnssd.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-dnssd.m4"; path = "../config-scripts/cups-dnssd.m4"; sourceTree = "<group>"; };
72E65BA918DC799B00097E89 /* cups-gssapi.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-gssapi.m4"; path = "../config-scripts/cups-gssapi.m4"; sourceTree = "<group>"; };
72E65BAA18DC799B00097E89 /* cups-largefile.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-largefile.m4"; path = "../config-scripts/cups-largefile.m4"; sourceTree = "<group>"; };
- 72E65BAB18DC799B00097E89 /* cups-ondemand.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-ondemand.m4"; path = "../config-scripts/cups-ondemand.m4"; sourceTree = "<group>"; };
+ 72E65BAB18DC799B00097E89 /* cups-startup.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-startup.m4"; path = "../config-scripts/cups-startup.m4"; sourceTree = "<group>"; };
72E65BAC18DC799B00097E89 /* cups-libtool.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-libtool.m4"; path = "../config-scripts/cups-libtool.m4"; sourceTree = "<group>"; };
72E65BAD18DC799B00097E89 /* cups-manpages.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-manpages.m4"; path = "../config-scripts/cups-manpages.m4"; sourceTree = "<group>"; };
72E65BAE18DC799B00097E89 /* cups-network.m4 */ = {isa = PBXFileReference; lastKnownFileType = text; name = "cups-network.m4"; path = "../config-scripts/cups-network.m4"; sourceTree = "<group>"; };
@@ -1408,6 +1408,13 @@
72E65BDA18DC852700097E89 /* api-mime.header */ = {isa = PBXFileReference; lastKnownFileType = text; name = "api-mime.header"; path = "../scheduler/api-mime.header"; sourceTree = SOURCE_ROOT; };
72E65BDB18DC852700097E89 /* api-mime.shtml */ = {isa = PBXFileReference; lastKnownFileType = text.html.other; name = "api-mime.shtml"; path = "../scheduler/api-mime.shtml"; sourceTree = SOURCE_ROOT; };
72E65BDC18DC852700097E89 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; name = Makefile; path = ../scheduler/Makefile; sourceTree = SOURCE_ROOT; };
+ 72E65BDD18DCA35700097E89 /* CHANGES-1.7.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = "CHANGES-1.7.txt"; path = "../CHANGES-1.7.txt"; sourceTree = "<group>"; };
+ 72E65BDE18DCA35700097E89 /* CHANGES.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = CHANGES.txt; path = ../CHANGES.txt; sourceTree = "<group>"; };
+ 72E65BDF18DCA35700097E89 /* CREDITS.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = CREDITS.txt; path = ../CREDITS.txt; sourceTree = "<group>"; };
+ 72E65BE018DCA35700097E89 /* INSTALL.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = INSTALL.txt; path = ../INSTALL.txt; sourceTree = "<group>"; };
+ 72E65BE118DCA35700097E89 /* IPPTOOL.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = IPPTOOL.txt; path = ../IPPTOOL.txt; sourceTree = "<group>"; };
+ 72E65BE218DCA35700097E89 /* LICENSE.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE.txt; path = ../LICENSE.txt; sourceTree = "<group>"; };
+ 72E65BE318DCA35700097E89 /* README.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.txt; path = ../README.txt; sourceTree = "<group>"; };
72F75A521336F950004BB496 /* cupstestppd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cupstestppd; sourceTree = BUILT_PRODUCTS_DIR; };
72F75A5B1336F988004BB496 /* cupstestppd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cupstestppd.c; path = ../systemv/cupstestppd.c; sourceTree = "<group>"; };
72F75A611336F9A3004BB496 /* libcupsimage.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcupsimage.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -2110,7 +2117,7 @@
72E65BA818DC799B00097E89 /* cups-dnssd.m4 */,
72E65BA918DC799B00097E89 /* cups-gssapi.m4 */,
72E65BAA18DC799B00097E89 /* cups-largefile.m4 */,
- 72E65BAB18DC799B00097E89 /* cups-ondemand.m4 */,
+ 72E65BAB18DC799B00097E89 /* cups-startup.m4 */,
72E65BAC18DC799B00097E89 /* cups-libtool.m4 */,
72E65BAD18DC799B00097E89 /* cups-manpages.m4 */,
72E65BAE18DC799B00097E89 /* cups-network.m4 */,
@@ -2128,6 +2135,13 @@
72E65BB818DC79F800097E89 /* Documentation */ = {
isa = PBXGroup;
children = (
+ 72E65BDE18DCA35700097E89 /* CHANGES.txt */,
+ 72E65BDD18DCA35700097E89 /* CHANGES-1.7.txt */,
+ 72E65BDF18DCA35700097E89 /* CREDITS.txt */,
+ 72E65BE018DCA35700097E89 /* INSTALL.txt */,
+ 72E65BE118DCA35700097E89 /* IPPTOOL.txt */,
+ 72E65BE218DCA35700097E89 /* LICENSE.txt */,
+ 72E65BE318DCA35700097E89 /* README.txt */,
72E65BB918DC7A3600097E89 /* doc */,
72E65BBA18DC7A3600097E89 /* man */,
72E65BBB18DC7A6B00097E89 /* api-array.header */,