Compare commits

..

83 Commits

Author SHA1 Message Date
Roy Marples
803dbbf0c8 Allow rc_runlevel/softlevel to set runlevel from kernel commandline. 2008-12-21 01:15:02 +00:00
Roy Marples
9e5e60f257 Store interactive mode after sysinit, #128 thanks to Matthias Schwarzott. 2008-12-13 22:20:21 +00:00
Roy Marples
6bf0289f33 Warn about stopping sysinit services, thanks to Matthias Schwarzott. Fixes #126. 2008-12-11 14:50:58 +00:00
Roy Marples
bdb3485b49 Punt redundant dirs from git mirgation. 2008-12-07 08:38:16 +00:00
Roy Marples
eb6daeca43 Fix dist for svn 2008-12-07 07:51:40 +00:00
Roy Marples
10e88090f6 Release 0.4.0 2008-12-07 07:49:24 +00:00
Roy Marples
8cce75925f Ignore FreeBSD targets. 2008-12-05 09:24:49 +00:00
Roy Marples
e72aeebbcd make ignore now updates svn:ignore as different OS's have different targets. 2008-12-04 19:21:47 +00:00
Roy Marples
dc712a109e runlevel override works correctly again. 2008-12-04 17:30:26 +00:00
Roy Marples
1acbfcf5ca Report invalid runlevels. 2008-12-04 17:17:09 +00:00
Roy Marples
f8210050e5 If we're building from subversion, brand the binary as such. 2008-12-04 13:12:46 +00:00
Roy Marples
38e6c9ba5c make ignore now configures the sv:ignore property. 2008-12-04 12:38:23 +00:00
Roy Marples
2c98c5326a Punt .gitignore files. 2008-12-04 12:12:09 +00:00
Roy Marples
57f90a42ba Include hotplugged services in our start list. 2008-12-01 08:46:50 +00:00
Roy Marples
bde35d03ed Actally show hotplugged services. 2008-12-01 08:46:25 +00:00
Roy Marples
8b76e1d2e0 Ignore interupts when waiting for processes to finish. Also, style fixes. 2008-11-28 10:48:01 +00:00
Roy Marples
b859710cc8 Style. 2008-11-28 10:47:17 +00:00
Roy Marples
c064393f08 Save screen space. 2008-11-28 10:46:58 +00:00
Roy Marples
e84f71596e Not needed. 2008-11-27 21:14:52 +00:00
Roy Marples
23e73957a0 Switch from select to poll and improve the no prefixing of eend calls. 2008-11-27 21:14:43 +00:00
Roy Marples
2537a07e10 Switch from select to poll and improve the no prefixing of eend calls. 2008-11-27 21:05:39 +00:00
Roy Marples
5403e70313 Save more screen space by removing the space befor the * for einfo and friends. Also remove the leading space before ... for ebegin. 2008-11-26 10:46:33 +00:00
Roy Marples
fe12134a5b Don't warn about waiting for services marked as notimeout, Gentoo #247306. 2008-11-23 18:40:43 +00:00
Roy Marples
1deaa0fae0 Fix lib. 2008-11-13 09:35:00 +00:00
Roy Marples
0cca768b82 Mark the addon code as deprecated. 2008-11-12 19:19:56 +00:00
Roy Marples
df22978de9 Punt halt init script. sysvinit should install it. See Gentoo bug #246502 on how to handle this. 2008-11-12 16:28:07 +00:00
Roy Marples
fe509db660 Save a needless malloc when re-creating PATH. 2008-11-12 10:55:42 +00:00
Roy Marples
937b1b2abf Don't set user info unless stated. 2008-11-11 19:47:30 +00:00
Roy Marples
eafbed0366 Fix stopping with a faulty pidfile. 2008-11-10 20:57:03 +00:00
Roy Marples
0786141026 Restore interface_exists, interface_up and interface_exists, #123. 2008-11-10 12:31:20 +00:00
Roy Marples
90d175ae27 Remove deprecated use of modprobe -l. If we need this functionaltiy back, we need to use something else, like say find. 2008-11-04 17:08:35 +00:00
Roy Marples
a178fd0f32 We should not update mtab here. 2008-11-04 17:07:32 +00:00
Roy Marples
03e8e0cb68 More Typos. 2008-11-04 14:28:51 +00:00
Roy Marples
a3d266e741 Use mount-ro 2008-11-04 11:32:07 +00:00
Roy Marples
42e6a95b1d Move romount to mount-ro and use the umount -r option as it's more reliable for / --bind mounts, Gentoo #239922. Thanks to Duncan. 2008-11-04 11:30:15 +00:00
Roy Marples
45044c9239 Typo 2008-11-04 11:28:24 +00:00
Roy Marples
5fc6f21169 Typo 2008-11-04 11:05:30 +00:00
Roy Marples
2cf24fe793 Ignore after dependencies for shutdown when not in the runlevel. 2008-11-04 09:32:21 +00:00
Roy Marples
cc14b55414 Now the linx fsck man page has return codes, I find them different from the BSD's so adjust accordingly. 2008-11-04 07:45:05 +00:00
Roy Marples
33d4fba5be We start off in sysinit correctly. 2008-11-04 00:21:30 +00:00
Roy Marples
32e17af92f No need for NULL here. 2008-11-03 23:13:36 +00:00
Roy Marples
77d56f5489 Avoid depends not in the runlevel for sysinit and shutdown. 2008-11-03 23:13:12 +00:00
Roy Marples
c520d4a23a --nice is -N, not -n. Also, correct default timeout. 2008-11-03 21:11:29 +00:00
Roy Marples
8a76c27325 Fix sending signals, #121. 2008-11-03 21:06:45 +00:00
Roy Marples
7467440a29 Fix fstabinfo for mounting /dev/shm, Gentoo #245367. 2008-11-03 18:00:55 +00:00
Roy Marples
282ad4bae6 Add descriptions. 2008-11-03 16:16:12 +00:00
Roy Marples
1e5a6f40e5 We shouldn't run halt.sh anymore. 2008-11-03 16:11:29 +00:00
Roy Marples
0af7d5bc20 Add a new shutdown runlevel, Gentoo #224537.
Split halt.sh into halt, killprocs, romount and savecache services.
The reboot runlevel is removed but mapped to shutdown.
The halt script should be moved to the sysvinit package.
2008-11-03 15:31:01 +00:00
Roy Marples
895c4f4149 Plug a leak and expand exec also. 2008-10-30 17:57:58 +00:00
Roy Marples
20380d3144 Allow ~ and ~user to expand for chdir and chroot. 2008-10-30 17:40:48 +00:00
Roy Marples
e1341e372b Fix --name when stopping, Gentoo #243088. 2008-10-30 16:26:05 +00:00
Roy Marples
1c73f2967c We no longer hotplug by default. 2008-10-30 15:03:12 +00:00
Roy Marples
2ff0838abb We should show hotplugged services, needed services and manually started services in rc-status. 2008-10-30 14:59:14 +00:00
Roy Marples
53ddd6ca96 Properly set PAM enviornment variables after opening session.
Without this change, modules like pam_mktemp or pam_env and similar
will be unable to change users' environments, like they are supposed
to.
2008-10-29 21:35:45 +00:00
Roy Marples
9ec6ff02bb Style and typo. 2008-10-28 15:43:36 +00:00
Roy Marples
aa991a3c99 Style. 2008-10-27 18:38:56 +00:00
Roy Marples
0d98d56188 Remove sysvinit specific code.
The runlevels shutdown, reboot, sysinit and single should be called by
init(8) and shutdown(8) and not manually.
sysvinit users will have to add sulogin to their inittab to secure the
console.
2008-10-27 18:01:03 +00:00
Roy Marples
ae692e294e Don't quote $tunnel, Gentoo #218123. 2008-10-26 19:58:57 +00:00
Roy Marples
f6e3c167ae Remove bash localisation feature, Gentoo #244444 thanks to Andrey Grozin. 2008-10-26 19:19:19 +00:00
Mike Frysinger
1d96620b84 hwclock: skip rtc checks if kernel lacks module support
Since we only use the result of the device scan to load modules, there is
no point in doing the scan if the kernel doesn't support modules in the
first place.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2008-10-26 07:09:02 +00:00
Roy Marples
d12bb5cf3c Really fix .depend 2008-10-20 16:47:56 +00:00
Roy Marples
9c76b077d6 Enable use of .depend on gmake. Also, generate extra dependencies for our shared libraries. 2008-10-20 12:09:14 +00:00
Roy Marples
0a39145a5e Include sysinit services even in single user. 2008-10-16 17:04:44 +00:00
Roy Marples
734e60608a Ignore new scripts. 2008-10-16 09:41:14 +00:00
Roy Marples
66ae6e38a7 Compile with FreeBSD 6.x make 2008-10-15 09:02:27 +00:00
Roy Marples
8d47d6c022 Fix fuser on BSD platforms. 2008-10-15 08:35:21 +00:00
Roy Marples
c18c74e816 Fix adding just the default route, #119 thanks to pva. 2008-10-14 15:27:52 +00:00
Roy Marples
da94fad3f5 Re-evaluate sys after running initsh. 2008-10-10 14:53:50 +00:00
Roy Marples
10cb4c18df Remove hardedcoded foo here. 2008-10-10 09:35:13 +00:00
Roy Marples
50b8aba8d9 Remove coldplug and just have hotplug which is a list of allowed/disallowed services. Makes things much easier. 2008-10-10 09:08:59 +00:00
Roy Marples
72dcac8c55 Shorten common messages for prefixed output. 2008-10-10 09:03:59 +00:00
Roy Marples
d6da8e8c48 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.
2008-10-10 08:37:21 +00:00
Roy Marples
247766695c Fix umounting reporting exit status, Gentoo #239922. 2008-10-09 16:36:42 +00:00
Roy Marples
1a88a43aa5 Warn about sulogin timeout and then continue as normal, Gentoo #240383 2008-10-09 16:34:21 +00:00
Roy Marples
c4e673edbc Add a better, but incomplete tgoto implementation to make gcc happy. 2008-10-08 21:07:04 +00:00
Roy Marples
a872fe5590 Fix status check, #239922 2008-10-08 18:32:39 +00:00
Roy Marples
8c8751fa60 Clean up warnings regarding printf. 2008-10-08 15:56:47 +00:00
Roy Marples
5cdc489573 Fix utmp permissions, Gentoo #240437. 2008-10-08 13:58:17 +00:00
Roy Marples
4d74e94c39 Merge branch 'master' of git@git.overlays.gentoo.org:proj/openrc 2008-10-07 12:18:22 +00:00
Roy Marples
d117b2d644 Fix tests, #Gentoo 240350. 2008-10-07 12:14:53 +00:00
Roy Marples
cb44b0a46c #ifdef atexit cleanups calling free as the OS should do this for us, but valgrind debuggers need it. 2008-10-06 15:02:32 +00:00
Roy Marples
4e4c4a5bf4 kenv is not always available. 2008-10-03 17:50:30 +00:00
Roy Marples
09a1a5ecd4 Fix a segfault when profile.env does not exist. 2008-10-03 17:50:10 +00:00
84 changed files with 1813 additions and 1931 deletions

3
.gitignore vendored
View File

@@ -1,3 +0,0 @@
openrc-0.1.tar.bz2
.gdb_history
.gdbinit

View File

@@ -3,7 +3,7 @@
# All rights reserved. Released under the 2-clause BSD license. # All rights reserved. Released under the 2-clause BSD license.
NAME= openrc NAME= openrc
VERSION= 0.3.0 VERSION= 0.4.0
PKG= ${NAME}-${VERSION} PKG= ${NAME}-${VERSION}
SUBDIR= conf.d doc etc init.d man net sh src SUBDIR= conf.d doc etc init.d man net sh src
@@ -17,7 +17,6 @@ include ${MK}/sys.mk
include ${MK}/os.mk include ${MK}/os.mk
include ${MK}/subdir.mk include ${MK}/subdir.mk
include ${MK}/dist.mk include ${MK}/dist.mk
include ${MK}/gitignore.mk
_installafter: _installafter:
${INSTALL} -d ${DESTDIR}/${PREFIX}/${RC_LIB}/init.d ${INSTALL} -d ${DESTDIR}/${PREFIX}/${RC_LIB}/init.d

2
README
View File

@@ -19,6 +19,8 @@ PREFIX=/usr/local
We don't support building a static OpenRC with PAM. We don't support building a static OpenRC with PAM.
You may need to use PROGLDFLAGS=-Wl,-Bstatic on glibc instead of just -static. You may need to use PROGLDFLAGS=-Wl,-Bstatic on glibc instead of just -static.
If you debug memory under valgrind, add -DDEBUG_MEMORY to your CPPFLAGS
so that all malloc memory should be freed at exit.
You can also brand OpenRC if you so wish like so You can also brand OpenRC if you so wish like so
BRANDING=\"Gentoo/$(uname -s)\" BRANDING=\"Gentoo/$(uname -s)\"

View File

@@ -1 +1 @@
CONF+= consolefont hwclock keymaps modules CONF+= consolefont dmesg hwclock keymaps modules

3
conf.d/dmesg Normal file
View File

@@ -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"

1
doc/.gitignore vendored
View File

@@ -1 +0,0 @@
net.example

3
etc/.gitignore vendored
View File

@@ -1,3 +0,0 @@
rc.conf
rc
rc.shutdown

View File

@@ -1,6 +1,8 @@
DIR= ${SYSCONFDIR} DIR= ${SYSCONFDIR}
CONF= rc.conf CONF= rc.conf
CLEANFILES+= rc.conf
MK= ../mk MK= ../mk
include ${MK}/os.mk include ${MK}/os.mk
include Makefile.${OS} include Makefile.${OS}

View File

@@ -6,20 +6,3 @@
# consolefont, numlock, etc ...) # consolefont, numlock, etc ...)
rc_tty_number=12 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"

View File

@@ -22,30 +22,22 @@ rc_interactive="YES"
# come up. # come up.
rc_depend_strict="YES" rc_depend_strict="YES"
# Do we allow services to be hotplugged? If not, set to rc_hotplug="NO" # rc_hotplug is a list of services that we allow to be hotplugged.
# NOTE: This does not affect anything hotplug/udev/devd related, just the # By default we do not allow hotplugging.
# starting/stopping of the init.d service triggered by it. # A hotplugged service is one started by a dynamic dev manager when a matching
rc_hotplug="YES" # hardware device is found.
# This service is intrinsically included in the boot runlevel.
# Dynamic /dev managers can trigger coldplug events which cause services to # To disable services, prefix with a !
# start before we are ready for them. If this happens, we can defer these # Example - rc_hotplug="net.wlan !net.*"
# 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
# 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.
# Example - rc_plug_services="net.wlan !net.*"
# This allows net.wlan and any service not matching net.* to be plugged. # This allows net.wlan and any service not matching net.* to be plugged.
rc_plug_services="" # Example - rc_hotplug="*"
# This allows all services to be hotplugged
#rc_hotplug="*"
# rc_logger launches a logging daemon to log the entire rc process to # rc_logger launches a logging daemon to log the entire rc process to
# /var/log/rc.log # /var/log/rc.log
# NOTE: Linux systems require the devfs service to be started before
# logging can take place and as such cannot log the sysinit runlevel.
rc_logger="NO" rc_logger="NO"
# By default we filter the environment for our running scripts. To allow other # By default we filter the environment for our running scripts. To allow other

View File

@@ -10,12 +10,9 @@
trap : SIGINT trap : SIGINT
trap "echo 'Boot interrupted'; exit 1" SIGQUIT trap "echo 'Boot interrupted'; exit 1" SIGQUIT
# BSD's init works somewhat differently to sysvinit. /sbin/rc sysinit || exit 1
# This block should 'translate' from the way init calls it to the way it would /sbin/rc boot || exit 1
# be called by sysvinit on linux. /sbin/rc default
RUNLEVEL="1" /sbin/rc sysinit || exit 1
RUNLEVEL="1" /sbin/rc boot || exit 1
PREVLEVEL="1" /sbin/rc default
# We don't actually care if rc default worked or not, we should exit 0 # We don't actually care if rc default worked or not, we should exit 0
# to allow logins # to allow logins

View File

@@ -14,13 +14,4 @@ export LD_LIBRARY_PATH="/lib${LD_LIBRARY_PATH:+:}${LDLIBRARY_PATH}"
[ -z "$TERM" -o "$TERM" = "dumb" ] && export TERM="@TERM@" [ -z "$TERM" -o "$TERM" = "dumb" ] && export TERM="@TERM@"
action=${1:-shutdown} action=${1:-shutdown}
# BSD's init works somewhat differently to sysvinit.
# This block should 'translate' from the way init calls it to the way it would
# be called by sysvinit on linux.
case "${action}" in
reboot) export RUNLEVEL=6;;
single) export RUNLEVEL=S;;
*) export RUNLEVEL=0;;
esac
exec /sbin/rc "${action}" exec /sbin/rc "${action}"

View File

@@ -1,9 +0,0 @@
avahi-dnsconfd
avahid
dbus
hald
named
ntpd
openvpn
polkitd
sshd

41
init.d/.gitignore vendored
View File

@@ -1,41 +0,0 @@
bootmisc
fsck
halt.sh
hostname
local
localmount
netmount
root
swap
sysctl
urandom
hostid
moused
newsyslog
pf
rarpd
rc-enabled
rpcbind
savecore
syslogd
adjkerntz
devd
dumpon
ipfw
mixer
nscd
powerd
syscons
net.lo
ttys
swap-blk
wscons
consolefont
hwclock
keymaps
modules
mtab
numlock
procfs
termencoding
devdb

View File

@@ -1,6 +1,6 @@
DIR= ${INITDIR} DIR= ${INITDIR}
SRCS= bootmisc.in fsck.in halt.sh.in hostname.in local.in localmount.in \ SRCS= bootmisc.in fsck.in hostname.in local.in localmount.in \
netmount.in root.in swap.in sysctl.in urandom.in netmount.in root.in savecache.in swap.in sysctl.in urandom.in
BIN= ${OBJS} BIN= ${OBJS}
INSTALLAFTER= _installafter INSTALLAFTER= _installafter

View File

@@ -1,7 +1,8 @@
NET_LO= net.lo NET_LO= net.lo
SRCS+= hwclock.in consolefont.in keymaps.in modules.in mtab.in numlock.in \ SRCS+= devfs.in dmesg.in hwclock.in consolefont.in keymaps.in killprocs.in \
procfs.in termencoding.in modules.in mount-ro.in mtab.in numlock.in procfs.in sysfs.in \
termencoding.in
.SUFFIXES: .Linux.in .SUFFIXES: .Linux.in
.Linux.in: .Linux.in:

View File

@@ -77,10 +77,13 @@ start()
if dir_writeable /var/run; then if dir_writeable /var/run; then
ebegin "Creating user login records" ebegin "Creating user login records"
cp /dev/null /var/run/utmp cp /dev/null /var/run/utmp
chgrp utmp /var/run/utmp
chmod 0664 /var/run/utmp
if dir_writeable /var/log; then if dir_writeable /var/log; then
logw=true logw=true
[ -e /var/log/wtmp ] || cp /dev/null /var/log/wtmp [ -e /var/log/wtmp ] || cp /dev/null /var/log/wtmp
chmod 0644 /var/run/utmp /var/log/wtmp chgrp utmp /var/log/wtmp
chmod 0664 /var/log/wtmp
fi fi
eend 0 eend 0
@@ -90,8 +93,12 @@ start()
! -name ld-elf.so.hints ! -name ld.so.hints); ! -name ld-elf.so.hints ! -name ld.so.hints);
do do
# Clean stale sockets # Clean stale sockets
if [ -S "${x}" ] && type fuser >/dev/null 2>&1; then if [ -S "${x}" ]; then
fuser -s "${x}" || rm "${x}" if type fuser >/dev/null 2>&1; then
fuser "${x}" 2>/dev/null || rm "${x}"
else
rm "${x}"
fi
fi fi
[ ! -f "${x}" ] && continue [ ! -f "${x}" ] && continue
# Do not remove pidfiles of already running daemons # Do not remove pidfiles of already running daemons

36
init.d/devfs.in Normal file
View File

@@ -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
}

17
init.d/dmesg.in Normal file
View File

@@ -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
}

View File

@@ -8,7 +8,7 @@ _IFS="
depend() depend()
{ {
after clock modules use dev clock modules
keyword nojail noopenvz noprefix notimeout novserver keyword nojail noopenvz noprefix notimeout novserver
} }
@@ -27,7 +27,7 @@ _reboot() {
start() start()
{ {
local reboot_opts= fsck_opts= p= check_extra= local fsck_opts= p= check_extra=
if [ -e /fastboot ]; then if [ -e /fastboot ]; then
ewarn "Skipping fsck due to /fastboot" ewarn "Skipping fsck due to /fastboot"
@@ -60,21 +60,31 @@ start()
fsck_opts="${fsck_opts} -R" fsck_opts="${fsck_opts} -R"
fi fi
fi fi
reboot_opts="-f"
fi fi
trap : INT QUIT trap : INT QUIT
fsck ${fsck_args--p} ${fsck_opts} "$@" fsck ${fsck_args--p} ${fsck_opts} "$@"
case $? in case $? in
0) eend 0; return 0;; 0) eend 0; return 0;;
1) ewend 1 "Filesystems repaired"; return 0;; 1) ewend 1 "Filesystems repaired"; return 0;;
2|3|4) ewend 1 "Filesystems repaired, but reboot needed" 2|3) if [ "${RC_UNAME}" = "Linux" ]; then
_reboot ${reboot_opts} || return 1;; ewend 1 "Filesystems repaired, but reboot needed"
8) ewend 1 "Operational error"; return 0;; _reboot -f
12) ewend 1 "fsck interupted"; return 1;; else
*) eend 2 "Filesystems couldn't be fixed" ewend 1 "Filesystems still have errors; manual fsck required"
_abort || return 1;; fi;;
4) if [ "${RC_UNAME}" = "Linux" ]; then
ewend 1 "Fileystem errors left uncorrected"
return 0
else
ewend 1 "Filesystems repaired, but reboot needed"
_reboot
fi;;
8) ewend 1 "Operational error"; return 0;;
12) ewend 1 "fsck interupted";;
*) eend 2 "Filesystems couldn't be fixed";;
esac esac
_abort || return 1
} }
stop() stop()

View File

@@ -1,119 +0,0 @@
#!@SHELL@
# Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
. @SYSCONFDIR@/init.d/functions.sh
. "${RC_LIBDIR}"/sh/rc-functions.sh
[ -r @SYSCONFDIR@/conf.d/localmount ] && . @SYSCONFDIR@/conf.d/localmount
[ -r @SYSCONFDIR@/rc.conf ] && . @SYSCONFDIR@/rc.conf
# Support LiveCD foo
if [ -r /sbin/livecd-functions.sh ]; then
. /sbin/livecd-functions.sh
livecd_read_commandline
fi
stop_addon devfs
stop_addon udev
# Really kill things off before unmounting
if [ -x /sbin/killall5 ]; then
killall5 -15
killall5 -9
fi
# Flush all pending disk writes now
sync; sync
# If we are in a VPS, we don't need anything below here, because
# 1) we don't need (and by default can't) umount anything (VServer) or
# 2) the host utils take care of all umounting stuff (OpenVZ)
if [ "${RC_SYS}" = "VSERVER" -o "${RC_SYS}" = "OPENVZ" ]; then
[ "${RC_SYS}" = "OPENVZ" -a "$1" = "reboot" ] && echo "" > /reboot
if [ -e @SYSCONFDIR@/init.d/"$1".sh ]; then
. @SYSCONFDIR@/init.d/"$1".sh
else
exit 0
fi
fi
# If $svcdir is still mounted, preserve it if we can
mnt=$(mountinfo --node "${RC_SVCDIR}")
if [ -n "${mnt}" ] && \
rm -rf "${RC_LIBDIR}/tmp.$$" && \
mkdir -p "${RC_LIBDIR}/tmp.$$" 2>/dev/null \
; then
rmdir "${RC_LIBDIR}/tmp.$$"
f_opts="-m -c"
[ "${RC_UNAME}" = "Linux" ] && f_opts="-c"
if type fuser >/dev/null 2>&1; then
if [ -n "$(fuser ${f_opts} "${svcdir}" 2>/dev/null)" ]; then
fuser -k ${f_opts} "${svcdir}" >/dev/null 2>&1
sleep 2
fi
fi
cp -p "${RC_SVCDIR}"/deptree "${RC_SVCDIR}"/depconfig \
"${RC_SVCDIR}"/softlevel "${RC_SVCDIR}"/nettree \
"${RC_SVCDIR}"/rc.log \
"${RC_LIBDIR}" 2>/dev/null
umount "${RC_SVCDIR}"
rm -rf "${RC_SVCDIR}"/*
# Pipe errors to /dev/null as we may have future timestamps
cp -p "${RC_LIBDIR}"/deptree "${RC_LIBDIR}"/depconfig \
"${RC_LIBDIR}"/softlevel "${RC_LIBDIR}"/nettree \
"${RC_LIBDIR}"/rc.log \
"${RC_SVCDIR}" 2>/dev/null
rm -f "${RC_LIBDIR}"/deptree "${RC_LIBDIR}"/depconfig \
"${RC_LIBDIR}"/softlevel "${RC_LIBDIR}"/nettree \
"${RC_LIBDIR}"/rc.log
# Release the memory disk if we used it
case "${mnt}" in
"/dev/md"[0-9]*) mdconfig -d -u "${mnt#/dev/md*}";;
esac
fi
unmounted=0
# Remount the remaining filesystems read-only
# Most BSD's don't need this as the kernel handles it nicely
if [ "${RC_UNAME}" = "Linux" ]; then
ebegin "Remounting remaining filesystems read-only"
# We need the do_unmount function
. "${RC_LIBDIR}"/sh/rc-mount.sh
eindent
no_umounts_r="/dev|/dev/.*|${RC_SVCDIR}"
# RC_NO_UMOUNTS is an env var that can be set by plugins
OIFS=${IFS} SIFS=${IFS-y}
IFS=$IFS:
for x in ${no_umounts} ${RC_NO_UMOUNTS}; do
no_umounts_r="${no_umounts_r}|${x}"
done
if [ "${SIFS}" = "y" ]; then
IFS=$OIFS
else
unset IFS
fi
no_umounts_r="${no_umounts_r}|/proc|/proc/.*|/sys|/sys/.*"
no_umounts_r="^(${no_umounts_r})$"
fs=
for x in ${net_fs_list}; do
fs="${fs}${fs:+|}${x}"
done
[ -n "${fs}" ] && fs="^(${fs})$"
do_unmount "mount -n -o remount,ro" \
--skip-point-regex "${no_umounts_r}" \
${fs:+--skip-fstype-regex} ${fs} --nonetdev
eoutdent
eend $?
unmounted=$?
fi
if [ ${unmounted} -ne 0 ]; then
[ -x /sbin/sulogin ] && sulogin -t 10 /dev/console
exit 1
fi
# Load the final script - not needed on BSD so they should not exist
[ -e @SYSCONFDIR@/init.d/"$1".sh ] && . @SYSCONFDIR@/init.d/"$1".sh
# Always exit 0 here
exit 0

View File

@@ -38,9 +38,11 @@ _set()
# otherwise we generate a random UUID. # otherwise we generate a random UUID.
reset() reset()
{ {
local uuid=$(kenv smbios.system.uuid 2>/dev/null) local uuid= x="[0-9a-f]" y="${x}${x}${x}${x}"
local x="[0-9a-f]"
local y="${x}${x}${x}${x}" if type kenv >/dev/null 2>&1; then
uuid=$(kenv smbios.system.uuid 2>/dev/null)
fi
case "${uuid}" in case "${uuid}" in
${y}${y}-${y}-${y}-${y}-${y}${y}${y});; ${y}${y}-${y}-${y}-${y}-${y}${y}${y});;
*) uuid=;; *) uuid=;;

View File

@@ -74,12 +74,14 @@ start()
fi fi
ebegin "Setting system clock using the hardware clock [${utc}]" ebegin "Setting system clock using the hardware clock [${utc}]"
local rtc= if [ -e /proc/modules ]; then
for rtc in /dev/rtc /dev/rtc[0-9]*; do local rtc=
[ -e "${rtc}" ] && break for rtc in /dev/rtc /dev/rtc[0-9]*; do
done [ -e "${rtc}" ] && break
if [ ! -e "${rtc}" -a -e /proc/modules ]; then done
modprobe -q rtc-cmos || modprobe -q rtc || modprobe -q genrtc if [ ! -e "${rtc}" ]; then
modprobe -q rtc-cmos || modprobe -q rtc || modprobe -q genrtc
fi
fi fi
if [ -e /etc/adjtime ] && yesno ${clock_adjfile}; then if [ -e /etc/adjtime ] && yesno ${clock_adjfile}; then

22
init.d/killprocs.in Normal file
View File

@@ -0,0 +1,22 @@
#!@PREFIX@/sbin/runscript
# Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
description="Kill all processes so we can unmount disks cleanly."
depend()
{
keyword noprefix
}
start()
{
ebegin "Terminating remaining processes"
killall5 -15
sleep 1
eend 0
ebegin "Killing remaining processes"
killall5 -9
sleep 1
eend 0
}

View File

@@ -39,5 +39,5 @@ stop()
. @SYSCONFDIR@/conf.d/local.stop . @SYSCONFDIR@/conf.d/local.stop
fi fi
eend $? $"Failed to stop local" eend $? "Failed to stop local"
} }

View File

@@ -60,11 +60,4 @@ start()
eend $? "Failed to load ${x}" && cnt=$((${cnt} + 1)) eend $? "Failed to load ${x}" && cnt=$((${cnt} + 1))
done done
einfo "Autoloaded ${cnt} module(s)" einfo "Autoloaded ${cnt} module(s)"
# Just in case a sysadmin prefers generic symbolic links in
# /lib/modules/boot for boot time modules we will load these modules
[ -n "$(modprobe -l -t boot)" ] && modprobe -a -t boot \* 2>/dev/null
# Above test clobbers the return
return 0
} }

45
init.d/mount-ro.in Normal file
View File

@@ -0,0 +1,45 @@
#!@PREFIX@/sbin/runscript
# Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
description="Re-mount filesytems read-only for a clean reboot."
depend()
{
need killprocs savecache
keyword noprefix noopenvz novserver
}
start()
{
# Flush all pending disk writes now
sync; sync
ebegin "Remounting remaining filesystems read-only"
# We need the do_unmount function
. "${RC_LIBDIR}"/sh/rc-mount.sh
eindent
local m="/dev|/dev/.*|/proc|/proc.*|/sys|/sys/.*|${RC_SVCDIR}" x= fs=
# RC_NO_UMOUNTS is an env var that can be set by plugins
local OIFS=$IFS SIFS=${IFS-y} IFS=$IFS
IFS=$IFS:
for x in ${no_umounts} ${RC_NO_UMOUNTS}; do
m="${m}|${x}"
done
if [ "${SIFS}" = y ]; then
IFS=$OIFS
else
unset IFS
fi
m="^(${m})$"
fs=
for x in ${net_fs_list}; do
fs="${fs}${fs:+|}${x}"
done
[ -n "${fs}" ] && fs="^(${fs})$"
do_unmount "umount -r" \
--skip-point-regex "${m}" \
${fs:+--skip-fstype-regex} ${fs} --nonetdev
eoutdent
eend $?
}

View File

@@ -445,6 +445,35 @@ _load_config()
config_index=-1 config_index=-1
} }
# Support functions
_run_if()
{
local cmd=$1 iface=$2 ifr=${IFACE} ifv=${IFVAR}
# Ensure that we don't stamp on real values
local IFACE= IFVAR=
shift
if [ -n "${iface}" ]; then
IFACE="${iface}"
[ "${iface}" != "${ifr}" ] && IFVAR=$(shell_var "${IFACE}")
else
IFACE=${ifr}
IFVAR=${ifv}
fi
${cmd}
}
interface_exists()
{
_run_if _exists "$@"
}
interface_up()
{
_run_if _up "$@"
}
interface_down()
{
_run_if _down "$@"
}
start() start()
{ {
local IFACE=${RC_SVCNAME#*.} oneworked=false module= local IFACE=${RC_SVCNAME#*.} oneworked=false module=
@@ -581,7 +610,8 @@ ${routes}"
-net" "*|-host" "*);; -net" "*|-host" "*);;
*" "netmask" "*) cmd="-net ${cmd}";; *" "netmask" "*) cmd="-net ${cmd}";;
*.*.*.*/32*) cmd="-host ${cmd}";; *.*.*.*/32*) cmd="-host ${cmd}";;
*.*.*.*/*|0.0.0.0" "*|default" "*) cmd="-net ${cmd}";; *.*.*.*/*|0.0.0.0|0.0.0.0" "*) cmd="-net ${cmd}";;
default|default" "*) cmd="-net ${cmd}";;
*) cmd="-host ${cmd}";; *) cmd="-host ${cmd}";;
esac esac
if ${hidefirstroute}; then if ${hidefirstroute}; then

View File

@@ -6,6 +6,7 @@ description="Mounts misc filesystems in /proc."
depend() depend()
{ {
use devfs
need localmount need localmount
keyword noopenvz noprefix novserver keyword noopenvz noprefix novserver
} }
@@ -39,7 +40,7 @@ start()
# Setup Kernel Support for the NFS daemon status # Setup Kernel Support for the NFS daemon status
if [ -d /proc/fs/nfsd ] && ! mountinfo -q /proc/fs/nfsd; then if [ -d /proc/fs/nfsd ] && ! mountinfo -q /proc/fs/nfsd; then
if grep -qs nfsd /proc/filesystems; then if grep -qs nfsd /proc/filesystems; then
ebegin "Mounting nfsd filesystem" ebegin "Mounting NFS filesystem"
mount -t nfsd -o nodev,noexec,nosuid \ mount -t nfsd -o nodev,noexec,nosuid \
nfsd /proc/fs/nfsd nfsd /proc/fs/nfsd
eend $? eend $?
@@ -56,26 +57,6 @@ start()
fi fi
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 # Setup Kernel Support for SELinux
if [ -d /selinux ] && ! mountinfo -q /selinux; then if [ -d /selinux ] && ! mountinfo -q /selinux; then
if grep -qs selinuxfs /proc/filesystems; then if grep -qs selinuxfs /proc/filesystems; then

25
init.d/savecache.in Normal file
View File

@@ -0,0 +1,25 @@
#!@PREFIX@/sbin/runscript
# Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
description="Saves the caches OpenRC uses to non volatile storage"
start()
{
ebegin "Saving dependency cache"
if [ ! -d "${RC_LIBDIR}"/cache ]; then
rm -rf "${RC_LIBDIR}"/cache
if ! mkdir "${RC_LIBDIR}"/cache; then
eend $?
return $?
fi
fi
local save=
for x in deptree depconfig softlevel nettree rc.log; do
[ -e "${RC_SVCDIR}/${x}" ] && save="${save} ${RC_SVCDIR}/${x}"
done
if [ -n "${save}" ]; then
cp -p ${save} "${RC_LIBDIR}"/cache 2>/dev/null
fi
eend $?
}

63
init.d/sysfs.in Normal file
View File

@@ -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 -n -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 -n -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}
}

View File

@@ -18,7 +18,7 @@ MAKE_LINKS= suffix=$${man\#*.}; \
MK= ../mk MK= ../mk
include ${MK}/sys.mk include ${MK}/sys.mk
include ${MK}/gitignore.mk include ${MK}/svnignore.mk
all: all:

View File

@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd Feb 22, 2008 .Dd November 03, 2008
.Dt RC 8 SMM .Dt RC 8 SMM
.Os OpenRC .Os OpenRC
.Sh NAME .Sh NAME
@@ -60,18 +60,25 @@ sysinit always runs when the host first starts should not be run again.
Generally the only services you should add to the boot runlevel are those Generally the only services you should add to the boot runlevel are those
which deal with the mounting of filesystems, set the initial state of attached which deal with the mounting of filesystems, set the initial state of attached
peripherals and logging. peripherals and logging.
Coldplugged services are added to the boot runlevel by the system. Hotplugged services are added to the boot runlevel by the system.
All services in the boot runlevel are automatically included in all other All services in the boot and sysinit runlevels are automatically included
runlevels except for those listed here. in all other runlevels except for those listed here.
.It Ar single .It Ar single
Stops all services and enters single user mode. Stops all services except for those in the sysinit runlevel.
.It Ar reboot
Changes to the single runlevel and then reboots the host.
.It Ar shutdown .It Ar shutdown
Changes to the single runlevel and then halts the host. Changes to the single runlevel and then halts the host.
.El .El
.Pp
You should not call any of these runlevels yourself.
Instead you should use
.Xr init 8
and
.Xr shutdown 8
and let them call these special runlevels.
.Sh SEE ALSO .Sh SEE ALSO
.Xr rc-status 8 , .Xr rc-status 8 ,
.Xr rc-update 8 .Xr rc-update 8 ,
.Xr init 8 ,
.Xr shutdown 8
.Sh AUTHORS .Sh AUTHORS
.An Roy Marples <roy@marples.name> .An Roy Marples <roy@marples.name>

View File

@@ -111,11 +111,11 @@ You should define a
function for the service so that function for the service so that
.Nm .Nm
will start and stop it in the right order in relation to other services. will start and stop it in the right order in relation to other services.
As it's a function it can be very flexable, see the example below. As it's a function it can be very flexible, see the example below.
Here is a list of the functions you can use in a Here is a list of the functions you can use in a
.Ic depend .Ic depend
function. You simply pass the names of the services to it to add to that function. You simply pass the names of the services to it to add to that
dpendency type, or prefix it with ! to remove it. dependency type, or prefix it with ! to remove it.
.Bl -tag -width "RC_DEFAULTLEVEL" .Bl -tag -width "RC_DEFAULTLEVEL"
.It Ic need .It Ic need
The service will refuse to start until needed services have started and it The service will refuse to start until needed services have started and it

View File

@@ -129,7 +129,7 @@ option. Only useful when used with daemons that run in the foreground and
forced into the background with the forced into the background with the
.Fl -b , -background .Fl -b , -background
option. option.
.It Fl n , -nice Ar level .It Fl N , -nice Ar level
Modifies the scheduling priority of the daemon. Modifies the scheduling priority of the daemon.
.It Fl 1 , -stdout Ar logfile .It Fl 1 , -stdout Ar logfile
Redirect the standard output of the process to logfile when started with Redirect the standard output of the process to logfile when started with
@@ -148,7 +148,7 @@ These options are only used for stopping daemons:
.It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout .It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout
You can either specify a timeout or a multiple signal/timeout pairs as a You can either specify a timeout or a multiple signal/timeout pairs as a
stopping schedule. stopping schedule.
If not specified then a default value of SIGTERM/5 is If not specified then a default value of SIGTERM/0 is
assumed. assumed.
.El .El
.Sh ENVIRONMENT .Sh ENVIRONMENT
@@ -177,7 +177,7 @@ to stop or signal.
.Xr rc_find_pids 3 .Xr rc_find_pids 3
.Sh BUGS .Sh BUGS
.Nm .Nm
cannot stop an interperted daemon that no longer exists without a pidfile. cannot stop an interpreted daemon that no longer exists without a pidfile.
.Sh HISTORY .Sh HISTORY
.Nm .Nm
first appeared in Debian. first appeared in Debian.

2
mk/depend-.mk Normal file
View File

@@ -0,0 +1,2 @@
# This space left intentionally blank because gmake does not load .depend
# by default

3
mk/depend-gmake.mk Normal file
View File

@@ -0,0 +1,3 @@
# Tell gmake to include the optional dependency file.
# This sucks, but I don't know any other way of portably making this work.
-include .depend

View File

@@ -1,8 +1,5 @@
# This only works for make implementations that always include a .depend if # Generate .depend
# it exists. Only GNU make does not do this.
# Copyright 2008 Roy Marples <roy@marples.name> # Copyright 2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
CLEANFILES+= .depend CLEANFILES+= .depend
IGNOREFILES+= .depend IGNOREFILES+= .depend
@@ -10,4 +7,11 @@ IGNOREFILES+= .depend
.depend: ${SRCS} .depend: ${SRCS}
${CC} ${CPPFLAGS} -MM ${SRCS} > .depend ${CC} ${CPPFLAGS} -MM ${SRCS} > .depend
depend: .depend depend: .depend extra_depend
# Nasty hack. depend-.mk is a blank file, depend-gmake.mk has a gmake specific
# command to optionally include .depend.
# Someone should patch gmake to optionally include .depend if it exists.
_INC_DEP= $(shell if ${MAKE} --version | grep -q "^GNU "; then \
echo "gmake"; else echo ""; fi)
include ${MK}/depend-${_INC_DEP}.mk

View File

@@ -2,11 +2,12 @@
# Copyright 2008 Roy Marples <roy@marples.name> # Copyright 2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license. # All rights reserved. Released under the 2-clause BSD license.
GITREF?= HEAD
DISTPREFIX?= ${NAME}-${VERSION} DISTPREFIX?= ${NAME}-${VERSION}
DISTFILE?= ${DISTPREFIX}.tar.bz2 DISTFILE?= ${DISTPREFIX}.tar.bz2
CLEANFILES+= ${DISTFILE} CLEANFILES+= ${DISTFILE}
dist: dist:
git archive --prefix=${DISTPREFIX}/ ${GITREF} | bzip2 > ${DISTFILE} svn export . ${DISTPREFIX}
tar cjpf ${DISTFILE} ${DISTPREFIX}
rm -rf ${DISTPREFIX}

View File

@@ -1,15 +0,0 @@
# rules to make .gitignore files
# Copyright 2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
IGNOREFILES+= ${CLEANFILES}
.PHONY: .gitignore
.gitignore:
@if test -n "${IGNOREFILES}"; then \
echo "Ignoring ${IGNOREFILES}"; \
echo ${IGNOREFILES} | tr ' ' '\n' > .gitignore; \
fi
gitignore: .gitignore

View File

@@ -16,6 +16,9 @@ CLEANFILES+= ${OBJS} ${SOBJS} ${_LIBS} ${SHLIB_LINK}
.SUFFIXES: .So .SUFFIXES: .So
.c.o:
${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@
.c.So: .c.So:
${CC} ${PICFLAG} -DPIC ${CPPFLAGS} ${CFLAGS} -c $< -o $@ ${CC} ${PICFLAG} -DPIC ${CPPFLAGS} ${CFLAGS} -c $< -o $@
@@ -53,7 +56,12 @@ check test::
clean: clean:
rm -f ${OBJS} ${SOBJS} ${_LIBS} ${SHLIB_LINK} ${CLEANFILES} rm -f ${OBJS} ${SOBJS} ${_LIBS} ${SHLIB_LINK} ${CLEANFILES}
extra_depend:
@TMP=depend.$$$$; \
${SED} -e 's/^\([^\.]*\).o[ ]*:/\1.o \1.So:/' .depend > $${TMP}; \
mv $${TMP} .depend
include ${MK}/sys.mk include ${MK}/sys.mk
include ${MK}/os.mk include ${MK}/os.mk
include ${MK}/depend.mk include ${MK}/depend.mk
include ${MK}/gitignore.mk include ${MK}/svnignore.mk

View File

@@ -33,7 +33,9 @@ ${PROG}: ${SCRIPTS} ${OBJS}
clean: clean:
rm -f ${CLEANFILES} rm -f ${CLEANFILES}
extra_depend:
include ${MK}/sys.mk include ${MK}/sys.mk
include ${MK}/os.mk include ${MK}/os.mk
include ${MK}/depend.mk include ${MK}/depend.mk
include ${MK}/gitignore.mk include ${MK}/svnignore.mk

View File

@@ -56,4 +56,4 @@ CLEANFILES+= ${OBJS}
clean: clean:
@if test -n "${CLEANFILES}"; then echo "rm -f ${CLEANFILES}"; rm -f ${CLEANFILES}; fi @if test -n "${CLEANFILES}"; then echo "rm -f ${CLEANFILES}"; rm -f ${CLEANFILES}; fi
include ${MK}/gitignore.mk include ${MK}/svnignore.mk

View File

@@ -27,5 +27,5 @@ check test::
${_SUBDIR} ${_SUBDIR}
depend: depend:
${_SUBDIR} ${_SUBDIR}
gitignore: ignore:
${_SUBDIR} ${_SUBDIR}

14
mk/svnignore.mk Normal file
View File

@@ -0,0 +1,14 @@
# rules to make svn ignore files
# Copyright 2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
IGNOREFILES+= ${CLEANFILES}
ignore:
@if test -n "${IGNOREFILES}"; then \
echo "=> Ignoring ${IGNOREFILES}"; \
files="$$(echo "${IGNOREFILES}" | tr ' ' '\n')"; \
efiles="$$(svn propget svn:ignore .)"; \
sfiles="$$(printf "$${files}\n$${efiles}" | sort -u)"; \
eval svn propset svn:ignore \'"$${sfiles}"\' .; \
fi

2
net/.gitignore vendored
View File

@@ -1,2 +0,0 @@
ifconfig.sh
iwconfig.sh

View File

@@ -278,7 +278,7 @@ ifconfig_pre_start()
metric=1000 metric=1000
ebegin "Creating tunnel ${IFVAR}" ebegin "Creating tunnel ${IFVAR}"
iptunnel add "${tunnel}" iptunnel add ${tunnel}
eend $? eend $?
} }

View File

@@ -31,13 +31,13 @@ ifplugd_pre_start()
for f in bond bridge tuntap vlan wireless; do for f in bond bridge tuntap vlan wireless; do
if type "_is_${f}" >/dev/null 2>&1; then if type "_is_${f}" >/dev/null 2>&1; then
if _is_${f}; then if _is_${f}; then
veinfo "netplug does not work with" "${f}" veinfo "ifplugd does not work with ${f}"
return 0 return 0
fi fi
fi fi
done done
ebegin "Starting ifplugd on" "${IFACE}" ebegin "Starting ifplugd on ${IFACE}"
eval args=\$ifplugd_${IFVAR} eval args=\$ifplugd_${IFVAR}
@@ -47,7 +47,7 @@ ifplugd_pre_start()
# Start ifplugd # Start ifplugd
eval start-stop-daemon --start --exec /usr/sbin/ifplugd \ eval start-stop-daemon --start --exec /usr/sbin/ifplugd \
--pidfile "${pidfile}" -- "${args}" --iface="${IFACE}" --pidfile "${pidfile}" -- "${args}" --iface="${IFACE}"
eend "$?" || return 1 eend $? || return 1
eindent eindent
@@ -85,7 +85,7 @@ ifplugd_stop()
local pidfile="/var/run/ifplugd.${IFACE}.pid" local pidfile="/var/run/ifplugd.${IFACE}.pid"
[ ! -e "${pidfile}" ] && return 0 [ ! -e "${pidfile}" ] && return 0
ebegin "Stopping ifplugd on" "${IFACE}" ebegin "Stopping ifplugd on ${IFACE}"
start-stop-daemon --stop --quiet --exec /usr/sbin/ifplugd \ start-stop-daemon --stop --quiet --exec /usr/sbin/ifplugd \
--pidfile "${pidfile}" --signal QUIT --pidfile "${pidfile}" --signal QUIT
eend $? eend $?

View File

@@ -137,7 +137,7 @@ iwconfig_associate()
case "${caps}" in case "${caps}" in
[EI]P*) [EI]P*)
if [ "${key}" = "-" ] ; then if [ "${key}" = "-" ] ; then
ewarn "WEP key is not set for \"${SSID}\"; not connecting" ewarn "WEP key is not set for \"${SSID}\""
return 1 return 1
fi fi
;; ;;
@@ -145,7 +145,7 @@ iwconfig_associate()
*) *)
if [ "${key}" != "-" ] ; then if [ "${key}" != "-" ] ; then
key="-" key="-"
ewarn "\"${SSID}\" is not WEP enabled; ignoring setting" ewarn "\"${SSID}\" is not WEP enabled"
fi fi
;; ;;
esac esac

View File

@@ -250,12 +250,12 @@ iwconfig_associate()
SSIDVAR=$(shell_var "${SSID}") SSIDVAR=$(shell_var "${SSID}")
key="$(iwconfig_get_wep_key "${mac}")" key="$(iwconfig_get_wep_key "${mac}")"
if [ "${wep_required}" = "on" -a "${key}" = "off" ]; then if [ "${wep_required}" = "on" -a "${key}" = "off" ]; then
ewarn "WEP key is not set for \"${SSID}\" - not connecting" ewarn "WEP key is not set for \"${SSID}\""
return 1 return 1
fi fi
if [ "${wep_required}" = "off" -a "${key}" != "off" ]; then if [ "${wep_required}" = "off" -a "${key}" != "off" ]; then
key="off" key="off"
ewarn "\"${SSID}\" is not WEP enabled - ignoring setting" ewarn "\"${SSID}\" is not WEP enabled"
fi fi
if ! eval iwconfig "${IFACE}" key "${key}"; then if ! eval iwconfig "${IFACE}" key "${key}"; then

View File

@@ -1,22 +1,33 @@
BOOT= bootmisc fsck hostname localmount \ BOOT= bootmisc fsck hostname localmount \
root swap sysctl urandom root swap sysctl urandom
DEFAULT= local netmount DEFAULT= local netmount
SHUTDOWN= savecache
LEVELDIR= ${DESTDIR}/${SYSCONFDIR}/runlevels LEVELDIR= ${DESTDIR}/${SYSCONFDIR}/runlevels
SYSINITDIR= ${LEVELDIR}/sysinit
BOOTDIR= ${LEVELDIR}/boot BOOTDIR= ${LEVELDIR}/boot
DEFAULTDIR= ${LEVELDIR}/default DEFAULTDIR= ${LEVELDIR}/default
SHUTDOWNDIR= ${LEVELDIR}/shutdown
INITDIR= ../init.d INITDIR= ../init.d
MK= ../mk MK= ../mk
include ${MK}/sys.mk include ${MK}/sys.mk
include ${MK}/os.mk include ${MK}/os.mk
include ${MK}/gitignore.mk include ${MK}/svnignore.mk
include Makefile.${OS} include Makefile.${OS}
all: all:
install: 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 \ if ! test -d "${BOOTDIR}"; then \
${INSTALL} -d ${BOOTDIR} || exit $$?; \ ${INSTALL} -d ${BOOTDIR} || exit $$?; \
for x in ${BOOT}; do \ for x in ${BOOT}; do \
@@ -35,6 +46,14 @@ install:
fi; \ fi; \
ln -snf ${PREFIX}/etc/init.d/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \ ln -snf ${PREFIX}/etc/init.d/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
fi fi
if ! test -d "${SHUTDOWNDIR}"; then \
${INSTALL} -d ${SHUTDOWNDIR} || exit $$?; \
for x in ${SHUTDOWN}; do \
if test -n "${PREFIX}"; then \
grep -q "keyword .*noprefix" ${INITDIR}/"$$x" && continue; \
fi; \
ln -snf ${PREFIX}/etc/init.d/"$$x" ${SHUTDOWNDIR}/"$$x" || exit $$?; done \
fi
check test:: check test::

View File

@@ -1,2 +1,3 @@
BOOT+= hwclock consolefont keymaps modules mtab net.lo procfs \ SYSINIT+= devfs dmesg
termencoding BOOT+= hwclock keymaps modules mtab net.lo procfs termencoding
SHUTDOWN+= killprocs mount-ro

10
sh/.gitignore vendored
View File

@@ -1,10 +0,0 @@
functions.sh
gendepends.sh
net.sh
rc-functions.sh
runscript.sh
init-common-post.sh
init-early.sh
init.sh
ifwatchd-carrier.sh
ifwatchd-nocarrier.sh

View File

@@ -9,21 +9,15 @@ retval=0
RC_SVCDIR=${RC_SVCDIR:-/@LIB@/rc/init.d} RC_SVCDIR=${RC_SVCDIR:-/@LIB@/rc/init.d}
if [ "${RC_SVCDIR}" != "/" ] && mkdir "${RC_SVCDIR}/.test.$$" 2>/dev/null; then if [ "${RC_SVCDIR}" != "/" ] && mkdir "${RC_SVCDIR}/.test.$$" 2>/dev/null; then
rmdir "${RC_SVCDIR}/.test.$$" rmdir "${RC_SVCDIR}/.test.$$"
for x in ${RC_SVCDIR}/*; do rm -rf "${RC_SVCDIR}"/*
[ -e "${x}" ] || continue
case ${x##*/} in
depconfig|deptree|ksoftlevel|rc.log);;
*) rm -rf "${x}";;
esac
done
else else
mount_svcdir mount_svcdir
retval=$? retval=$?
fi fi
if [ -e "${RC_LIBDIR}"/cache/deptree ]; then
cp -p "${RC_LIBDIR}"/cache/* "${RC_SVCDIR}" 2>/dev/null
fi
echo "sysinit" > "${RC_SVCDIR}/softlevel" 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} exit ${retval}

View File

@@ -10,18 +10,6 @@
# FreeBSD-7 supports tmpfs now :) # FreeBSD-7 supports tmpfs now :)
mount_svcdir() mount_svcdir()
{ {
local dotmp=false release=false retval=0
if [ -e "${RC_SVCDIR}"/deptree ]; then
dotmp=true
if ! mount -t tmpfs none "${RC_LIBDIR}"/tmp 2>/dev/null; then
mdconfig -a -t malloc -s 1m -u 1
newfs /dev/md1
mount /dev/md1 "${RC_LIBDIR}"/tmp
release=true
fi
cp -p "${RC_SVCDIR}"/deptree "${RC_SVCDIR}"/depconfig \
"${RC_SVCDIR}"/nettree "${RC_LIBDIR}"/tmp 2>/dev/null
fi
if ! fstabinfo --mount "${RC_SVCDIR}"; then if ! fstabinfo --mount "${RC_SVCDIR}"; then
if ! mount -t tmpfs -o rw,noexec,nosuid none "${RC_SVCDIR}" 2>/dev/null; then if ! mount -t tmpfs -o rw,noexec,nosuid none "${RC_SVCDIR}" 2>/dev/null; then
mdconfig -a -t malloc -s "${rc_svcsize:-1024}"k -u 0 mdconfig -a -t malloc -s "${rc_svcsize:-1024}"k -u 0
@@ -29,15 +17,6 @@ mount_svcdir()
mount -o rw,noexec,nosuid /dev/md0 "${RC_SVCDIR}" mount -o rw,noexec,nosuid /dev/md0 "${RC_SVCDIR}"
fi fi
fi fi
retval=$?
if ${dotmp}; then
cp -p "${RC_LIBDIR}"/tmp/deptree "${RC_LIBDIR}"/tmp/depconfig \
"${RC_LIBDIR}"/tmp/nettree "${RC_SVCDIR}" 2>/dev/null
umount "${RC_LIBDIR}"/tmp
${release} && mdconfig -d -u 1
fi
return ${retval}
} }
. "${RC_LIBDIR}"/sh/functions.sh . "${RC_LIBDIR}"/sh/functions.sh

View File

@@ -3,13 +3,13 @@
# Copyright 2007-2008 Roy Marples <roy@marples.name> # Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license. # All rights reserved. Released under the 2-clause BSD license.
# This basically mounts $RC_SVCDIR as a ramdisk, but preserving its content # This basically mounts $RC_SVCDIR as a ramdisk.
# which allows us to store service state and generate dependencies if needed.
# The tricky part is finding something our kernel supports # The tricky part is finding something our kernel supports
# tmpfs and ramfs are easy, so force one or the other. # tmpfs and ramfs are easy, so force one or the other.
mount_svcdir() 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" x=
local svcsize=${rc_svcsize:-1024} local svcsize=${rc_svcsize:-1024}
if grep -Eq "[[:space:]]+tmpfs$" /proc/filesystems; then if grep -Eq "[[:space:]]+tmpfs$" /proc/filesystems; then
@@ -18,55 +18,29 @@ mount_svcdir()
elif grep -Eq "[[:space:]]+ramfs$" /proc/filesystems; then elif grep -Eq "[[:space:]]+ramfs$" /proc/filesystems; then
fs="ramfs" fs="ramfs"
# ramfs has no special options # ramfs has no special options
elif [ -e /dev/ram0 -a -e /dev/ram1 ] \ elif [ -e /dev/ram0 ] \
&& grep -Eq "[[:space:]]+ext2$" /proc/filesystems; then && grep -Eq "[[:space:]]+ext2$" /proc/filesystems; then
devdir="/dev/ram0" devdir="/dev/ram0"
devtmp="/dev/ram1"
fs="ext2" fs="ext2"
for x in ${devdir} ${devtmp}; do dd if=/dev/zero of="${devdir}" bs=1k count="${svcsize}"
dd if=/dev/zero of="${x}" bs=1k count="${svcsize}" mkfs -t "${fs}" -i 1024 -vm0 "${devdir}" "${svcsize}"
mkfs -t "${fs}" -i 1024 -vm0 "${x}" "${svcsize}"
done
else else
echo echo
eerror "OpenRC requires tmpfs, ramfs or 2 ramdisks + ext2" eerror "OpenRC requires tmpfs, ramfs or a ramdisk + ext2"
eerror "compiled into the kernel" eerror "compiled into the kernel"
echo echo
return 1 return 1
fi fi
local dotmp=false
if [ -e "${RC_SVCDIR}"/deptree ]; then
dotmp=true
mount -n -t "${fs}" -o rw "${devtmp}" "${RC_LIBDIR}"/tmp
cp -p "${RC_SVCDIR}"/deptree "${RC_SVCDIR}"/depconfig \
"${RC_SVCDIR}"/nettree "${RC_LIBDIR}"/tmp 2>/dev/null
fi
# If we have no entry in fstab for $RC_SVCDIR, provide our own # If we have no entry in fstab for $RC_SVCDIR, provide our own
if ! fstabinfo --mount "${RC_SVCDIR}"; then if ! fstabinfo --mount "${RC_SVCDIR}"; then
mount -n -t "${fs}" ${fsopts} "${devdir}" "${RC_SVCDIR}" mount -n -t "${fs}" ${fsopts} "${devdir}" "${RC_SVCDIR}"
fi fi
if ${dotmp}; then
cp -p "${RC_LIBDIR}"/tmp/deptree "${RC_LIBDIR}"/tmp/depconfig \
"${RC_LIBDIR}"/tmp/nettree "${RC_SVCDIR}" 2>/dev/null
umount -n "${RC_LIBDIR}"/tmp
fi
} }
. /etc/init.d/functions.sh . /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 [ -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! # By default VServer already has /proc mounted, but OpenVZ does not!
# However, some of our users have an old proc image in /proc # 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 # NFC how they managed that, but the end result means we have to test if
@@ -82,7 +56,6 @@ if [ -e /proc/uptime ]; then
einfo "/proc is already mounted, skipping" einfo "/proc is already mounted, skipping"
mountproc=false mountproc=false
fi fi
unset up
fi fi
if ${mountproc}; then if ${mountproc}; then
@@ -94,98 +67,5 @@ if ${mountproc}; then
fi fi
eend $? eend $?
fi 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 . "${RC_LIBDIR}"/sh/init-common-post.sh

View File

@@ -7,11 +7,21 @@ has_addon()
[ -e "${RC_LIBDIR}/addons/$1.sh" ] || [ -e /@LIB@/rcscripts/addons/"$1".sh ] [ -e "${RC_LIBDIR}/addons/$1.sh" ] || [ -e /@LIB@/rcscripts/addons/"$1".sh ]
} }
_addon_warn()
{
eindent
ewarn "${RC_SVCNAME} uses addon code which is deprecated"
ewarn "and may not be available in the future."
eoutdent
}
import_addon() import_addon()
{ {
if [ -e "${RC_LIBDIR}/addons/$1.sh" ]; then if [ -e "${RC_LIBDIR}/addons/$1.sh" ]; then
_addon_warn
. "${RC_LIBDIR}/addons/$1.sh" . "${RC_LIBDIR}/addons/$1.sh"
elif [ -e /@LIB@/rcscripts/addons/"$1".sh ]; then elif [ -e /@LIB@/rcscripts/addons/"$1".sh ]; then
_addon_warn
. /@LIB@/rcscripts/addons/"$1".sh . /@LIB@/rcscripts/addons/"$1".sh
else else
return 1 return 1

View File

@@ -1,6 +1,10 @@
# Copyright 2007-2008 Roy Marples <roy@marples.name> # Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license. # All rights reserved. Released under the 2-clause BSD license.
# Declare this here so that no formatting doesn't affect the embedded newline
__IFS="
"
# Handy function to handle all our unmounting needs # Handy function to handle all our unmounting needs
# mountinfo is a C program to actually find our mounts on our supported OS's # mountinfo is a C program to actually find our mounts on our supported OS's
# We rely on fuser being preset, so if it's not then we don't unmount anything. # We rely on fuser being preset, so if it's not then we don't unmount anything.
@@ -15,17 +19,20 @@ do_unmount()
fi fi
shift shift
mountinfo "$@" | while read mnt; do local IFS="$__IFS"
set -- $(mountinfo "$@")
unset IFS
for mnt; do
# Unmounting a shared mount can unmount other mounts, so # Unmounting a shared mount can unmount other mounts, so
# we need to check the mount is still valid # we need to check the mount is still valid
mountinfo --quiet "${mnt}" || continue mountinfo --quiet "${mnt}" || continue
case "${cmd}" in case "${cmd}" in
umount*) umount)
ebegin "Unmounting ${mnt}" ebegin "Unmounting ${mnt}"
;; ;;
*) *)
ebegin "Remounting ${mnt}" ebegin "Remounting ${mnt} read only"
;; ;;
esac esac

View File

@@ -143,7 +143,6 @@ char *rc_conf_value(const char *var);
bool rc_conf_yesno(const char *var); bool rc_conf_yesno(const char *var);
void env_filter(void); void env_filter(void);
void env_config(void); void env_config(void);
bool service_plugable(const char *service);
int signal_setup(int sig, void (*handler)(int)); int signal_setup(int sig, void (*handler)(int));
pid_t exec_service(const char *, const char *); pid_t exec_service(const char *, const char *);

View File

@@ -1,7 +0,0 @@
.depend
libeinfo.o
libeinfo.So
libeinfo.a
libeinfo.so.1
libeinfo.so
.depend

View File

@@ -28,13 +28,11 @@
#define __EINFO_H__ #define __EINFO_H__
#if defined(__GNUC__) #if defined(__GNUC__)
# define __EINFO_PRINTF __attribute__ ((__format__ (__printf__, 1, 2))) # define EINFO_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
# define __EINFO_XPRINTF __attribute__ ((__noreturn__, __format__ (__printf__, 1, 2))) # define EINFO_XPRINTF(a, b) __attribute__((__noreturn__,__format__(__printf__, a, b)))
# define __EEND_PRINTF __attribute__ ((__format__ (__printf__, 2, 3)))
#else #else
# define __EINFO_PRINTF # define EINFO_PRINTF(a, b)
# define __EINFO_XPRINTF # define EINFO_XPRINTF(a, b)
# define __EEND_PRINTF
#endif #endif
#include <sys/types.h> #include <sys/types.h>
@@ -42,12 +40,12 @@
/* Although OpenRC requires C99, linking to us should not. */ /* Although OpenRC requires C99, linking to us should not. */
#ifdef restrict #ifdef restrict
# define __EINFO_RESTRICT restrict # define EINFO_RESTRICT restrict
#else #else
# ifdef __restrict # ifdef __restrict
# define __EINFO_RESTRICT __restrict # define EINFO_RESTRICT __restrict
# else # else
# define __EINFO_RESTRICT # define EINFO_RESTRICT
# endif # endif
#endif #endif
@@ -68,7 +66,7 @@ typedef enum
const char *ecolor(ECOLOR); const char *ecolor(ECOLOR);
/*! @brief Writes to syslog. */ /*! @brief Writes to syslog. */
void elog(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; void elog(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
/*! /*!
* @brief Display informational messages. * @brief Display informational messages.
@@ -86,22 +84,22 @@ void elog(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
* The v suffix means only print if EINFO_VERBOSE is yes. * The v suffix means only print if EINFO_VERBOSE is yes.
*/ */
/*@{*/ /*@{*/
int einfon(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int einfon(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ewarnn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int eerrorn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int eerrorn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int einfo(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int einfo(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ewarn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
void ewarnx(const char * __EINFO_RESTRICT, ...) __EINFO_XPRINTF; void ewarnx(const char * __EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
int eerror(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int eerror(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
void eerrorx(const char * __EINFO_RESTRICT, ...) __EINFO_XPRINTF; void eerrorx(const char * __EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
int einfovn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int einfovn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnvn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ewarnvn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ebeginvn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ebeginvn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int eendvn(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; int eendvn(int, const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int ewendvn(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; int ewendvn(int, const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int einfov(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int einfov(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ewarnv(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ewarnv(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
/*@}*/ /*@}*/
/*! @ingroup ebegin /*! @ingroup ebegin
@@ -109,8 +107,8 @@ int ewarnv(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
* *
* Similar to einfo, but we add ... to the end of the message */ * Similar to einfo, but we add ... to the end of the message */
/*@{*/ /*@{*/
int ebeginv(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ebeginv(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
int ebegin(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF; int ebegin(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
/*@}*/ /*@}*/
/*! @ingroup eend /*! @ingroup eend
@@ -122,12 +120,12 @@ int ebegin(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
* *
* ebracket allows you to specifiy the position, color and message */ * ebracket allows you to specifiy the position, color and message */
/*@{*/ /*@{*/
int eend(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; int eend(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int ewend(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; int ewend(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
void ebracket(int, ECOLOR, const char * __EINFO_RESTRICT); void ebracket(int, ECOLOR, const char * EINFO_RESTRICT);
int eendv(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; int eendv(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
int ewendv(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF; int ewendv(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
/*@}*/ /*@}*/
/*! @ingroup eindent /*! @ingroup eindent
@@ -141,7 +139,7 @@ void eindentv(void);
void eoutdentv(void); void eoutdentv(void);
/*! @brief Prefix each einfo line with something */ /*! @brief Prefix each einfo line with something */
void eprefix(const char * __EINFO_RESTRICT); void eprefix(const char * EINFO_RESTRICT);
__END_DECLS __END_DECLS
#endif #endif

View File

@@ -306,17 +306,71 @@ is_verbose(void)
/* Fake tgoto call - very crapy, but works for our needs */ /* Fake tgoto call - very crapy, but works for our needs */
#ifndef HAVE_TERMCAP #ifndef HAVE_TERMCAP
static char * static char *
tgoto(const char *cap, int a, int b) tgoto(const char *cap, int col, int line)
{ {
static char buf[20]; static char buf[20];
char *p, *e, c, dbuf[6];
int oncol = 0, which = line, i;
snprintf(buf, sizeof(buf), cap, b, a); p = buf;
e = p + sizeof(buf);
while ((c = *cap++)) {
if (c != '%' || ((c = *cap++) == '%')) {
*p++ = c;
if (p >= e) {
errno = E2BIG;
return NULL;
}
continue;
}
switch (c) {
case '3':
case '2':
case 'd':
i = 0;
do
dbuf[i++] = which % 10 | '0';
while ((which /= 10));
if (c != 'd') {
c -= '0';
if (i > c) {
errno = EINVAL;
return NULL;
}
while (i < c)
dbuf[i++] = '0';
}
if (p + i >= e) {
errno = E2BIG;
return NULL;
}
do
*p++ = dbuf[--i];
while (i);
break;
case 'r':
oncol = 0;
break;
case 'i':
col++;
line++;
which++;
continue;
default:
errno = EINVAL;
return NULL;
}
oncol = 1 - oncol;
which = oncol ? col : line;
}
*p = '\0';
return buf; return buf;
} }
#endif #endif
static bool static bool
colour_terminal(FILE * __EINFO_RESTRICT f) colour_terminal(FILE * EINFO_RESTRICT f)
{ {
static int in_colour = -1; static int in_colour = -1;
char *e, *ee, *end, *d, *p; char *e, *ee, *end, *d, *p;
@@ -460,7 +514,7 @@ colour_terminal(FILE * __EINFO_RESTRICT f)
} }
static int static int
get_term_columns(FILE * __EINFO_RESTRICT stream) get_term_columns(FILE * EINFO_RESTRICT stream)
{ {
struct winsize ws; struct winsize ws;
char *env = getenv("COLUMNS"); char *env = getenv("COLUMNS");
@@ -480,14 +534,14 @@ get_term_columns(FILE * __EINFO_RESTRICT stream)
} }
void void
eprefix(const char *__EINFO_RESTRICT prefix) eprefix(const char *EINFO_RESTRICT prefix)
{ {
_eprefix = prefix; _eprefix = prefix;
} }
hidden_def(eprefix) hidden_def(eprefix)
static void static void EINFO_PRINTF(2, 0)
elogv(int level, const char *__EINFO_RESTRICT fmt, va_list ap) elogv(int level, const char *EINFO_RESTRICT fmt, va_list ap)
{ {
char *e = getenv("EINFO_LOG"); char *e = getenv("EINFO_LOG");
va_list apc; va_list apc;
@@ -503,7 +557,7 @@ elogv(int level, const char *__EINFO_RESTRICT fmt, va_list ap)
} }
void void
elog(int level, const char *__EINFO_RESTRICT fmt, ...) elog(int level, const char *EINFO_RESTRICT fmt, ...)
{ {
va_list ap; va_list ap;
@@ -514,7 +568,7 @@ elog(int level, const char *__EINFO_RESTRICT fmt, ...)
hidden_def(elog) hidden_def(elog)
static int static int
_eindent(FILE * __EINFO_RESTRICT stream) _eindent(FILE * EINFO_RESTRICT stream)
{ {
char *env = getenv("EINFO_INDENT"); char *env = getenv("EINFO_INDENT");
int amount = 0; int amount = 0;
@@ -538,7 +592,7 @@ _eindent(FILE * __EINFO_RESTRICT stream)
} }
static const char * static const char *
_ecolor(FILE * __EINFO_RESTRICT f, ECOLOR color) _ecolor(FILE * EINFO_RESTRICT f, ECOLOR color)
{ {
unsigned int i; unsigned int i;
@@ -575,9 +629,8 @@ ecolor(ECOLOR color)
setenv("EINFO_LASTCMD", _cmd, 1); \ setenv("EINFO_LASTCMD", _cmd, 1); \
} }
static int static int EINFO_PRINTF(3, 0)
_einfo(FILE *f, ECOLOR color, const char *__EINFO_RESTRICT fmt, va_list va) _einfo(FILE *f, ECOLOR color, const char *EINFO_RESTRICT fmt, va_list va)
{ {
int retval = 0; int retval = 0;
char *last = getenv("EINFO_LASTCMD"); char *last = getenv("EINFO_LASTCMD");
@@ -590,7 +643,7 @@ _einfo(FILE *f, ECOLOR color, const char *__EINFO_RESTRICT fmt, va_list va)
fprintf(f, "\n"); fprintf(f, "\n");
if (_eprefix) if (_eprefix)
fprintf(f, "%s%s%s|", _ecolor(f, color), _eprefix, _ecolor(f, ECOLOR_NORMAL)); fprintf(f, "%s%s%s|", _ecolor(f, color), _eprefix, _ecolor(f, ECOLOR_NORMAL));
fprintf(f, " %s*%s ", _ecolor(f, color), _ecolor(f, ECOLOR_NORMAL)); fprintf(f, "%s*%s ", _ecolor(f, color), _ecolor(f, ECOLOR_NORMAL));
retval += _eindent(f); retval += _eindent(f);
va_copy(ap, va); va_copy(ap, va);
retval += vfprintf(f, fmt, ap) + 3; retval += vfprintf(f, fmt, ap) + 3;
@@ -605,7 +658,7 @@ _einfo(FILE *f, ECOLOR color, const char *__EINFO_RESTRICT fmt, va_list va)
#define _eerrorvn(fmt, ap) _einfo(stderr, ECOLOR_BAD, fmt, ap) #define _eerrorvn(fmt, ap) _einfo(stderr, ECOLOR_BAD, fmt, ap)
int int
einfon(const char *__EINFO_RESTRICT fmt, ...) einfon(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -621,7 +674,7 @@ einfon(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(einfon) hidden_def(einfon)
int int
ewarnn(const char *__EINFO_RESTRICT fmt, ...) ewarnn(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -637,7 +690,7 @@ ewarnn(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ewarnn) hidden_def(ewarnn)
int int
eerrorn(const char *__EINFO_RESTRICT fmt, ...) eerrorn(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -651,7 +704,7 @@ eerrorn(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(eerrorn) hidden_def(eerrorn)
int int
einfo(const char *__EINFO_RESTRICT fmt, ...) einfo(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -668,7 +721,7 @@ einfo(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(einfo) hidden_def(einfo)
int int
ewarn(const char *__EINFO_RESTRICT fmt, ...) ewarn(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -686,7 +739,7 @@ ewarn(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ewarn) hidden_def(ewarn)
void void
ewarnx(const char *__EINFO_RESTRICT fmt, ...) ewarnx(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -703,7 +756,7 @@ ewarnx(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ewarnx) hidden_def(ewarnx)
int int
eerror(const char *__EINFO_RESTRICT fmt, ...) eerror(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -721,7 +774,7 @@ eerror(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(eerror) hidden_def(eerror)
void void
eerrorx(const char *__EINFO_RESTRICT fmt, ...) eerrorx(const char *EINFO_RESTRICT fmt, ...)
{ {
va_list ap; va_list ap;
@@ -737,7 +790,7 @@ eerrorx(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(eerrorx) hidden_def(eerrorx)
int int
ebegin(const char *__EINFO_RESTRICT fmt, ...) ebegin(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -747,7 +800,7 @@ ebegin(const char *__EINFO_RESTRICT fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
retval = _einfovn(fmt, ap); retval = _einfovn(fmt, ap);
va_end(ap); va_end(ap);
retval += printf(" ..."); retval += printf("...");
if (colour_terminal(stdout)) if (colour_terminal(stdout))
retval += printf("\n"); retval += printf("\n");
LASTCMD("ebegin"); LASTCMD("ebegin");
@@ -756,7 +809,7 @@ ebegin(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ebegin) hidden_def(ebegin)
static void static void
_eend(FILE * __EINFO_RESTRICT fp, int col, ECOLOR color, const char *msg) _eend(FILE * EINFO_RESTRICT fp, int col, ECOLOR color, const char *msg)
{ {
int i; int i;
int cols; int cols;
@@ -793,8 +846,8 @@ _eend(FILE * __EINFO_RESTRICT fp, int col, ECOLOR color, const char *msg)
} }
} }
static int static int EINFO_PRINTF(3, 0)
_do_eend(const char *cmd, int retval, const char *__EINFO_RESTRICT fmt, va_list ap) _do_eend(const char *cmd, int retval, const char *EINFO_RESTRICT fmt, va_list ap)
{ {
int col = 0; int col = 0;
FILE *fp = stdout; FILE *fp = stdout;
@@ -817,7 +870,7 @@ _do_eend(const char *cmd, int retval, const char *__EINFO_RESTRICT fmt, va_list
} }
int int
eend(int retval, const char *__EINFO_RESTRICT fmt, ...) eend(int retval, const char *EINFO_RESTRICT fmt, ...)
{ {
va_list ap; va_list ap;
@@ -832,7 +885,7 @@ eend(int retval, const char *__EINFO_RESTRICT fmt, ...)
hidden_def(eend) hidden_def(eend)
int int
ewend(int retval, const char *__EINFO_RESTRICT fmt, ...) ewend(int retval, const char *EINFO_RESTRICT fmt, ...)
{ {
va_list ap; va_list ap;
@@ -900,7 +953,7 @@ void eoutdent(void)
hidden_def(eoutdent) hidden_def(eoutdent)
int int
einfovn(const char *__EINFO_RESTRICT fmt, ...) einfovn(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -916,7 +969,7 @@ einfovn(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(einfovn) hidden_def(einfovn)
int int
ewarnvn(const char *__EINFO_RESTRICT fmt, ...) ewarnvn(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -932,7 +985,7 @@ ewarnvn(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ewarnvn) hidden_def(ewarnvn)
int int
einfov(const char *__EINFO_RESTRICT fmt, ...) einfov(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -949,7 +1002,7 @@ einfov(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(einfov) hidden_def(einfov)
int int
ewarnv(const char *__EINFO_RESTRICT fmt, ...) ewarnv(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -966,7 +1019,7 @@ ewarnv(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ewarnv) hidden_def(ewarnv)
int int
ebeginv(const char *__EINFO_RESTRICT fmt, ...) ebeginv(const char *EINFO_RESTRICT fmt, ...)
{ {
int retval; int retval;
va_list ap; va_list ap;
@@ -976,7 +1029,7 @@ ebeginv(const char *__EINFO_RESTRICT fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
retval = _einfovn(fmt, ap); retval = _einfovn(fmt, ap);
retval += printf(" ..."); retval += printf("...");
if (colour_terminal(stdout)) if (colour_terminal(stdout))
retval += printf("\n"); retval += printf("\n");
va_end(ap); va_end(ap);
@@ -986,7 +1039,7 @@ ebeginv(const char *__EINFO_RESTRICT fmt, ...)
hidden_def(ebeginv) hidden_def(ebeginv)
int int
eendv(int retval, const char *__EINFO_RESTRICT fmt, ...) eendv(int retval, const char *EINFO_RESTRICT fmt, ...)
{ {
va_list ap; va_list ap;
@@ -1001,7 +1054,7 @@ eendv(int retval, const char *__EINFO_RESTRICT fmt, ...)
hidden_def(eendv) hidden_def(eendv)
int int
ewendv(int retval, const char *__EINFO_RESTRICT fmt, ...) ewendv(int retval, const char *EINFO_RESTRICT fmt, ...)
{ {
va_list ap; va_list ap;

16
src/librc/.gitignore vendored
View File

@@ -1,16 +0,0 @@
.depend
librc.o
librc-daemon.o
librc-depend.o
librc-misc.o
librc-stringlist.o
librc.So
librc-daemon.So
librc-depend.So
librc-misc.So
librc-stringlist.So
librc.a
librc.so.1
librc.so
.depend
rc.h

View File

@@ -187,18 +187,30 @@ valid_service(const char *runlevel, const char *service, const char *type)
strcmp(type, "needsme") == 0) strcmp(type, "needsme") == 0)
return true; return true;
if (rc_service_in_runlevel(service, runlevel))
return true;
if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
return false;
if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 &&
strcmp(type, "iafter") == 0)
return false;
if (strcmp(runlevel, bootlevel) != 0) {
if (rc_service_in_runlevel(service, bootlevel))
return true;
}
state = rc_service_state(service); state = rc_service_state(service);
return ((strcmp(runlevel, bootlevel) != 0 && if (state & RC_SERVICE_HOTPLUGGED ||
rc_service_in_runlevel(service, bootlevel)) || state & RC_SERVICE_STARTED)
rc_service_in_runlevel(service, runlevel) || return true;
state & RC_SERVICE_COLDPLUGGED ||
state & RC_SERVICE_STARTED); return false;
} }
static bool static bool
get_provided1(const char *runlevel, RC_STRINGLIST *providers, get_provided1(const char *runlevel, RC_STRINGLIST *providers,
RC_DEPTYPE *deptype, const char *level, RC_DEPTYPE *deptype, const char *level,
bool coldplugged, RC_SERVICE state) bool hotplugged, RC_SERVICE state)
{ {
RC_STRING *service; RC_STRING *service;
RC_SERVICE st; RC_SERVICE st;
@@ -213,8 +225,8 @@ get_provided1(const char *runlevel, RC_STRINGLIST *providers,
if (level) if (level)
ok = rc_service_in_runlevel(svc, level); ok = rc_service_in_runlevel(svc, level);
else if (coldplugged) else if (hotplugged)
ok = (st & RC_SERVICE_COLDPLUGGED && ok = (st & RC_SERVICE_HOTPLUGGED &&
!rc_service_in_runlevel(svc, runlevel) && !rc_service_in_runlevel(svc, runlevel) &&
!rc_service_in_runlevel(svc, bootlevel)); !rc_service_in_runlevel(svc, bootlevel));
if (!ok) if (!ok)
@@ -272,13 +284,13 @@ get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
} }
/* If we're strict or starting, then only use what we have in our /* If we're strict or starting, then only use what we have in our
* runlevel and bootlevel. If we starting then check cold-plugged too. */ * runlevel and bootlevel. If we starting then check hotplugged too. */
if (options & RC_DEP_STRICT || options & RC_DEP_START) { if (options & RC_DEP_STRICT || options & RC_DEP_START) {
TAILQ_FOREACH(service, dt->services, entries) TAILQ_FOREACH(service, dt->services, entries)
if (rc_service_in_runlevel(service->value, runlevel) || if (rc_service_in_runlevel(service->value, runlevel) ||
rc_service_in_runlevel(service->value, bootlevel) || rc_service_in_runlevel(service->value, bootlevel) ||
(options & RC_DEP_START && (options & RC_DEP_START &&
rc_service_state(service->value) & RC_SERVICE_COLDPLUGGED)) rc_service_state(service->value) & RC_SERVICE_HOTPLUGGED))
rc_stringlist_add(providers, service->value); rc_stringlist_add(providers, service->value);
if (TAILQ_FIRST(providers)) if (TAILQ_FIRST(providers))
return providers; return providers;
@@ -292,7 +304,7 @@ get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
* We apply this to these states in order:- * We apply this to these states in order:-
* started, starting | stopping | inactive, stopped * started, starting | stopping | inactive, stopped
* Our sub preference in each of these is in order:- * Our sub preference in each of these is in order:-
* runlevel, coldplugged, bootlevel, any * runlevel, hotplugged, bootlevel, any
*/ */
#define DO \ #define DO \
if (TAILQ_FIRST(providers)) { \ if (TAILQ_FIRST(providers)) { \
@@ -344,7 +356,7 @@ get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
static void static void
visit_service(const RC_DEPTREE *deptree, visit_service(const RC_DEPTREE *deptree,
const RC_STRINGLIST *types, const RC_STRINGLIST *types,
RC_STRINGLIST **sorted, RC_STRINGLIST *sorted,
RC_STRINGLIST *visited, RC_STRINGLIST *visited,
const RC_DEPINFO *depinfo, const RC_DEPINFO *depinfo,
const char *runlevel, int options) const char *runlevel, int options)
@@ -373,9 +385,7 @@ visit_service(const RC_DEPTREE *deptree,
if (!(options & RC_DEP_TRACE) || if (!(options & RC_DEP_TRACE) ||
strcmp(type->value, "iprovide") == 0) strcmp(type->value, "iprovide") == 0)
{ {
if (!*sorted) rc_stringlist_add(sorted, service->value);
*sorted = rc_stringlist_new();
rc_stringlist_add(*sorted, service->value);
continue; continue;
} }
@@ -420,12 +430,10 @@ visit_service(const RC_DEPTREE *deptree,
/* We've visited everything we need, so add ourselves unless we /* We've visited everything we need, so add ourselves unless we
are also the service calling us or we are provided by something */ are also the service calling us or we are provided by something */
svcname = getenv("RC_SVCNAME"); svcname = getenv("RC_SVCNAME");
if (!svcname || strcmp(svcname, depinfo->service) != 0) if (!svcname || strcmp(svcname, depinfo->service) != 0) {
if (!get_deptype(depinfo, "providedby")) { if (!get_deptype(depinfo, "providedby"))
if (!*sorted) rc_stringlist_add(sorted, depinfo->service);
*sorted = rc_stringlist_new(); }
rc_stringlist_add(*sorted, depinfo->service);
}
} }
RC_STRINGLIST * RC_STRINGLIST *
@@ -437,15 +445,15 @@ rc_deptree_depend(const RC_DEPTREE *deptree,
RC_STRINGLIST *svcs; RC_STRINGLIST *svcs;
RC_STRING *svc; RC_STRING *svc;
svcs = rc_stringlist_new();
if (!(di = get_depinfo(deptree, service)) || if (!(di = get_depinfo(deptree, service)) ||
!(dt = get_deptype(di, type))) !(dt = get_deptype(di, type)))
{ {
errno = ENOENT; errno = ENOENT;
return NULL; return svcs;
} }
/* For consistency, we copy the array */ /* For consistency, we copy the array */
svcs = rc_stringlist_new();
TAILQ_FOREACH(svc, dt->services, entries) TAILQ_FOREACH(svc, dt->services, entries)
rc_stringlist_add(svcs, svc->value); rc_stringlist_add(svcs, svc->value);
return svcs; return svcs;
@@ -458,7 +466,7 @@ rc_deptree_depends(const RC_DEPTREE *deptree,
const RC_STRINGLIST *services, const RC_STRINGLIST *services,
const char *runlevel, int options) const char *runlevel, int options)
{ {
RC_STRINGLIST *sorted = NULL; RC_STRINGLIST *sorted = rc_stringlist_new();
RC_STRINGLIST *visited = rc_stringlist_new(); RC_STRINGLIST *visited = rc_stringlist_new();
RC_DEPINFO *di; RC_DEPINFO *di;
const RC_STRING *service; const RC_STRING *service;
@@ -472,7 +480,7 @@ rc_deptree_depends(const RC_DEPTREE *deptree,
continue; continue;
} }
if (types) if (types)
visit_service(deptree, types, &sorted, visited, visit_service(deptree, types, sorted, visited,
di, runlevel, options); di, runlevel, options);
} }
rc_stringlist_free(visited); rc_stringlist_free(visited);
@@ -494,47 +502,29 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
/* When shutting down, list all running services */ /* When shutting down, list all running services */
if (strcmp(runlevel, RC_LEVEL_SINGLE) == 0 || if (strcmp(runlevel, RC_LEVEL_SINGLE) == 0 ||
strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 || strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0)
strcmp(runlevel, RC_LEVEL_REBOOT) == 0)
{ {
list = rc_services_in_state(RC_SERVICE_STARTED); list = rc_services_in_state(RC_SERVICE_STARTED);
list2 = rc_services_in_state(RC_SERVICE_INACTIVE); list2 = rc_services_in_state(RC_SERVICE_INACTIVE);
if (list2) { TAILQ_CONCAT(list, list2, entries);
if (list) { free(list2);
TAILQ_CONCAT(list, list2, entries);
free(list2);
} else
list = list2;
}
list2 = rc_services_in_state(RC_SERVICE_STARTING); list2 = rc_services_in_state(RC_SERVICE_STARTING);
if (list2) { TAILQ_CONCAT(list, list2, entries);
if (list) { free(list2);
TAILQ_CONCAT(list, list2, entries);
free(list2);
} else
list = list2;
}
} else { } else {
list = rc_services_in_runlevel(runlevel); list = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
/* Add coldplugged services */ if (strcmp(runlevel, RC_LEVEL_SYSINIT) != 0) {
list2 = rc_services_in_state(RC_SERVICE_COLDPLUGGED); list2 = rc_services_in_runlevel(runlevel);
if (list2) { TAILQ_CONCAT(list, list2, entries);
if (list) { free(list2);
list2 = rc_services_in_state(RC_SERVICE_HOTPLUGGED);
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); TAILQ_CONCAT(list, list2, entries);
free(list2); 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;
} }
} }
} }
@@ -638,7 +628,7 @@ static const char *const depdirs[] =
RC_SVCDIR "/inactive", RC_SVCDIR "/inactive",
RC_SVCDIR "/wasinactive", RC_SVCDIR "/wasinactive",
RC_SVCDIR "/failed", RC_SVCDIR "/failed",
RC_SVCDIR "/coldplugged", RC_SVCDIR "/hotplugged",
RC_SVCDIR "/daemons", RC_SVCDIR "/daemons",
RC_SVCDIR "/options", RC_SVCDIR "/options",
RC_SVCDIR "/exclusive", RC_SVCDIR "/exclusive",
@@ -683,15 +673,13 @@ rc_deptree_update_needed(void)
/* Some init scripts dependencies change depending on config files /* Some init scripts dependencies change depending on config files
* outside of baselayout, like syslog-ng, so we check those too. */ * outside of baselayout, like syslog-ng, so we check those too. */
config = rc_config_list(RC_DEPCONFIG); config = rc_config_list(RC_DEPCONFIG);
if (config) { TAILQ_FOREACH(s, config, entries) {
TAILQ_FOREACH(s, config, entries) { if (!rc_newer_than(RC_DEPTREE_CACHE, s->value)) {
if (!rc_newer_than(RC_DEPTREE_CACHE, s->value)) { newer = true;
newer = true; break;
break;
}
} }
rc_stringlist_free(config);
} }
rc_stringlist_free(config);
return newer; return newer;
} }
librc_hidden_def(rc_deptree_update_needed) librc_hidden_def(rc_deptree_update_needed)
@@ -907,13 +895,11 @@ rc_deptree_update(void)
deptype = get_deptype(depinfo, "ibefore"); deptype = get_deptype(depinfo, "ibefore");
if (!deptype) if (!deptype)
continue; continue;
sorted = NULL; sorted = rc_stringlist_new();
visited = rc_stringlist_new(); visited = rc_stringlist_new();
visit_service(deptree, types, &sorted, visited, depinfo, visit_service(deptree, types, sorted, visited, depinfo,
NULL, 0); NULL, 0);
rc_stringlist_free(visited); rc_stringlist_free(visited);
if (!sorted)
continue;
TAILQ_FOREACH_SAFE(s2, deptype->services, entries, s2_np) { TAILQ_FOREACH_SAFE(s2, deptype->services, entries, s2_np) {
TAILQ_FOREACH(s3, sorted, entries) { TAILQ_FOREACH(s3, sorted, entries) {
di = get_depinfo(deptree, s3->value); di = get_depinfo(deptree, s3->value);

View File

@@ -84,10 +84,10 @@ RC_STRINGLIST *rc_config_list(const char *file)
size_t len = 0; size_t len = 0;
char *p; char *p;
char *token; char *token;
RC_STRINGLIST *list = NULL; RC_STRINGLIST *list = rc_stringlist_new();
if (!(fp = fopen(file, "r"))) if (!(fp = fopen(file, "r")))
return NULL; return list;
while ((rc_getline(&buffer, &len, fp))) { while ((rc_getline(&buffer, &len, fp))) {
p = buffer; p = buffer;
@@ -104,8 +104,6 @@ RC_STRINGLIST *rc_config_list(const char *file)
if (token[strlen(token) - 1] == '\n') if (token[strlen(token) - 1] == '\n')
token[strlen(token) - 1] = 0; token[strlen(token) - 1] = 0;
if (!list)
list = rc_stringlist_new();
rc_stringlist_add(list, token); rc_stringlist_add(list, token);
} }
} }
@@ -131,9 +129,6 @@ RC_STRINGLIST *rc_config_load(const char *file)
char *p; char *p;
list = rc_config_list(file); list = rc_config_list(file);
if (!list)
return NULL;
config = rc_stringlist_new(); config = rc_stringlist_new();
TAILQ_FOREACH(line, list, entries) { TAILQ_FOREACH(line, list, entries) {
/* Get entry */ /* Get entry */
@@ -203,9 +198,6 @@ char *rc_config_value(RC_STRINGLIST *list, const char *entry)
RC_STRING *line; RC_STRING *line;
char *p; char *p;
if (!list)
return NULL;
TAILQ_FOREACH(line, list, entries) { TAILQ_FOREACH(line, list, entries) {
p = strchr(line->value, '='); p = strchr(line->value, '=');
if (p && if (p &&

View File

@@ -59,7 +59,7 @@ static const rc_service_state_name_t rc_service_state_names[] = {
{ RC_SERVICE_STOPPING, "stopping" }, { RC_SERVICE_STOPPING, "stopping" },
{ RC_SERVICE_INACTIVE, "inactive" }, { RC_SERVICE_INACTIVE, "inactive" },
{ RC_SERVICE_WASINACTIVE, "wasinactive" }, { RC_SERVICE_WASINACTIVE, "wasinactive" },
{ RC_SERVICE_COLDPLUGGED, "coldplugged" }, { RC_SERVICE_HOTPLUGGED, "hotplugged" },
{ RC_SERVICE_FAILED, "failed" }, { RC_SERVICE_FAILED, "failed" },
{ RC_SERVICE_SCHEDULED, "scheduled"}, { RC_SERVICE_SCHEDULED, "scheduled"},
{ 0, NULL} { 0, NULL}
@@ -67,7 +67,8 @@ static const rc_service_state_name_t rc_service_state_names[] = {
#define LS_INITD 0x01 #define LS_INITD 0x01
#define LS_DIR 0x02 #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; DIR *dp;
struct dirent *d; struct dirent *d;
@@ -77,15 +78,15 @@ static RC_STRINGLIST *ls_dir(const char *dir, int options)
char file[PATH_MAX]; char file[PATH_MAX];
int r; int r;
list = rc_stringlist_new();
if ((dp = opendir(dir)) == NULL) if ((dp = opendir(dir)) == NULL)
return NULL; return list;
while (((d = readdir(dp)) != NULL)) { while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') { if (d->d_name[0] != '.') {
if (options & LS_INITD) { if (options & LS_INITD) {
/* Check that our file really exists. /* Check that our file really exists.
* This is important as a service maybe in a runlevel, but * This is important as a service maybe in a
* could also have been removed. */ * runlevel, but could have been removed. */
snprintf(file, sizeof(file), "%s/%s", snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name); dir, d->d_name);
r = stat(file, &buf); r = stat(file, &buf);
@@ -104,17 +105,15 @@ static RC_STRINGLIST *ls_dir(const char *dir, int options)
! S_ISDIR(buf.st_mode)) ! S_ISDIR(buf.st_mode))
continue; continue;
} }
if (! list)
list = rc_stringlist_new();
rc_stringlist_add(list, d->d_name); rc_stringlist_add(list, d->d_name);
} }
} }
closedir(dp); closedir(dp);
return list; return list;
} }
static bool rm_dir(const char *pathname, bool top) static bool
rm_dir(const char *pathname, bool top)
{ {
DIR *dp; DIR *dp;
struct dirent *d; struct dirent *d;
@@ -127,16 +126,17 @@ static bool rm_dir(const char *pathname, bool top)
errno = 0; errno = 0;
while (((d = readdir(dp)) != NULL) && errno == 0) { while (((d = readdir(dp)) != NULL) && errno == 0) {
if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) { if (strcmp(d->d_name, ".") != 0 &&
snprintf(file, sizeof(file), "%s/%s", pathname, d->d_name); strcmp(d->d_name, "..") != 0)
{
snprintf(file, sizeof(file),
"%s/%s", pathname, d->d_name);
if (stat(file, &s) != 0) { if (stat(file, &s) != 0) {
retval = false; retval = false;
break; break;
} }
if (S_ISDIR(s.st_mode)) { if (S_ISDIR(s.st_mode)) {
if (! rm_dir(file, true)) if (!rm_dir(file, true))
{ {
retval = false; retval = false;
break; break;
@@ -151,7 +151,7 @@ static bool rm_dir(const char *pathname, bool top)
} }
closedir(dp); closedir(dp);
if (! retval) if (!retval)
return false; return false;
if (top && rmdir(pathname) != 0) 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 */ /* Other systems may need this at some point, but for now it's Linux only */
#ifdef __linux__ #ifdef __linux__
static bool file_regex(const char *file, const char *regex) static bool
file_regex(const char *file, const char *regex)
{ {
FILE *fp; FILE *fp;
char *line = NULL; char *line = NULL;
@@ -171,12 +172,12 @@ static bool file_regex(const char *file, const char *regex)
bool retval = false; bool retval = false;
int result; int result;
if (! (fp = fopen(file, "r"))) if (!(fp = fopen(file, "r")))
return false; return false;
if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) { if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
fclose(fp); fclose(fp);
line = xmalloc(sizeof (char) * BUFSIZ); line = xmalloc(sizeof(char) * BUFSIZ);
regerror(result, &re, line, BUFSIZ); regerror(result, &re, line, BUFSIZ);
fprintf(stderr, "file_regex: %s", line); fprintf(stderr, "file_regex: %s", line);
free(line); free(line);
@@ -197,8 +198,8 @@ static bool file_regex(const char *file, const char *regex)
} }
#endif #endif
const char *
const char *rc_sys(void) rc_sys(void)
{ {
#ifdef PREFIX #ifdef PREFIX
return RC_SYS_PREFIX; return RC_SYS_PREFIX;
@@ -242,7 +243,8 @@ const char *rc_sys(void)
} }
librc_hidden_def(rc_sys) 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; int i;
@@ -250,17 +252,18 @@ static const char *rc_parse_service_state(RC_SERVICE state)
if (rc_service_state_names[i].state == state) if (rc_service_state_names[i].state == state)
return rc_service_state_names[i].name; return rc_service_state_names[i].name;
} }
return NULL; return NULL;
} }
bool rc_runlevel_starting(void) bool
rc_runlevel_starting(void)
{ {
return exists(RC_STARTING); return exists(RC_STARTING);
} }
librc_hidden_def(rc_runlevel_starting) librc_hidden_def(rc_runlevel_starting)
bool rc_runlevel_stopping(void) bool
rc_runlevel_stopping(void)
{ {
return exists(RC_STOPPING); return exists(RC_STOPPING);
} }
@@ -272,15 +275,17 @@ RC_STRINGLIST *rc_runlevel_list(void)
} }
librc_hidden_def(rc_runlevel_list) librc_hidden_def(rc_runlevel_list)
char *rc_runlevel_get(void) char *
rc_runlevel_get(void)
{ {
FILE *fp; FILE *fp;
char *runlevel = NULL; char *runlevel = NULL;
size_t i;
if ((fp = fopen(RC_RUNLEVEL, "r"))) { if ((fp = fopen(RC_RUNLEVEL, "r"))) {
runlevel = xmalloc(sizeof(char) * PATH_MAX); runlevel = xmalloc(sizeof(char) * PATH_MAX);
if (fgets(runlevel, PATH_MAX, fp)) { if (fgets(runlevel, PATH_MAX, fp)) {
int i = strlen(runlevel) - 1; i = strlen(runlevel) - 1;
if (runlevel[i] == '\n') if (runlevel[i] == '\n')
runlevel[i] = 0; runlevel[i] = 0;
} else } else
@@ -288,7 +293,7 @@ char *rc_runlevel_get(void)
fclose(fp); fclose(fp);
} }
if (! runlevel || ! *runlevel) { if (!runlevel || !*runlevel) {
free(runlevel); free(runlevel);
runlevel = xstrdup(RC_LEVEL_SYSINIT); runlevel = xstrdup(RC_LEVEL_SYSINIT);
} }
@@ -297,11 +302,12 @@ char *rc_runlevel_get(void)
} }
librc_hidden_def(rc_runlevel_get) 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"); FILE *fp = fopen(RC_RUNLEVEL, "w");
if (! fp) if (!fp)
return false; return false;
fprintf(fp, "%s", runlevel); fprintf(fp, "%s", runlevel);
fclose(fp); fclose(fp);
@@ -309,14 +315,14 @@ bool rc_runlevel_set(const char *runlevel)
} }
librc_hidden_def(rc_runlevel_set) librc_hidden_def(rc_runlevel_set)
bool rc_runlevel_exists(const char *runlevel) bool
rc_runlevel_exists(const char *runlevel)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
struct stat buf; struct stat buf;
if (! runlevel) if (!runlevel)
return false; return false;
snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel); snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel);
if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode)) if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))
return true; return true;
@@ -325,14 +331,15 @@ bool rc_runlevel_exists(const char *runlevel)
librc_hidden_def(rc_runlevel_exists) librc_hidden_def(rc_runlevel_exists)
/* Resolve a service name to it's full path */ /* 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 buffer[PATH_MAX];
char file[PATH_MAX]; char file[PATH_MAX];
int r; int r;
struct stat buf; struct stat buf;
if (! service) if (!service)
return NULL; return NULL;
if (service[0] == '/') if (service[0] == '/')
@@ -377,14 +384,15 @@ char *rc_service_resolve(const char *service)
} }
librc_hidden_def(rc_service_resolve) librc_hidden_def(rc_service_resolve)
bool rc_service_exists(const char *service) bool
rc_service_exists(const char *service)
{ {
char *file; char *file;
bool retval = false; bool retval = false;
int len; int len;
struct stat buf; struct stat buf;
if (! service) if (!service)
return false; return false;
len = strlen(service); len = strlen(service);
@@ -395,7 +403,7 @@ bool rc_service_exists(const char *service)
service[len - 1] == 'h') service[len - 1] == 'h')
return false; return false;
if (! (file = rc_service_resolve(service))) if (!(file = rc_service_resolve(service)))
return false; return false;
if (stat(file, &buf) == 0 && buf.st_mode & S_IXUGO) 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) librc_hidden_def(rc_service_exists)
#define OPTSTR ". '%s'; echo \"${opts}\"" #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 *svc;
char *cmd = NULL; char *cmd = NULL;
@@ -418,10 +427,9 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
FILE *fp; FILE *fp;
size_t l; size_t l;
if (! (svc = rc_service_resolve(service))) if (!(svc = rc_service_resolve(service)))
return NULL; return NULL;
l = strlen(OPTSTR) + strlen(svc) + 1; l = strlen(OPTSTR) + strlen(svc) + 1;
cmd = xmalloc(sizeof(char) * l); cmd = xmalloc(sizeof(char) * l);
snprintf(cmd, l, OPTSTR, svc); snprintf(cmd, l, OPTSTR, svc);
@@ -431,7 +439,7 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
rc_getline(&buffer, &len, fp); rc_getline(&buffer, &len, fp);
p = buffer; p = buffer;
while ((token = strsep(&p, " "))) { while ((token = strsep(&p, " "))) {
if (! commands) if (!commands)
commands = rc_stringlist_new(); commands = rc_stringlist_new();
rc_stringlist_add(commands, token); 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) librc_hidden_def(rc_service_extra_commands)
#define DESCSTR ". '%s'; echo \"${description%s%s}\"" #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 *svc;
char *cmd; char *cmd;
@@ -453,7 +462,7 @@ char *rc_service_description(const char *service, const char *option)
FILE *fp; FILE *fp;
size_t l; size_t l;
if (! (svc = rc_service_resolve(service))) if (!(svc = rc_service_resolve(service)))
return NULL; return NULL;
if (!option) if (!option)
@@ -472,7 +481,8 @@ char *rc_service_description(const char *service, const char *option)
} }
librc_hidden_def(rc_service_description) 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]; 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) 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]; char file[PATH_MAX];
int i = 0; int i = 0;
@@ -496,11 +507,10 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
RC_STRING *dir; RC_STRING *dir;
int serrno; int serrno;
if (! init) if (!init)
return false; return false;
base = basename_c(service); base = basename_c(service);
if (state != RC_SERVICE_STOPPED) { if (state != RC_SERVICE_STOPPED) {
if (!exists(init)) { if (!exists(init)) {
free(init); free(init);
@@ -519,7 +529,7 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
skip_state = state; skip_state = state;
} }
if (state == RC_SERVICE_COLDPLUGGED || state == RC_SERVICE_FAILED) { if (state == RC_SERVICE_HOTPLUGGED || state == RC_SERVICE_FAILED) {
free(init); free(init);
return true; return true;
} }
@@ -530,7 +540,7 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
if ((s != skip_state && if ((s != skip_state &&
s != RC_SERVICE_STOPPED && s != RC_SERVICE_STOPPED &&
s != RC_SERVICE_COLDPLUGGED && s != RC_SERVICE_HOTPLUGGED &&
s != RC_SERVICE_SCHEDULED) && s != RC_SERVICE_SCHEDULED) &&
(! skip_wasinactive || s != RC_SERVICE_WASINACTIVE)) (! skip_wasinactive || s != RC_SERVICE_WASINACTIVE))
{ {
@@ -583,29 +593,26 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) { if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) {
snprintf(file, sizeof(file), RC_SVCDIR "/%s", "scheduled"); snprintf(file, sizeof(file), RC_SVCDIR "/%s", "scheduled");
dirs = ls_dir(file, 0); dirs = ls_dir(file, 0);
if (dirs) { TAILQ_FOREACH(dir, dirs, entries) {
TAILQ_FOREACH(dir, dirs, entries) { snprintf(was, sizeof(was), "%s/%s/%s",
snprintf(was, sizeof(was), "%s/%s/%s", file, dir->value, base);
file, dir->value, base); unlink(was);
unlink(was);
/* Try and remove the dir - we don't care about errors */ /* Try and remove the dir; we don't care about errors */
snprintf(was, sizeof(was), "%s/%s", snprintf(was, sizeof(was), "%s/%s", file, dir->value);
file, dir->value); serrno = errno;
serrno = errno; rmdir(was);
rmdir(was); errno = serrno;
errno = serrno;
}
rc_stringlist_free(dirs);
} }
rc_stringlist_free(dirs);
} }
free(init); free(init);
return true; return true;
} }
librc_hidden_def(rc_service_mark) 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 i;
int state = RC_SERVICE_STOPPED; int state = RC_SERVICE_STOPPED;
@@ -627,25 +634,24 @@ RC_SERVICE rc_service_state(const char *service)
if (state & RC_SERVICE_STOPPED) { if (state & RC_SERVICE_STOPPED) {
dirs = ls_dir(RC_SVCDIR "/scheduled", 0); dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
if (dirs) { TAILQ_FOREACH (dir, dirs, entries) {
TAILQ_FOREACH (dir, dirs, entries) { snprintf(file, sizeof(file),
snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s",
RC_SVCDIR "/scheduled/%s/%s", dir->value, service);
dir->value, service); if (exists(file)) {
if (exists(file)) { state |= RC_SERVICE_SCHEDULED;
state |= RC_SERVICE_SCHEDULED; break;
break;
}
} }
rc_stringlist_free(dirs);
} }
rc_stringlist_free(dirs);
} }
return state; return state;
} }
librc_hidden_def(rc_service_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; FILE *fp;
char *line = NULL; 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) librc_hidden_def(rc_service_value_get)
bool rc_service_value_set(const char *service, const char *option, bool
const char *value) rc_service_value_set(const char *service, const char *option,
const char *value)
{ {
FILE *fp; FILE *fp;
char file[PATH_MAX]; 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) librc_hidden_def(rc_service_value_set)
bool rc_service_schedule_start(const char *service, bool
const char *service_to_start) rc_service_schedule_start(const char *service, const char *service_to_start)
{ {
char file[PATH_MAX]; char file[PATH_MAX];
char *p = file; char *p = file;
@@ -703,32 +710,34 @@ bool rc_service_schedule_start(const char *service,
return false; return false;
init = rc_service_resolve(service_to_start); 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); retval = (exists(file) || symlink(init, file) == 0);
free(init); free(init);
return retval; return retval;
} }
librc_hidden_def(rc_service_schedule_start) 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]; char dir[PATH_MAX];
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s", snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
basename_c(service)); basename_c(service));
if (! rm_dir(dir, true) && errno == ENOENT) if (!rm_dir(dir, true) && errno == ENOENT)
return true; return true;
return false; return false;
} }
librc_hidden_def(rc_service_schedule_clear) 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]; char dir[PATH_MAX];
RC_STRINGLIST *list; RC_STRINGLIST *list = NULL;
if (! runlevel) { if (!runlevel) {
#ifdef RC_PKG_INITDIR #ifdef RC_PKG_INITDIR
RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD); RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD);
#endif #endif
@@ -739,36 +748,32 @@ RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
list = ls_dir(RC_INITDIR, LS_INITD); list = ls_dir(RC_INITDIR, LS_INITD);
#ifdef RC_PKG_INITDIR #ifdef RC_PKG_INITDIR
if (pkg) { TAILQ_CONCAT(list, pkg, entries);
TAILQ_CONCAT(list, pkg, entries); free(pkg);
free(pkg);
}
#endif #endif
#ifdef RC_LOCAL_INITDIR #ifdef RC_LOCAL_INITDIR
if (local) { TAILQ_CONCAT(list, local, entries);
TAILQ_CONCAT(list, local, entries); free(local);
free(local);
}
#endif #endif
return list; return list;
} }
/* These special levels never contain any services */ /* These special levels never contain any services */
if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 || if (strcmp(runlevel, RC_LEVEL_SINGLE) != 0) {
strcmp(runlevel, RC_LEVEL_SINGLE) == 0) { snprintf(dir, sizeof(dir), RC_RUNLEVELDIR "/%s", runlevel);
return NULL; list = ls_dir(dir, LS_INITD);
} }
if (!list)
snprintf(dir, sizeof(dir), RC_RUNLEVELDIR "/%s", runlevel); list = rc_stringlist_new();
list = ls_dir(dir, LS_INITD);
return list; return list;
} }
librc_hidden_def(rc_services_in_runlevel) 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 *services;
RC_STRINGLIST *list = NULL; RC_STRINGLIST *list;
RC_STRINGLIST *dirs; RC_STRINGLIST *dirs;
RC_STRING *d; RC_STRING *d;
char dir[PATH_MAX]; char dir[PATH_MAX];
@@ -780,28 +785,26 @@ RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
if (state != RC_SERVICE_SCHEDULED) if (state != RC_SERVICE_SCHEDULED)
return ls_dir(dir, LS_INITD); return ls_dir(dir, LS_INITD);
dirs = ls_dir(dir, 0); dirs = ls_dir(dir, 0);
list = rc_stringlist_new();
if (! dirs) if (! dirs)
return NULL; return list;
TAILQ_FOREACH(d, dirs, entries) { TAILQ_FOREACH(d, dirs, entries) {
snprintf(p, sizeof(dir) - (p - dir), "/%s", d->value); snprintf(p, sizeof(dir) - (p - dir), "/%s", d->value);
services = ls_dir(dir, LS_INITD); services = ls_dir(dir, LS_INITD);
if (! list) if (services) {
services = list;
else if (services) {
TAILQ_CONCAT(list, services, entries); TAILQ_CONCAT(list, services, entries);
free(services); free(services);
} }
} }
rc_stringlist_free(dirs); rc_stringlist_free(dirs);
return list; return list;
} }
librc_hidden_def(rc_services_in_state) 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; bool retval;
char *init; char *init;
@@ -811,7 +814,7 @@ bool rc_service_add(const char *runlevel, const char *service)
char binit[PATH_MAX]; char binit[PATH_MAX];
char *i; char *i;
if (! rc_runlevel_exists(runlevel)) { if (!rc_runlevel_exists(runlevel)) {
errno = ENOENT; errno = ENOENT;
return false; 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 /* We need to ensure that only things in /etc/init.d are added
* to the boot runlevel */ * to the boot runlevel */
if (strcmp (runlevel, RC_LEVEL_BOOT) == 0) { if (strcmp(runlevel, RC_LEVEL_BOOT) == 0) {
p = realpath(dirname(init), path); p = realpath(dirname(init), path);
if (! *p) { if (!*p) {
free(init); free(init);
return false; return false;
} }
if (strcmp(path, RC_INITDIR) != 0) { if (strcmp(path, RC_INITDIR) != 0) {
free(init); free(init);
@@ -849,7 +851,8 @@ bool rc_service_add(const char *runlevel, const char *service)
} }
librc_hidden_def(rc_service_add) 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]; char file[PATH_MAX];
@@ -861,32 +864,27 @@ bool rc_service_delete (const char *runlevel, const char *service)
} }
librc_hidden_def(rc_service_delete) 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 *dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
RC_STRINGLIST *list = NULL; RC_STRINGLIST *list = rc_stringlist_new();
RC_STRING *dir; RC_STRING *dir;
char file[PATH_MAX]; char file[PATH_MAX];
if (! dirs)
return NULL;
TAILQ_FOREACH (dir, dirs, entries) { TAILQ_FOREACH (dir, dirs, entries) {
snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s", snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s",
dir->value, service); dir->value, service);
if (exists(file)) { if (exists(file))
if (! list)
list = rc_stringlist_new();
rc_stringlist_add(list, file); rc_stringlist_add(list, file);
}
} }
rc_stringlist_free(dirs); rc_stringlist_free(dirs);
return list; return list;
} }
librc_hidden_def(rc_services_scheduled_by) 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]; char dir[PATH_MAX];

View File

@@ -70,7 +70,6 @@ typedef TAILQ_HEAD(rc_stringlist, rc_string) RC_STRINGLIST;
#define RC_LEVEL_SYSINIT "sysinit" #define RC_LEVEL_SYSINIT "sysinit"
#define RC_LEVEL_SINGLE "single" #define RC_LEVEL_SINGLE "single"
#define RC_LEVEL_SHUTDOWN "shutdown" #define RC_LEVEL_SHUTDOWN "shutdown"
#define RC_LEVEL_REBOOT "reboot"
/*! Return the current runlevel. /*! Return the current runlevel.
* @return the current runlevel */ * @return the current runlevel */
@@ -115,8 +114,8 @@ typedef enum
RC_SERVICE_STARTING = 0x0008, RC_SERVICE_STARTING = 0x0008,
RC_SERVICE_INACTIVE = 0x0010, RC_SERVICE_INACTIVE = 0x0010,
/* Service may or may not have been coldplugged */ /* Service may or may not have been hotplugged */
RC_SERVICE_COLDPLUGGED = 0x0100, RC_SERVICE_HOTPLUGGED = 0x0100,
/* Optional states service could also be in */ /* Optional states service could also be in */
RC_SERVICE_FAILED = 0x0200, RC_SERVICE_FAILED = 0x0200,

73
src/rc/.gitignore vendored
View File

@@ -1,73 +0,0 @@
.depend
version.h
rc-status
rc-service
rc-update
runscript
start-stop-daemon
einfon
einfo
ewarnn
ewarn
eerrorn
eerror
ebegin
eend
ewaitfile
ewend
eindent
eoutdent
esyslog
eval_ecolors
veinfo
vewarn
vebegin
veend
vewend
veindent
veoutdent
service_starting
service_started
service_stopping
service_stopped
service_inactive
service_wasinactive
service_coldplugged
service_started_daemon
checkpath
fstabinfo
mountinfo
rc-depend
service_get_value
service_set_value
get_options
save_options
shell_var
is_newer_than
is_older_than
mark_service_starting
mark_service_started
mark_service_stopping
mark_service_stopped
mark_service_inactive
mark_service_wasinactive
mark_service_coldplugged
mark_service_failed
rc-abort
checkpath.o
fstabinfo.o
mountinfo.o
start-stop-daemon.o
rc-applets.o
rc-depend.o
rc-logger.o
rc-misc.o
rc-plugin.o
rc-service.o
rc-status.o
rc-update.o
runscript.o
rc.o
rc.core
rc
.depend

View File

@@ -18,14 +18,14 @@ RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
service_starting service_started \ service_starting service_started \
service_stopping service_stopped \ service_stopping service_stopped \
service_inactive service_wasinactive \ service_inactive service_wasinactive \
service_coldplugged service_started_daemon \ service_hotplugged service_started_daemon \
checkpath fstabinfo mountinfo rc-depend \ checkpath fstabinfo mountinfo rc-depend \
service_get_value service_set_value get_options save_options \ service_get_value service_set_value get_options save_options \
shell_var is_newer_than is_older_than shell_var is_newer_than is_older_than
RC_SBINLINKS= mark_service_starting mark_service_started \ RC_SBINLINKS= mark_service_starting mark_service_started \
mark_service_stopping mark_service_stopped \ mark_service_stopping mark_service_stopped \
mark_service_inactive mark_service_wasinactive \ mark_service_inactive mark_service_wasinactive \
mark_service_coldplugged mark_service_failed \ mark_service_hotplugged mark_service_failed \
rc-abort rc-abort
ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS} ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
CLEANFILES+= ${ALL_LINKS} CLEANFILES+= ${ALL_LINKS}
@@ -43,9 +43,17 @@ include ${MK}/${MKTERMCAP}.mk
LDADD+= ${LIBDL} ${LIBKVM} LDADD+= ${LIBDL} ${LIBKVM}
include ${MK}/${MKPAM}.mk include ${MK}/${MKPAM}.mk
_SVNVER_SH= if type svnversion >/dev/null 2>&1; then \
echo "-svn-$$(svnversion)"; \
else \
echo ""; \
fi
_SVNVER!= ${_SVNVER_SH}
SVNVER= ${_SVNVER}$(shell ${_SVNVER_SH})
${SRCS}: version.h ${SRCS}: version.h
version.h: version.h:
sed -n -e 's/^VERSION=[[:space:]]*\([^[:space:]]*\).*/#define VERSION "\1\"/p' ../../Makefile > version.h sed -n -e 's/^VERSION=[[:space:]]*\([^[:space:]]*\).*/#define VERSION "\1${SVNVER}\"/p' ../../Makefile > version.h
if test -n "${BRANDING}"; then \ if test -n "${BRANDING}"; then \
echo "#define BRANDING \"${BRANDING}\"" >> version.h; \ echo "#define BRANDING \"${BRANDING}\"" >> version.h; \
fi fi

View File

@@ -75,7 +75,8 @@
#include "rc-misc.h" #include "rc-misc.h"
#ifdef HAVE_GETMNTENT #ifdef HAVE_GETMNTENT
static struct mntent *getmntfile(const char *file) static struct mntent *
getmntfile(const char *file)
{ {
struct mntent *ent; struct mntent *ent;
FILE *fp; FILE *fp;
@@ -107,21 +108,21 @@ static int do_mount(struct ENT *ent)
argv[6] = ENT_FILE(*ent); argv[6] = ENT_FILE(*ent);
argv[7] = NULL; argv[7] = NULL;
switch (pid = vfork()) { switch (pid = vfork()) {
case -1: case -1:
eerrorx("%s: vfork: %s", applet, strerror(errno)); eerrorx("%s: vfork: %s", applet, strerror(errno));
/* NOTREACHED */ /* NOTREACHED */
case 0: case 0:
execvp(argv[0], argv); execvp(argv[0], argv);
eerror("%s: execv: %s", applet, strerror(errno)); eerror("%s: execv: %s", applet, strerror(errno));
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
/* NOTREACHED */ /* NOTREACHED */
default: default:
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
if (WIFEXITED(status)) if (WIFEXITED(status))
return WEXITSTATUS(status); return WEXITSTATUS(status);
else else
return -1; return -1;
/* NOTREACHED */ /* NOTREACHED */
} }
} }
@@ -154,7 +155,8 @@ static const char * const longopts_help[] = {
#define OUTPUT_BLOCKDEV (1 << 5) #define OUTPUT_BLOCKDEV (1 << 5)
#define OUTPUT_MOUNT (1 << 6) #define OUTPUT_MOUNT (1 << 6)
int fstabinfo(int argc, char **argv) int
fstabinfo(int argc, char **argv)
{ {
struct ENT *ent; struct ENT *ent;
int result = EXIT_SUCCESS; int result = EXIT_SUCCESS;
@@ -238,7 +240,7 @@ int fstabinfo(int argc, char **argv)
} }
if (optind < argc) { if (optind < argc) {
if (files) { if (TAILQ_FIRST(files)) {
TAILQ_FOREACH_SAFE(file, files, entries, file_np) { TAILQ_FOREACH_SAFE(file, files, entries, file_np) {
for (i = optind; i < argc; i++) for (i = optind; i < argc; i++)
if (strcmp(argv[i], file->value) == 0) if (strcmp(argv[i], file->value) == 0)
@@ -250,17 +252,17 @@ int fstabinfo(int argc, char **argv)
while (optind < argc) while (optind < argc)
rc_stringlist_add(files, argv[optind++]); rc_stringlist_add(files, argv[optind++]);
} }
} else if (! filtered) { } else if (!filtered) {
START_ENT; START_ENT;
while ((ent = GET_ENT)) while ((ent = GET_ENT))
rc_stringlist_add(files, ENT_FILE(ent)); rc_stringlist_add(files, ENT_FILE(ent));
END_ENT; END_ENT;
if (! TAILQ_FIRST(files)) if (!TAILQ_FIRST(files))
eerrorx("%s: emtpy fstab", argv[0]); eerrorx("%s: emtpy fstab", argv[0]);
} }
if (!files || !TAILQ_FIRST(files)) { if (!TAILQ_FIRST(files)) {
rc_stringlist_free(files); rc_stringlist_free(files);
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
@@ -268,7 +270,7 @@ int fstabinfo(int argc, char **argv)
/* Ensure we always display something */ /* Ensure we always display something */
START_ENT; START_ENT;
TAILQ_FOREACH(file, files, entries) { TAILQ_FOREACH(file, files, entries) {
if (! (ent = GET_ENT_FILE(file->value))) { if (!(ent = GET_ENT_FILE(file->value))) {
result = EXIT_FAILURE; result = EXIT_FAILURE;
continue; continue;
} }

View File

@@ -84,8 +84,8 @@ static int do_e(int argc, char **argv)
int level = 0; int level = 0;
struct timespec ts; struct timespec ts;
struct timeval stop, now; struct timeval stop, now;
int (*e) (const char *, ...) __EINFO_PRINTF = NULL; int (*e) (const char *, ...) EINFO_PRINTF(1, 2) = NULL;
int (*ee) (int, const char *, ...) __EEND_PRINTF = NULL; int (*ee) (int, const char *, ...) EINFO_PRINTF(2, 3) = NULL;
/* Punt applet */ /* Punt applet */
argc--; argc--;
@@ -205,9 +205,10 @@ static int do_e(int argc, char **argv)
ee = eend; ee = eend;
else if (strcmp(applet, "ewend") == 0) else if (strcmp(applet, "ewend") == 0)
ee = ewend; ee = ewend;
else if (strcmp(applet, "esyslog") == 0) else if (strcmp(applet, "esyslog") == 0) {
ee = elog; elog(retval, "%s", message);
else if (strcmp(applet, "veinfo") == 0) retval = 0;
} else if (strcmp(applet, "veinfo") == 0)
e = einfov; e = einfov;
else if (strcmp(applet, "veinfon") == 0) else if (strcmp(applet, "veinfon") == 0)
e = einfovn; e = einfovn;
@@ -275,8 +276,8 @@ static int do_service(int argc, char **argv)
ok = (rc_service_state(service) & RC_SERVICE_STARTING); ok = (rc_service_state(service) & RC_SERVICE_STARTING);
else if (strcmp(applet, "service_stopping") == 0) else if (strcmp(applet, "service_stopping") == 0)
ok = (rc_service_state(service) & RC_SERVICE_STOPPING); ok = (rc_service_state(service) & RC_SERVICE_STOPPING);
else if (strcmp(applet, "service_coldplugged") == 0) else if (strcmp(applet, "service_hotplugged") == 0)
ok = (rc_service_state(service) & RC_SERVICE_COLDPLUGGED); ok = (rc_service_state(service) & RC_SERVICE_HOTPLUGGED);
else if (strcmp(applet, "service_wasinactive") == 0) else if (strcmp(applet, "service_wasinactive") == 0)
ok = (rc_service_state(service) & RC_SERVICE_WASINACTIVE); ok = (rc_service_state(service) & RC_SERVICE_WASINACTIVE);
else if (strcmp(applet, "service_started_daemon") == 0) { else if (strcmp(applet, "service_started_daemon") == 0) {
@@ -328,8 +329,8 @@ static int do_mark_service(int argc, char **argv)
ok = rc_service_mark(service, RC_SERVICE_STARTING); ok = rc_service_mark(service, RC_SERVICE_STARTING);
else if (strcmp(applet, "mark_service_stopping") == 0) else if (strcmp(applet, "mark_service_stopping") == 0)
ok = rc_service_mark(service, RC_SERVICE_STOPPING); ok = rc_service_mark(service, RC_SERVICE_STOPPING);
else if (strcmp(applet, "mark_service_coldplugged") == 0) else if (strcmp(applet, "mark_service_hotplugged") == 0)
ok = rc_service_mark(service, RC_SERVICE_COLDPLUGGED); ok = rc_service_mark(service, RC_SERVICE_HOTPLUGGED);
else if (strcmp(applet, "mark_service_failed") == 0) else if (strcmp(applet, "mark_service_failed") == 0)
ok = rc_service_mark(service, RC_SERVICE_FAILED); ok = rc_service_mark(service, RC_SERVICE_FAILED);
else else

View File

@@ -48,7 +48,8 @@
extern const char *applet; extern const char *applet;
RC_DEPTREE *_rc_deptree_load(int *regen) { RC_DEPTREE *
_rc_deptree_load(int *regen) {
int fd; int fd;
int retval; int retval;
int serrno = errno; int serrno = errno;
@@ -65,12 +66,10 @@ RC_DEPTREE *_rc_deptree_load(int *regen) {
if (regen) if (regen)
*regen = 1; *regen = 1;
ebegin("Caching service dependencies"); ebegin("Caching service dependencies");
retval = rc_deptree_update(); retval = rc_deptree_update();
eend (retval ? 0 : -1, "Failed to update the dependency tree"); eend (retval ? 0 : -1, "Failed to update the dependency tree");
} }
return rc_deptree_load(); return rc_deptree_load();
} }
@@ -96,7 +95,8 @@ static const char * const longopts_help[] = {
}; };
#include "_usage.c" #include "_usage.c"
int rc_depend(int argc, char **argv) int
rc_depend(int argc, char **argv)
{ {
RC_STRINGLIST *list; RC_STRINGLIST *list;
RC_STRINGLIST *types; RC_STRINGLIST *types;
@@ -112,7 +112,6 @@ int rc_depend(int argc, char **argv)
char *token; char *token;
types = rc_stringlist_new(); types = rc_stringlist_new();
while ((opt = getopt_long(argc, argv, getoptstring, while ((opt = getopt_long(argc, argv, getoptstring,
longopts, (int *) 0)) != -1) longopts, (int *) 0)) != -1)
{ {
@@ -145,14 +144,14 @@ int rc_depend(int argc, char **argv)
ebegin("Caching service dependencies"); ebegin("Caching service dependencies");
update = rc_deptree_update(); update = rc_deptree_update();
eend(update ? 0 : -1, "%s: %s", applet, strerror(errno)); eend(update ? 0 : -1, "%s: %s", applet, strerror(errno));
if (! update) if (!update)
eerrorx("Failed to update the dependency tree"); eerrorx("Failed to update the dependency tree");
} }
if (! (deptree = _rc_deptree_load(NULL))) if (!(deptree = _rc_deptree_load(NULL)))
eerrorx("failed to load deptree"); eerrorx("failed to load deptree");
if (! runlevel) if (!runlevel)
runlevel = rc_runlevel_get(); runlevel = rc_runlevel_get();
services = rc_stringlist_new(); services = rc_stringlist_new();
@@ -161,8 +160,9 @@ int rc_depend(int argc, char **argv)
rc_stringlist_add(list, argv[optind]); rc_stringlist_add(list, argv[optind]);
errno = 0; errno = 0;
depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0); depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0);
if (! depends && errno == ENOENT) if (!depends && errno == ENOENT)
eerror("no dependency info for service `%s'", argv[optind]); eerror("no dependency info for service `%s'",
argv[optind]);
else else
rc_stringlist_add(services, argv[optind]); rc_stringlist_add(services, argv[optind]);
@@ -170,7 +170,7 @@ int rc_depend(int argc, char **argv)
rc_stringlist_free(list); rc_stringlist_free(list);
optind++; optind++;
} }
if (! TAILQ_FIRST(services)) { if (!TAILQ_FIRST(services)) {
rc_stringlist_free(services); rc_stringlist_free(services);
rc_stringlist_free(types); rc_stringlist_free(types);
rc_deptree_free(deptree); 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 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, "ineed");
rc_stringlist_add(types, "iuse"); 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)) { if (TAILQ_FIRST(depends)) {
TAILQ_FOREACH(s, depends, entries) { TAILQ_FOREACH(s, depends, entries) {

View File

@@ -36,6 +36,7 @@
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -143,17 +144,16 @@ void rc_logger_open(const char *level)
struct termios tt; struct termios tt;
struct winsize ws; struct winsize ws;
char *buffer; char *buffer;
fd_set rset; struct pollfd fd[2];
int s = 0; int s = 0;
size_t bytes; size_t bytes;
int selfd;
int i; int i;
FILE *log = NULL; FILE *log = NULL;
if (! isatty(STDOUT_FILENO)) if (!isatty(STDOUT_FILENO))
return; return;
if (! rc_conf_yesno("rc_logger")) if (!rc_conf_yesno("rc_logger"))
return; return;
if (pipe(signal_pipe) == -1) if (pipe(signal_pipe) == -1)
@@ -197,19 +197,19 @@ void rc_logger_open(const char *level)
} }
buffer = xmalloc(sizeof (char) * BUFSIZ); buffer = xmalloc(sizeof (char) * BUFSIZ);
selfd = rc_logger_tty > signal_pipe[0] ? rc_logger_tty : signal_pipe[0]; fd[0].fd = signal_pipe[0];
fd[0].events = fd[1].events = POLLIN;
fd[0].revents = fd[1].revents = 0;
if (rc_logger_tty >= 0)
fd[1].fd = rc_logger_tty;
for (;;) { for (;;) {
FD_ZERO(&rset); if ((s = poll(fd, rc_logger_tty >= 0 ? 2 : 1, -1)) == -1) {
FD_SET(rc_logger_tty, &rset); eerror("poll: %s", strerror(errno));
FD_SET(signal_pipe[0], &rset);
if ((s = select(selfd + 1, &rset, NULL, NULL, NULL)) == -1) {
eerror("select: %s", strerror(errno));
break; break;
} }
if (s > 0) { if (s > 0) {
if (FD_ISSET(rc_logger_tty, &rset)) { if (fd[1].revents & (POLLIN | POLLHUP)) {
memset(buffer, 0, BUFSIZ); memset(buffer, 0, BUFSIZ);
bytes = read(rc_logger_tty, buffer, BUFSIZ); bytes = read(rc_logger_tty, buffer, BUFSIZ);
write(STDOUT_FILENO, buffer, bytes); write(STDOUT_FILENO, buffer, bytes);
@@ -230,7 +230,7 @@ void rc_logger_open(const char *level)
} }
/* Only SIGTERMS signals come down this pipe */ /* Only SIGTERMS signals come down this pipe */
if (FD_ISSET(signal_pipe[0], &rset)) if (fd[0].revents & (POLLIN | POLLHUP))
break; break;
} }
} }

View File

@@ -61,12 +61,16 @@ static RC_STRINGLIST *rc_conf = NULL;
extern char** environ; extern char** environ;
static void _free_rc_conf(void) #ifdef DEBUG_MEMORY
static void
_free_rc_conf(void)
{ {
rc_stringlist_free(rc_conf); rc_stringlist_free(rc_conf);
} }
#endif
char *rc_conf_value(const char *setting) char *
rc_conf_value(const char *setting)
{ {
RC_STRINGLIST *old; RC_STRINGLIST *old;
RC_STRING *s; RC_STRING *s;
@@ -74,36 +78,35 @@ char *rc_conf_value(const char *setting)
if (! rc_conf) { if (! rc_conf) {
rc_conf = rc_config_load(RC_CONF); rc_conf = rc_config_load(RC_CONF);
#ifdef DEBUG_MEMORY
atexit(_free_rc_conf); atexit(_free_rc_conf);
#endif
/* Support old configs */ /* Support old configs */
if (exists(RC_CONF_OLD)) { if (exists(RC_CONF_OLD)) {
old = rc_config_load(RC_CONF_OLD); old = rc_config_load(RC_CONF_OLD);
if (old) { TAILQ_CONCAT(rc_conf, old, entries);
if (rc_conf) { #ifdef DEBUG_MEMORY
TAILQ_CONCAT(rc_conf, old, entries); free(old);
free(old); #endif
} else
rc_conf = old;
}
} }
/* Convert old uppercase to lowercase */ /* Convert old uppercase to lowercase */
if (rc_conf) TAILQ_FOREACH(s, rc_conf, entries) {
TAILQ_FOREACH(s, rc_conf, entries) { p = s->value;
p = s->value; while (p && *p && *p != '=') {
while (p && *p && *p != '=') { if (isupper((unsigned char)*p))
if (isupper((unsigned char)*p)) *p = tolower((unsigned char)*p);
*p = tolower((unsigned char)*p); p++;
p++;
}
} }
}
} }
return rc_config_value(rc_conf, setting); 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)); return rc_yesno(rc_conf_value (setting));
} }
@@ -118,23 +121,23 @@ static const char *const env_whitelist[] = {
NULL NULL
}; };
void env_filter(void) void
env_filter(void)
{ {
RC_STRINGLIST *env_allow; RC_STRINGLIST *env_allow;
RC_STRINGLIST *profile = NULL; RC_STRINGLIST *profile;
RC_STRINGLIST *env_list; RC_STRINGLIST *env_list;
RC_STRING *env; RC_STRING *env;
char *e; char *e;
size_t i = 0; size_t i = 0;
/* Add the user defined list of vars */ /* Add the user defined list of vars */
env_allow = rc_stringlist_split(rc_conf_value ("rc_env_allow"), " "); 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 */ /* Copy the env and work from this so we can manipulate it safely */
env_list = rc_stringlist_new(); env_list = rc_stringlist_new();
while (environ[i]) { while (environ && environ[i]) {
env = rc_stringlist_add(env_list, environ[i++]); env = rc_stringlist_add(env_list, environ[i++]);
e = strchr(env->value, '='); e = strchr(env->value, '=');
if (e) if (e)
@@ -165,14 +168,16 @@ void env_filter(void)
if (!getenv(env->value)) if (!getenv(env->value))
setenv(env->value, e + 1, 1); setenv(env->value, e + 1, 1);
} }
#ifdef DEBUG_MEMORY
rc_stringlist_free(env_list); rc_stringlist_free(env_list);
rc_stringlist_free(env_allow); rc_stringlist_free(env_allow);
rc_stringlist_free(profile); rc_stringlist_free(profile);
#endif
} }
void env_config(void) void
env_config(void)
{ {
size_t pplen = strlen(PATH_PREFIX); size_t pplen = strlen(PATH_PREFIX);
char *path; char *path;
@@ -198,7 +203,8 @@ void env_config(void)
e = p = xmalloc(sizeof(char) * l); e = p = xmalloc(sizeof(char) * l);
p += snprintf(p, l, "%s", PATH_PREFIX); 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, ":"))) { while ((token = strsep(&path, ":"))) {
np = npp = xstrdup(PATH_PREFIX); np = npp = xstrdup(PATH_PREFIX);
while ((tok = strsep(&npp, ":"))) while ((tok = strsep(&npp, ":")))
@@ -254,48 +260,8 @@ void env_config(void)
setenv("EINFO_COLOR", "NO", 1); setenv("EINFO_COLOR", "NO", 1);
} }
bool service_plugable(const char *service) int
{ signal_setup(int sig, void (*handler)(int))
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))
{ {
struct sigaction sa; struct sigaction sa;
@@ -305,7 +271,8 @@ int signal_setup(int sig, void (*handler)(int))
return sigaction(sig, &sa, NULL); 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 *file;
char fifo[PATH_MAX]; char fifo[PATH_MAX];
@@ -315,7 +282,7 @@ pid_t exec_service(const char *service, const char *arg)
struct sigaction sa; struct sigaction sa;
file = rc_service_resolve(service); file = rc_service_resolve(service);
if (! exists(file)) { if (!exists(file)) {
rc_service_mark(service, RC_SERVICE_STOPPED); rc_service_mark(service, RC_SERVICE_STOPPED);
free(file); free(file);
return 0; return 0;
@@ -363,7 +330,6 @@ pid_t exec_service(const char *service, const char *arg)
sigprocmask(SIG_SETMASK, &old, NULL); sigprocmask(SIG_SETMASK, &old, NULL);
free(file); free(file);
return pid; return pid;
} }

View File

@@ -58,7 +58,8 @@ static const char * const longopts_help[] = {
}; };
#include "_usage.c" #include "_usage.c"
int rc_service(int argc, char **argv) int
rc_service(int argc, char **argv)
{ {
int opt; int opt;
char *service; char *service;
@@ -75,17 +76,21 @@ int rc_service(int argc, char **argv)
case 'e': case 'e':
service = rc_service_resolve(optarg); service = rc_service_resolve(optarg);
opt = service ? EXIT_SUCCESS : EXIT_FAILURE; opt = service ? EXIT_SUCCESS : EXIT_FAILURE;
#ifdef DEBUG_MEMORY
free(service); free(service);
#endif
return opt; return opt;
/* NOTREACHED */ /* NOTREACHED */
case 'l': case 'l':
list = rc_services_in_runlevel(NULL); list = rc_services_in_runlevel(NULL);
if (! list) if (!TAILQ_FIRST(list))
return EXIT_FAILURE; return EXIT_FAILURE;
rc_stringlist_sort(&list); rc_stringlist_sort(&list);
TAILQ_FOREACH(s, list, entries) TAILQ_FOREACH(s, list, entries)
printf("%s\n", s->value); printf("%s\n", s->value);
#ifdef DEBUG_MEMORY
rc_stringlist_free(list); rc_stringlist_free(list);
#endif
return EXIT_SUCCESS; return EXIT_SUCCESS;
/* NOTREACHED */ /* NOTREACHED */
case 'r': case 'r':
@@ -93,7 +98,9 @@ int rc_service(int argc, char **argv)
if (!service) if (!service)
return EXIT_FAILURE; return EXIT_FAILURE;
printf("%s\n", service); printf("%s\n", service);
#ifdef DEBUG_MEMORY
free(service); free(service);
#endif
return EXIT_SUCCESS; return EXIT_SUCCESS;
/* NOTREACHED */ /* NOTREACHED */
@@ -103,13 +110,10 @@ int rc_service(int argc, char **argv)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (!*argv) if (!*argv)
eerrorx("%s: you need to specify a service", applet); eerrorx("%s: you need to specify a service", applet);
if (!(service = rc_service_resolve(*argv))) if (!(service = rc_service_resolve(*argv)))
eerrorx("%s: service `%s' does not exist", applet, *argv); eerrorx("%s: service `%s' does not exist", applet, *argv);
*argv = service; *argv = service;
execv(*argv, argv); execv(*argv, argv);
eerrorx("%s: %s", applet, strerror(errno)); eerrorx("%s: %s", applet, strerror(errno));

View File

@@ -42,10 +42,14 @@
extern const char *applet; extern const char *applet;
static bool test_crashed = false; static bool test_crashed = false;
static RC_DEPTREE *deptree = NULL; static RC_DEPTREE *deptree;
static RC_STRINGLIST *types = NULL; static RC_STRINGLIST *types;
bool _rc_can_find_pids(void) static RC_STRINGLIST *levels, *services, *tmp, *alist;
static RC_STRINGLIST *sservices, *nservices, *needsme;
bool
_rc_can_find_pids(void)
{ {
RC_PIDLIST *pids; RC_PIDLIST *pids;
RC_PID *pid; RC_PID *pid;
@@ -70,11 +74,11 @@ bool _rc_can_find_pids(void)
} }
free(pids); free(pids);
} }
return retval; return retval;
} }
static void print_level(const char *level) static void
print_level(const char *level)
{ {
printf ("Runlevel: "); printf ("Runlevel: ");
if (isatty(fileno(stdout))) if (isatty(fileno(stdout)))
@@ -86,7 +90,8 @@ static void print_level(const char *level)
printf("%s\n", level); printf("%s\n", level);
} }
static void print_service(const char *service) static void
print_service(const char *service)
{ {
char status[10]; char status[10];
int cols = printf(" %s", service); int cols = printf(" %s", service);
@@ -125,24 +130,25 @@ static void print_service(const char *service)
ebracket(cols, color, status); ebracket(cols, color, status);
} }
static void print_services(const char *runlevel, RC_STRINGLIST *services) static void
print_services(const char *runlevel, RC_STRINGLIST *svcs)
{ {
RC_STRINGLIST *l = NULL; RC_STRINGLIST *l = NULL;
RC_STRING *s; RC_STRING *s;
char *r = NULL; char *r = NULL;
if (! services) if (!svcs)
return; return;
if (! deptree) if (!deptree)
deptree = _rc_deptree_load(NULL); deptree = _rc_deptree_load(NULL);
if (! deptree) { if (!deptree) {
TAILQ_FOREACH(s, services, entries) TAILQ_FOREACH(s, svcs, entries)
if (!runlevel || if (!runlevel ||
rc_service_in_runlevel(s->value, runlevel)) rc_service_in_runlevel(s->value, runlevel))
print_service(s->value); print_service(s->value);
return; return;
} }
if (! types) { if (!types) {
types = rc_stringlist_new(); types = rc_stringlist_new();
rc_stringlist_add(types, "ineed"); rc_stringlist_add(types, "ineed");
rc_stringlist_add(types, "iuse"); rc_stringlist_add(types, "iuse");
@@ -150,13 +156,13 @@ static void print_services(const char *runlevel, RC_STRINGLIST *services)
} }
if (!runlevel) if (!runlevel)
r = rc_runlevel_get(); r = rc_runlevel_get();
l = rc_deptree_depends(deptree, types, services, r ? r : runlevel, l = rc_deptree_depends(deptree, types, svcs, r ? r : runlevel,
RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START); RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START);
free(r); free(r);
if (!l) if (!l)
return; return;
TAILQ_FOREACH(s, l, entries) { TAILQ_FOREACH(s, l, entries) {
if (!rc_stringlist_find(services, s->value)) if (!rc_stringlist_find(svcs, s->value))
continue; continue;
if (!runlevel || rc_service_in_runlevel(s->value, runlevel)) if (!runlevel || rc_service_in_runlevel(s->value, runlevel))
print_service(s->value); print_service(s->value);
@@ -185,13 +191,12 @@ static const char * const longopts_help[] = {
}; };
#include "_usage.c" #include "_usage.c"
int rc_status(int argc, char **argv) int
rc_status(int argc, char **argv)
{ {
RC_STRINGLIST *levels = NULL;
RC_STRINGLIST *services = NULL;
RC_STRING *s, *l, *t; RC_STRING *s, *l, *t;
char *p; char *p, *runlevel = NULL;
int opt; int opt, aflag = 0;
test_crashed = _rc_can_find_pids(); test_crashed = _rc_can_find_pids();
@@ -199,6 +204,7 @@ int rc_status(int argc, char **argv)
(int *) 0)) != -1) (int *) 0)) != -1)
switch (opt) { switch (opt) {
case 'a': case 'a':
aflag++;
levels = rc_runlevel_list(); levels = rc_runlevel_list();
break; break;
case 'l': case 'l':
@@ -208,9 +214,8 @@ int rc_status(int argc, char **argv)
goto exit; goto exit;
/* NOTREACHED */ /* NOTREACHED */
case 'r': case 'r':
p = rc_runlevel_get(); runlevel = rc_runlevel_get();
printf("%s\n", p); printf("%s\n", runlevel);
free(p);
goto exit; goto exit;
/* NOTREACHED */ /* NOTREACHED */
case 's': case 's':
@@ -237,14 +242,21 @@ int rc_status(int argc, char **argv)
case_RC_COMMON_GETOPT case_RC_COMMON_GETOPT
} }
if (! levels) if (!levels)
levels = rc_stringlist_new(); levels = rc_stringlist_new();
while (optind < argc) opt = (optind < argc) ? 0 : 1;
rc_stringlist_add(levels, argv[optind++]); while (optind < argc) {
if (! TAILQ_FIRST(levels)) { if (rc_runlevel_exists(argv[optind])) {
p = rc_runlevel_get(); rc_stringlist_add(levels, argv[optind++]);
rc_stringlist_add(levels, p); opt++;
free(p); } else
eerror("runlevel `%s' does not exist", argv[optind++]);
}
if (opt == 0)
exit(EXIT_FAILURE);
if (!TAILQ_FIRST(levels)) {
runlevel = rc_runlevel_get();
rc_stringlist_add(levels, runlevel);
} }
/* Output the services in the order in which they would start */ /* Output the services in the order in which they would start */
@@ -258,33 +270,78 @@ int rc_status(int argc, char **argv)
services = NULL; services = NULL;
} }
/* Show unassigned running too */ if (aflag || argc < 2) {
if (argc < 2 && /* Show hotplugged services */
(services = rc_services_in_runlevel(NULL))) print_level("hotplugged");
{ services = rc_services_in_state(RC_SERVICE_HOTPLUGGED);
print_level("UNASSIGNED"); print_services(NULL, services);
rc_stringlist_free(levels); rc_stringlist_free(services);
levels = rc_runlevel_list(); services = NULL;
/* Show manually started and unassigned depended services */
if (aflag) {
rc_stringlist_free(levels);
levels = rc_stringlist_new();
if (!runlevel)
runlevel = rc_runlevel_get();
rc_stringlist_add(levels, runlevel);
}
rc_stringlist_add(levels, RC_LEVEL_SYSINIT);
rc_stringlist_add(levels, RC_LEVEL_BOOT);
services = rc_services_in_runlevel(NULL);
sservices = rc_stringlist_new();
TAILQ_FOREACH(l, levels, entries) {
nservices = rc_services_in_runlevel(l->value);
TAILQ_CONCAT(sservices, nservices, entries);
free(nservices);
}
TAILQ_FOREACH_SAFE(s, services, entries, t) { TAILQ_FOREACH_SAFE(s, services, entries, t) {
TAILQ_FOREACH(l, levels, entries) { if (rc_stringlist_find(sservices, s->value) ||
if (rc_service_in_runlevel(s->value, l->value) || rc_service_state(s->value) & RC_SERVICE_STOPPED)
rc_service_state(s->value) & RC_SERVICE_STOPPED) {
{ TAILQ_REMOVE(services, s, entries);
TAILQ_REMOVE(services, s, entries); free(s->value);
free(s->value); free(s);
free(s);
break;
}
} }
} }
needsme = rc_stringlist_new();
rc_stringlist_add(needsme, "needsme");
nservices = rc_stringlist_new();
alist = rc_stringlist_new();
l = rc_stringlist_add(alist, "");
p = l->value;
if (!runlevel)
runlevel = rc_runlevel_get();
TAILQ_FOREACH_SAFE(s, services, entries, t) {
l->value = s->value;
unsetenv("RC_SVCNAME");
setenv("RC_SVCNAME", l->value, 1);
tmp = rc_deptree_depends(deptree, needsme, alist, runlevel, RC_DEP_TRACE);
if (TAILQ_FIRST(tmp)) {
TAILQ_REMOVE(services, s, entries);
TAILQ_INSERT_TAIL(nservices, s, entries);
}
rc_stringlist_free(tmp);
}
l->value = p;
print_level("needed");
print_services(NULL, nservices);
print_level("manual");
print_services(NULL, services); print_services(NULL, services);
} }
exit: exit:
free(runlevel);
#ifdef DEBUG_MEMORY
rc_stringlist_free(alist);
rc_stringlist_free(needsme);
rc_stringlist_free(sservices);
rc_stringlist_free(nservices);
rc_stringlist_free(services); rc_stringlist_free(services);
rc_stringlist_free(types); rc_stringlist_free(types);
rc_stringlist_free(levels); rc_stringlist_free(levels);
rc_deptree_free(deptree); rc_deptree_free(deptree);
#endif
return(EXIT_SUCCESS); return(EXIT_SUCCESS);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -96,10 +96,10 @@ typedef struct scheduleitem
TAILQ_ENTRY(scheduleitem) entries; TAILQ_ENTRY(scheduleitem) entries;
} SCHEDULEITEM; } SCHEDULEITEM;
TAILQ_HEAD(, scheduleitem) schedule; TAILQ_HEAD(, scheduleitem) schedule;
static char **nav = NULL; static char **nav;
extern const char *applet; extern const char *applet;
static char *changeuser = NULL; static char *changeuser, *ch_root, *ch_dir;
extern char **environ; extern char **environ;
@@ -116,13 +116,14 @@ static void free_schedulelist(void)
TAILQ_INIT(&schedule); TAILQ_INIT(&schedule);
} }
#ifdef DEBUG_MEMORY
static void cleanup(void) static void cleanup(void)
{ {
free(changeuser); free(changeuser);
free(nav); free(nav);
free_schedulelist(); free_schedulelist();
} }
#endif
static int parse_signal(const char *sig) static int parse_signal(const char *sig)
{ {
@@ -370,7 +371,7 @@ static int run_stop_schedule(const char *exec, const char *const *argv,
if (verbose) { if (verbose) {
if (exec) if (exec)
einfo ("Will stop %s\n", exec); einfo ("Will stop %s", exec);
if (pidfile) if (pidfile)
einfo("Will stop PID in pidfile `%s'", pidfile); einfo("Will stop PID in pidfile `%s'", pidfile);
if (uid) if (uid)
@@ -497,6 +498,47 @@ static void handle_signal(int sig)
errno = serrno; errno = serrno;
} }
static char *
expand_home(const char *home, const char *path)
{
char *opath, *ppath, *p, *nh;
size_t len;
struct passwd *pw;
if (!path || *path != '~')
return xstrdup(path);
opath = ppath = xstrdup(path);
if (ppath[1] != '/' && ppath[1] != '\0') {
p = strchr(ppath + 1, '/');
if (p)
*p = '\0';
pw = getpwnam(ppath + 1);
if (pw) {
home = pw->pw_dir;
ppath = p;
if (ppath)
*ppath = '/';
} else
home = NULL;
} else
ppath++;
if (!home) {
free(opath);
return xstrdup(path);
}
if (!ppath) {
free(opath);
return xstrdup(home);
}
len = strlen(ppath) + strlen(home) + 1;
nh = xmalloc(len);
snprintf(nh, len, "%s%s", home, ppath);
free(opath);
return nh;
}
#include "_usage.h" #include "_usage.h"
#define getoptstring "KN:R:Sbc:d:e:g:k:mn:op:s:tu:r:x:1:2:" getoptstring_COMMON #define getoptstring "KN:R:Sbc:d:e:g:k:mn:op:s:tu:r:x:1:2:" getoptstring_COMMON
@@ -562,10 +604,12 @@ int start_stop_daemon(int argc, char **argv)
#ifdef HAVE_PAM #ifdef HAVE_PAM
pam_handle_t *pamh = NULL; pam_handle_t *pamh = NULL;
int pamr; int pamr;
const char *const *pamenv = NULL;
#endif #endif
int opt; int opt;
bool start = true; bool start = false;
bool stop = false;
bool oknodo = false; bool oknodo = false;
bool test = false; bool test = false;
bool quiet; bool quiet;
@@ -574,14 +618,13 @@ int start_stop_daemon(int argc, char **argv)
char *startas = NULL; char *startas = NULL;
char *name = NULL; char *name = NULL;
char *pidfile = NULL; char *pidfile = NULL;
int sig = SIGTERM; int sig = 0;
int nicelevel = 0; int nicelevel = 0;
bool background = false; bool background = false;
bool makepidfile = false; bool makepidfile = false;
uid_t uid = 0; uid_t uid = 0;
gid_t gid = 0; gid_t gid = 0;
char *ch_root = NULL; char *home = NULL;
char *ch_dir = NULL;
int tid = 0; int tid = 0;
char *redirect_stderr = NULL; char *redirect_stderr = NULL;
char *redirect_stdout = NULL; char *redirect_stdout = NULL;
@@ -609,7 +652,9 @@ int start_stop_daemon(int argc, char **argv)
unsigned int start_wait = 0; unsigned int start_wait = 0;
TAILQ_INIT(&schedule); TAILQ_INIT(&schedule);
#ifdef DEBUG_MEMORY
atexit(cleanup); atexit(cleanup);
#endif
signal_setup(SIGINT, handle_signal); signal_setup(SIGINT, handle_signal);
signal_setup(SIGQUIT, handle_signal); signal_setup(SIGQUIT, handle_signal);
@@ -620,16 +665,24 @@ int start_stop_daemon(int argc, char **argv)
eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)", eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
applet, tmp); applet, tmp);
/* Get our initial dir */
home = getenv("HOME");
if (!home) {
pw = getpwuid(getuid());
if (pw)
home = pw->pw_dir;
}
while ((opt = getopt_long(argc, argv, getoptstring, longopts, while ((opt = getopt_long(argc, argv, getoptstring, longopts,
(int *) 0)) != -1) (int *) 0)) != -1)
switch (opt) { switch (opt) {
case 'K': /* --stop */ case 'K': /* --stop */
start = false; stop = true;
break; break;
case 'N': /* --nice */ case 'N': /* --nice */
if (sscanf(optarg, "%d", &nicelevel) != 1) if (sscanf(optarg, "%d", &nicelevel) != 1)
eerrorx("%s: invalid nice level `%s'", applet, optarg); eerrorx("%s: invalid nice level `%s'",
applet, optarg);
break; break;
case 'R': /* --retry <schedule>|<timeout> */ case 'R': /* --retry <schedule>|<timeout> */
@@ -655,10 +708,12 @@ int start_stop_daemon(int argc, char **argv)
else else
pw = getpwuid((uid_t) tid); pw = getpwuid((uid_t) tid);
if (! pw) if (!pw)
eerrorx("%s: user `%s' not found", applet, tmp); eerrorx("%s: user `%s' not found",
applet, tmp);
uid = pw->pw_uid; uid = pw->pw_uid;
if (! gid) home = pw->pw_dir;
if (!gid)
gid = pw->pw_gid; gid = pw->pw_gid;
if (p) { if (p) {
@@ -668,8 +723,9 @@ int start_stop_daemon(int argc, char **argv)
else else
gr = getgrgid((gid_t) tid); gr = getgrgid((gid_t) tid);
if (! gr) if (!gr)
eerrorx("%s: group `%s' not found", eerrorx("%s: group `%s'"
" not found",
applet, tmp); applet, tmp);
gid = gr->gr_gid; gid = gr->gr_gid;
} }
@@ -682,9 +738,10 @@ int start_stop_daemon(int argc, char **argv)
case 'e': /* --env */ case 'e': /* --env */
if (putenv(optarg) == 0) { if (putenv(optarg) == 0) {
if (strncmp("HOME=", optarg, 5) == 0) if (strncmp("HOME=", optarg, 5) == 0) {
sethome = true; sethome = true;
else if (strncmp("USER=", optarg, 5) == 0) home = strchr(optarg, '=') + 1;
} else if (strncmp("USER=", optarg, 5) == 0)
setuser = true; setuser = true;
} }
break; break;
@@ -696,8 +753,9 @@ int start_stop_daemon(int argc, char **argv)
else else
gr = getgrgid((gid_t) tid); gr = getgrgid((gid_t) tid);
if (! gr) if (!gr)
eerrorx("%s: group `%s' not found", applet, optarg); eerrorx("%s: group `%s' not found",
applet, optarg);
gid = gr->gr_gid; gid = gr->gr_gid;
} }
break; break;
@@ -764,6 +822,7 @@ int start_stop_daemon(int argc, char **argv)
/* Allow start-stop-daemon --signal HUP --exec /usr/sbin/dnsmasq /* Allow start-stop-daemon --signal HUP --exec /usr/sbin/dnsmasq
* instead of forcing --stop --oknodo as well */ * instead of forcing --stop --oknodo as well */
if (!start && if (!start &&
!stop &&
sig != SIGINT && sig != SIGINT &&
sig != SIGTERM && sig != SIGTERM &&
sig != SIGQUIT && sig != SIGQUIT &&
@@ -777,31 +836,44 @@ int start_stop_daemon(int argc, char **argv)
if (!exec) { if (!exec) {
exec = *argv; exec = *argv;
if (name) if (!exec)
exec = name;
if (name && start)
*argv = name; *argv = name;
} else if (name) } else if (name && (start || **argv))
*--argv = name; *--argv = name;
else else
*--argv = exec; *--argv = exec;
if (stop || sig) {
if ( !*argv && !pidfile && !name && !uid)
eerrorx("%s: --stop needs --exec, --pidfile,"
" --name or --user", applet);
if (background)
eerrorx("%s: --background is only relevant with"
" --start", applet);
if (makepidfile)
eerrorx("%s: --make-pidfile is only relevant with"
" --start", applet);
if (redirect_stdout || redirect_stderr)
eerrorx("%s: --stdout and --stderr are only relevant"
" with --start", applet);
} else {
if (!exec)
eerrorx("%s: nothing to start", applet);
if (makepidfile && !pidfile)
eerrorx("%s: --make-pidfile is only relevant with"
" --pidfile", applet);
if ((redirect_stdout || redirect_stderr) && !background)
eerrorx("%s: --stdout and --stderr are only relevant"
" with --background", applet);
}
if (start && !exec) if (stop || sig) {
eerrorx("%s: nothing to start", applet); if (!sig)
sig = SIGTERM;
if (!start && !*argv && !pidfile && !name && !uid) if (!stop)
eerrorx("%s: --stop needs --exec, --pidfile, --name or --user", applet); oknodo = true;
if (makepidfile && !pidfile)
eerrorx("%s: --make-pidfile is only relevant with --pidfile", applet);
if (background && !start)
eerrorx("%s: --background is only relevant with --start", applet);
if ((redirect_stdout || redirect_stderr) && !background)
eerrorx("%s: --stdout and --stderr are only relevant with --background",
applet);
if (!start) {
if (!TAILQ_FIRST(&schedule)) { if (!TAILQ_FIRST(&schedule)) {
if (test || oknodo) if (test || oknodo)
parse_schedule("0", sig); parse_schedule("0", sig);
@@ -830,6 +902,14 @@ int start_stop_daemon(int argc, char **argv)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
/* Expand ~ */
if (ch_dir && *ch_dir == '~')
ch_dir = expand_home(home, ch_dir);
if (ch_root && *ch_root == '~')
ch_root = expand_home(home, ch_root);
if (*exec == '~')
exec = expand_home(home, exec);
/* Validate that the binary exists if we are starting */ /* Validate that the binary exists if we are starting */
if (*exec == '/' || *exec == '.') { if (*exec == '/' || *exec == '.') {
/* Full or relative path */ /* Full or relative path */
@@ -992,9 +1072,9 @@ int start_stop_daemon(int argc, char **argv)
eerrorx("%s: unable to set groupid to %d", applet, gid); eerrorx("%s: unable to set groupid to %d", applet, gid);
if (changeuser && initgroups(changeuser, gid)) if (changeuser && initgroups(changeuser, gid))
eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid); eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
if (uid && setuid(uid)) if (uid) {
eerrorx ("%s: unable to set userid to %d", applet, uid); if (setuid(uid))
else { eerrorx ("%s: unable to set userid to %d", applet, uid);
pw = getpwuid(uid); pw = getpwuid(uid);
if (pw) { if (pw) {
if (!sethome) { if (!sethome) {
@@ -1023,6 +1103,19 @@ int start_stop_daemon(int argc, char **argv)
i = 0; i = 0;
while(environ[i]) while(environ[i])
rc_stringlist_add(env_list, environ[i++]); rc_stringlist_add(env_list, environ[i++]);
#ifdef HAVE_PAM
pamenv = (const char *const *)pam_getenvlist(pamh);
if (pamenv) {
while (*pamenv) {
/* Don't add strings unless they set a var */
if (strchr(*pamenv, '='))
putenv(xstrdup(*pamenv));
pamenv++;
}
}
#endif
TAILQ_FOREACH(env, env_list, entries) { TAILQ_FOREACH(env, env_list, entries) {
if ((strncmp(env->value, "RC_", 3) == 0 && if ((strncmp(env->value, "RC_", 3) == 0 &&
strncmp(env->value, "RC_SERVICE=", 10) != 0 && strncmp(env->value, "RC_SERVICE=", 10) != 0 &&
@@ -1038,22 +1131,28 @@ int start_stop_daemon(int argc, char **argv)
rc_stringlist_free(env_list); rc_stringlist_free(env_list);
/* For the path, remove the rcscript bin dir from it */ /* For the path, remove the rcscript bin dir from it */
if ((tmp = xstrdup(getenv("PATH")))) { if ((token = getenv("PATH"))) {
len = strlen(tmp); len = strlen(token);
newpath = np = xmalloc(len); newpath = np = xmalloc(len + 1);
p = tmp; while (token && *token) {
while ((token = strsep(&p, ":"))) { p = strchr(token, ':');
if (strcmp(token, RC_LIBDIR "/bin") == 0 || if (p) {
strcmp(token, RC_LIBDIR "/sbin") == 0) *p++ = '\0';
continue; while (*p == ':')
len = strlen(token); p++;
if (np != newpath) }
*np++ = ':'; if (strcmp(token, RC_LIBDIR "/bin") != 0 &&
memcpy(np, token, len); strcmp(token, RC_LIBDIR "/sbin") != 0)
np += len; {
*np = '\0'; len = strlen(token);
if (np != newpath)
*np++ = ':';
memcpy(np, token, len);
np += len;
}
token = p;
} }
free(tmp); *np = '\0';
unsetenv("PATH"); unsetenv("PATH");
setenv("PATH", newpath, 1); setenv("PATH", newpath, 1);
} }

2
src/test/.gitignore vendored
View File

@@ -1,2 +0,0 @@
/*.out
tmp-*

View File

@@ -2,7 +2,7 @@ all:
install: install:
gitignore: ignore:
check test:: check test::
./runtests.sh ./runtests.sh

View File

@@ -41,8 +41,10 @@ rc_services_scheduled_by
rc_stringlist_add rc_stringlist_add
rc_stringlist_addu rc_stringlist_addu
rc_stringlist_delete rc_stringlist_delete
rc_stringlist_find
rc_stringlist_free rc_stringlist_free
rc_stringlist_new rc_stringlist_new
rc_stringlist_sort rc_stringlist_sort
rc_stringlist_split
rc_sys rc_sys
rc_yesno rc_yesno

View File

@@ -82,12 +82,16 @@ rc_stringlist_addu
rc_stringlist_addu@@RC_1.0 rc_stringlist_addu@@RC_1.0
rc_stringlist_delete rc_stringlist_delete
rc_stringlist_delete@@RC_1.0 rc_stringlist_delete@@RC_1.0
rc_stringlist_find
rc_stringlist_find@@RC_1.0
rc_stringlist_free rc_stringlist_free
rc_stringlist_free@@RC_1.0 rc_stringlist_free@@RC_1.0
rc_stringlist_new rc_stringlist_new
rc_stringlist_new@@RC_1.0 rc_stringlist_new@@RC_1.0
rc_stringlist_sort rc_stringlist_sort
rc_stringlist_sort@@RC_1.0 rc_stringlist_sort@@RC_1.0
rc_stringlist_split
rc_stringlist_split@@RC_1.0
rc_sys rc_sys
rc_sys@@RC_1.0 rc_sys@@RC_1.0
rc_yesno rc_yesno

View File

@@ -1 +0,0 @@
tmp-*