aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-10-10 08:37:21 +0000
committerRoy Marples <roy@marples.name>2008-10-10 08:37:21 +0000
commitd6da8e8c48feb8faf9287fc86fbbf0890c37a87c (patch)
treee6cdf21f0f3a3270b705fe14b876f92b14b38dbf
parent247766695cd7c5e8d83dff72f7eb7e6578bf57b8 (diff)
sysinit is now a real runlevel that handles things like udev, dmesg and
mounting various bits in /dev and /sys. init.sh JUST mounts /lib/rc/init.d (and /proc for Linux systems) To make development of this easier we now return an empty RC_STRINGLIST instead of a NULL for empty things. If you don't have a udev init script installed, don't reboot your box OR roll back to an older OpenRC version.
-rw-r--r--conf.d/Makefile.Linux2
-rw-r--r--conf.d/dmesg3
-rw-r--r--etc/rc.conf.Linux17
-rw-r--r--etc/rc.conf.in16
-rw-r--r--init.d/Makefile.Linux4
-rw-r--r--init.d/devfs.in36
-rw-r--r--init.d/dmesg.in17
-rw-r--r--init.d/fsck.in2
-rw-r--r--init.d/procfs.in23
-rw-r--r--init.d/sysfs.in63
-rw-r--r--runlevels/Makefile9
-rw-r--r--runlevels/Makefile.Linux4
-rw-r--r--sh/init-common-post.sh.in4
-rw-r--r--sh/init.sh.Linux.in106
-rw-r--r--src/includes/rc-misc.h1
-rw-r--r--src/librc/librc-depend.c108
-rw-r--r--src/librc/librc-misc.c12
-rw-r--r--src/librc/librc.c246
-rw-r--r--src/rc/rc-depend.c27
-rw-r--r--src/rc/rc-misc.c115
-rw-r--r--src/rc/rc-service.c14
-rw-r--r--src/rc/rc.c215
-rw-r--r--src/rc/runscript.c663
23 files changed, 779 insertions, 928 deletions
diff --git a/conf.d/Makefile.Linux b/conf.d/Makefile.Linux
index 628636b0..74679400 100644
--- a/conf.d/Makefile.Linux
+++ b/conf.d/Makefile.Linux
@@ -1 +1 @@
-CONF+= consolefont hwclock keymaps modules
+CONF+= consolefont dmesg hwclock keymaps modules
diff --git a/conf.d/dmesg b/conf.d/dmesg
new file mode 100644
index 00000000..eb065f2f
--- /dev/null
+++ b/conf.d/dmesg
@@ -0,0 +1,3 @@
+# Sets the level at which logging of messages is done to the
+# console. See dmesg(8) for more info.
+dmesg_level="1"
diff --git a/etc/rc.conf.Linux b/etc/rc.conf.Linux
index d1c216f3..e1f5ef5b 100644
--- a/etc/rc.conf.Linux
+++ b/etc/rc.conf.Linux
@@ -6,20 +6,3 @@
# consolefont, numlock, etc ...)
rc_tty_number=12
-# Use this variable to control the /dev management behavior.
-# devfs - use devfs (requires sys-fs/devfsd)
-# mdev - use mdev (requires sys-apps/busybox)
-# udev - use udev (requires sys-fs/udev)
-# static - let the user manage /dev (YOU need to create ALL device nodes)
-# Leave it blank to let rc work it out (udev, mdev, devfs, static)
-#rc_devices=""
-
-# UDEV OPTION:
-# Set to "yes" if you want to save /dev to a tarball on shutdown
-# and restore it on startup. This is useful if you have a lot of
-# custom device nodes that udev does not handle/know about.
-rc_device_tarball="NO"
-
-# Sets the level at which logging of messages is done to the
-# console. See dmesg(8) for more info.
-dmesg_level="1"
diff --git a/etc/rc.conf.in b/etc/rc.conf.in
index b09fe3d0..46767337 100644
--- a/etc/rc.conf.in
+++ b/etc/rc.conf.in
@@ -27,25 +27,17 @@ rc_depend_strict="YES"
# starting/stopping of the init.d service triggered by it.
rc_hotplug="YES"
-# Dynamic /dev managers can trigger coldplug events which cause services to
-# start before we are ready for them. If this happens, we can defer these
-# services to start in the boot runlevel. Set rc_coldplug="NO" if you don't
-# want this.
-# NOTE: This also affects module coldplugging in udev-096 and higher
-# If you want module coldplugging but not coldplugging of services then you
-# can set rc_coldplug="YES" and rc_plug_services="!*"
-rc_coldplug="YES"
-
-# Some people want a finer grain over hotplug/coldplug. rc_plug_services is a
+# Some people want a finer grain over hotplug. rc_plug_services is a
# list of services that are matched in order, either allowing or not. By
-# default we allow services through as rc_coldplug/rc_hotplug has to be YES
-# anyway.
+# default we allow services through as rc_hotplug has to be YES anyway.
# Example - rc_plug_services="net.wlan !net.*"
# This allows net.wlan and any service not matching net.* to be plugged.
rc_plug_services=""
# rc_logger launches a logging daemon to log the entire rc process to
# /var/log/rc.log
+# NOTE: Linux systems require the devfs service to be started before
+# logging can take place.
rc_logger="NO"
# By default we filter the environment for our running scripts. To allow other
diff --git a/init.d/Makefile.Linux b/init.d/Makefile.Linux
index ae9e6ba4..be519c80 100644
--- a/init.d/Makefile.Linux
+++ b/init.d/Makefile.Linux
@@ -1,7 +1,7 @@
NET_LO= net.lo
-SRCS+= hwclock.in consolefont.in keymaps.in modules.in mtab.in numlock.in \
- procfs.in termencoding.in
+SRCS+= devfs.in dmesg.in hwclock.in consolefont.in keymaps.in modules.in \
+ mtab.in numlock.in procfs.in sysfs.in termencoding.in
.SUFFIXES: .Linux.in
.Linux.in:
diff --git a/init.d/devfs.in b/init.d/devfs.in
new file mode 100644
index 00000000..2e140f0a
--- /dev/null
+++ b/init.d/devfs.in
@@ -0,0 +1,36 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+description="Mount system critical filesystems in /dev."
+
+depend() {
+ use dev
+ keyword noprefix
+}
+
+start() {
+ # Mount required stuff as user may not have then in /etc/fstab
+ for x in \
+ "devpts /dev/pts 0755 ,gid=5,mode=0620 devpts" \
+ "tmpfs /dev/shm 1777 ,nodev shm" \
+ ; do
+ set -- ${x}
+ grep -Eq "[[:space:]]+$1$" /proc/filesystems || continue
+ mountinfo -q "$2" && continue
+
+ if [ ! -d "$2" ]; then
+ mkdir -m "$3" -p "$2" >/dev/null 2>&1 || \
+ ewarn "Could not create $2!"
+ fi
+
+ if [ -d "$2" ]; then
+ ebegin "Mounting $2"
+ if ! fstabinfo --mount "$2"; then
+ mount -n -t "$1" -o noexec,nosuid"$4" "$5" "$2"
+ fi
+ eend $?
+ fi
+ done
+ return 0
+}
diff --git a/init.d/dmesg.in b/init.d/dmesg.in
new file mode 100644
index 00000000..6aad0e28
--- /dev/null
+++ b/init.d/dmesg.in
@@ -0,0 +1,17 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+description="Set the dmesg level for a cleaner boot"
+
+depend()
+{
+ before dev modules
+}
+
+start()
+{
+ if [ -n "${dmesg_level}" ]; then
+ dmesg -n"${dmesg_level}"
+ fi
+}
diff --git a/init.d/fsck.in b/init.d/fsck.in
index ee2acdcc..5f7099a6 100644
--- a/init.d/fsck.in
+++ b/init.d/fsck.in
@@ -8,7 +8,7 @@ _IFS="
depend()
{
- after clock modules
+ use dev clock modules
keyword nojail noopenvz noprefix notimeout novserver
}
diff --git a/init.d/procfs.in b/init.d/procfs.in
index 410a6e3b..b6dfbb62 100644
--- a/init.d/procfs.in
+++ b/init.d/procfs.in
@@ -6,6 +6,7 @@ description="Mounts misc filesystems in /proc."
depend()
{
+ use devfs
need localmount
keyword noopenvz noprefix novserver
}
@@ -39,7 +40,7 @@ start()
# Setup Kernel Support for the NFS daemon status
if [ -d /proc/fs/nfsd ] && ! mountinfo -q /proc/fs/nfsd; then
if grep -qs nfsd /proc/filesystems; then
- ebegin "Mounting nfsd filesystem"
+ ebegin "Mounting NFS filesystem"
mount -t nfsd -o nodev,noexec,nosuid \
nfsd /proc/fs/nfsd
eend $?
@@ -56,26 +57,6 @@ start()
fi
fi
- # Setup Kernel Support for securityfs
- if [ -d /sys/kernel/security ] && ! mountinfo -q /sys/kernel/security; then
- if grep -qs securityfs /proc/filesystems; then
- ebegin "Mounting security filesystem"
- mount -t securityfs -o nodev,noexec,nosuid \
- securityfs /sys/kernel/security
- eend $?
- fi
- fi
-
- # Setup Kernel Support for debugfs
- if [ -d /sys/kernel/debug ] && ! mountinfo -q /sys/kernel/debug; then
- if grep -qs debugfs /proc/filesystems; then
- ebegin "Mounting debug filesystem"
- mount -t debugfs -o nodev,noexec,nosuid \
- debugfs /sys/kernel/debug
- eend $?
- fi
- fi
-
# Setup Kernel Support for SELinux
if [ -d /selinux ] && ! mountinfo -q /selinux; then
if grep -qs selinuxfs /proc/filesystems; then
diff --git a/init.d/sysfs.in b/init.d/sysfs.in
new file mode 100644
index 00000000..e711aee4
--- /dev/null
+++ b/init.d/sysfs.in
@@ -0,0 +1,63 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+description="Mount the sys filesystem."
+
+depend()
+{
+ keyword noprefix
+}
+
+mount_sys()
+{
+ grep -Eq "[[:space:]]+sysfs$" /proc/filesystems || return 1
+ mountinfo -q /sys && return 0
+
+ if [ ! -d /sys ]; then
+ if ! mkdir -m 0755 /sys; then
+ ewarn "Could not create /sys!"
+ return 1
+ fi
+ fi
+
+ ebegin "Mounting /sys"
+ if ! fstabinfo --mount /sys; then
+ mount -n -t sysfs -o noexec,nosuid,nodev sysfs /sys
+ fi
+ eend $?
+}
+
+mount_misc()
+{
+ # Setup Kernel Support for securityfs
+ if [ -d /sys/kernel/security ] && ! mountinfo -q /sys/kernel/security; then
+ if grep -qs securityfs /proc/filesystems; then
+ ebegin "Mounting security filesystem"
+ mount -t securityfs -o nodev,noexec,nosuid \
+ securityfs /sys/kernel/security
+ eend $?
+ fi
+ fi
+
+ # Setup Kernel Support for debugfs
+ if [ -d /sys/kernel/debug ] && ! mountinfo -q /sys/kernel/debug; then
+ if grep -qs debugfs /proc/filesystems; then
+ ebegin "Mounting debug filesystem"
+ mount -t debugfs -o nodev,noexec,nosuid \
+ debugfs /sys/kernel/debug
+ eend $?
+ fi
+ fi
+}
+
+start()
+{
+ local retval
+ mount_sys
+ retval=$?
+ if [ ${retval} -eq 0 ]; then
+ mount_misc
+ fi
+ return ${retval}
+}
diff --git a/runlevels/Makefile b/runlevels/Makefile
index 41ba12b0..9e3131a9 100644
--- a/runlevels/Makefile
+++ b/runlevels/Makefile
@@ -3,6 +3,7 @@ BOOT= bootmisc fsck hostname localmount \
DEFAULT= local netmount
LEVELDIR= ${DESTDIR}/${SYSCONFDIR}/runlevels
+SYSINITDIR= ${LEVELDIR}/sysinit
BOOTDIR= ${LEVELDIR}/boot
DEFAULTDIR= ${LEVELDIR}/default
@@ -17,6 +18,14 @@ include Makefile.${OS}
all:
install:
+ if ! test -d "${SYSINITDIR}"; then \
+ ${INSTALL} -d ${SYSINITDIR} || exit $$?; \
+ for x in ${SYSINIT}; do \
+ if test -n "${PREFIX}"; then \
+ grep -q "keyword .*noprefix" ${INITDIR}/"$$x" && continue; \
+ fi; \
+ ln -snf ${PREFIX}/etc/init.d/"$$x" ${SYSINITDIR}/"$$x" || exit $$?; done \
+ fi
if ! test -d "${BOOTDIR}"; then \
${INSTALL} -d ${BOOTDIR} || exit $$?; \
for x in ${BOOT}; do \
diff --git a/runlevels/Makefile.Linux b/runlevels/Makefile.Linux
index 31b48621..c5649b20 100644
--- a/runlevels/Makefile.Linux
+++ b/runlevels/Makefile.Linux
@@ -1,2 +1,2 @@
-BOOT+= hwclock consolefont keymaps modules mtab net.lo procfs \
- termencoding
+SYSINIT+= devfs dmesg
+BOOT+= hwclock keymaps modules mtab net.lo procfs termencoding
diff --git a/sh/init-common-post.sh.in b/sh/init-common-post.sh.in
index 93acb299..2b1641df 100644
--- a/sh/init-common-post.sh.in
+++ b/sh/init-common-post.sh.in
@@ -22,8 +22,4 @@ else
fi
echo "sysinit" > "${RC_SVCDIR}/softlevel"
-
-# sysinit is now done, so allow init scripts to run normally
-[ -e /dev/.rcsysinit ] && rm -f /dev/.rcsysinit
-
exit ${retval}
diff --git a/sh/init.sh.Linux.in b/sh/init.sh.Linux.in
index 63b263ac..6d99d49e 100644
--- a/sh/init.sh.Linux.in
+++ b/sh/init.sh.Linux.in
@@ -9,7 +9,8 @@
# tmpfs and ramfs are easy, so force one or the other.
mount_svcdir()
{
- local fs= fsopts="-o rw,noexec,nodev,nosuid" devdir="rc-svcdir" devtmp="none" x=
+ local fs= fsopts="-o rw,noexec,nodev,nosuid"
+ local devdir="rc-svcdir" devtmp="none" x=
local svcsize=${rc_svcsize:-1024}
if grep -Eq "[[:space:]]+tmpfs$" /proc/filesystems; then
@@ -56,17 +57,8 @@ mount_svcdir()
}
. /etc/init.d/functions.sh
-. "${RC_LIBDIR}"/sh/rc-functions.sh
-[ -r /etc/conf.d/rc ] && . /etc/conf.d/rc
[ -r /etc/rc.conf ] && . /etc/rc.conf
-# Set the console loglevel to 1 for a cleaner boot
-# the logger should anyhow dump the ring-0 buffer at start to the
-# logs, and that with dmesg can be used to check for problems
-if [ -n "${dmesg_level}" -a "${RC_SYS}" != "VSERVER" ]; then
- dmesg -n "${dmesg_level}"
-fi
-
# By default VServer already has /proc mounted, but OpenVZ does not!
# However, some of our users have an old proc image in /proc
# NFC how they managed that, but the end result means we have to test if
@@ -82,7 +74,6 @@ if [ -e /proc/uptime ]; then
einfo "/proc is already mounted, skipping"
mountproc=false
fi
- unset up
fi
if ${mountproc}; then
@@ -94,98 +85,5 @@ if ${mountproc}; then
fi
eend $?
fi
-unset mountproc
-
-# Re-load RC_SYS if empty now we have /proc mounted
-[ -z "${RC_SYS}" ] && export RC_SYS="$(rc --sys)"
-
-# Read off the kernel commandline to see if there's any special settings
-# especially check to see if we need to set the CDBOOT environment variable
-# Note: /proc MUST be mounted
-if [ -r /sbin/livecd-functions.sh ]; then
- . /sbin/livecd-functions.sh
- livecd_read_commandline
-fi
-
-if [ "${RC_UNAME}" != "GNU/kFreeBSD" \
- -a "${RC_SYS}" != "VSERVER" ];
-then
- if grep -Eq "[[:space:]]+sysfs$" /proc/filesystems; then
- if [ -d /sys ]; then
- if ! mountinfo --quiet /sys; then
- ebegin "Mounting /sys"
- if ! fstabinfo --mount /sys; then
- mount -n -t sysfs -o noexec,nosuid,nodev sysfs /sys
- fi
- eend $?
- fi
- else
- ewarn "No /sys to mount sysfs needed in 2.6 and later kernels!"
- fi
- fi
-fi
-
-# Default OpenVZ to static devices
-if [ "${RC_SYS}" = "OPENVZ" ]; then
- rc_devices=${rc_devices:-static}
-fi
-
-# Try to figure out how the user wants /dev handled
-if [ "${rc_devices}" = "static" \
- -o "${RC_SYS}" = "VSERVER" \
- -o "${RC_UNAME}" = "GNU/kFreeBSD" ]
-then
- ebegin "Using existing device nodes in /dev"
- eend 0
-else
- case ${rc_devices} in
- devfs) managers="devfs udev mdev";;
- udev) managers="udev devfs mdev";;
- mdev) managers="mdev udev devfs";;
- *) managers="udev devfs mdev";;
- esac
-
- for m in ${managers}; do
- # Check kernel params
- if get_bootparam "no${m}" || ! has_addon ${m}-start; then
- continue
- fi
- # Let's see if we can get this puppy rolling
- start_addon ${m} && break
-
- # Clean up
- mountinfo -q /dev && umount -n /dev
- done
-fi
-
-# Mount required stuff as user may not have then in /etc/fstab
-for x in "devpts /dev/pts 0755 ,gid=5,mode=0620 devpts" "tmpfs /dev/shm 1777 ,nodev shm"
-do
- set -- ${x}
- grep -Eq "[[:space:]]+$1$" /proc/filesystems || continue
- mountinfo -q "$2" && continue
-
- if [ ! -d "$2" ] && \
- [ "${m}" = "devfs" -o "${m}" = "udev" ]; then
- mkdir -m "$3" -p "$2" >/dev/null 2>&1 || \
- ewarn "Could not create $2!"
- fi
-
- if [ -d "$2" ]; then
- ebegin "Mounting $2"
- if ! fstabinfo --mount "$2"; then
- mount -n -t "$1" -o noexec,nosuid"$4" "$5" "$2"
- fi
- eend $?
- fi
-done
-
-# If booting off CD, we want to update inittab before setting the runlevel
-if [ -f /sbin/livecd-functions.sh -a -n "${CDBOOT}" ]; then
- ebegin "Updating inittab"
- livecd_fix_inittab
- eend $?
- telinit q &>/dev/null
-fi
. "${RC_LIBDIR}"/sh/init-common-post.sh
diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h
index 12154b95..e0cfde74 100644
--- a/src/includes/rc-misc.h
+++ b/src/includes/rc-misc.h
@@ -143,7 +143,6 @@ char *rc_conf_value(const char *var);
bool rc_conf_yesno(const char *var);
void env_filter(void);
void env_config(void);
-bool service_plugable(const char *service);
int signal_setup(int sig, void (*handler)(int));
pid_t exec_service(const char *, const char *);
diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index 20196aff..f020e6d3 100644
--- a/src/librc/librc-depend.c
+++ b/src/librc/librc-depend.c
@@ -187,12 +187,21 @@ valid_service(const char *runlevel, const char *service, const char *type)
strcmp(type, "needsme") == 0)
return true;
+ if (rc_service_in_runlevel(service, runlevel))
+ return true;
+ if (strcmp(runlevel, RC_LEVEL_SYSINIT) != 0 &&
+ strcmp(runlevel, bootlevel) != 0)
+ {
+ if (rc_service_in_runlevel(service, bootlevel))
+ return true;
+ }
+
state = rc_service_state(service);
- return ((strcmp(runlevel, bootlevel) != 0 &&
- rc_service_in_runlevel(service, bootlevel)) ||
- rc_service_in_runlevel(service, runlevel) ||
- state & RC_SERVICE_COLDPLUGGED ||
- state & RC_SERVICE_STARTED);
+ if (state & RC_SERVICE_COLDPLUGGED ||
+ state & RC_SERVICE_STARTED)
+ return true;
+
+ return false;
}
static bool
@@ -344,7 +353,7 @@ get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
static void
visit_service(const RC_DEPTREE *deptree,
const RC_STRINGLIST *types,
- RC_STRINGLIST **sorted,
+ RC_STRINGLIST *sorted,
RC_STRINGLIST *visited,
const RC_DEPINFO *depinfo,
const char *runlevel, int options)
@@ -373,9 +382,7 @@ visit_service(const RC_DEPTREE *deptree,
if (!(options & RC_DEP_TRACE) ||
strcmp(type->value, "iprovide") == 0)
{
- if (!*sorted)
- *sorted = rc_stringlist_new();
- rc_stringlist_add(*sorted, service->value);
+ rc_stringlist_add(sorted, service->value);
continue;
}
@@ -420,12 +427,10 @@ visit_service(const RC_DEPTREE *deptree,
/* We've visited everything we need, so add ourselves unless we
are also the service calling us or we are provided by something */
svcname = getenv("RC_SVCNAME");
- if (!svcname || strcmp(svcname, depinfo->service) != 0)
- if (!get_deptype(depinfo, "providedby")) {
- if (!*sorted)
- *sorted = rc_stringlist_new();
- rc_stringlist_add(*sorted, depinfo->service);
- }
+ if (!svcname || strcmp(svcname, depinfo->service) != 0) {
+ if (!get_deptype(depinfo, "providedby"))
+ rc_stringlist_add(sorted, depinfo->service);
+ }
}
RC_STRINGLIST *
@@ -437,15 +442,15 @@ rc_deptree_depend(const RC_DEPTREE *deptree,
RC_STRINGLIST *svcs;
RC_STRING *svc;
+ svcs = rc_stringlist_new();
if (!(di = get_depinfo(deptree, service)) ||
!(dt = get_deptype(di, type)))
{
errno = ENOENT;
- return NULL;
+ return svcs;
}
/* For consistency, we copy the array */
- svcs = rc_stringlist_new();
TAILQ_FOREACH(svc, dt->services, entries)
rc_stringlist_add(svcs, svc->value);
return svcs;
@@ -458,7 +463,7 @@ rc_deptree_depends(const RC_DEPTREE *deptree,
const RC_STRINGLIST *services,
const char *runlevel, int options)
{
- RC_STRINGLIST *sorted = NULL;
+ RC_STRINGLIST *sorted = rc_stringlist_new();
RC_STRINGLIST *visited = rc_stringlist_new();
RC_DEPINFO *di;
const RC_STRING *service;
@@ -472,7 +477,7 @@ rc_deptree_depends(const RC_DEPTREE *deptree,
continue;
}
if (types)
- visit_service(deptree, types, &sorted, visited,
+ visit_service(deptree, types, sorted, visited,
di, runlevel, options);
}
rc_stringlist_free(visited);
@@ -499,42 +504,25 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
{
list = rc_services_in_state(RC_SERVICE_STARTED);
list2 = rc_services_in_state(RC_SERVICE_INACTIVE);
- if (list2) {
- if (list) {
- TAILQ_CONCAT(list, list2, entries);
- free(list2);
- } else
- list = list2;
- }
+ TAILQ_CONCAT(list, list2, entries);
+ free(list2);
list2 = rc_services_in_state(RC_SERVICE_STARTING);
- if (list2) {
- if (list) {
- TAILQ_CONCAT(list, list2, entries);
- free(list2);
- } else
- list = list2;
- }
+ TAILQ_CONCAT(list, list2, entries);
+ free(list2);
} else {
- list = rc_services_in_runlevel(runlevel);
- /* Add coldplugged services */
- list2 = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
- if (list2) {
- if (list) {
+ list = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
+ if (strcmp(runlevel, RC_LEVEL_SYSINIT) != 0) {
+ list2 = rc_services_in_runlevel(runlevel);
+ TAILQ_CONCAT(list, list2, entries);
+ free(list2);
+ list2 = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
+ TAILQ_CONCAT(list, list2, entries);
+ free(list2);
+ /* If we're not the boot runlevel then add that too */
+ if (strcmp(runlevel, bootlevel) != 0) {
+ list2 = rc_services_in_runlevel(bootlevel);
TAILQ_CONCAT(list, list2, entries);
free(list2);
- } else
- list = list2;
- }
-
- /* If we're not the boot runlevel then add that too */
- if (strcmp(runlevel, bootlevel) != 0) {
- list2 = rc_services_in_runlevel (bootlevel);
- if (list2) {
- if (list) {
- TAILQ_CONCAT(list, list2, entries);
- free(list2);
- } else
- list = list2;
}
}
}
@@ -683,15 +671,13 @@ rc_deptree_update_needed(void)
/* Some init scripts dependencies change depending on config files
* outside of baselayout, like syslog-ng, so we check those too. */
config = rc_config_list(RC_DEPCONFIG);
- if (config) {
- TAILQ_FOREACH(s, config, entries) {
- if (!rc_newer_than(RC_DEPTREE_CACHE, s->value)) {
- newer = true;
- break;
- }
+ TAILQ_FOREACH(s, config, entries) {
+ if (!rc_newer_than(RC_DEPTREE_CACHE, s->value)) {
+ newer = true;
+ break;
}
- rc_stringlist_free(config);
}
+ rc_stringlist_free(config);
return newer;
}
librc_hidden_def(rc_deptree_update_needed)
@@ -907,13 +893,11 @@ rc_deptree_update(void)
deptype = get_deptype(depinfo, "ibefore");
if (!deptype)
continue;
- sorted = NULL;
+ sorted = rc_stringlist_new();
visited = rc_stringlist_new();
- visit_service(deptree, types, &sorted, visited, depinfo,
+ visit_service(deptree, types, sorted, visited, depinfo,
NULL, 0);
rc_stringlist_free(visited);
- if (!sorted)
- continue;
TAILQ_FOREACH_SAFE(s2, deptype->services, entries, s2_np) {
TAILQ_FOREACH(s3, sorted, entries) {
di = get_depinfo(deptree, s3->value);
diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c
index b6157009..749fd812 100644
--- a/src/librc/librc-misc.c
+++ b/src/librc/librc-misc.c
@@ -84,10 +84,10 @@ RC_STRINGLIST *rc_config_list(const char *file)
size_t len = 0;
char *p;
char *token;
- RC_STRINGLIST *list = NULL;
+ RC_STRINGLIST *list = rc_stringlist_new();
if (!(fp = fopen(file, "r")))
- return NULL;
+ return list;
while ((rc_getline(&buffer, &len, fp))) {
p = buffer;
@@ -104,8 +104,6 @@ RC_STRINGLIST *rc_config_list(const char *file)
if (token[strlen(token) - 1] == '\n')
token[strlen(token) - 1] = 0;
- if (!list)
- list = rc_stringlist_new();
rc_stringlist_add(list, token);
}
}
@@ -131,9 +129,6 @@ RC_STRINGLIST *rc_config_load(const char *file)
char *p;
list = rc_config_list(file);
- if (!list)
- return NULL;
-
config = rc_stringlist_new();
TAILQ_FOREACH(line, list, entries) {
/* Get entry */
@@ -203,9 +198,6 @@ char *rc_config_value(RC_STRINGLIST *list, const char *entry)
RC_STRING *line;
char *p;
- if (!list)
- return NULL;
-
TAILQ_FOREACH(line, list, entries) {
p = strchr(line->value, '=');
if (p &&
diff --git a/src/librc/librc.c b/src/librc/librc.c
index e97425ef..b625b06a 100644
--- a/src/librc/librc.c
+++ b/src/librc/librc.c
@@ -67,7 +67,8 @@ static const rc_service_state_name_t rc_service_state_names[] = {
#define LS_INITD 0x01
#define LS_DIR 0x02
-static RC_STRINGLIST *ls_dir(const char *dir, int options)
+static RC_STRINGLIST *
+ls_dir(const char *dir, int options)
{
DIR *dp;
struct dirent *d;
@@ -77,15 +78,15 @@ static RC_STRINGLIST *ls_dir(const char *dir, int options)
char file[PATH_MAX];
int r;
+ list = rc_stringlist_new();
if ((dp = opendir(dir)) == NULL)
- return NULL;
-
+ return list;
while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') {
if (options & LS_INITD) {
/* Check that our file really exists.
- * This is important as a service maybe in a runlevel, but
- * could also have been removed. */
+ * This is important as a service maybe in a
+ * runlevel, but could have been removed. */
snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name);
r = stat(file, &buf);
@@ -104,17 +105,15 @@ static RC_STRINGLIST *ls_dir(const char *dir, int options)
! S_ISDIR(buf.st_mode))
continue;
}
- if (! list)
- list = rc_stringlist_new();
rc_stringlist_add(list, d->d_name);
}
}
closedir(dp);
-
return list;
}
-static bool rm_dir(const char *pathname, bool top)
+static bool
+rm_dir(const char *pathname, bool top)
{
DIR *dp;
struct dirent *d;
@@ -127,16 +126,17 @@ static bool rm_dir(const char *pathname, bool top)
errno = 0;
while (((d = readdir(dp)) != NULL) && errno == 0) {
- if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
- snprintf(file, sizeof(file), "%s/%s", pathname, d->d_name);
-
+ if (strcmp(d->d_name, ".") != 0 &&
+ strcmp(d->d_name, "..") != 0)
+ {
+ snprintf(file, sizeof(file),
+ "%s/%s", pathname, d->d_name);
if (stat(file, &s) != 0) {
retval = false;
break;
}
-
if (S_ISDIR(s.st_mode)) {
- if (! rm_dir(file, true))
+ if (!rm_dir(file, true))
{
retval = false;
break;
@@ -151,7 +151,7 @@ static bool rm_dir(const char *pathname, bool top)
}
closedir(dp);
- if (! retval)
+ if (!retval)
return false;
if (top && rmdir(pathname) != 0)
@@ -162,7 +162,8 @@ static bool rm_dir(const char *pathname, bool top)
/* Other systems may need this at some point, but for now it's Linux only */
#ifdef __linux__
-static bool file_regex(const char *file, const char *regex)
+static bool
+file_regex(const char *file, const char *regex)
{
FILE *fp;
char *line = NULL;
@@ -171,12 +172,12 @@ static bool file_regex(const char *file, const char *regex)
bool retval = false;
int result;
- if (! (fp = fopen(file, "r")))
+ if (!(fp = fopen(file, "r")))
return false;
if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
fclose(fp);
- line = xmalloc(sizeof (char) * BUFSIZ);
+ line = xmalloc(sizeof(char) * BUFSIZ);
regerror(result, &re, line, BUFSIZ);
fprintf(stderr, "file_regex: %s", line);
free(line);
@@ -197,8 +198,8 @@ static bool file_regex(const char *file, const char *regex)
}
#endif
-
-const char *rc_sys(void)
+const char *
+rc_sys(void)
{
#ifdef PREFIX
return RC_SYS_PREFIX;
@@ -242,7 +243,8 @@ const char *rc_sys(void)
}
librc_hidden_def(rc_sys)
-static const char *rc_parse_service_state(RC_SERVICE state)
+static const char *
+rc_parse_service_state(RC_SERVICE state)
{
int i;
@@ -250,17 +252,18 @@ static const char *rc_parse_service_state(RC_SERVICE state)
if (rc_service_state_names[i].state == state)
return rc_service_state_names[i].name;
}
-
return NULL;
}
-bool rc_runlevel_starting(void)
+bool
+rc_runlevel_starting(void)
{
return exists(RC_STARTING);
}
librc_hidden_def(rc_runlevel_starting)
-bool rc_runlevel_stopping(void)
+bool
+rc_runlevel_stopping(void)
{
return exists(RC_STOPPING);
}
@@ -272,15 +275,17 @@ RC_STRINGLIST *rc_runlevel_list(void)
}
librc_hidden_def(rc_runlevel_list)
-char *rc_runlevel_get(void)
+char *
+rc_runlevel_get(void)
{
FILE *fp;
char *runlevel = NULL;
+ size_t i;
if ((fp = fopen(RC_RUNLEVEL, "r"))) {
runlevel = xmalloc(sizeof(char) * PATH_MAX);
if (fgets(runlevel, PATH_MAX, fp)) {
- int i = strlen(runlevel) - 1;
+ i = strlen(runlevel) - 1;
if (runlevel[i] == '\n')
runlevel[i] = 0;
} else
@@ -288,7 +293,7 @@ char *rc_runlevel_get(void)
fclose(fp);
}
- if (! runlevel || ! *runlevel) {
+ if (!runlevel || !*runlevel) {
free(runlevel);
runlevel = xstrdup(RC_LEVEL_SYSINIT);
}
@@ -297,11 +302,12 @@ char *rc_runlevel_get(void)
}
librc_hidden_def(rc_runlevel_get)
-bool rc_runlevel_set(const char *runlevel)
+bool
+rc_runlevel_set(const char *runlevel)
{
FILE *fp = fopen(RC_RUNLEVEL, "w");
- if (! fp)
+ if (!fp)
return false;
fprintf(fp, "%s", runlevel);
fclose(fp);
@@ -309,14 +315,14 @@ bool rc_runlevel_set(const char *runlevel)
}
librc_hidden_def(rc_runlevel_set)
-bool rc_runlevel_exists(const char *runlevel)
+bool
+rc_runlevel_exists(const char *runlevel)
{
char path[PATH_MAX];
struct stat buf;
- if (! runlevel)
+ if (!runlevel)
return false;
-
snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel);
if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))
return true;
@@ -325,14 +331,15 @@ bool rc_runlevel_exists(const char *runlevel)
librc_hidden_def(rc_runlevel_exists)
/* Resolve a service name to it's full path */
-char *rc_service_resolve(const char *service)
+char *
+rc_service_resolve(const char *service)
{
char buffer[PATH_MAX];
char file[PATH_MAX];
int r;
struct stat buf;
- if (! service)
+ if (!service)
return NULL;
if (service[0] == '/')
@@ -377,14 +384,15 @@ char *rc_service_resolve(const char *service)
}
librc_hidden_def(rc_service_resolve)
-bool rc_service_exists(const char *service)
+bool
+rc_service_exists(const char *service)
{
char *file;
bool retval = false;
int len;
struct stat buf;
- if (! service)
+ if (!service)
return false;
len = strlen(service);
@@ -395,7 +403,7 @@ bool rc_service_exists(const char *service)
service[len - 1] == 'h')
return false;
- if (! (file = rc_service_resolve(service)))
+ if (!(file = rc_service_resolve(service)))
return false;
if (stat(file, &buf) == 0 && buf.st_mode & S_IXUGO)
@@ -406,7 +414,8 @@ bool rc_service_exists(const char *service)
librc_hidden_def(rc_service_exists)
#define OPTSTR ". '%s'; echo \"${opts}\""
-RC_STRINGLIST *rc_service_extra_commands(const char *service)
+RC_STRINGLIST *
+rc_service_extra_commands(const char *service)
{
char *svc;
char *cmd = NULL;
@@ -418,10 +427,9 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve(service)))
+ if (!(svc = rc_service_resolve(service)))
return NULL;
-
l = strlen(OPTSTR) + strlen(svc) + 1;
cmd = xmalloc(sizeof(char) * l);
snprintf(cmd, l, OPTSTR, svc);
@@ -431,7 +439,7 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
rc_getline(&buffer, &len, fp);
p = buffer;
while ((token = strsep(&p, " "))) {
- if (! commands)
+ if (!commands)
commands = rc_stringlist_new();
rc_stringlist_add(commands, token);
}
@@ -444,7 +452,8 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
librc_hidden_def(rc_service_extra_commands)
#define DESCSTR ". '%s'; echo \"${description%s%s}\""
-char *rc_service_description(const char *service, const char *option)
+char *
+rc_service_description(const char *service, const char *option)
{
char *svc;
char *cmd;
@@ -453,7 +462,7 @@ char *rc_service_description(const char *service, const char *option)
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve(service)))
+ if (!(svc = rc_service_resolve(service)))
return NULL;
if (!option)
@@ -472,7 +481,8 @@ char *rc_service_description(const char *service, const char *option)
}
librc_hidden_def(rc_service_description)
-bool rc_service_in_runlevel(const char *service, const char *runlevel)
+bool
+rc_service_in_runlevel(const char *service, const char *runlevel)
{
char file[PATH_MAX];
@@ -482,7 +492,8 @@ bool rc_service_in_runlevel(const char *service, const char *runlevel)
}
librc_hidden_def(rc_service_in_runlevel)
-bool rc_service_mark(const char *service, const RC_SERVICE state)
+bool
+rc_service_mark(const char *service, const RC_SERVICE state)
{
char file[PATH_MAX];
int i = 0;
@@ -496,11 +507,10 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
RC_STRING *dir;
int serrno;
- if (! init)
+ if (!init)
return false;
base = basename_c(service);
-
if (state != RC_SERVICE_STOPPED) {
if (!exists(init)) {
free(init);
@@ -583,29 +593,26 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) {
snprintf(file, sizeof(file), RC_SVCDIR "/%s", "scheduled");
dirs = ls_dir(file, 0);
- if (dirs) {
- TAILQ_FOREACH(dir, dirs, entries) {
- snprintf(was, sizeof(was), "%s/%s/%s",
- file, dir->value, base);
- unlink(was);
-
- /* Try and remove the dir - we don't care about errors */
- snprintf(was, sizeof(was), "%s/%s",
- file, dir->value);
- serrno = errno;
- rmdir(was);
- errno = serrno;
- }
- rc_stringlist_free(dirs);
+ TAILQ_FOREACH(dir, dirs, entries) {
+ snprintf(was, sizeof(was), "%s/%s/%s",
+ file, dir->value, base);
+ unlink(was);
+
+ /* Try and remove the dir; we don't care about errors */
+ snprintf(was, sizeof(was), "%s/%s", file, dir->value);
+ serrno = errno;
+ rmdir(was);
+ errno = serrno;
}
+ rc_stringlist_free(dirs);
}
-
free(init);
return true;
}
librc_hidden_def(rc_service_mark)
-RC_SERVICE rc_service_state(const char *service)
+RC_SERVICE
+rc_service_state(const char *service)
{
int i;
int state = RC_SERVICE_STOPPED;
@@ -627,25 +634,24 @@ RC_SERVICE rc_service_state(const char *service)
if (state & RC_SERVICE_STOPPED) {
dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
- if (dirs) {
- TAILQ_FOREACH (dir, dirs, entries) {
- snprintf(file, sizeof(file),
- RC_SVCDIR "/scheduled/%s/%s",
- dir->value, service);
- if (exists(file)) {
- state |= RC_SERVICE_SCHEDULED;
- break;
- }
+ TAILQ_FOREACH (dir, dirs, entries) {
+ snprintf(file, sizeof(file),
+ RC_SVCDIR "/scheduled/%s/%s",
+ dir->value, service);
+ if (exists(file)) {
+ state |= RC_SERVICE_SCHEDULED;
+ break;
}
- rc_stringlist_free(dirs);
}
+ rc_stringlist_free(dirs);
}
return state;
}
librc_hidden_def(rc_service_state)
-char *rc_service_value_get(const char *service, const char *option)
+char *
+rc_service_value_get(const char *service, const char *option)
{
FILE *fp;
char *line = NULL;
@@ -663,8 +669,9 @@ char *rc_service_value_get(const char *service, const char *option)
}
librc_hidden_def(rc_service_value_get)
-bool rc_service_value_set(const char *service, const char *option,
- const char *value)
+bool
+rc_service_value_set(const char *service, const char *option,
+ const char *value)
{
FILE *fp;
char file[PATH_MAX];
@@ -685,8 +692,8 @@ bool rc_service_value_set(const char *service, const char *option,
librc_hidden_def(rc_service_value_set)
-bool rc_service_schedule_start(const char *service,
- const char *service_to_start)
+bool
+rc_service_schedule_start(const char *service, const char *service_to_start)
{
char file[PATH_MAX];
char *p = file;
@@ -703,32 +710,34 @@ bool rc_service_schedule_start(const char *service,
return false;
init = rc_service_resolve(service_to_start);
- snprintf(p, sizeof(file) - (p - file), "/%s", basename_c(service_to_start));
+ snprintf(p, sizeof(file) - (p - file),
+ "/%s", basename_c(service_to_start));
retval = (exists(file) || symlink(init, file) == 0);
free(init);
-
return retval;
}
librc_hidden_def(rc_service_schedule_start)
-bool rc_service_schedule_clear(const char *service)
+bool
+rc_service_schedule_clear(const char *service)
{
char dir[PATH_MAX];
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
basename_c(service));
- if (! rm_dir(dir, true) && errno == ENOENT)
+ if (!rm_dir(dir, true) && errno == ENOENT)
return true;
return false;
}
librc_hidden_def(rc_service_schedule_clear)
-RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
+RC_STRINGLIST *
+rc_services_in_runlevel(const char *runlevel)
{
char dir[PATH_MAX];
- RC_STRINGLIST *list;
+ RC_STRINGLIST *list = NULL;
- if (! runlevel) {
+ if (!runlevel) {
#ifdef RC_PKG_INITDIR
RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD);
#endif
@@ -739,36 +748,32 @@ RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
list = ls_dir(RC_INITDIR, LS_INITD);
#ifdef RC_PKG_INITDIR
- if (pkg) {
- TAILQ_CONCAT(list, pkg, entries);
- free(pkg);
- }
+ TAILQ_CONCAT(list, pkg, entries);
+ free(pkg);
#endif
#ifdef RC_LOCAL_INITDIR
- if (local) {
- TAILQ_CONCAT(list, local, entries);
- free(local);
- }
+ TAILQ_CONCAT(list, local, entries);
+ free(local);
#endif
return list;
}
/* These special levels never contain any services */
- if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 ||
- strcmp(runlevel, RC_LEVEL_SINGLE) == 0) {
- return NULL;
+ if (strcmp(runlevel, RC_LEVEL_SINGLE) != 0) {
+ snprintf(dir, sizeof(dir), RC_RUNLEVELDIR "/%s", runlevel);
+ list = ls_dir(dir, LS_INITD);
}
-
- snprintf(dir, sizeof(dir), RC_RUNLEVELDIR "/%s", runlevel);
- list = ls_dir(dir, LS_INITD);
+ if (!list)
+ list = rc_stringlist_new();
return list;
}
librc_hidden_def(rc_services_in_runlevel)
-RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
+RC_STRINGLIST *
+rc_services_in_state(RC_SERVICE state)
{
RC_STRINGLIST *services;
- RC_STRINGLIST *list = NULL;
+ RC_STRINGLIST *list;
RC_STRINGLIST *dirs;
RC_STRING *d;
char dir[PATH_MAX];
@@ -780,28 +785,26 @@ RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
if (state != RC_SERVICE_SCHEDULED)
return ls_dir(dir, LS_INITD);
-
dirs = ls_dir(dir, 0);
+ list = rc_stringlist_new();
if (! dirs)
- return NULL;
+ return list;
TAILQ_FOREACH(d, dirs, entries) {
snprintf(p, sizeof(dir) - (p - dir), "/%s", d->value);
services = ls_dir(dir, LS_INITD);
- if (! list)
- services = list;
- else if (services) {
+ if (services) {
TAILQ_CONCAT(list, services, entries);
free(services);
}
}
rc_stringlist_free(dirs);
-
return list;
}
librc_hidden_def(rc_services_in_state)
-bool rc_service_add(const char *runlevel, const char *service)
+bool
+rc_service_add(const char *runlevel, const char *service)
{
bool retval;
char *init;
@@ -811,7 +814,7 @@ bool rc_service_add(const char *runlevel, const char *service)
char binit[PATH_MAX];
char *i;
- if (! rc_runlevel_exists(runlevel)) {
+ if (!rc_runlevel_exists(runlevel)) {
errno = ENOENT;
return false;
}
@@ -827,12 +830,11 @@ bool rc_service_add(const char *runlevel, const char *service)
/* We need to ensure that only things in /etc/init.d are added
* to the boot runlevel */
- if (strcmp (runlevel, RC_LEVEL_BOOT) == 0) {
+ if (strcmp(runlevel, RC_LEVEL_BOOT) == 0) {
p = realpath(dirname(init), path);
- if (! *p) {
+ if (!*p) {
free(init);
return false;
-
}
if (strcmp(path, RC_INITDIR) != 0) {
free(init);
@@ -849,7 +851,8 @@ bool rc_service_add(const char *runlevel, const char *service)
}
librc_hidden_def(rc_service_add)
-bool rc_service_delete (const char *runlevel, const char *service)
+bool
+rc_service_delete(const char *runlevel, const char *service)
{
char file[PATH_MAX];
@@ -861,32 +864,27 @@ bool rc_service_delete (const char *runlevel, const char *service)
}
librc_hidden_def(rc_service_delete)
-RC_STRINGLIST *rc_services_scheduled_by(const char *service)
+RC_STRINGLIST *
+rc_services_scheduled_by(const char *service)
{
RC_STRINGLIST *dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
- RC_STRINGLIST *list = NULL;
+ RC_STRINGLIST *list = rc_stringlist_new();
RC_STRING *dir;
char file[PATH_MAX];
- if (! dirs)
- return NULL;
-
TAILQ_FOREACH (dir, dirs, entries) {
snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s",
dir->value, service);
- if (exists(file)) {
- if (! list)
- list = rc_stringlist_new();
+ if (exists(file))
rc_stringlist_add(list, file);
- }
}
rc_stringlist_free(dirs);
-
return list;
}
librc_hidden_def(rc_services_scheduled_by)
-RC_STRINGLIST *rc_services_scheduled(const char *service)
+RC_STRINGLIST *
+rc_services_scheduled(const char *service)
{
char dir[PATH_MAX];
diff --git a/src/rc/rc-depend.c b/src/rc/rc-depend.c
index 1166d4c6..1cd32ffd 100644
--- a/src/rc/rc-depend.c
+++ b/src/rc/rc-depend.c
@@ -48,7 +48,8 @@
extern const char *applet;
-RC_DEPTREE *_rc_deptree_load(int *regen) {
+RC_DEPTREE *
+_rc_deptree_load(int *regen) {
int fd;
int retval;
int serrno = errno;
@@ -65,12 +66,10 @@ RC_DEPTREE *_rc_deptree_load(int *regen) {
if (regen)
*regen = 1;
-
ebegin("Caching service dependencies");
retval = rc_deptree_update();
eend (retval ? 0 : -1, "Failed to update the dependency tree");
}
-
return rc_deptree_load();
}
@@ -96,7 +95,8 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int rc_depend(int argc, char **argv)
+int
+rc_depend(int argc, char **argv)
{
RC_STRINGLIST *list;
RC_STRINGLIST *types;
@@ -112,7 +112,6 @@ int rc_depend(int argc, char **argv)
char *token;
types = rc_stringlist_new();
-
while ((opt = getopt_long(argc, argv, getoptstring,
longopts, (int *) 0)) != -1)
{
@@ -145,14 +144,14 @@ int rc_depend(int argc, char **argv)
ebegin("Caching service dependencies");
update = rc_deptree_update();
eend(update ? 0 : -1, "%s: %s", applet, strerror(errno));
- if (! update)
+ if (!update)
eerrorx("Failed to update the dependency tree");
}
- if (! (deptree = _rc_deptree_load(NULL)))
+ if (!(deptree = _rc_deptree_load(NULL)))
eerrorx("failed to load deptree");
- if (! runlevel)
+ if (!runlevel)
runlevel = rc_runlevel_get();
services = rc_stringlist_new();
@@ -161,8 +160,9 @@ int rc_depend(int argc, char **argv)
rc_stringlist_add(list, argv[optind]);
errno = 0;
depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0);
- if (! depends && errno == ENOENT)
- eerror("no dependency info for service `%s'", argv[optind]);
+ if (!depends && errno == ENOENT)
+ eerror("no dependency info for service `%s'",
+ argv[optind]);
else
rc_stringlist_add(services, argv[optind]);
@@ -170,7 +170,7 @@ int rc_depend(int argc, char **argv)
rc_stringlist_free(list);
optind++;
}
- if (! TAILQ_FIRST(services)) {
+ if (!TAILQ_FIRST(services)) {
rc_stringlist_free(services);
rc_stringlist_free(types);
rc_deptree_free(deptree);
@@ -181,12 +181,13 @@ int rc_depend(int argc, char **argv)
}
/* If we don't have any types, then supply some defaults */
- if (! TAILQ_FIRST(types)) {
+ if (!TAILQ_FIRST(types)) {
rc_stringlist_add(types, "ineed");
rc_stringlist_add(types, "iuse");
}
- depends = rc_deptree_depends(deptree, types, services, runlevel, options);
+ depends = rc_deptree_depends(deptree, types, services,
+ runlevel, options);
if (TAILQ_FIRST(depends)) {
TAILQ_FOREACH(s, depends, entries) {
diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c
index 27846382..58af1418 100644
--- a/src/rc/rc-misc.c
+++ b/src/rc/rc-misc.c
@@ -62,13 +62,15 @@ static RC_STRINGLIST *rc_conf = NULL;
extern char** environ;
#ifdef DEBUG_MEMORY
-static void _free_rc_conf(void)
+static void
+_free_rc_conf(void)
{
rc_stringlist_free(rc_conf);
}
#endif
-char *rc_conf_value(const char *setting)
+char *
+rc_conf_value(const char *setting)
{
RC_STRINGLIST *old;
RC_STRING *s;
@@ -83,31 +85,28 @@ char *rc_conf_value(const char *setting)
/* Support old configs */
if (exists(RC_CONF_OLD)) {
old = rc_config_load(RC_CONF_OLD);
- if (old) {
- if (rc_conf) {
- TAILQ_CONCAT(rc_conf, old, entries);
- free(old);
- } else
- rc_conf = old;
- }
+ TAILQ_CONCAT(rc_conf, old, entries);
+#ifdef DEBUG_MEMORY
+ free(old);
+#endif
}
/* Convert old uppercase to lowercase */
- if (rc_conf)
- TAILQ_FOREACH(s, rc_conf, entries) {
- p = s->value;
- while (p && *p && *p != '=') {
- if (isupper((unsigned char)*p))
- *p = tolower((unsigned char)*p);
- p++;
- }
+ TAILQ_FOREACH(s, rc_conf, entries) {
+ p = s->value;
+ while (p && *p && *p != '=') {
+ if (isupper((unsigned char)*p))
+ *p = tolower((unsigned char)*p);
+ p++;
}
+ }
}
return rc_config_value(rc_conf, setting);
}
-bool rc_conf_yesno(const char *setting)
+bool
+rc_conf_yesno(const char *setting)
{
return rc_yesno(rc_conf_value (setting));
}
@@ -122,10 +121,11 @@ static const char *const env_whitelist[] = {
NULL
};
-void env_filter(void)
+void
+env_filter(void)
{
RC_STRINGLIST *env_allow;
- RC_STRINGLIST *profile = NULL;
+ RC_STRINGLIST *profile;
RC_STRINGLIST *env_list;
RC_STRING *env;
char *e;
@@ -133,8 +133,7 @@ void env_filter(void)
/* Add the user defined list of vars */
env_allow = rc_stringlist_split(rc_conf_value("rc_env_allow"), " ");
- if (exists(PROFILE_ENV))
- profile = rc_config_load(PROFILE_ENV);
+ profile = rc_config_load(PROFILE_ENV);
/* Copy the env and work from this so we can manipulate it safely */
env_list = rc_stringlist_new();
@@ -163,21 +162,22 @@ void env_filter(void)
}
/* Now add anything missing from the profile */
- if (profile) {
- TAILQ_FOREACH(env, profile, entries) {
- e = strchr(env->value, '=');
- *e = '\0';
- if (!getenv(env->value))
- setenv(env->value, e + 1, 1);
- }
+ TAILQ_FOREACH(env, profile, entries) {
+ e = strchr(env->value, '=');
+ *e = '\0';
+ if (!getenv(env->value))
+ setenv(env->value, e + 1, 1);
}
-
+
+#ifdef DEBUG_MEMORY
rc_stringlist_free(env_list);
rc_stringlist_free(env_allow);
rc_stringlist_free(profile);
+#endif
}
-void env_config(void)
+void
+env_config(void)
{
size_t pplen = strlen(PATH_PREFIX);
char *path;
@@ -203,7 +203,8 @@ void env_config(void)
e = p = xmalloc(sizeof(char) * l);
p += snprintf(p, l, "%s", PATH_PREFIX);
- /* Now go through the env var and only add bits not in our PREFIX */
+ /* Now go through the env var and only add bits not in our
+ * PREFIX */
while ((token = strsep(&path, ":"))) {
np = npp = xstrdup(PATH_PREFIX);
while ((tok = strsep(&npp, ":")))
@@ -259,48 +260,8 @@ void env_config(void)
setenv("EINFO_COLOR", "NO", 1);
}
-bool service_plugable(const char *service)
-{
- char *list;
- char *p;
- char *star;
- char *token;
- bool allow = true;
- char *match = rc_conf_value("rc_plug_services");
- bool truefalse;
-
- if (! match)
- return true;
-
- list = xstrdup(match);
- p = list;
- while ((token = strsep(&p, " "))) {
- if (token[0] == '!') {
- truefalse = false;
- token++;
- } else
- truefalse = true;
-
- star = strchr(token, '*');
- if (star) {
- if (strncmp(service, token, (size_t)(star - token)) == 0)
- {
- allow = truefalse;
- break;
- }
- } else {
- if (strcmp(service, token) == 0) {
- allow = truefalse;
- break;
- }
- }
- }
-
- free(list);
- return allow;
-}
-
-int signal_setup(int sig, void (*handler)(int))
+int
+signal_setup(int sig, void (*handler)(int))
{
struct sigaction sa;
@@ -310,7 +271,8 @@ int signal_setup(int sig, void (*handler)(int))
return sigaction(sig, &sa, NULL);
}
-pid_t exec_service(const char *service, const char *arg)
+pid_t
+exec_service(const char *service, const char *arg)
{
char *file;
char fifo[PATH_MAX];
@@ -320,7 +282,7 @@ pid_t exec_service(const char *service, const char *arg)
struct sigaction sa;
file = rc_service_resolve(service);
- if (! exists(file)) {
+ if (!exists(file)) {
rc_service_mark(service, RC_SERVICE_STOPPED);
free(file);
return 0;
@@ -368,7 +330,6 @@ pid_t exec_service(const char *service, const char *arg)
sigprocmask(SIG_SETMASK, &old, NULL);
free(file);
-
return pid;
}
diff --git a/src/rc/rc-service.c b/src/rc/rc-service.c
index 11b6b58f..ab3d47b2 100644
--- a/src/rc/rc-service.c
+++ b/src/rc/rc-service.c
@@ -58,7 +58,8 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int rc_service(int argc, char **argv)
+int
+rc_service(int argc, char **argv)
{
int opt;
char *service;
@@ -75,17 +76,21 @@ int rc_service(int argc, char **argv)
case 'e':
service = rc_service_resolve(optarg);
opt = service ? EXIT_SUCCESS : EXIT_FAILURE;
+#ifdef DEBUG_MEMORY
free(service);
+#endif
return opt;
/* NOTREACHED */
case 'l':
list = rc_services_in_runlevel(NULL);
- if (! list)
+ if (!TAILQ_FIRST(list))
return EXIT_FAILURE;
rc_stringlist_sort(&list);
TAILQ_FOREACH(s, list, entries)
printf("%s\n", s->value);
+#ifdef DEBUG_MEMORY
rc_stringlist_free(list);
+#endif
return EXIT_SUCCESS;
/* NOTREACHED */
case 'r':
@@ -93,7 +98,9 @@ int rc_service(int argc, char **argv)
if (!service)
return EXIT_FAILURE;
printf("%s\n", service);
+#ifdef DEBUG_MEMORY
free(service);
+#endif
return EXIT_SUCCESS;
/* NOTREACHED */
@@ -103,13 +110,10 @@ int rc_service(int argc, char **argv)
argc -= optind;
argv += optind;
-
if (!*argv)
eerrorx("%s: you need to specify a service", applet);
-
if (!(service = rc_service_resolve(*argv)))
eerrorx("%s: service `%s' does not exist", applet, *argv);
-
*argv = service;
execv(*argv, argv);
eerrorx("%s: %s", applet, strerror(errno));
diff --git a/src/rc/rc.c b/src/rc/rc.c
index 4fee7002..cb4045f0 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -43,12 +43,6 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <sys/utsname.h>
#include <sys/wait.h>
-/* So we can coldplug net devices */
-#ifdef BSD
-# include <sys/socket.h>
-# include <ifaddrs.h>
-#endif
-
#ifdef __linux__
# include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#endif
@@ -519,115 +513,10 @@ static void handle_signal(int sig)
errno = serrno;
}
-static void do_coldplug(void)
-{
- size_t l;
- DIR *dp;
- struct dirent *d;
- char *service;
- RC_STRING *s;
-#ifdef BSD
- struct ifaddrs *ifap;
- struct ifaddrs *ifa;
- char *p;
-#endif
-
- errno = 0;
- if (!rc_conf_yesno("rc_coldplug") && errno != ENOENT)
- return;
-
- /* We need to ensure our state dirs exist.
- * We should have a better call than this, but oh well. */
- rc_deptree_update_needed();
-
-#ifdef BSD
- if (getifaddrs(&ifap) == 0) {
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr->sa_family != AF_LINK)
- continue;
-
- l = strlen("net.") + strlen(ifa->ifa_name) + 1;
- service = xmalloc(sizeof (char) * l);
- snprintf(service, l, "net.%s", ifa->ifa_name);
- if (rc_service_exists(service) &&
- service_plugable(service))
- rc_service_mark(service, RC_SERVICE_COLDPLUGGED);
- free(service);
- }
- freeifaddrs (ifap);
- }
-
- /* The mice are a little more tricky.
- * If we coldplug anything else, we'll probably do it here. */
- if ((dp = opendir("/dev"))) {
- while ((d = readdir(dp))) {
- if (strncmp(d->d_name, "psm", 3) == 0 ||
- strncmp(d->d_name, "ums", 3) == 0)
- {
- p = d->d_name + 3;
- if (p && isdigit((unsigned char)*p)) {
- l = strlen("moused.") + strlen(d->d_name) + 1;
- service = xmalloc(sizeof(char) * l);
- snprintf (service, l, "moused.%s", d->d_name);
- if (rc_service_exists (service) &&
- service_plugable (service))
- rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
- free(service);
- }
- }
- }
- closedir (dp);
- }
-
-#else
-
- /* udev likes to start services before we're ready when it does
- * its coldplugging thing. runscript knows when we're not ready so it
- * stores a list of coldplugged services in DEVBOOT for us to pick up
- * here when we are ready for them */
- if ((dp = opendir(DEVBOOT))) {
- while ((d = readdir(dp))) {
- if (d->d_name[0] == '.' &&
- (d->d_name[1] == '\0' ||
- (d->d_name[1] == '.' && d->d_name[2] == '\0')))
- continue;
-
- if (rc_service_exists(d->d_name) &&
- service_plugable(d->d_name))
- rc_service_mark(d->d_name, RC_SERVICE_COLDPLUGGED);
-
- l = strlen(DEVBOOT "/") + strlen(d->d_name) + 1;
- service = xmalloc(sizeof (char) * l);
- snprintf(service, l, DEVBOOT "/%s", d->d_name);
- if (unlink(service))
- eerror("%s: unlink `%s': %s", applet, service,
- strerror(errno));
- free(service);
- }
- closedir(dp);
- rmdir(DEVBOOT);
- }
-#endif
-
- if (rc_yesno(getenv("EINFO_QUIET")))
- return;
-
- /* Load our list of coldplugged services and display them */
- einfon("Device initiated services:%s", ecolor(ECOLOR_HILITE));
- coldplugged_services = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
- if (coldplugged_services)
- TAILQ_FOREACH(s, coldplugged_services, entries)
- printf(" %s", s->value);
- printf("%s\n", ecolor(ECOLOR_NORMAL));
-}
-
static void do_newlevel(const char *newlevel)
{
struct utsname uts;
const char *sys;
-#ifdef __linux__
- char *cmd;
-#endif
if (strcmp(newlevel, RC_LEVEL_SYSINIT) == 0
#ifndef PREFIX
@@ -669,39 +558,13 @@ static void do_newlevel(const char *newlevel)
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
setenv("RC_RUNLEVEL", newlevel, 1);
- rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel);
- hook_out = RC_HOOK_RUNLEVEL_START_OUT;
run_program(INITSH);
-
-#ifdef __linux__
- /* If we requested a runlevel, save it now */
- if ((cmd = proc_getent("rc_runlevel"))) {
- set_krunlevel(cmd);
- free(cmd);
- } else if ((cmd = proc_getent("softlevel"))) {
- set_krunlevel(cmd);
- free(cmd);
- } else
- set_krunlevel(NULL);
-#endif
-
- /* Setup our coldplugged services now */
- do_coldplug();
-
- rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, newlevel);
- hook_out = 0;
-
- if (want_interactive())
- mark_interactive();
-
- exit(EXIT_SUCCESS);
} else if (strcmp(newlevel, RC_LEVEL_SINGLE) == 0) {
#ifndef PREFIX
if (! RUNLEVEL ||
(strcmp(RUNLEVEL, "S") != 0 &&
strcmp(RUNLEVEL, "1") != 0))
{
- /* Remember the current runlevel for when we come back */
set_krunlevel(runlevel);
single_user();
}
@@ -883,7 +746,12 @@ interactive_option:
if (! parallel) {
rc_waitpid(pid);
remove_pid(pid);
+ /* Attempt to open the logger as a service may
+ * mount the needed /dev/pts for this to work */
+ if (rc_logger_tty == -1)
+ rc_logger_open(runlevel);
}
+
}
}
@@ -1076,7 +944,8 @@ int main(int argc, char **argv)
{
/* Try not to join boot and krunlevels together */
if (! newlevel ||
- strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0)
+ (strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0 &&
+ strcmp(newlevel, RC_LEVEL_SYSINIT) != 0))
if (get_krunlevel(krunlevel, sizeof(krunlevel)))
newlevel = krunlevel;
} else if (! RUNLEVEL ||
@@ -1135,21 +1004,11 @@ int main(int argc, char **argv)
* correct order for stopping them */
stop_services = rc_services_in_state(RC_SERVICE_STARTED);
tmplist = rc_services_in_state(RC_SERVICE_INACTIVE);
- if (tmplist) {
- if (stop_services) {
- TAILQ_CONCAT(stop_services, tmplist, entries);
- free(tmplist);
- } else
- stop_services = tmplist;
- }
+ TAILQ_CONCAT(stop_services, tmplist, entries);
+ free(tmplist);
tmplist = rc_services_in_state(RC_SERVICE_STARTING);
- if (tmplist) {
- if (stop_services) {
- TAILQ_CONCAT(stop_services, tmplist, entries);
- free(tmplist);
- } else
- stop_services = tmplist;
- }
+ TAILQ_CONCAT(stop_services, tmplist, entries);
+ free(tmplist);
if (stop_services)
rc_stringlist_sort(&stop_services);
@@ -1171,24 +1030,30 @@ int main(int argc, char **argv)
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
{
- /* We need to include the boot runlevel services if we're not in it */
- start_services = rc_services_in_runlevel(bootlevel);
- if (strcmp (newlevel ? newlevel : runlevel, bootlevel) != 0) {
- tmplist = rc_services_in_runlevel(newlevel ? newlevel : runlevel);
- if (tmplist) {
- if (start_services) {
- TAILQ_CONCAT(start_services, tmplist, entries);
- free(tmplist);
- } else
- start_services = tmplist;
+ start_services = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
+ if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SYSINIT)
+ != 0)
+ {
+ /* We need to include the boot runlevel services */
+ tmplist = rc_services_in_runlevel(bootlevel);
+ TAILQ_CONCAT(start_services, tmplist, entries);
+ free(tmplist);
+ if (strcmp (newlevel ? newlevel : runlevel, bootlevel)
+ != 0)
+ {
+ tmplist = rc_services_in_runlevel(newlevel ?
+ newlevel :
+ runlevel);
+ TAILQ_CONCAT(start_services, tmplist, entries);
+ free(tmplist);
}
- }
- if (coldplugged_services) {
- if (!start_services)
- start_services = rc_stringlist_new();
- TAILQ_FOREACH(service, coldplugged_services, entries)
- rc_stringlist_addu(start_services, service->value);
+ if (coldplugged_services) {
+ if (!start_services)
+ start_services = rc_stringlist_new();
+ TAILQ_FOREACH(service, coldplugged_services, entries)
+ rc_stringlist_addu(start_services, service->value);
+ }
}
}
@@ -1265,14 +1130,15 @@ int main(int argc, char **argv)
if (start_services) {
do_start_services(parallel);
+ /* FIXME: If we skip the boot runlevel and go straight
+ * to default from sysinit, we should now re-evaluate our
+ * start services + coldplugged services and call
+ * do_start_services a second time. */
/* Wait for our services to finish */
wait_for_services();
}
- rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, runlevel);
- hook_out = 0;
-
#ifdef __linux__
/* mark any services skipped as stopped */
if (PREVLEVEL && strcmp(PREVLEVEL, "N") == 0) {
@@ -1285,12 +1151,15 @@ int main(int argc, char **argv)
}
#endif
+ rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, runlevel);
+ hook_out = 0;
+
/* If we're in the boot runlevel and we regenerated our dependencies
* we need to delete them so that they are regenerated again in the
- * default runlevel as they may depend on things that are now available */
+ * default runlevel as they may depend on things that are now
+ * available */
if (regen && strcmp(runlevel, bootlevel) == 0)
unlink(RC_DEPTREE_CACHE);
return EXIT_SUCCESS;
}
-
diff --git a/src/rc/runscript.c b/src/rc/runscript.c
index e263a4f4..d0425ab7 100644
--- a/src/rc/runscript.c
+++ b/src/rc/runscript.c
@@ -108,9 +108,8 @@ static RC_STRINGLIST *types_mua = NULL;
static void (*selinux_run_init_old)(void);
static void (*selinux_run_init_new)(int argc, char **argv);
-static void setup_selinux(int argc, char **argv);
-
-static void setup_selinux(int argc, char **argv)
+static void
+setup_selinux(int argc, char **argv)
{
void *lib_handle = NULL;
@@ -141,7 +140,8 @@ static void setup_selinux(int argc, char **argv)
}
#endif
-static void handle_signal(int sig)
+static void
+handle_signal(int sig)
{
int serrno = errno;
char signame[10] = { '\0' };
@@ -155,7 +155,8 @@ static void handle_signal(int sig)
case SIGCHLD:
if (signal_pipe[1] > -1) {
if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
- eerror("%s: send: %s", service, strerror(errno));
+ eerror("%s: send: %s",
+ service, strerror(errno));
} else
rc_waitpid(-1);
break;
@@ -168,15 +169,15 @@ static void handle_signal(int sig)
break;
case SIGINT:
- if (! signame[0])
+ if (!signame[0])
snprintf(signame, sizeof(signame), "SIGINT");
/* FALLTHROUGH */
case SIGTERM:
- if (! signame[0])
+ if (!signame[0])
snprintf(signame, sizeof(signame), "SIGTERM");
/* FALLTHROUGH */
case SIGQUIT:
- if (! signame[0])
+ if (!signame[0])
snprintf(signame, sizeof(signame), "SIGQUIT");
/* Send the signal to our children too */
if (service_pid > 0)
@@ -192,18 +193,17 @@ static void handle_signal(int sig)
errno = serrno;
}
-static time_t get_mtime(const char *pathname, bool follow_link)
+static time_t
+get_mtime(const char *pathname, bool follow_link)
{
struct stat buf;
int retval;
- if (! pathname)
+ if (!pathname)
return 0;
-
retval = follow_link ? stat(pathname, &buf) : lstat(pathname, &buf);
- if (! retval)
+ if (!retval)
return buf.st_mtime;
-
errno = 0;
return 0;
}
@@ -211,7 +211,8 @@ static time_t get_mtime(const char *pathname, bool follow_link)
static const char *const tests[] = {
"starting", "started", "stopping", "inactive", "wasinactive", NULL
};
-static bool in_control()
+static bool
+in_control()
{
char file[PATH_MAX];
time_t m;
@@ -221,17 +222,18 @@ static bool in_control()
if (sighup)
return false;
- if (! *mtime_test || ! exists(mtime_test))
+ if (!*mtime_test || !exists(mtime_test))
return false;
if (rc_service_state(applet) & RC_SERVICE_STOPPED)
return false;
- if (! (mtime = get_mtime(mtime_test, false)))
+ if (!(mtime = get_mtime(mtime_test, false)))
return false;
while (tests[i]) {
- snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s", tests[i], applet);
+ snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
+ tests[i], applet);
if (exists(file)) {
m = get_mtime(file, false);
if (mtime < m && m != 0)
@@ -243,7 +245,8 @@ static bool in_control()
return true;
}
-static void uncoldplug()
+static void
+uncoldplug()
{
char file[PATH_MAX];
@@ -252,11 +255,13 @@ static void uncoldplug()
eerror("%s: unlink `%s': %s", applet, file, strerror(errno));
}
-static void start_services(RC_STRINGLIST *list) {
+static void
+start_services(RC_STRINGLIST *list)
+{
RC_STRING *svc;
RC_SERVICE state = rc_service_state (service);
- if (! list)
+ if (!list)
return;
if (state & RC_SERVICE_INACTIVE ||
@@ -265,28 +270,30 @@ static void start_services(RC_STRINGLIST *list) {
state & RC_SERVICE_STARTED)
{
TAILQ_FOREACH(svc, list, entries) {
- if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) {
- if (state & RC_SERVICE_INACTIVE ||
- state & RC_SERVICE_WASINACTIVE)
- {
- rc_service_schedule_start(service, svc->value);
- ewarn("WARNING: %s is scheduled to started"
- " when %s has started",
- svc->value, applet);
- } else
- service_start(svc->value);
- }
+ if (!(rc_service_state(svc->value) &
+ RC_SERVICE_STOPPED))
+ continue;
+ if (state & RC_SERVICE_INACTIVE ||
+ state & RC_SERVICE_WASINACTIVE)
+ {
+ rc_service_schedule_start(service,
+ svc->value);
+ ewarn("WARNING: %s is scheduled to started"
+ " when %s has started",
+ svc->value, applet);
+ } else
+ service_start(svc->value);
}
}
}
-static void restore_state(void)
+static void
+restore_state(void)
{
RC_SERVICE state;
- if (rc_in_plugin || ! in_control())
+ if (rc_in_plugin || !in_control())
return;
-
state = rc_service_state(applet);
if (state & RC_SERVICE_STOPPING) {
if (state & RC_SERVICE_WASINACTIVE)
@@ -310,17 +317,20 @@ static void restore_state(void)
}
}
-static void cleanup(void)
+static void
+cleanup(void)
{
restore_state();
- if (! rc_in_plugin) {
+ if (!rc_in_plugin) {
if (hook_out) {
rc_plugin_run(hook_out, applet);
if (hook_out == RC_HOOK_SERVICE_START_DONE)
- rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_OUT,
+ applet);
else if (hook_out == RC_HOOK_SERVICE_STOP_DONE)
- rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT,
+ applet);
}
if (restart_services)
@@ -353,7 +363,9 @@ static void cleanup(void)
unlink(mtime_test);
}
-static int write_prefix(const char *buffer, size_t bytes, bool *prefixed) {
+static int
+write_prefix(const char *buffer, size_t bytes, bool *prefixed)
+{
unsigned int i;
const char *ec = ecolor(ECOLOR_HILITE);
const char *ec_normal = ecolor(ECOLOR_NORMAL);
@@ -374,7 +386,7 @@ static int write_prefix(const char *buffer, size_t bytes, bool *prefixed) {
if (buffer[i] == '\033')
*prefixed = true;
- if (! *prefixed) {
+ if (!*prefixed) {
ret += write(fd, ec, strlen(ec));
ret += write(fd, prefix, strlen(prefix));
ret += write(fd, ec_normal, strlen(ec_normal));
@@ -389,11 +401,11 @@ static int write_prefix(const char *buffer, size_t bytes, bool *prefixed) {
/* Release the lock */
close(lock_fd);
-
return ret;
}
-static bool svc_exec(const char *arg1, const char *arg2)
+static bool
+svc_exec(const char *arg1, const char *arg2)
{
bool execok;
int fdout = fileno(stdout);
@@ -430,7 +442,6 @@ static bool svc_exec(const char *arg1, const char *arg2)
/* If the below call fails due to not enough ptys then we don't
* prefix the output, but we still work */
openpty(&master_tty, &slave_tty, NULL, &tt, &ws);
-
if (master_tty >= 0 &&
(flags = fcntl(master_tty, F_GETFD, 0)) == 0)
fcntl(master_tty, F_SETFD, flags | FD_CLOEXEC);
@@ -450,13 +461,15 @@ static bool svc_exec(const char *arg1, const char *arg2)
}
if (exists(RC_SVCDIR "/runscript.sh")) {
- execl(RC_SVCDIR "/runscript.sh", RC_SVCDIR "/runscript.sh",
+ execl(RC_SVCDIR "/runscript.sh",
+ RC_SVCDIR "/runscript.sh",
service, arg1, arg2, (char *) NULL);
eerror("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
service, strerror(errno));
_exit(EXIT_FAILURE);
} else {
- execl(RC_LIBDIR "/sh/runscript.sh", RC_LIBDIR "/sh/runscript.sh",
+ execl(RC_LIBDIR "/sh/runscript.sh",
+ RC_LIBDIR "/sh/runscript.sh",
service, arg1, arg2, (char *) NULL);
eerror("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
service, strerror(errno));
@@ -474,7 +487,8 @@ static bool svc_exec(const char *arg1, const char *arg2)
if ((s = select(selfd, &rset, NULL, NULL, NULL)) == -1) {
if (errno != EINTR) {
- eerror("%s: select: %s", service, strerror(errno));
+ eerror("%s: select: %s", service,
+ strerror(errno));
break;
}
}
@@ -509,7 +523,8 @@ static bool svc_exec(const char *arg1, const char *arg2)
return execok;
}
-static bool svc_wait(const char *svc)
+static bool
+svc_wait(const char *svc)
{
char fifo[PATH_MAX];
struct timespec ts;
@@ -525,12 +540,13 @@ static bool svc_wait(const char *svc)
forever = true;
rc_stringlist_free(keywords);
- snprintf(fifo, sizeof(fifo), RC_SVCDIR "/exclusive/%s", basename_c(svc));
+ snprintf(fifo, sizeof(fifo), RC_SVCDIR "/exclusive/%s",
+ basename_c(svc));
ts.tv_sec = 0;
ts.tv_nsec = WAIT_INTERVAL;
while (nloops) {
- if (! exists(fifo)) {
+ if (!exists(fifo)) {
retval = true;
break;
}
@@ -540,7 +556,7 @@ static bool svc_wait(const char *svc)
break;
}
- if (! forever)
+ if (!forever)
nloops --;
if (--sloops == 0) {
@@ -549,12 +565,13 @@ static bool svc_wait(const char *svc)
}
}
- if (! exists(fifo))
+ if (!exists(fifo))
retval = true;
return retval;
}
-static RC_SERVICE svc_status(void)
+static RC_SERVICE
+svc_status(void)
{
char status[10];
int (*e) (const char *fmt, ...) EINFO_PRINTF(1, 2) = einfo;
@@ -586,19 +603,21 @@ static RC_SERVICE svc_status(void)
return state;
}
-static void make_exclusive(void)
+static void
+make_exclusive(void)
{
/* We create a fifo so that other services can wait until we complete */
- if (! *exclusive)
- snprintf(exclusive, sizeof(exclusive), RC_SVCDIR "/exclusive/%s",
- applet);
+ if (!*exclusive)
+ snprintf(exclusive, sizeof(exclusive),
+ RC_SVCDIR "/exclusive/%s", applet);
if (mkfifo(exclusive, 0600) != 0 && errno != EEXIST &&
(errno != EACCES || geteuid () == 0))
eerrorx ("%s: unable to create fifo `%s': %s",
applet, exclusive, strerror(errno));
- snprintf(mtime_test, sizeof(mtime_test), RC_SVCDIR "/exclusive/%s.%d", applet, getpid());
+ snprintf(mtime_test, sizeof(mtime_test),
+ RC_SVCDIR "/exclusive/%s.%d", applet, getpid());
if (exists(mtime_test) && unlink(mtime_test) != 0) {
eerror("%s: unlink `%s': %s",
@@ -614,28 +633,28 @@ static void make_exclusive(void)
}
}
-static void unlink_mtime_test(void)
+static void
+unlink_mtime_test(void)
{
if (unlink(mtime_test) != 0)
- eerror("%s: unlink `%s': %s", applet, mtime_test, strerror(errno));
+ eerror("%s: unlink `%s': %s",
+ applet, mtime_test, strerror(errno));
*mtime_test = '\0';
}
-static void get_started_services(void)
+static void
+get_started_services(void)
{
RC_STRINGLIST *tmp = rc_services_in_state(RC_SERVICE_INACTIVE);
+
rc_stringlist_free(restart_services);
restart_services = rc_services_in_state(RC_SERVICE_STARTED);
- if (tmp) {
- if (restart_services) {
- TAILQ_CONCAT(restart_services, tmp, entries);
- free(tmp);
- } else
- restart_services = tmp;
- }
+ TAILQ_CONCAT(restart_services, tmp, entries);
+ free(tmp);
}
-static void setup_types(void)
+static void
+setup_types(void)
{
types_b = rc_stringlist_new();
rc_stringlist_add(types_b, "broken");
@@ -661,7 +680,8 @@ static void setup_types(void)
rc_stringlist_add(types_mua, "beforeme");
}
-static void svc_start(bool deps)
+static void
+svc_start(bool deps)
{
bool started;
bool background = false;
@@ -682,6 +702,10 @@ static void svc_start(bool deps)
! state & RC_SERVICE_STOPPED)
exit(EXIT_FAILURE);
background = true;
+ rc_service_mark(service, RC_SERVICE_COLDPLUGGED);
+ if (rc_runlevel_starting())
+ ewarnx("WARNING: %s will be started when the runlevel"
+ " has finished.", applet);
}
if (state & RC_SERVICE_STARTED) {
@@ -692,16 +716,16 @@ static void svc_start(bool deps)
else if (state & RC_SERVICE_STOPPING)
ewarnx("WARNING: %s is stopping", applet);
else if (state & RC_SERVICE_INACTIVE && ! background)
- ewarnx("WARNING: %s has already started, but is inactive", applet);
+ ewarnx("WARNING: %s has already started, but is inactive",
+ applet);
- if (! rc_service_mark(service, RC_SERVICE_STARTING)) {
+ if (!rc_service_mark(service, RC_SERVICE_STARTING)) {
if (errno == EACCES)
eerrorx("%s: superuser access required", applet);
eerrorx("ERROR: %s has been started by something else", applet);
}
make_exclusive();
-
hook_out = RC_HOOK_SERVICE_START_OUT;
rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet);
@@ -710,15 +734,14 @@ static void svc_start(bool deps)
depoptions |= RC_DEP_STRICT;
if (deps) {
- if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
+ if (!deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
eerrorx("failed to load deptree");
-
- if (! types_b)
+ if (!types_b)
setup_types();
services = rc_deptree_depends(deptree, types_b, applet_list,
runlevel, 0);
- if (services && TAILQ_FIRST(services)) {
+ if (TAILQ_FIRST(services)) {
eerrorn("ERROR: `%s' needs ", applet);
first = true;
TAILQ_FOREACH(svc, services, entries) {
@@ -733,12 +756,14 @@ static void svc_start(bool deps)
rc_stringlist_free(services);
services = NULL;
- need_services = rc_deptree_depends(deptree, types_n, applet_list,
- runlevel, depoptions);
- use_services = rc_deptree_depends(deptree, types_nu, applet_list,
- runlevel, depoptions);
+ need_services = rc_deptree_depends(deptree, types_n,
+ applet_list, runlevel,
+ depoptions);
+ use_services = rc_deptree_depends(deptree, types_nu,
+ applet_list, runlevel,
+ depoptions);
- if (! rc_runlevel_starting() && use_services)
+ if (!rc_runlevel_starting()) {
TAILQ_FOREACH(svc, use_services, entries) {
state = rc_service_state(svc->value);
/* Don't stop failed services again.
@@ -753,90 +778,89 @@ static void svc_start(bool deps)
rc_waitpid(pid);
}
}
+ }
/* Now wait for them to start */
services = rc_deptree_depends(deptree, types_nua, applet_list,
runlevel, depoptions);
-
- if (services) {
- /* We use tmplist to hold our scheduled by list */
- tmplist = NULL;
- TAILQ_FOREACH(svc, services, entries) {
- state = rc_service_state(svc->value);
- if (state & RC_SERVICE_STARTED)
+ /* We use tmplist to hold our scheduled by list */
+ tmplist = rc_stringlist_new();
+ TAILQ_FOREACH(svc, services, entries) {
+ state = rc_service_state(svc->value);
+ if (state & RC_SERVICE_STARTED)
+ continue;
+
+ /* Don't wait for services which went inactive but are
+ * now in starting state which we are after */
+ if (state & RC_SERVICE_STARTING &&
+ state & RC_SERVICE_WASINACTIVE)
+ {
+ if (!rc_stringlist_find(need_services,
+ svc->value) &&
+ !rc_stringlist_find(use_services,
+ svc->value))
continue;
+ }
- /* Don't wait for services which went inactive but are now in
- * starting state which we are after */
- if (state & RC_SERVICE_STARTING &&
+ if (!svc_wait(svc->value))
+ eerror("%s: timed out waiting for %s",
+ applet, svc->value);
+ state = rc_service_state(svc->value);
+ if (state & RC_SERVICE_STARTED)
+ continue;
+ if (rc_stringlist_find(need_services, svc->value)) {
+ if (state & RC_SERVICE_INACTIVE ||
state & RC_SERVICE_WASINACTIVE)
{
- if (!rc_stringlist_find(need_services, svc->value) &&
- !rc_stringlist_find(use_services, svc->value))
- continue;
- }
-
- if (!svc_wait(svc->value))
- eerror ("%s: timed out waiting for %s",
+ rc_stringlist_add(tmplist, svc->value);
+ } else if (!TAILQ_FIRST(tmplist))
+ eerrorx("ERROR: cannot start %s as"
+ " %s would not start",
applet, svc->value);
- state = rc_service_state(svc->value);
- if (state & RC_SERVICE_STARTED)
- continue;
- if (rc_stringlist_find(need_services, svc->value)) {
- if (state & RC_SERVICE_INACTIVE ||
- state & RC_SERVICE_WASINACTIVE)
- {
- if (! tmplist)
- tmplist = rc_stringlist_new();
- rc_stringlist_add(tmplist, svc->value);
- } else if (!tmplist)
- eerrorx("ERROR: cannot start %s as"
- " %s would not start",
- applet, svc->value);
- }
}
+ }
- if (tmplist && TAILQ_FIRST(tmplist)) {
- /* Set the state now, then unlink our exclusive so that
- our scheduled list is preserved */
- rc_service_mark(service, RC_SERVICE_STOPPED);
- unlink_mtime_test();
+ if (TAILQ_FIRST(tmplist)) {
+ /* Set the state now, then unlink our exclusive so that
+ our scheduled list is preserved */
+ rc_service_mark(service, RC_SERVICE_STOPPED);
+ unlink_mtime_test();
+ rc_stringlist_free(use_services);
+ use_services = NULL;
+ len = 0;
+ n = 0;
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ rc_service_schedule_start(svc->value, service);
+ use_services = rc_deptree_depend(deptree,
+ "iprovide",
+ svc->value);
+ TAILQ_FOREACH(svc2, use_services, entries)
+ rc_service_schedule_start(svc2->value,
+ service);
rc_stringlist_free(use_services);
use_services = NULL;
- len = 0;
- n = 0;
- TAILQ_FOREACH(svc, tmplist, entries) {
- rc_service_schedule_start(svc->value, service);
- use_services = rc_deptree_depend(deptree, "iprovide",
- svc->value);
- if (use_services) {
- TAILQ_FOREACH (svc2, use_services, entries)
- rc_service_schedule_start(svc2->value, service);
- rc_stringlist_free(use_services);
- use_services = NULL;
- }
- len += strlen(svc->value) + 2;
- n++;
- }
-
- len += 5;
- tmp = p = xmalloc(sizeof(char) * len);
- TAILQ_FOREACH(svc, tmplist, entries) {
- if (p != tmp)
- p += snprintf(p, len, ", ");
- p += snprintf(p, len - (p - tmp), "%s", svc->value);
- }
- rc_stringlist_free(tmplist);
- tmplist = NULL;
- ewarnx("WARNING: %s is scheduled to start when %s has started",
- applet, tmp);
- free(tmp);
+ len += strlen(svc->value) + 2;
+ n++;
}
- rc_stringlist_free(services);
- services = NULL;
+ len += 5;
+ tmp = p = xmalloc(sizeof(char) * len);
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ if (p != tmp)
+ p += snprintf(p, len, ", ");
+ p += snprintf(p, len - (p - tmp),
+ "%s", svc->value);
+ }
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
+ ewarnx("WARNING: %s is scheduled to start when "
+ "%s has started", applet, tmp);
+ free(tmp);
}
+
+ rc_stringlist_free(services);
+ services = NULL;
}
if (ibsave)
@@ -848,13 +872,15 @@ static void svc_start(bool deps)
unsetenv("IN_BACKGROUND");
if (in_control()) {
- if (! started)
+ if (!started)
eerrorx("ERROR: %s failed to start", applet);
} else {
if (rc_service_state(service) & RC_SERVICE_INACTIVE)
- ewarnx("WARNING: %s has started, but is inactive", applet);
+ ewarnx("WARNING: %s has started, but is inactive",
+ applet);
else
- ewarnx("WARNING: %s not under our control, aborting", applet);
+ ewarnx("WARNING: %s not under our control, aborting",
+ applet);
}
rc_service_mark(service, RC_SERVICE_STARTED);
@@ -865,28 +891,23 @@ static void svc_start(bool deps)
/* Now start any scheduled services */
services = rc_services_scheduled(service);
- if (services) {
- TAILQ_FOREACH(svc, services, entries)
- if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
- service_start(svc->value);
- rc_stringlist_free(services);
- services = NULL;
- }
+ TAILQ_FOREACH(svc, services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ service_start(svc->value);
+ rc_stringlist_free(services);
+ services = NULL;
/* Do the same for any services we provide */
if (deptree) {
tmplist = rc_deptree_depend(deptree, "iprovide", applet);
- if (tmplist) {
- TAILQ_FOREACH(svc, tmplist, entries) {
- services = rc_services_scheduled(svc->value);
- if (! services)
- continue;
- TAILQ_FOREACH(svc2, services, entries)
- if (rc_service_state(svc2->value) & RC_SERVICE_STOPPED)
- service_start(svc2->value);
- rc_stringlist_free(services);
- services = NULL;
- }
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ services = rc_services_scheduled(svc->value);
+ TAILQ_FOREACH(svc2, services, entries)
+ if (rc_service_state(svc2->value) &
+ RC_SERVICE_STOPPED)
+ service_start(svc2->value);
+ rc_stringlist_free(services);
+ services = NULL;
}
rc_stringlist_free(tmplist);
tmplist = NULL;
@@ -896,20 +917,21 @@ static void svc_start(bool deps)
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
}
-static void svc_stop(bool deps)
+static void
+svc_stop(bool deps)
{
bool stopped;
RC_SERVICE state = rc_service_state(service);
int depoptions = RC_DEP_TRACE;
RC_STRING *svc;
- if (rc_runlevel_stopping() &&
- state & RC_SERVICE_FAILED)
- exit (EXIT_FAILURE);
+
+ if (rc_runlevel_stopping() && state & RC_SERVICE_FAILED)
+ exit(EXIT_FAILURE);
if (rc_yesno(getenv("IN_HOTPLUG")) || in_background)
- if (! (state & RC_SERVICE_STARTED) &&
- ! (state & RC_SERVICE_INACTIVE))
+ if (!(state & RC_SERVICE_STARTED) &&
+ !(state & RC_SERVICE_INACTIVE))
exit (EXIT_FAILURE);
if (state & RC_SERVICE_STOPPED) {
@@ -918,7 +940,7 @@ static void svc_stop(bool deps)
} else if (state & RC_SERVICE_STOPPING)
ewarnx("WARNING: %s is already stopping", applet);
- if (! rc_service_mark(service, RC_SERVICE_STOPPING)) {
+ if (!rc_service_mark(service, RC_SERVICE_STOPPING)) {
if (errno == EACCES)
eerrorx("%s: superuser access required", applet);
eerrorx("ERROR: %s has been stopped by something else", applet);
@@ -929,90 +951,87 @@ static void svc_stop(bool deps)
hook_out = RC_HOOK_SERVICE_STOP_OUT;
rc_plugin_run(RC_HOOK_SERVICE_STOP_IN, applet);
- if (! rc_runlevel_stopping() &&
+ if (!rc_runlevel_stopping() &&
rc_service_in_runlevel(service, RC_LEVEL_BOOT))
ewarn ("WARNING: you are stopping a boot service");
- if (deps && ! (state & RC_SERVICE_WASINACTIVE)) {
+ if (deps && !(state & RC_SERVICE_WASINACTIVE)) {
errno = 0;
if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
depoptions |= RC_DEP_STRICT;
- if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
- eerrorx ("failed to load deptree");
+ if (!deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
+ eerrorx("failed to load deptree");
- if (! types_m)
+ if (!types_m)
setup_types();
services = rc_deptree_depends(deptree, types_m, applet_list,
runlevel, depoptions);
- if (services) {
- TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
+ tmplist = rc_stringlist_new();
+ TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
+ state = rc_service_state(svc->value);
+ /* Don't stop failed services again.
+ * If you remove this check, ensure that the
+ * exclusive file isn't created. */
+ if (state & RC_SERVICE_FAILED &&
+ rc_runlevel_stopping())
+ continue;
+ if (state & RC_SERVICE_STARTED ||
+ state & RC_SERVICE_INACTIVE)
+ {
+ svc_wait(svc->value);
state = rc_service_state(svc->value);
- /* Don't stop failed services again.
- * If you remove this check, ensure that the
- * exclusive file isn't created. */
- if (state & RC_SERVICE_FAILED &&
- rc_runlevel_stopping())
- continue;
if (state & RC_SERVICE_STARTED ||
state & RC_SERVICE_INACTIVE)
{
- svc_wait(svc->value);
- state = rc_service_state(svc->value);
- if (state & RC_SERVICE_STARTED ||
- state & RC_SERVICE_INACTIVE)
- {
- pid_t pid = service_stop(svc->value);
- if (! rc_conf_yesno("rc_parallel"))
- rc_waitpid(pid);
- if (! tmplist)
- tmplist = rc_stringlist_new();
- rc_stringlist_add(tmplist, svc->value);
- }
+ pid_t pid = service_stop(svc->value);
+ if (!rc_conf_yesno("rc_parallel"))
+ rc_waitpid(pid);
+ rc_stringlist_add(tmplist, svc->value);
}
}
- rc_stringlist_free(services);
- services = NULL;
}
+ rc_stringlist_free(services);
+ services = NULL;
- if (tmplist) {
- TAILQ_FOREACH(svc, tmplist, entries) {
- if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ continue;
+ svc_wait(svc->value);
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ continue;
+ if (rc_runlevel_stopping()) {
+ /* If shutting down, we should stop even
+ * if a dependant failed */
+ if (runlevel &&
+ (strcmp(runlevel,
+ RC_LEVEL_SHUTDOWN) == 0 ||
+ strcmp(runlevel,
+ RC_LEVEL_REBOOT) == 0 ||
+ strcmp(runlevel,
+ RC_LEVEL_SINGLE) == 0))
continue;
- svc_wait(svc->value);
- if (! (rc_service_state(svc->value) & RC_SERVICE_STOPPED)) {
- if (rc_runlevel_stopping()) {
- /* If shutting down, we should stop even
- * if a dependant failed */
- if (runlevel &&
- (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp(runlevel, RC_LEVEL_REBOOT) == 0 ||
- strcmp(runlevel, RC_LEVEL_SINGLE) == 0))
- continue;
- rc_service_mark(service, RC_SERVICE_FAILED);
- }
- eerrorx("ERROR: cannot stop %s as %s is still up",
- applet, svc->value);
- }
+ rc_service_mark(service, RC_SERVICE_FAILED);
}
- rc_stringlist_free(tmplist);
- tmplist = NULL;
+ eerrorx("ERROR: cannot stop %s as %s "
+ "is still up", applet, svc->value);
}
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
+
- /* We now wait for other services that may use us and are stopping
- This is important when a runlevel stops */
+ /* We now wait for other services that may use us and are
+ * stopping. This is important when a runlevel stops */
services = rc_deptree_depends(deptree, types_mua, applet_list,
runlevel, depoptions);
- if (services) {
- TAILQ_FOREACH(svc, services, entries) {
- if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
- continue;
- svc_wait(svc->value);
- }
- rc_stringlist_free(services);
- services = NULL;
+ TAILQ_FOREACH(svc, services, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ continue;
+ svc_wait(svc->value);
}
+ rc_stringlist_free(services);
+ services = NULL;
}
/* If we're stopping localmount, set LC_ALL=C so that
@@ -1028,10 +1047,10 @@ static void svc_stop(bool deps)
if (ibsave)
unsetenv("IN_BACKGROUND");
- if (! in_control())
+ if (!in_control())
ewarnx("WARNING: %s not under our control, aborting", applet);
- if (! stopped)
+ if (!stopped)
eerrorx("ERROR: %s failed to stop", applet);
if (in_background)
@@ -1047,17 +1066,21 @@ static void svc_stop(bool deps)
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
}
-static void svc_restart(bool deps)
+static void
+svc_restart(bool deps)
{
/* This is hairly and a better way needs to be found I think!
- The issue is this - openvpn need net and dns. net can restart
- dns via resolvconf, so you could have openvpn trying to restart dnsmasq
- which in turn is waiting on net which in turn is waiting on dnsmasq.
- The work around is for resolvconf to restart it's services with --nodeps
- which means just that. The downside is that there is a small window when
- our status is invalid.
- One workaround would be to introduce a new status, or status locking. */
- if (! deps) {
+ * The issue is this - openvpn need net and dns. net can restart
+ * dns via resolvconf, so you could have openvpn trying to restart
+ * dnsmasq which in turn is waiting on net which in turn is waiting
+ * on dnsmasq.
+ * The work around is for resolvconf to restart it's services with
+ * --nodeps which means just that.
+ * The downside is that there is a small window when our status is
+ * invalid.
+ * One workaround would be to introduce a new status,
+ * or status locking. */
+ if (!deps) {
RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
svc_exec("stop", "start");
@@ -1066,7 +1089,7 @@ static void svc_restart(bool deps)
return;
}
- if (! (rc_service_state(service) & RC_SERVICE_STOPPED)) {
+ if (!(rc_service_state(service) & RC_SERVICE_STOPPED)) {
get_started_services();
svc_stop(deps);
}
@@ -1077,6 +1100,51 @@ static void svc_restart(bool deps)
restart_services = NULL;
}
+static bool
+service_plugable(void)
+{
+ char *list;
+ char *p;
+ char *star;
+ char *token;
+ bool allow = true;
+ char *match = rc_conf_value("rc_plug_services");
+ bool truefalse;
+
+ if (! match)
+ return true;
+
+ list = xstrdup(match);
+ p = list;
+ while ((token = strsep(&p, " "))) {
+ if (token[0] == '!') {
+ truefalse = false;
+ token++;
+ } else
+ truefalse = true;
+
+ star = strchr(token, '*');
+ if (star) {
+ if (strncmp(applet, token,
+ (size_t)(star - token)) == 0)
+ {
+ allow = truefalse;
+ break;
+ }
+ } else {
+ if (strcmp(applet, token) == 0) {
+ allow = truefalse;
+ break;
+ }
+ }
+ }
+
+#ifdef DEBUG_MEMORY
+ free(list);
+#endif
+ return allow;
+}
+
#include "_usage.h"
#define getoptstring "dDsv" getoptstring_COMMON
#define extraopts "stop | start | restart | describe | zap"
@@ -1086,7 +1154,7 @@ static const struct option longopts[] = {
{ "nodeps", 0, NULL, 'D'},
longopts_COMMON
};
-static const char * const longopts_help[] = {
+static const char *const longopts_help[] = {
"set xtrace when running the script",
"only run commands when started",
"ignore dependencies",
@@ -1094,7 +1162,8 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int runscript(int argc, char **argv)
+int
+runscript(int argc, char **argv)
{
bool deps = true;
bool doneone = false;
@@ -1112,7 +1181,7 @@ int runscript(int argc, char **argv)
struct stat stbuf;
/* Show help if insufficient args */
- if (argc < 2 || ! exists(argv[1])) {
+ if (argc < 2 || !exists(argv[1])) {
fprintf(stderr, "runscript should not be run directly\n");
exit(EXIT_FAILURE);
}
@@ -1165,20 +1234,6 @@ int runscript(int argc, char **argv)
/* Change dir to / to ensure all init scripts don't use stuff in pwd */
chdir("/");
-#ifdef __linux__
- /* coldplug events can trigger init scripts, but we don't want to run
- * them until after rc sysinit has completed so we punt them to the
- * boot runlevel */
- if (exists("/dev/.rcsysinit")) {
- eerror("%s: cannot run until sysvinit completes", applet);
- if (mkdir("/dev/.rcboot", 0755) != 0 && errno != EEXIST)
- eerrorx("%s: mkdir `/dev/.rcboot': %s", applet, strerror(errno));
- snprintf(exclusive, sizeof(exclusive), "/dev/.rcboot/%s", applet);
- symlink(service, exclusive);
- exit (EXIT_FAILURE);
- }
-#endif
-
if ((runlevel = xstrdup (getenv ("RC_RUNLEVEL"))) == NULL) {
env_filter();
env_config();
@@ -1198,15 +1253,16 @@ int runscript(int argc, char **argv)
if (rc_conf_yesno("rc_parallel")) {
/* Get the longest service name */
services = rc_services_in_runlevel(NULL);
- if (services) {
- TAILQ_FOREACH(svc, services, entries) {
- ll = strlen(svc->value);
- if (ll > l)
- l = ll;
- }
- rc_stringlist_free(services);
- services = NULL;
- } else l = strlen(applet);
+ TAILQ_FOREACH(svc, services, entries) {
+ ll = strlen(svc->value);
+ if (ll > l)
+ l = ll;
+ }
+ rc_stringlist_free(services);
+ services = NULL;
+ ll = strlen(applet);
+ if (ll > l)
+ l = ll;
/* Make our prefix string */
prefix = xmalloc(sizeof(char) * l + 1);
@@ -1227,13 +1283,14 @@ int runscript(int argc, char **argv)
argv++;
/* Right then, parse any options there may be */
- while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring,
+ longopts, (int *)0)) != -1)
switch (opt) {
case 'd':
setenv("RC_DEBUG", "yes", 1);
break;
case 's':
- if (! (rc_service_state(service) & RC_SERVICE_STARTED))
+ if (!(rc_service_state(service) & RC_SERVICE_STARTED))
exit(EXIT_FAILURE);
break;
case 'D':
@@ -1251,7 +1308,7 @@ int runscript(int argc, char **argv)
}
if (rc_yesno(getenv("IN_HOTPLUG"))) {
- if (! rc_conf_yesno("rc_hotplug") || ! service_plugable(applet))
+ if (!rc_conf_yesno("rc_hotplug") || !service_plugable())
eerrorx("%s: not allowed to be hotplugged", applet);
}
@@ -1286,8 +1343,8 @@ int runscript(int argc, char **argv)
doneone = true;
- if (strcmp (optarg, "describe") == 0 ||
- strcmp (optarg, "help") == 0)
+ if (strcmp(optarg, "describe") == 0 ||
+ strcmp(optarg, "help") == 0)
{
save = prefix;
eprefix(NULL);
@@ -1304,25 +1361,25 @@ int runscript(int argc, char **argv)
strcmp(optarg, "iprovide") == 0)
{
errno = 0;
- if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
+ if (rc_conf_yesno("rc_depend_strict") ||
+ errno == ENOENT)
depoptions |= RC_DEP_STRICT;
- if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
+ if (!deptree &&
+ ((deptree = _rc_deptree_load(NULL)) == NULL))
eerrorx("failed to load deptree");
tmplist = rc_stringlist_new();
rc_stringlist_add(tmplist, optarg);
- services = rc_deptree_depends(deptree, tmplist, applet_list,
+ services = rc_deptree_depends(deptree, tmplist,
+ applet_list,
runlevel, depoptions);
rc_stringlist_free(tmplist);
- tmplist = NULL;
- if (services) {
- TAILQ_FOREACH(svc, services, entries)
- printf("%s ", svc->value);
- printf ("\n");
- rc_stringlist_free(services);
- services = NULL;
- }
+ TAILQ_FOREACH(svc, services, entries)
+ printf("%s ", svc->value);
+ printf ("\n");
+ rc_stringlist_free(services);
+ services = NULL;
} else if (strcmp (optarg, "status") == 0) {
RC_SERVICE r = svc_status();
retval = (int) r;
@@ -1332,7 +1389,8 @@ int runscript(int argc, char **argv)
if (strcmp(optarg, "conditionalrestart") == 0 ||
strcmp(optarg, "condrestart") == 0)
{
- if (rc_service_state(service) & RC_SERVICE_STARTED)
+ if (rc_service_state(service) &
+ RC_SERVICE_STARTED)
svc_restart(deps);
} else if (strcmp(optarg, "restart") == 0) {
svc_restart (deps);
@@ -1341,37 +1399,44 @@ int runscript(int argc, char **argv)
} else if (strcmp(optarg, "stop") == 0) {
if (deps && in_background)
get_started_services();
-
svc_stop(deps);
-
if (deps) {
if (! in_background &&
! rc_runlevel_stopping() &&
- rc_service_state(service) & RC_SERVICE_STOPPED)
+ rc_service_state(service) &
+ RC_SERVICE_STOPPED)
uncoldplug();
if (in_background &&
- rc_service_state(service) & RC_SERVICE_INACTIVE)
+ rc_service_state(service) &
+ RC_SERVICE_INACTIVE)
{
- TAILQ_FOREACH(svc, restart_services, entries)
- if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ TAILQ_FOREACH(svc,
+ restart_services,
+ entries)
+ if (rc_service_state(svc->value) &
+ RC_SERVICE_STOPPED)
rc_service_schedule_start(service, svc->value);
}
}
} else if (strcmp(optarg, "zap") == 0) {
- einfo("Manually resetting %s to stopped state", applet);
- if (!rc_service_mark(applet, RC_SERVICE_STOPPED))
- eerrorx("rc_service_mark: %s", strerror(errno));
+ einfo("Manually resetting %s to stopped state",
+ applet);
+ if (!rc_service_mark(applet,
+ RC_SERVICE_STOPPED))
+ eerrorx("rc_service_mark: %s",
+ strerror(errno));
uncoldplug();
} else
svc_exec(optarg, NULL);
- /* We should ensure this list is empty after an action is done */
+ /* We should ensure this list is empty after
+ * an action is done */
rc_stringlist_free(restart_services);
restart_services = NULL;
}
- if (! doneone)
+ if (!doneone)
usage(EXIT_FAILURE);
}