summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog186
-rw-r--r--etc/conf.d/domainname21
-rw-r--r--etc/conf.d/env_whitelist11
-rw-r--r--etc/group7
-rw-r--r--etc/passwd7
-rwxr-xr-xsbin/depscan.sh4
-rwxr-xr-xsbin/env-update.sh11
-rwxr-xr-xsbin/functions.sh151
-rwxr-xr-xsbin/init-common-post.sh58
-rwxr-xr-xsbin/init-common-pre.sh7
-rwxr-xr-xsbin/init-functions.sh57
-rwxr-xr-xsbin/init.linux.sh43
-rwxr-xr-xsbin/rc189
-rwxr-xr-xsbin/rc-daemon.sh13
-rwxr-xr-xsbin/rc-help.sh116
-rwxr-xr-xsbin/rc-services.sh164
-rwxr-xr-xsbin/runscript.sh32
-rw-r--r--src/awk/genenviron.awk9
-rw-r--r--src/core/ChangeLog71
-rw-r--r--src/core/Makefile4
-rw-r--r--src/core/TODO11
-rw-r--r--src/core/debug.h6
-rw-r--r--src/core/depend.c107
-rw-r--r--src/core/misc.c98
-rw-r--r--src/core/misc.h68
-rw-r--r--src/core/parse.c600
-rw-r--r--src/core/parse.h1
-rw-r--r--src/core/simple-regex.c151
-rw-r--r--src/core/simple-regex.h8
-rw-r--r--src/env_whitelist1
-rw-r--r--src/runscript.c3
-rw-r--r--src/start-stop-daemon.c323
32 files changed, 1416 insertions, 1122 deletions
diff --git a/ChangeLog b/ChangeLog
index 849dc2a..295db48 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,128 @@
# ChangeLog for Gentoo System Intialization ("rc") scripts
# Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2
+ 23 Sep 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Add a note to conf.d/clock for people who dual boot with Windows.
+
+ Touchup comments in conf.d/domainname to help clear confusion.
+
+ Rework how we setup default rc variables in sbin/functions.sh to help
+ keep users from doing stupid things and destroying their system.
+
+ 17 Sep 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Fix up support for NetBSD #106112 by Damian Florczyk.
+
+ When doing a forced fsck, don't show title at startup (-T).
+
+ 16 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ iwconfig and wpa_supplicant now check to see if /proc/net/wireless exists
+ before checking for extensions, #106036
+
+ 14 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ netplug module renamed to netplugd for consistency
+
+ pppd module added, #53954 thanks to Alin Nastac
+
+ 14 Sep 2005; Martin Schlemmer <azarah@gentoo.org>:
+
+ Need to source init-functions.sh to provid try() for halt.sh.
+
+ 13 Sep 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Don't mount ${svcdir} with -n since / is writable at that point.
+
+ Clean up udev tarball temp files in halt.sh #105827 by Robert Forsman.
+
+ 13 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ Changed net.lo depend from isdn4linux to isdn, #102846
+
+ 12 Sep 2005; Martin Schlemmer <azarah@gentoo.org>:
+
+ Split /sbin/rc into more modular pieces to allow easy porting to the bsd's.
+ Thanks goes to Mike who did the initial version.
+
+ Split out devfs and udev stuff to addons.
+
+ Lots of syntax and quoting fixes.
+
+ Move noblock_read() back to /sbin/rc, as its used there.
+
+ 12 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ Set essid before mode for ad-hoc/master configurations, #105452
+
+ Fixed force_any associate order option, #99256
+
+ 09 Sep 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Add PKG_CONFIG_PATH to incremental env var list #105384 by Sven Wegener.
+
+ 08 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ Added ifplugd module, but we prefer netplug by default
+
+ 07 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ replace the apipa module with a generic arping module which can now
+ do gateway detection and apply a configuration for it as well as the
+ apipa stuff
+
+ updated env_whitelist so that nothing is allowed by default
+
+ system module now runs through pre instead of post and is run by
+ lo as well, so dns_ options can be configured for it
+
+ netplug and wpa_supplicant understand negative timeouts to be defined
+ as "return immediately and don't wait for success"
+
+ dns options and sortlist now get merged in resolv.conf too
+
+ bridge error message regarding the kernel module should work with
+ newer versions of bridge-utils
+
+ 06 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ dns_*, nis_* and ntp_* options now work globally too, but are overridden
+ by specific interface/essid/mac ones.
+
+ dhcpcd and pump now support the "options" and "sortlist" directives too,
+ #104870
+
+ 05 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ Added resolv.conf options for "options" and "sortlist" directives, #104870
+
+ dns_search_path_eth0 renamed to dns_search_eth0 so that all the dns_
+ variables match their resolv.conf counterpart.
+
+ 04 Sep 2005; Martin Schlemmer <azarah@gentoo.org>:
+
+ Do not unmount /usr, but rather remount it ro, else we run into issues
+ with systems that have locales enabled, as the fuser call in halt.sh tries
+ to kill bash (due to it using /usr/lib/locale/*).
+
+ 03 Sep 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Clean up netmount and don't unmount afs filesystems if the user has the
+ afs-client init.d script running.
+
+ Update rc-help.sh to show custom init.d opts #49663 and in general make
+ the output a lot more useful.
+
+ 03 Sep 2005; Martin Schlemmer <azarah@gentoo.org>:
+
+ Add warning about having LANG in env_whitelist, add TERM to system
+ env_whitelist, set argv[0] to '/bin/bash' and not 'runscript'.
+
+ 02 Sep 2005; Roy Marples <uberlord@gentoo.org>:
+
+ Fixed netplug from stopping on the wrong interface
+
* baselayout-1.12.0_pre8 (02 Sep 2005)
02 Sep 2005; Martin Schlemmer <azarah@gentoo.org>:
@@ -54,10 +176,21 @@
fixed IPv6 address problems in ifconfig and iproute2 modules
+ 25 Aug 2005; Martin Schlemmer <azarah@gentoo.org>:
+
+ Fix typo in /sbin/rc - we should check if ${argv1} is in /etc/inittab, and
+ not if 'default' is in there ...
+
+ Add /sbin/evms_activate to populate_udev(), bug #50711.
+
24 Aug 2005; Roy Marples <uberlord@gentoo.org>:
rc-daemon now handles --signal correct - fixes #103182
+ 23 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Sync our MAKEDEV with Debian's latest version.
+
19 Aug 2005; Roy Marples <uberlord@gentoo.org>:
dhcpcd now reports the correct needed version
@@ -70,14 +203,26 @@
18 Aug 2005; Roy Marples <uberlord@gentoo.org>:
RC_AUTO_INTERFACE defaults to NO - but we still default to DHCP
-
+
consoletype is now cached. This has the benefit of being very slightly
faster and you now get coloured text for parallel startup
-
+
Parallel startup also does parallel shutdown as well
-
+
You're now warned if you're using a deprecated conf.d/net syntax
-
+
+ 18 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Add a note about the 6th field for root filesystems #95846.
+
+ 16 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ rquotad is supposed to be an alias for port 4003 not 4002.
+
+ 15 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Add ocfs2 to the NET_FS_LIST #102659 by Lazar Obradovic.
+
15 Aug 2005; Roy Marples <uberlord@gentoo.org>:
iproute2 now understands the old iface_xxx syntax, but this only works
@@ -111,13 +256,20 @@
Remove tail from depdir() in /sbin/modules-update
-* baselayout-1.12.0_pre5 (11 Aug 2005)
+ 10 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Document the boot logging option RC_BOOTLOG with app-admin/showconsole.
08 Aug 2005; Roy Marples <uberlord@gentoo.org>:
Add failup/faildown user functions when an interface fails to come up/go
down. Fixes bug #101087.
+ 06 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Add a lot more documentation to /etc/hosts from FreeBSD's standard hosts
+ file #101418 by Mark Cooper.
+
06 Aug 2005; Martin Schlemmer <azarah@gentoo.org>:
Revert 'mtime' changes to depscan.sh, and just make it warn if it detects
@@ -137,8 +289,6 @@
Try a workaround for the "mtime in future" issues we have with depscan.sh.
-* baselayout-1.12.0_pre4 (05 Aug 2005)
-
05 Aug 2005; Roy Marples <uberlord@gentoo.org>:
Rationalise if/then/else login in runscript.sh svc_start() and svc_stop()
@@ -180,6 +330,10 @@
iwconfig no longer downs and ups the interface after a scan - instead we
set essid any just before doing it
+ 01 Aug 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Only create /dev/core if /proc/kcore exists #100978 by Timo Hirvonen.
+
01 Aug 2005; Roy Marples <uberlord@gentoo.org>:
dhclient now has to be told it can edit dhclient.conf instead of assuming
@@ -201,8 +355,6 @@
Fixed dhclient sending hostname #100745, thanks to Benoit Boissinot.
-* baselayout-1.12.0_pre3 (29 Jul 2005)
-
26 Jul 2005; Martin Schlemmer <azarah@gentoo.org>:
Remove the "parallel" depend stuff from the awk backend.
@@ -239,8 +391,6 @@
Do not restart dependencies on runlevel change if the service that needs
them are in the next runlevel.
-* baselayout-1.12.0_pre2 (22 Jul 2005)
-
22 Jul 2005; Roy Marples <uberlord@gentoo.org>:
When a service is stopped, the IN_BACKGROUND variable is cleared
@@ -280,10 +430,8 @@
19 Jul 2005; Mike Frysinger <vapier@gentoo.org>:
- Punt the cyrus/mysql/slocate/vpopmail users/groups to the
- respective ebuilds.
-
- Removed trailing tab from local.start - fixes #99624
+ Punt the at/bind/cron/cyrus/ftp/games/man/mysql/qmail/slocate/squid/
+ sshd/vpopmail users/groups to the respective ebuilds.
19 Jul 2005; Roy Marples <uberlord@gentoo.org>:
@@ -305,7 +453,13 @@
Do not run depmod in modules-update if System.map is missing, bug #59188.
-* baselayout-1.12.0_pre1 (14 Jul 2005)
+ 14 Jul 2005; Mike Frysinger <vapier@gentoo.org>:
+
+ Remove pointless check of depmod existence in modules init.d since the
+ modules-update script checks for it.
+
+ Run kbd_mode earlier for unicode users so initial loadkeys doesn't
+ trigger a warning #94048 by Eugene Pavlovsky.
13 Jul 2005; Roy Marples <uberlord@gentoo.org>:
diff --git a/etc/conf.d/domainname b/etc/conf.d/domainname
index 75631ac..7d8374b 100644
--- a/etc/conf.d/domainname
+++ b/etc/conf.d/domainname
@@ -1,17 +1,20 @@
# /etc/conf.d/domainname
# When setting up resolv.conf, what should take precedence?
-# If you wish to always override DHCP/whatever, set this to 1.
+# 0 = let dhcp/whatever override DNSDOMAIN
+# 1 = override dhcp/whatever with DNSDOMAIN
+
OVERRIDE=1
# To have a proper FQDN, you need to setup /etc/hosts and /etc/resolv.conf
-# properly (domain entry in /etc/resolv.conf, and FQDN in /etc/hosts).
-#
-#DNSDOMAIN=""
-
-# This only set what /bin/hostname returns. If you need to setup NIS, meaning
-# what /bin/domainname returns, please see:
+# (domain entry in /etc/resolv.conf and FQDN in /etc/hosts).
#
+# DNSDOMAIN merely sets the domain entry in /etc/resolv.conf, see
+# the resolv.conf(5) manpage for more info.
+
+DNSDOMAIN=""
+
+# For information on setting up NIS, please see:
# http://www.linux-nis.org/nis-howto/HOWTO/
-#
-#NISDOMAIN=""
+
+NISDOMAIN=""
diff --git a/etc/conf.d/env_whitelist b/etc/conf.d/env_whitelist
index 03fc270..e04ba9e 100644
--- a/etc/conf.d/env_whitelist
+++ b/etc/conf.d/env_whitelist
@@ -1,10 +1,11 @@
# /etc/conf.d/env_whitelist: Environment whitelist for rc-system
-# Specify which variables is allowed to be passed from the environment to the
+# Specify which variables are allowed to be passed from the environment to the
# rc-system. If it is not set by the environment, then the variable will be
# taken from /etc/profile.env - meaning, if you need to set LANG or such,
-# do it in a /etc/env.d/00myownstuff file for example, and run env-update.
-
-# User controlled
-LANG
+# do it in a /etc/env.d/99myownstuff file for example, and run env-update.
+# Locale settings
+#LANG
+#LANGUAGE
+#LC_ALL
diff --git a/etc/group b/etc/group
index 2d58052..b58bd79 100644
--- a/etc/group
+++ b/etc/group
@@ -13,21 +13,14 @@ floppy::11:root
mail::12:mail
news::13:news
uucp::14:uucp
-man::15:man
-cron::16:cron
console::17:
audio::18:
cdrom::19:
dialout::20:root
-ftp::21:
-sshd::22:
-at::25:at
tape::26:root
video::27:root
-squid::31:squid
gdm::32:gdm
xfs::33:xfs
-games::35:
postgres::70:
cdrw::80:
nut::84:
diff --git a/etc/passwd b/etc/passwd
index e30265c..d108763 100644
--- a/etc/passwd
+++ b/etc/passwd
@@ -10,16 +10,9 @@ mail:x:8:12:mail:/var/spool/mail:/bin/false
news:x:9:13:news:/usr/lib/news:/bin/false
uucp:x:10:14:uucp:/var/spool/uucppublic:/bin/false
operator:x:11:0:operator:/root:/bin/bash
-man:x:13:15:man:/usr/share/man:/bin/false
postmaster:x:14:12:postmaster:/var/spool/mail:/bin/false
-cron:x:16:16:cron:/var/spool/cron:/bin/false
-ftp:x:21:21::/home/ftp:/bin/false
-sshd:x:22:22:sshd:/dev/null:/bin/false
-at:x:25:25:at:/var/spool/cron/atjobs:/bin/false
-squid:x:31:31:Squid:/var/cache/squid:/bin/false
gdm:x:32:32:GDM:/var/lib/gdm:/bin/false
xfs:x:33:33:X Font Server:/etc/X11/fs:/bin/false
-games:x:35:35:games:/usr/games:/bin/false
postgres:x:70:70::/var/lib/postgresql:/bin/bash
nut:x:84:84:nut:/var/state/nut:/bin/false
postfix:x:207:207:postfix:/var/spool/postfix:/bin/false
diff --git a/sbin/depscan.sh b/sbin/depscan.sh
index 1fbf0ef..59bda9d 100755
--- a/sbin/depscan.sh
+++ b/sbin/depscan.sh
@@ -9,7 +9,7 @@ if [[ $1 == "--debug" ]] ; then
set -x
fi
-if [[ ! -d ${svcdir} ]]; then
+if [[ ! -d ${svcdir} ]] ; then
if ! mkdir -p -m 0755 "${svcdir}" 2>/dev/null ; then
eerror "Could not create needed directory '${svcdir}'!"
fi
@@ -18,7 +18,7 @@ fi
for x in softscripts snapshot options daemons \
started starting inactive stopping failed \
exclusive exitcodes ; do
- if [[ ! -d "${svcdir}/${x}" ]] ; then
+ if [[ ! -d ${svcdir}/${x} ]] ; then
if ! mkdir -p -m 0755 "${svcdir}/${x}" 2>/dev/null ; then
eerror "Could not create needed directory '${svcdir}/${x}'!"
fi
diff --git a/sbin/env-update.sh b/sbin/env-update.sh
index 533e989..975203d 100755
--- a/sbin/env-update.sh
+++ b/sbin/env-update.sh
@@ -4,8 +4,7 @@
source /sbin/functions.sh || exit 1
-if [ "${EUID}" -ne 0 ]
-then
+if [[ ${EUID} -ne 0 ]] ; then
eerror "$0: must be root."
exit 1
fi
@@ -20,17 +19,15 @@ note:
exit 1
}
-export SVCDIR="${svcdir}"
+export SVCDIR=${svcdir}
# Only update if files have actually changed
-if [ "$1" == "-u" ]
-then
+if [[ $1 == "-u" ]] ; then
is_older_than "${svcdir}/envcache" /etc/env.d && exit 0
shift
fi
-if [ "$#" -ne 0 ]
-then
+if [[ $# -ne 0 ]] ; then
usage
else
/bin/gawk \
diff --git a/sbin/functions.sh b/sbin/functions.sh
index e9bf234..5c5d870 100755
--- a/sbin/functions.sh
+++ b/sbin/functions.sh
@@ -3,12 +3,15 @@
RC_GOT_FUNCTIONS="yes"
+# Override defaults with user settings ...
+[ -f /etc/conf.d/rc ] && source /etc/conf.d/rc
+
# daemontools dir
SVCDIR="/var/lib/supervise"
# Check /etc/conf.d/rc for a description of these ...
-svcdir="/var/lib/init.d"
svclib="/lib/rcscripts"
+svcdir=${svcdir:-/var/lib/init.d}
# Different types of dependencies
deptypes="need use"
@@ -31,8 +34,8 @@ RC_ENDCOL="yes"
#
# Default values for rc system
#
-RC_TTY_NUMBER=0
-RC_PARALLEL_STARTUP="no"
+RC_TTY_NUMBER=${RC_TTY_NUMBER:-0}
+RC_PARALLEL_STARTUP=${RC_PARALLEL_STARTUP:-no}
#
# Default values for e-message indentation and dots
@@ -42,9 +45,6 @@ RC_DEFAULT_INDENT=2
#RC_DOT_PATTERN=' .'
RC_DOT_PATTERN=''
-# Override defaults with user settings ...
-[ -f /etc/conf.d/rc ] && source /etc/conf.d/rc
-
# void import_addon(char *addon)
#
# Import code from the specified addon if it exists
@@ -98,11 +98,11 @@ get_bootconfig() {
setup_defaultlevels() {
get_bootconfig
- if [ -z "${SOFTLEVEL}" ] ; then
- if [ -f "${svcdir}/softlevel" ] ; then
- export SOFTLEVEL="$(< ${svcdir}/softlevel)"
+ if [[ -z ${SOFTLEVEL} ]] ; then
+ if [[ -f ${svcdir}/softlevel ]] ; then
+ export SOFTLEVEL=$(< "${svcdir}/softlevel")
else
- export SOFTLEVEL="${BOOTLEVEL}"
+ export SOFTLEVEL=${BOOTLEVEL}
fi
fi
@@ -114,10 +114,10 @@ setup_defaultlevels() {
# prints the current libdir {lib,lib32,lib64}
#
get_libdir() {
- if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then
- CONF_LIBDIR="${CONF_LIBDIR_OVERRIDE}"
- elif [ -x "/usr/bin/portageq" ] ; then
- CONF_LIBDIR="$(/usr/bin/portageq envvar CONF_LIBDIR)"
+ if [[ -n ${CONF_LIBDIR_OVERRIDE} ]] ; then
+ CONF_LIBDIR=${CONF_LIBDIR_OVERRIDE}
+ elif [[ -x /usr/bin/portageq ]] ; then
+ CONF_LIBDIR=$(/usr/bin/portageq envvar CONF_LIBDIR)
fi
echo ${CONF_LIBDIR:=lib}
}
@@ -130,10 +130,9 @@ esyslog() {
local pri=
local tag=
- if [ -x /usr/bin/logger ]
- then
- pri="$1"
- tag="$2"
+ if [[ -x /usr/bin/logger ]] ; then
+ pri=$1
+ tag=$2
shift 2
[[ -z "$*" ]] && return 0
@@ -181,7 +180,7 @@ esetdent() {
#
einfo() {
einfon "$*\n"
- LAST_E_CMD=einfo
+ LAST_E_CMD="einfo"
return 0
}
@@ -190,10 +189,10 @@ einfo() {
# show an informative message (without a newline)
#
einfon() {
- [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
- [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
+ [[ ${RC_QUIET_STDOUT} == "yes" ]] && return 0
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -ne " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
- LAST_E_CMD=einfon
+ LAST_E_CMD="einfon"
return 0
}
@@ -202,17 +201,17 @@ einfon() {
# show a warning message + log it
#
ewarn() {
- if [[ ${RC_QUIET_STDOUT} == yes ]]; then
+ if [[ ${RC_QUIET_STDOUT} == "yes" ]] ; then
echo " $*"
else
- [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e " ${WARN}*${NORMAL} ${RC_INDENTATION}$*"
fi
# Log warnings to system log
esyslog "daemon.warning" "rc-scripts" "$*"
- LAST_E_CMD=ewarn
+ LAST_E_CMD="ewarn"
return 0
}
@@ -221,17 +220,17 @@ ewarn() {
# show an error message + log it
#
eerror() {
- if [[ ${RC_QUIET_STDOUT} == yes ]]; then
+ if [[ ${RC_QUIET_STDOUT} == "yes" ]] ; then
echo " $*" >/dev/stderr
else
- [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e " ${BAD}*${NORMAL} ${RC_INDENTATION}$*"
fi
# Log errors to system log
esyslog "daemon.err" "rc-scripts" "$*"
- LAST_E_CMD=eerror
+ LAST_E_CMD="eerror"
return 0
}
@@ -241,9 +240,9 @@ eerror() {
#
ebegin() {
local msg="$*" dots spaces=${RC_DOT_PATTERN//?/ }
- [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
+ [[ ${RC_QUIET_STDOUT} == "yes" ]] && return 0
- if [[ -n ${RC_DOT_PATTERN} ]]; then
+ if [[ -n ${RC_DOT_PATTERN} ]] ; then
dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')
dots=${dots//${spaces}/${RC_DOT_PATTERN}}
msg="${msg}${dots}"
@@ -251,10 +250,10 @@ ebegin() {
msg="${msg} ..."
fi
einfon "${msg}"
- [[ ${RC_ENDCOL} == yes ]] && echo
+ [[ ${RC_ENDCOL} == "yes" ]] && echo
LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
- LAST_E_CMD=ebegin
+ LAST_E_CMD="ebegin"
return 0
}
@@ -270,17 +269,17 @@ _eend() {
local retval=${1:-0} efunc=${2:-eerror} msg
shift 2
- if [[ ${retval} == 0 ]]; then
- [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
+ if [[ ${retval} == "0" ]]; then
+ [[ ${RC_QUIET_STDOUT} == "yes" ]] && return 0
msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
else
- if [[ -n "$*" ]]; then
+ if [[ -n $* ]] ; then
${efunc} "$*"
fi
msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
fi
- if [[ ${RC_ENDCOL} == yes ]]; then
+ if [[ ${RC_ENDCOL} == "yes" ]] ; then
echo -e "${ENDCOL} ${msg}"
else
[[ ${LAST_E_CMD} == ebegin ]] || LAST_E_LEN=0
@@ -301,8 +300,8 @@ eend() {
_eend ${retval} eerror "$*"
- LAST_E_CMD=eend
- return $retval
+ LAST_E_CMD="eend"
+ return ${retval}
}
# void ewend(int error, char* errstr)
@@ -316,23 +315,23 @@ ewend() {
_eend ${retval} ewarn "$*"
- LAST_E_CMD=ewend
- return $retval
+ LAST_E_CMD="ewend"
+ return ${retval}
}
# v-e-commands honor RC_VERBOSE which defaults to no.
# The condition is negated so the return value will be zero.
-veinfo() { [[ "${RC_VERBOSE}" != yes ]] || einfo "$@"; }
-veinfon() { [[ "${RC_VERBOSE}" != yes ]] || einfon "$@"; }
-vewarn() { [[ "${RC_VERBOSE}" != yes ]] || ewarn "$@"; }
-veerror() { [[ "${RC_VERBOSE}" != yes ]] || eerror "$@"; }
-vebegin() { [[ "${RC_VERBOSE}" != yes ]] || ebegin "$@"; }
+veinfo() { [[ ${RC_VERBOSE} != "yes" ]] || einfo "$@"; }
+veinfon() { [[ ${RC_VERBOSE} != "yes" ]] || einfon "$@"; }
+vewarn() { [[ ${RC_VERBOSE} != "yes" ]] || ewarn "$@"; }
+veerror() { [[ ${RC_VERBOSE} != "yes" ]] || eerror "$@"; }
+vebegin() { [[ ${RC_VERBOSE} != "yes" ]] || ebegin "$@"; }
veend() {
- [[ "${RC_VERBOSE}" == yes ]] && { eend "$@"; return $?; }
+ [[ ${RC_VERBOSE} == "yes" ]] && { eend "$@"; return $?; }
return ${1:-0}
}
veend() {
- [[ "${RC_VERBOSE}" == yes ]] && { ewend "$@"; return $?; }
+ [[ ${RC_VERBOSE} == "yes" ]] && { ewend "$@"; return $?; }
return ${1:-0}
}
@@ -344,7 +343,7 @@ KV_major() {
[[ -z $1 ]] && return 1
local KV=$@
- echo ${KV%%.*}
+ echo "${KV%%.*}"
}
# char *KV_minor(string)
@@ -356,7 +355,7 @@ KV_minor() {
local KV=$@
KV=${KV#*.}
- echo ${KV%%.*}
+ echo "${KV%%.*}"
}
# char *KV_micro(string)
@@ -368,7 +367,7 @@ KV_micro() {
local KV=$@
KV=${KV#*.*.}
- echo ${KV%%[^[:digit:]]*}
+ echo "${KV%%[^[:digit:]]*}"
}
# int KV_to_int(string)
@@ -404,7 +403,7 @@ KV_to_int() {
get_KV() {
local KV=$(uname -r)
- echo $(KV_to_int "${KV}")
+ echo "$(KV_to_int "${KV}")"
return $?
}
@@ -436,25 +435,21 @@ dolisting() {
local mylist=
local mypath="$*"
- if [ "${mypath%/\*}" != "${mypath}" ]
- then
- mypath="${mypath%/\*}"
+ if [[ ${mypath%/\*} != "${mypath}" ]] ; then
+ mypath=${mypath%/\*}
fi
- for x in ${mypath}
- do
- [ ! -e "${x}" ] && continue
+ for x in ${mypath} ; do
+ [[ ! -e ${x} ]] && continue
- if [ ! -d "${x}" ] && ( [ -L "${x}" -o -f "${x}" ] )
- then
+ if [[ ! -d ${x} ]] && [[ -L ${x} || -f ${x} ]] ; then
mylist="${mylist} $(ls "${x}" 2> /dev/null)"
else
- [ "${x%/}" != "${x}" ] && x="${x%/}"
+ [[ ${x%/} != "${x}" ]] && x=${x%/}
- cd "${x}"; tmpstr="$(ls)"
+ cd "${x}"; tmpstr=$(ls)
- for y in ${tmpstr}
- do
+ for y in ${tmpstr} ; do
mylist="${mylist} ${x}/${y}"
done
fi
@@ -468,11 +463,10 @@ dolisting() {
# save the settings ("optstring") for "option"
#
save_options() {
- local myopts="$1"
+ local myopts=$1
shift
- if [ ! -d "${svcdir}/options/${myservice}" ]
- then
+ if [[ ! -d ${svcdir}/options/${myservice} ]] ; then
mkdir -p -m 0755 "${svcdir}/options/${myservice}"
fi
@@ -487,8 +481,7 @@ save_options() {
# by calling the save_options function
#
get_options() {
- if [ -f "${svcdir}/options/${myservice}/$1" ]
- then
+ if [[ -f ${svcdir}/options/${myservice}/$1 ]] ; then
echo "$(< ${svcdir}/options/${myservice}/$1)"
fi
@@ -511,7 +504,7 @@ add_suffix() {
get_base_ver() {
[[ ! -r /etc/gentoo-release ]] && return 0
local ver=$(</etc/gentoo-release)
- echo ${ver##* }
+ echo "${ver##* }"
}
# Network filesystems list for common use in rc-scripts.
@@ -580,7 +573,7 @@ get_mount_fstab() {
# Returns the reversed order of list
#
reverse_list() {
- for (( i = $# ; i > 0 ; --i )); do
+ for (( i = $# ; i > 0 ; --i )) ; do
echo -n "${!i} "
done
}
@@ -591,7 +584,7 @@ reverse_list() {
#
start_addon() {
local addon=$1
- (import_addon ${addon}-start.sh)
+ (import_addon "${addon}-start.sh")
return 0
}
@@ -609,7 +602,7 @@ start_volumes() {
#
stop_addon() {
local addon=$1
- (import_addon ${addon}-stop.sh)
+ (import_addon "${addon}-stop.sh")
return 0
}
@@ -675,7 +668,7 @@ requote() {
# #
##############################################################################
-if [ -z "${EBUILD}" ] ; then
+if [[ -z ${EBUILD} ]] ; then
# Setup a basic $PATH. Just add system default to existing.
# This should solve both /sbin and /usr/sbin not present when
# doing 'su -c foo', or for something like: PATH= rcscript start
@@ -684,7 +677,7 @@ if [ -z "${EBUILD}" ] ; then
# Cache the CONSOLETYPE - this is important as backgrounded shells don't
# have a TTY. rc unsets it at the end of running so it shouldn't hang
# around
- if [[ -z ${CONSOLETYPE} ]]; then
+ if [[ -z ${CONSOLETYPE} ]] ; then
export CONSOLETYPE=$( /sbin/consoletype 2>/dev/null )
fi
if [[ ${CONSOLETYPE} == "serial" ]] ; then
@@ -704,10 +697,10 @@ if [ -z "${EBUILD}" ] ; then
setup_defaultlevels
else
# Should we use colors ?
- if [[ $* != *depend* ]]; then
+ if [[ $* != *depend* ]] ; then
# Check user pref in portage
RC_NOCOLOR="$(portageq envvar NOCOLOR 2>/dev/null)"
- [ "${RC_NOCOLOR}" = "true" ] && RC_NOCOLOR="yes"
+ [[ ${RC_NOCOLOR} == "true" ]] && RC_NOCOLOR="yes"
else
# We do not want colors during emerge depend
RC_NOCOLOR="yes"
@@ -716,7 +709,7 @@ else
fi
fi
-if [[ -n ${EBUILD} && $* = *depend* ]]; then
+if [[ -n ${EBUILD} && $* == *depend* ]]; then
# We do not want stty to run during emerge depend
COLS=80
else
@@ -726,14 +719,14 @@ else
(( COLS > 0 )) || (( COLS = 80 )) # width of [ ok ] == 7
fi
-if [[ ${RC_ENDCOL} == yes ]]; then
+if [[ ${RC_ENDCOL} == "yes" ]]; then
ENDCOL=$'\e[A\e['$(( COLS - 8 ))'C'
else
ENDCOL=''
fi
# Setup the colors so our messages all look pretty
-if [[ ${RC_NOCOLOR} == yes ]]; then
+if [[ ${RC_NOCOLOR} == "yes" ]]; then
unset GOOD WARN BAD NORMAL HILITE BRACKET
else
GOOD=$'\e[32;01m'
diff --git a/sbin/init-common-post.sh b/sbin/init-common-post.sh
new file mode 100755
index 0000000..5d4e102
--- /dev/null
+++ b/sbin/init-common-post.sh
@@ -0,0 +1,58 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# We set the forced softlevel from the kernel command line
+# It needs to be run right after proc is mounted for the
+# boot runlevel
+setup_defaultlevels
+
+# $BOOT can be used by rc-scripts to test if it is the first time
+# the 'boot' runlevel is executed. Now also needed by some stuff in
+# the 'sysinit' runlevel ...
+export BOOT="yes"
+
+# We first try to find a locally defined list of critical services
+# for a particular runlevel. If we cannot find it, we use the
+# defaults.
+get_critical_services
+
+export START_CRITICAL="yes"
+
+# We do not want to break compatibility, so we do not fully integrate
+# these into /sbin/rc, but rather start them by hand ...
+for x in ${CRITICAL_SERVICES} ; do
+ if ! start_critical_service "${x}" ; then
+ echo
+ eerror "One of more critical startup scripts failed to start!"
+ einfo "Rebooting"
+ /sbin/reboot -f
+ fi
+done
+
+unset START_CRITICAL
+
+# Check that $svcdir exists ...
+check_statedir "${svcdir}"
+
+# Clear $svcdir from stale entries, but leave the caches around, as it
+# should help speed things up a bit
+rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
+ grep -ve '\(depcache\|deptree\|envcache\)')
+
+echo "sysinit" > "${svcdir}/softlevel"
+
+# Update the dependency cache
+/sbin/depscan.sh -u
+
+# Now that the dependency cache are up to date, make sure these
+# are marked as started ...
+(
+ # Needed for mark_service_started()
+ source "${svclib}"/sh/rc-services.sh
+
+ for x in ${CRITICAL_SERVICES} ; do
+ mark_service_started "${x}"
+ done
+)
+
+# vim:ts=4
diff --git a/sbin/init-common-pre.sh b/sbin/init-common-pre.sh
new file mode 100755
index 0000000..5c4ef4c
--- /dev/null
+++ b/sbin/init-common-pre.sh
@@ -0,0 +1,7 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# Setup initial $PATH just in case
+export PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}"
+
+# vim:ts=4
diff --git a/sbin/init-functions.sh b/sbin/init-functions.sh
new file mode 100755
index 0000000..04a1f13
--- /dev/null
+++ b/sbin/init-functions.sh
@@ -0,0 +1,57 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# bool check_statedir(dir)
+#
+# Check that 'dir' exists, if not, drop to a shell.
+#
+check_statedir() {
+ [[ -z $1 ]] && return 0
+
+ if [[ ! -d $1 ]] && ! mkdir -p "$1" &>/dev/null ; then
+ splash "critical" &
+ echo
+ eerror "For Gentoo to function properly, \"$1\" needs to exist."
+ if [[ ${RC_FORCE_AUTO} == "yes" ]] ; then
+ eerror "Attempting to create \"$1\" for you ..."
+ mount -o remount,rw /
+ mkdir -p "$1"
+ fi
+ if [[ ! -d $1 ]] ; then
+ eerror "Please mount your root partition read/write, and execute:"
+ echo
+ eerror " # mkdir -p $1"
+ echo; echo
+ single_user
+ fi
+ fi
+
+ return 0
+}
+
+# void start_critical_service()
+#
+# Start critical services needed for bootup
+#
+start_critical_service() {
+ (
+ local retval=
+ local service=$1
+ # Needed for some addons like dm-crypt that starts in critical services
+ local myservice=$1
+
+ source "/etc/init.d/${service}" || eerror "Failed to source /etc/init.d/${service}"
+ retval=$?
+ [[ ${retval} -ne 0 ]] && return "${retval}"
+ [[ -e /etc/conf.d/${service} ]] && source "/etc/conf.d/${service}"
+ source /etc/rc.conf
+
+ start || eerror "Failed to start /etc/init.d/${service}"
+ retval=$?
+
+ return "${retval}"
+ )
+}
+
+
+# vim:ts=4
diff --git a/sbin/init.linux.sh b/sbin/init.linux.sh
new file mode 100755
index 0000000..338f7cb
--- /dev/null
+++ b/sbin/init.linux.sh
@@ -0,0 +1,43 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# void single_user()
+#
+# Drop to a shell, remount / ro, and then reboot
+#
+single_user() {
+ einfo "Rebooting"
+ /sbin/reboot -f
+}
+
+source "${svclib}"/sh/init-functions.sh
+source "${svclib}"/sh/init-common-pre.sh
+
+echo
+echo -e "${GOOD}Gentoo Linux${GENTOO_VERS}; ${BRACKET}http://www.gentoo.org/${NORMAL}"
+echo -e " Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2"
+echo
+echo -e "Press ${GOOD}I${NORMAL} to enter interactive boot mode"
+echo
+
+check_statedir /proc
+check_statedir /dev
+
+source "${svclib}"/sh/init-common-post.sh
+
+# Setup login records ... this has to be done here because when
+# we exit this runlevel, init will write a boot record to utmp
+# If /var/run is readonly, then print a warning, not errors
+if touch /var/run/utmp 2>/dev/null ; then
+ > /var/run/utmp
+ touch /var/log/wtmp
+ chgrp utmp /var/run/utmp /var/log/wtmp
+ chmod 0664 /var/run/utmp /var/log/wtmp
+ # Remove /var/run/utmpx (bug from the past)
+ rm -f /var/run/utmpx
+else
+ ewarn "Skipping /var/run/utmp initialization (ro root?)"
+fi
+
+
+# vim:ts=4
diff --git a/sbin/rc b/sbin/rc
index 13cff6a..97b973e 100755
--- a/sbin/rc
+++ b/sbin/rc
@@ -6,30 +6,16 @@ trap ":" INT QUIT TSTP
source /sbin/functions.sh
umask 022
-# Check that $1 exists ...
-check_statedir() {
- [ -z "$1" ] && return 0
-
- if [ ! -d "$1" ] ; then
- if ! mkdir -p "$1" &>/dev/null ; then
- echo
- eerror "For Gentoo to function properly, \"$1\" needs to exist."
- einfo "Rebooting"
- /sbin/reboot -f
- fi
- fi
-
- return 0
-}
-
+# void get_critical_services()
+#
+# Get critical services needed for bootup, and exports CRITICAL_SERVICES
+#
get_critical_services() {
local x=
CRITICAL_SERVICES=
- if [ -f "/etc/runlevels/${BOOTLEVEL}/.critical" ]
- then
- for x in $(< /etc/runlevels/${BOOTLEVEL}/.critical)
- do
+ if [[ -f /etc/runlevels/${BOOTLEVEL}/.critical ]] ; then
+ for x in $(< "/etc/runlevels/${BOOTLEVEL}/.critical") ; do
CRITICAL_SERVICES="${CRITICAL_SERVICES} ${x##*/}"
done
else
@@ -42,7 +28,7 @@ get_critical_services() {
}
# Save $1
-argv1="$1"
+argv1=$1
# we need this to prevent a warning below
[[ ! -e ${svcdir}/softlevel ]] && touch ${svcdir}/softlevel
@@ -52,108 +38,11 @@ argv1="$1"
# directly ...
if [[ ${argv1} = "sysinit" || ( ${argv1} = "boot" && "$(<${svcdir}/softlevel)" != "sysinit" ) ]]
then
- # Setup initial $PATH just in case
- PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}"
-
- echo
- echo -e "${GOOD}Gentoo Linux${GENTOO_VERS}; ${BRACKET}http://www.gentoo.org/${NORMAL}"
- echo -e " Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2"
- echo
-
- check_statedir /proc
- check_statedir /dev
-
- # We set the forced softlevel from the kernel command line
- # It needs to be run right after proc is mounted for the
- # boot runlevel
- setup_defaultlevels
-
- # $BOOT can be used by rc-scripts to test if it is the first time
- # the 'boot' runlevel is executed. Now also needed by some stuff in
- # the 'sysinit' runlevel ...
- export BOOT="yes"
-
- start_critical_service() {
- (
- local retval=
- local service=$1
- # Needed for some addons like dm-crypt that starts in critical services
- local myservice=$1
-
- source "/etc/init.d/${service}" || eerror "Failed to source /etc/init.d/${service}"
- retval=$?
- [ "${retval}" -ne 0 ] && return "${retval}"
- [ -e "/etc/conf.d/${service}" ] && source "/etc/conf.d/${service}"
- source /etc/rc.conf
-
- start || eerror "Failed to start /etc/init.d/${service}"
- retval=$?
-
- return "${retval}"
- )
+ source "${svclib}"/sh/init.sh || {
+ echo "Could not source init.sh !?"
+ exit 1
}
-
- # We first try to find a locally defined list of critical services
- # for a particular runlevel. If we cannot find it, we use the
- # defaults.
- get_critical_services
-
- export START_CRITICAL="yes"
- # We do not want to break compatibility, so we do not fully integrate
- # these into /sbin/rc, but rather start them by hand ...
- for x in ${CRITICAL_SERVICES}
- do
- if ! start_critical_service "${x}" ; then
- echo
- eerror "One of more critical startup scripts failed to start!"
- einfo "Rebooting"
- /sbin/reboot -f
- fi
- done
-
- unset START_CRITICAL
-
- # Check that $svcdir exists ...
- check_statedir "${svcdir}"
-
- # Clear $svcdir from stale entries, but leave the caches around, as it
- # should help speed things up a bit
- rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
- grep -ve '\(depcache\|deptree\|envcache\)')
-
- echo "sysinit" > "${svcdir}/softlevel"
-
- # Update the dependency cache
- /sbin/depscan.sh -u
-
- # Now that the dependency cache are up to date, make sure these
- # are marked as started ...
- (
- # Needed for mark_service_started()
- source "${svclib}/sh/rc-services.sh"
-
- for x in ${CRITICAL_SERVICES}
- do
- mark_service_started "${x}"
- done
- )
-
- # Setup login records ... this has to be done here because when
- # we exit this runlevel, init will write a boot record to utmp
- # If /var/run is readonly, then print a warning, not errors
- if touch /var/run/utmp 2>/dev/null
- then
- > /var/run/utmp
- touch /var/log/wtmp
- chgrp utmp /var/run/utmp /var/log/wtmp
- chmod 0664 /var/run/utmp /var/log/wtmp
- # Remove /var/run/utmpx (bug from the past)
- rm -f /var/run/utmpx
- else
- ewarn "Skipping /var/run/utmp initialization (ro root?)"
- fi
-
[[ ${argv1} = "boot" ]] || exit 0
fi # Sysinit ends here
@@ -167,67 +56,58 @@ then
# We reset argv1 to the bootlevel given on the kernel command line
# if there is one
- argv1="${BOOTLEVEL}"
+ argv1=${BOOTLEVEL}
fi
source "${svclib}/sh/rc-services.sh"
-if [ -f "${svcdir}/softlevel" ]
-then
+if [[ -f ${svcdir}/softlevel ]] ; then
# Set OLDSOFTLEVEL if we had a valid SOFTLEVEL
- export OLDSOFTLEVEL="$(< ${svcdir}/softlevel)"
+ export OLDSOFTLEVEL=$(< ${svcdir}/softlevel)
else
export OLDSOFTLEVEL=
fi
-if [ -z "${argv1}" ]
-then
- if [ -f "${svcdir}/softlevel" ]
- then
- export SOFTLEVEL="$(< ${svcdir}/softlevel)"
+if [[ -z ${argv1} ]] ; then
+ if [[ -f ${svcdir}/softlevel ]] ; then
+ export SOFTLEVEL=$(< ${svcdir}/softlevel)
else
- export SOFTLEVEL="${BOOTLEVEL}"
+ export SOFTLEVEL=${BOOTLEVEL}
fi
else
- export SOFTLEVEL="${argv1}"
+ export SOFTLEVEL=${argv1}
fi
-if [ ! -f "${svcdir}/softlevel" ]
-then
+if [[ ! -f ${svcdir}/softlevel ]] ; then
echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
fi
# For keeping a list of services that fails during boot/halt
-if [ ! -d "${svcdir}/failed" ]
-then
+if [[ ! -d ${svcdir}/failed ]] ; then
mkdir -p -m 0755 "${svcdir}/failed"
else
rm -rf "${svcdir}"/failed/*
fi
-if [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
-then
+if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
myscripts=
-elif [ ! -d "/etc/runlevels/${SOFTLEVEL}" ]
-then
+elif [[ ! -d /etc/runlevels/${SOFTLEVEL} ]] ; then
eerror "ERROR: runlevel ${SOFTLEVEL} does not exist; exiting ..."
exit 1
else
myscripts=
- if [ "${SOFTLEVEL}" != "${BOOTLEVEL}" ]
- then
+ if [[ ${SOFTLEVEL} != "${BOOTLEVEL}" ]] ; then
# Normal runlevels *include* boot scripts
- mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
+ mylevels=$(dolisting "/etc/runlevels/${SOFTLEVEL}/")
mylevels="${mylevels} $(dolisting /etc/runlevels/${BOOTLEVEL}/)"
else
# Non-normal runlevels don't include boot scripts as default
- mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
+ mylevels=$(dolisting "/etc/runlevels/${SOFTLEVEL}/")
fi
- for x in ${mylevels}
- do
- [ -L "${x}" ] && myscripts="${myscripts} ${x##*/}"
+ for x in ${mylevels} ; do
+ [[ -L ${x} ]] && myscripts="${myscripts} ${x##*/}"
done
fi
@@ -253,7 +133,7 @@ get_stop_services() {
local x list
for x in $(dolisting "${svcdir}/inactive/") \
- $(dolisting "${svcdir}/started/") ; do
+ $(dolisting "${svcdir}/started/") ; do
list="${list} ${x##*/}"
done
@@ -280,7 +160,7 @@ dep_stop() {
for dep in $(needsme "${myservice}") ; do
#if service_started "${dep}" && \
- if [[ -L "${svcdir}/softscripts.new/${dep}" ]] ; then
+ if [[ -L ${svcdir}/softscripts.new/${dep} ]] ; then
# This dep is valid
needsme=1
@@ -294,8 +174,7 @@ dep_stop() {
# Stop services
if [[ ${SOFTLEVEL} != "reboot" && \
- ${SOFTLEVEL} != "shutdown" ]]
-then
+ ${SOFTLEVEL} != "shutdown" ]] ; then
for i in $(get_stop_services) ; do
dep_stop "${i}"
done
@@ -322,7 +201,7 @@ else
done
# Wait for any services that may still be stopping ...
- [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
+ [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
export STOP_CRITICAL="yes"
# Now stop the rest
@@ -345,6 +224,9 @@ if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
grep -ve '\(depcache\|deptree\|envcache\)')
+ # Need try(), etc
+ source "${svclib}"/sh/init-functions.sh
+
source /etc/init.d/halt.sh
# we just die here since we have no init
@@ -394,7 +276,7 @@ for i in $(get_start_services) ; do
done
# Wait for any services that may still be running ...
-[ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
+[[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
# Clean the old runlevel
rm -rf "${svcdir}/softscripts.old" &>/dev/null
@@ -414,4 +296,5 @@ fi
# Remove the cached CONSOLETYPE
unset CONSOLETYPE
+
# vim:ts=4
diff --git a/sbin/rc-daemon.sh b/sbin/rc-daemon.sh
index fab3577..e5cc63e 100755
--- a/sbin/rc-daemon.sh
+++ b/sbin/rc-daemon.sh
@@ -358,8 +358,17 @@ start-stop-daemon() {
# We started the daemon sucessfully
# so we add it to our state
local max="${#RC_DAEMONS[@]}"
- RC_DAEMONS[max]="${cmd}"
- RC_PIDFILES[max]="${pidfile}"
+ for (( i=0; i<${max}; i++ )); do
+ if [[ ${RC_DAEMONS[i]} == "{cmd}" \
+ && ${RC_PIDFILES[i]}="${pidfile}" ]]; then
+ break
+ fi
+ done
+
+ if [[ ${i} == "${max}" ]]; then
+ RC_DAEMONS[max]="${cmd}"
+ RC_PIDFILES[max]="${pidfile}"
+ fi
fi
fi
diff --git a/sbin/rc-help.sh b/sbin/rc-help.sh
index 2a28859..214c19d 100755
--- a/sbin/rc-help.sh
+++ b/sbin/rc-help.sh
@@ -1,11 +1,10 @@
#!/bin/bash
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source /sbin/functions.sh
-if [ "${RC_NOCOLOR}" = "yes" ]
-then
+if [[ ${RC_NOCOLOR} == "yes" ]] ; then
unset BLUE GREEN OFF CYAN
else
BLUE="\033[34;01m"
@@ -14,23 +13,43 @@ else
CYAN="\033[36;01m"
fi
-myscript="${1}"
-if [ -L "${1}" ]
-then
- myservice="$(readlink "${1}")"
-else
- myservice=${1}
+myscript=$1
+if [[ -z ${myscript} ]] ; then
+ echo "Please execute an init.d script"
+ exit 1
fi
+if [[ -L ${myscript} ]] ; then
+ myservice=$(readlink "${myscript}")
+else
+ myservice=${myscript}
+fi
myservice=${myservice##*/}
+if [[ $2 == "help" ]] ; then
+ BE_VERBOSE="yes"
+ NL=$'\n'
+else
+ BE_VERBOSE="no"
+ NL=
+fi
+
+default_opts="start stop restart pause zap"
+extra_opts=$(source "${myscript}" 2>/dev/null ; echo ${opts})
+
+if [[ ${BE_VERBOSE} == "yes" ]] ; then
echo -e "
-${GREEN}Gentoo Linux RC-Scripts; ${BLUE}http://www.gentoo.org/${OFF}
- Copyright 1999-2004 Gentoo Foundation; Distributed under the GPL
+${GREEN}Gentoo RC-Scripts; ${BLUE}http://www.gentoo.org/${OFF}
+ Copyright 1999-2005 Gentoo Foundation; Distributed under the GPL
+"
+fi
+
+echo -e "Usage: ${CYAN}${myservice}${OFF} [ ${GREEN}flags${OFF} ] < ${GREEN}options${OFF} >
-Usage: ${CYAN}${myservice}${OFF} < ${GREEN}flags${OFF} > [ ${GREEN}options${OFF} ]
+${CYAN}Normal Options:${OFF}"
-${CYAN}Options:${OFF}
+if [[ ${BE_VERBOSE} == "yes" ]] ; then
+echo -e "
${GREEN}start${OFF}
Start service, as well as the services it depends on (if not already
started).
@@ -75,18 +94,35 @@ ${CYAN}Options:${OFF}
${GREEN}broken${OFF}
List the missing or broken dependencies of type 'need' this service
depends on.
+"
-${CYAN}Flags:${OFF}
- ${GREEN}--quiet${OFF}
- Suppress output to stdout, except if:
+else
- 1) It is a warning, then output to stdout
- 2) It is an error, then output to stderr
+echo -e " ${GREEN}${default_opts}${OFF}
+ Default init.d options."
+
+fi
+
+if [[ -n ${extra_opts} ]] ; then
+echo -e "
+${CYAN}Additional Options:${OFF}${NL}
+ ${GREEN}${extra_opts}${OFF}
+ Extra options supported by this init.d script."
+fi
+echo -e "
+${CYAN}Flags:${OFF}${NL}
+ ${GREEN}--quiet${OFF}
+ Suppress output to stdout, except if:${NL}
+ 1) It is a warning, then output to stdout
+ 2) It is an error, then output to stderr${NL}
${GREEN}--nocolor${OFF}
- Suppress the use of colors.
+ Suppress the use of colors."
+if [[ ${BE_VERBOSE} == "yes" ]] ; then
+echo -e "
${CYAN}Dependencies:${OFF}
+
This is the heart of the Gentoo RC-Scripts, as it determines the order
in which services gets started, and also to some extend what services
get started in the first place.
@@ -105,17 +141,17 @@ ${CYAN}Dependencies:${OFF}
on one line only.
${GREEN}need${OFF}
- These are all the services needed for this service to start. If any service
- in the 'need' line is not started, it will be started even if it is not
- in the current, or 'boot' runlevel, and then this service will be started.
- If any services in the 'need' line fails to start or is missing, this
- service will never be started.
+ These are all the services needed for this service to start. If any
+ service in the 'need' line is not started, it will be started even if it
+ is not in the current, or 'boot' runlevel, and then this service will be
+ started. If any services in the 'need' line fails to start or is
+ missing, this service will never be started.
${GREEN}use${OFF}
This can be seen as representing optional services this service depends on
that are not critical for it to start. For any service in the 'use' line,
- it must be added to the 'boot' or current runlevel to be considered a valid
- 'use' dependency. It can also be used to determine startup order.
+ it must be added to the 'boot' or current runlevel to be considered a
+ valid 'use' dependency. It can also be used to determine startup order.
${GREEN}before${OFF}
This, together with the 'after' dependency type, can be used to control
@@ -137,8 +173,8 @@ ${CYAN}Dependencies:${OFF}
of a system logger depend on 'logger'. This should make things much more
generic.
- Note that the 'need', 'use', 'before' and 'after' dependeny types can have '*'
- as argument. Having:
+ Note that the 'need', 'use', 'before', and 'after' dependency types accept
+ an '*' as an argument. Having:
depend() {
before *
@@ -157,6 +193,7 @@ ${CYAN}Dependencies:${OFF}
been warned!
${CYAN}'net' Dependency and 'net.*' Services:${OFF}
+
Example:
depend() {
@@ -171,16 +208,31 @@ ${CYAN}'net' Dependency and 'net.*' Services:${OFF}
1. It is part of the 'boot' runlevel
2. It is part of the current runlevel
- A few examples are the /etc/init.d/net.eth0 and /etc/init.d/net.lo services.
+ A few examples are the /etc/init.d/net.eth0 and /etc/init.d/net.lo services."
+fi
+
+echo -e "
+${CYAN}Configuration files:${OFF}"
-${CYAN}Configuration files:${OFF}
+if [[ ${BE_VERBOSE} == "yes" ]] ; then
+echo -e "
There are two files which will be sourced for possible configuration by
the rc-scripts. They are (sourced from top to bottom):
+"
+fi
- /etc/conf.d/${myservice}
- /etc/rc.conf
+echo -e " /etc/conf.d/${myservice}${NL} /etc/rc.conf"
+if [[ ${BE_VERBOSE} == "yes" ]] ; then
+echo -e "
${CYAN}Management:${OFF}
+
Services are added and removed via the 'rc-update' tool. Running it without
arguments should give sufficient help.
"
+else
+echo -e "
+For more info, please run '${myscript} help'."
+fi
+
+exit 0
diff --git a/sbin/rc-services.sh b/sbin/rc-services.sh
index d928a5f..4a177cd 100755
--- a/sbin/rc-services.sh
+++ b/sbin/rc-services.sh
@@ -7,7 +7,7 @@ RC_GOT_SERVICES="yes"
[[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
-if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]]; then
+if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then
# Only try and update if we are root
if [[ ${EUID} == "0" ]] && ! /sbin/depscan.sh -u ; then
echo
@@ -17,7 +17,7 @@ if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]]; then
fi
source "${svcdir}/deptree"
- if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]]; then
+ if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then
echo
eerror "Dependency info is missing! Please run"
eerror " # /sbin/depscan.sh"
@@ -53,23 +53,23 @@ rc_mtime=
# Print the index of 'service'. 'index' is the current index.
#
get_service_index() {
- if [[ -z $1 || -z $2 ]]; then
+ if [[ -z $1 || -z $2 ]] ; then
echo "0"
return 1
fi
- local x myservice="$1" index="$2"
+ local x myservice=$1 index=$2
# Do we already have the index?
if [[ -n ${index} && ${index} -gt 0 \
- && ${myservice} == ${RC_DEPEND_TREE[${index}]} ]]; then
+ && ${myservice} == "${RC_DEPEND_TREE[${index}]}" ]] ; then
echo "${index}"
return 0
fi
for (( x=1; x<=${RC_DEPEND_TREE[0]}; x++ )); do
index=$(( ${x} * ${rc_index_scale} ))
- if [[ ${myservice} == ${RC_DEPEND_TREE[${index}]} ]]; then
+ if [[ ${myservice} == "${RC_DEPEND_TREE[${index}]}" ]] ; then
echo "${index}"
return 0
fi
@@ -86,10 +86,10 @@ get_service_index() {
get_dep_info() {
[[ -z $1 ]] && return 1
- local myservice="$1"
+ local myservice=$1
# We already have the right stuff ...
- [[ ${myservice} == ${rc_name} && -n ${rc_mtime} ]] && return 0
+ [[ ${myservice} == "${rc_name}" && -n ${rc_mtime} ]] && return 0
rc_index="`get_service_index "${myservice}" "${rc_index}"`"
rc_mtime="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_mtime}))]}"
@@ -97,7 +97,7 @@ get_dep_info() {
# Verify that we have the correct index (rc_index) ...
# [[ ${rc_index} == "0" ]] && return 1
- rc_name="${RC_DEPEND_TREE[${rc_index}]}"
+ rc_name=${RC_DEPEND_TREE[${rc_index}]}
rc_ineed="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_ineed}))]}"
rc_needsme="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_needsme}))]}"
rc_iuse="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_iuse}))]}"
@@ -125,11 +125,11 @@ check_dependency() {
local x myservice deps
# Set the dependency variables to relate to 'service1'
- if [[ $2 == "-t" ]]; then
+ if [[ $2 == "-t" ]] ; then
[[ -z $3 || -z $4 ]] && return 1
- myservice="$3"
+ myservice=$3
else
- myservice="$2"
+ myservice=$2
fi
if ! get_dep_info "${myservice}" >/dev/null ; then
@@ -146,8 +146,8 @@ check_dependency() {
if [[ $2 == "-t" && -n $4 ]]; then
# Check if 'service1' have 'deptype' dependency on 'service2'
- for x in ${deps}; do
- [[ ${x} == $4 ]] && return 0
+ for x in ${deps} ; do
+ [[ ${x} == "$4" ]] && return 0
done
return 1
else
@@ -213,14 +213,14 @@ is_fake_service() {
[[ -z $1 || -z $2 ]] && return 1
- [[ $2 != ${BOOTLEVEL} && -e "/etc/runlevels/${BOOTLEVEL}/.fake" ]] \
- && fake_services="$( < /etc/runlevels/${BOOTLEVEL}/.fake )"
+ [[ $2 != "${BOOTLEVEL}" && -e /etc/runlevels/${BOOTLEVEL}/.fake ]] && \
+ fake_services=$( < /etc/runlevels/${BOOTLEVEL}/.fake )
- [[ -e "/etc/runlevels/$2/.fake" ]] \
- && fake_services="${fake_services} $( < /etc/runlevels/$2/.fake )"
+ [[ -e /etc/runlevels/$2/.fake ]] && \
+ fake_services="${fake_services} $( < /etc/runlevels/$2/.fake )"
- for x in ${fake_services}; do
- [[ $1 == ${x##*/} ]] && return 0
+ for x in ${fake_services} ; do
+ [[ $1 == "${x##*/}" ]] && return 0
done
return 1
@@ -233,7 +233,7 @@ is_fake_service() {
in_runlevel() {
[[ -z $1 || -z $2 ]] && return 1
- [[ -L "/etc/runlevels/$2/$1" ]] && return 0
+ [[ -L /etc/runlevels/$2/$1 ]] && return 0
return 1
}
@@ -269,15 +269,15 @@ service_message() {
[[ ${RC_PARALLEL_STARTUP} != "yes" ]] && return
local cmd="einfo"
- if [[ $1 == 1 || $1 == "error" || $1 == "eerror" ]]; then
+ if [[ $1 == "1" || $1 == "error" || $1 == "eerror" ]] ; then
cmd="eerror"
shift
fi
- local r="${RC_QUIET_STDOUT}"
+ local r=${RC_QUIET_STDOUT}
RC_QUIET_STDOUT="no"
${cmd} "$@"
- RC_QUIET_STDOUT="${r}"
+ RC_QUIET_STDOUT=${r}
}
# bool begin_service( service )
@@ -289,8 +289,7 @@ service_message() {
# whatever is in here can only be executed by one process
# end_service service
# fi
-begin_service()
-{
+begin_service() {
[[ {$START_CRITICAL} == "yes" ]] && return 0
mkfifo "${svcdir}/exclusive/${service}" 2> /dev/null
@@ -302,9 +301,8 @@ begin_service()
# stops executing a exclusive region and
# wakes up anybody who is waiting for the exclusive region
#
-end_service()
-{
- local service="$1" exitstatus="$2"
+end_service() {
+ local service=$1 exitstatus=$2
# if we are doing critical services, there is no fifo
[[ ${START_CRITICAL} == "yes" ]] && return
@@ -315,7 +313,7 @@ end_service()
# move the fifo to a unique name so no-one is waiting for it
local fifo="${svcdir}/exclusive/${service}"
- if [[ -e "${fifo}" ]]; then
+ if [[ -e ${fifo} ]] ; then
local tempname="${fifo}.$$"
mv -f "${fifo}" "${tempname}"
@@ -332,9 +330,8 @@ end_service()
# If a service has started, or a fifo does not exist return 0
# Otherwise, wait until we get an exit code via the fifo and return
# that instead.
-wait_service()
-{
- local service="$1"
+wait_service() {
+ local service=$1
local fifo="${svcdir}/exclusive/${service}"
[[ ${START_CRITICAL} == "yes" || ${STOP_CRITICAL} == "yes" ]] && return 0
@@ -353,10 +350,10 @@ wait_service()
# Start 'service' if it is not already running.
#
start_service() {
- local service="$1"
+ local service=$1
[[ -z ${service} ]] && return 1
- if [[ ! -e "/etc/init.d/${service}" ]]; then
+ if [[ ! -e "/etc/init.d/${service}" ]] ; then
mark_service_stopped "${service}"
return 1
fi
@@ -371,19 +368,19 @@ start_service() {
fi
begin_service "${service}" || return 0
- if [[ ${RC_PARALLEL_STARTUP} != "yes" \
- || ${START_CRITICAL} == "yes" ]] ; then
+ if [[ ${RC_PARALLEL_STARTUP} != "yes" || \
+ ${START_CRITICAL} == "yes" ]] ; then
# if we can not start the services in parallel
# then just start it and return the exit status
( "/etc/init.d/${service}" start )
- retval="$?"
+ retval=$?
end_service "${service}" "${retval}"
return "${retval}"
else
# if parallel startup is allowed, start it in background
(
"/etc/init.d/${service}" start
- retval="$?"
+ retval=$?
end_service "${service}" "${retval}"
) &
return 0
@@ -395,10 +392,10 @@ start_service() {
# Stop 'service' if it is not already running.
#
stop_service() {
- local service="$1"
+ local service=$1
[[ -z ${service} ]] && return 1
- if [[ ! -e "/etc/init.d/${service}" ]]; then
+ if [[ ! -e /etc/init.d/${service} ]] ; then
mark_service_stopped "${service}"
return 0
fi
@@ -407,7 +404,7 @@ stop_service() {
service_stopped "${service}" && return 0
local level="${SOFTLEVEL}"
- is_runlevel_stop && level="${OLDSOFTLEVEL}"
+ is_runlevel_stop && level=${OLDSOFTLEVEL}
if is_fake_service "${service}" "${level}" ; then
mark_service_stopped "${service}"
@@ -416,19 +413,19 @@ stop_service() {
begin_service "${service}" || return 0
- if [[ ${RC_PARALLEL_STARTUP} != "yes" \
- || ${STOP_CRITICAL} == "yes" ]] ; then
+ if [[ ${RC_PARALLEL_STARTUP} != "yes" || \
+ ${STOP_CRITICAL} == "yes" ]] ; then
# if we can not start the services in parallel
# then just start it and return the exit status
( "/etc/init.d/${service}" stop )
- retval="$?"
+ retval=$?
end_service "${service}" "${retval}"
return "${retval}"
else
# if parallel startup is allowed, start it in background
(
( "/etc/init.d/${service}" stop )
- retval="$?"
+ retval=$?
end_service "${service}" "${retval}"
) &
return 0
@@ -445,9 +442,9 @@ mark_service_starting() {
ln -snf "/etc/init.d/$1" "${svcdir}/starting/$1"
local retval=$?
- [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
- [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
- [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
+ [[ -f ${svcdir}/started/$1 ]] && rm -f "${svcdir}/started/$1"
+ [[ -f ${svcdir}/inactive/$1 ]] && rm -f "${svcdir}/inactive/$1"
+ [[ -f ${svcdir}/stopping/$1 ]] && rm -f "${svcdir}/stopping/$1"
return "${retval}"
}
@@ -460,11 +457,11 @@ mark_service_started() {
[[ -z $1 ]] && return 1
ln -snf "/etc/init.d/$1" "${svcdir}/started/$1"
- local retval="$?"
+ local retval=$?
- [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
- [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
- [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
+ [[ -f ${svcdir}/starting/$1 ]] && rm -f "${svcdir}/starting/$1"
+ [[ -f ${svcdir}/inactive/$1 ]] && rm -f "${svcdir}/inactive/$1"
+ [[ -f ${svcdir}/stopping/$1 ]] && rm -f "${svcdir}/stopping/$1"
return "${retval}"
}
@@ -477,10 +474,10 @@ mark_service_inactive() {
[[ -z $1 ]] && return 1
ln -snf "/etc/init.d/$1" "${svcdir}/inactive/$1"
- local retval="$?"
- [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
- [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
- [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
+ local retval=$?
+ [[ -f ${svcdir}/started/$1 ]] && rm -f "${svcdir}/started/$1"
+ [[ -f ${svcdir}/starting/$1 ]] && rm -f "${svcdir}/starting/$1"
+ [[ -f ${svcdir}/stopping/$1 ]] && rm -f "${svcdir}/stopping/$1"
return "${retval}"
}
@@ -493,11 +490,11 @@ mark_service_stopping() {
[[ -z $1 ]] && return 1
ln -snf "/etc/init.d/$1" "${svcdir}/stopping/$1"
- local retval="$?"
+ local retval=$?
- [ -f "${svcdir}/starting/$1" ] && rm -f "${svcdir}/starting/$1"
- [ -f "${svcdir}/started/$1" ] && rm -f "${svcdir}/started/$1"
- [ -f "${svcdir}/inactive/$1" ] && rm -f "${svcdir}/inactive/$1"
+ [ -f ${svcdir}/starting/$1 ] && rm -f "${svcdir}/starting/$1"
+ [ -f ${svcdir}/started/$1 ] && rm -f "${svcdir}/started/$1"
+ [ -f ${svcdir}/inactive/$1 ] && rm -f "${svcdir}/inactive/$1"
return "${retval}"
}
@@ -509,10 +506,11 @@ mark_service_stopping() {
mark_service_stopped() {
[[ -z $1 ]] && return 1
- [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
- [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
- [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
- [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
+ [[ -f ${svcdir}/daemons/$1 ]] && rm -f "${svcdir}/daemons/$1"
+ [[ -f ${svcdir}/starting/$1 ]] && rm -f "${svcdir}/starting/$1"
+ [[ -f ${svcdir}/started/$1 ]] && rm -f "${svcdir}/started/$1"
+ [[ -f ${svcdir}/inactive/$1 ]] && rm -f "${svcdir}/inactive/$1"
+ [[ -f ${svcdir}/stopping/$1 ]] && rm -f "${svcdir}/stopping/$1"
return $?
}
@@ -529,7 +527,7 @@ test_service_state() {
# Service is in the state requested
[[ -L ${f} ]] && return 0
- if [[ ! -e ${f} ]]; then
+ if [[ ! -e ${f} ]] ; then
rm -f "${f}"
return 1
fi
@@ -590,7 +588,7 @@ service_stopped() {
# this is only valid on runlevel change ...
#
mark_service_failed() {
- [[ -z $1 || ! -d "${svcdir}/failed" ]] && return 1
+ [[ -z $1 || ! -d ${svcdir}/failed ]] && return 1
ln -snf "/etc/init.d/$1" "${svcdir}/failed/$1"
}
@@ -600,7 +598,7 @@ mark_service_failed() {
# Return true if 'service' have failed during this runlevel.
#
service_failed() {
- [[ -n $1 && -L "${svcdir}/failed/$1" ]]
+ [[ -n $1 && -L ${svcdir}/failed/$1 ]]
}
# bool dependon(service1, service2)
@@ -625,10 +623,9 @@ valid_i() {
# Cannot be SOFTLEVEL, as we need to know current runlevel
[[ -f ${svcdir}/softlevel ]] && mylevel=$( < "${svcdir}/softlevel" )
- for x in $( i$1 "$2" )
- do
- [[ -e "/etc/runlevels/${BOOTLEVEL}/${x}" \
- || -e "/etc/runlevels/${mylevel}/${x}" ]] \
+ for x in $( i$1 "$2" ) ; do
+ [[ -e /etc/runlevels/${BOOTLEVEL}/${x} || \
+ -e "/etc/runlevels/${mylevel}/${x}" ]] \
&& echo "${x}"
done
@@ -661,8 +658,8 @@ trace_dependencies() {
local -a services=( "$@" ) deps
local i j
- if [[ $1 == -* ]]; then
- deptype="${1/-}"
+ if [[ $1 == -* ]] ; then
+ deptype=${1/-}
services=( "${myservice}" )
fi
@@ -672,9 +669,9 @@ trace_dependencies() {
}
local last=""
- while [[ ${services[@]} != "${last}" ]]; do
+ while [[ ${services[@]} != "${last}" ]] ; do
last="${services[*]}"
- for (( i=0; i<${#services[@]}; i++ )); do
+ for (( i=0; i<${#services[@]}; i++ )) ; do
if [[ -n ${deptype} ]] ; then
deps=( "${deps[@]}" $( "${deptype}" "${services[i]}" ) )
else
@@ -698,34 +695,34 @@ trace_dependencies() {
# revisit any dependencies. Finally we add ourselves to the sorted list.
# This should never get into an infinite loop, thanks to our dead array.
local -a dead=() deadname=() sorted=()
- for (( i=0; i<${#services[@]}; i++ )); do
- dead[i]=false;
+ for (( i=0; i<${#services[@]}; i++ )) ; do
+ dead[i]="false"
deadname[i]="${services[i]}"
done
after_visit() {
- local service="$1" i
+ local service=$1 i
- for (( i=0; i<${#deadname[@]}; i++)); do
+ for (( i=0; i<${#deadname[@]}; i++)) ; do
[[ ${service} == ${deadname[i]} ]] && break
done
${dead[i]} && return
- dead[i]=true
+ dead[i]="true"
local x deps="$( ineed ${service} ) $( valid_iuse ${service} )"
if is_runlevel_start || is_runlevel_stop ; then
deps="${deps} $( valid_iafter ${service} )"
fi
- for x in ${deps}; do
+ for x in ${deps} ; do
after_visit "${x}"
done
sorted=( "${sorted[@]}" "${service}" )
}
- for (( i=0; i<${#services[*]}; i++ )); do
+ for (( i=0; i<${#services[*]}; i++ )) ; do
after_visit "${services[i]}"
done
services=( "${sorted[@]}" )
@@ -758,4 +755,5 @@ query_before() {
return 1
}
+
# vim:ts=4
diff --git a/sbin/runscript.sh b/sbin/runscript.sh
index bb31bfc..79820f3 100755
--- a/sbin/runscript.sh
+++ b/sbin/runscript.sh
@@ -20,7 +20,7 @@ svcpause="no"
svcrestart="no"
myscript=$1
-if [[ -L $1 ]] && [[ ! -L /etc/init.d/${1##*/} ]] ; then
+if [[ -L $1 && ! -L /etc/init.d/${1##*/} ]] ; then
myservice=$(readlink "$1")
else
myservice=$1
@@ -97,8 +97,7 @@ svc_stop() {
service_message "Stopping service ${myservice}"
if in_runlevel "${myservice}" "${BOOTLEVEL}" && \
- [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]]
- then
+ [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]] ; then
ewarn "WARNING: you are stopping a boot service."
fi
@@ -115,8 +114,7 @@ svc_stop() {
# If some service 'need' $mydep, stop it first; or if it is a runlevel change,
# first stop all services that is started 'after' $mydep.
if needsme "${mydep}" >/dev/null || \
- (is_runlevel_stop && ibefore "${mydep}" >/dev/null)
- then
+ (is_runlevel_stop && ibefore "${mydep}" >/dev/null) ; then
local -a sl=( $(needsme "${mydep}") )
# On runlevel change, stop all services "after $mydep" first ...
@@ -133,8 +131,7 @@ svc_stop() {
fi
if ibefore -t "${mydep}" "${x}" >/dev/null && \
- [[ -L ${svcdir}/softscripts.new/${x} ]]
- then
+ [[ -L ${svcdir}/softscripts.new/${x} ]] ; then
# Service do not 'need' $mydep, and is still present in
# new runlevel ...
unset sl[x]
@@ -154,8 +151,7 @@ svc_stop() {
service_stopped "${x}" && continue
if ibefore -t "${mydep}" "${x}" >/dev/null && \
- [[ -L "${svcdir}/softscripts.new/${x}" ]]
- then
+ [[ -L ${svcdir}/softscripts.new/${x} ]] ; then
# Service do not 'need' $mydep, and is still present in
# new runlevel ...
continue
@@ -168,8 +164,8 @@ svc_stop() {
# clean as possible, else do not stop our service if
# a dependent service did not stop.
if needsme -t "${mydep}" "${x}" >/dev/null && \
- [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]]
- then
+ [[ ${SOFTLEVEL} != "reboot" && \
+ ${SOFTLEVEL} != "shutdown" ]] ; then
retval=1
fi
break
@@ -270,7 +266,7 @@ svc_start() {
# Start dependencies, if any
for x in ${startupservices} ; do
- if service_stopped "${x}"; then
+ if service_stopped "${x}" ; then
start_service "${x}"
fi
done
@@ -315,7 +311,7 @@ svc_start() {
service_inactive "${myservice}" && return 1
fi
- if [[ ${retval} != 0 ]]; then
+ if [[ ${retval} != 0 ]] ; then
is_runlevel_start && mark_service_failed "${myservice}"
# Remove link if service didn't start; but only if we're not booting
@@ -400,7 +396,7 @@ svc_homegrown() {
# Walk through the list of available options, looking for the
# requested one.
for x in ${opts} ; do
- if [[ ${x} == ${arg} ]] ; then
+ if [[ ${x} == "${arg}" ]] ; then
if typeset -F "${x}" &>/dev/null ; then
# Run the homegrown function
"${x}"
@@ -468,9 +464,8 @@ for arg in $* ; do
# Simple way to try and detect if the service use svc_{start,stop}
# to restart if it have a custom restart() funtion.
if [[ -n $(egrep '^[[:space:]]*restart[[:space:]]*()' "/etc/init.d/${myservice}") ]] ; then
- if [[ -z $(egrep 'svc_stop' "/etc/init.d/${myservice}") ]] || \
- [[ -z $(egrep 'svc_start' "/etc/init.d/${myservice}") ]]
- then
+ if [[ -z $(egrep 'svc_stop' "/etc/init.d/${myservice}") || \
+ -z $(egrep 'svc_start' "/etc/init.d/${myservice}") ]] ; then
echo
ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
ewarn "restart the service in its custom 'restart()' function."
@@ -507,6 +502,9 @@ for arg in $* ; do
;;
--quiet|--nocolor)
;;
+ help)
+ exec "${svclib}"/sh/rc-help.sh "${myscript}" help
+ ;;
*)
# Allow for homegrown functions
svc_homegrown ${arg}
diff --git a/src/awk/genenviron.awk b/src/awk/genenviron.awk
index 087bed3..3ba5333 100644
--- a/src/awk/genenviron.awk
+++ b/src/awk/genenviron.awk
@@ -1,6 +1,5 @@
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header$
BEGIN {
@@ -53,7 +52,11 @@ BEGIN {
# SPECIALS are treated differently. For each env.d file, the variables are
# appended seperated with a ':'. If not in specials, for each env.d file,
# the variable are just set to the new value.
- tmpspecials="KDEDIRS:PATH:CLASSPATH:LDPATH:MANPATH:INFOPATH:ROOTPATH:CONFIG_PROTECT:CONFIG_PROTECT_MASK:PRELINK_PATH:PRELINK_PATH_MASK:PYTHONPATH:ADA_INCLUDE_PATH:ADA_OBJECTS_PATH"
+ tmpspecials = \
+ "ADA_INCLUDE_PATH:ADA_OBJECTS_PATH:CLASSPATH:" \
+ "CONFIG_PROTECT:CONFIG_PROTECT_MASK:INFOPATH:" \
+ "KDEDIRS:LDPATH:MANPATH:PATH:PKG_CONFIG_PATH:" \
+ "PRELINK_PATH:PRELINK_PATH_MASK:PYTHONPATH:ROOTPATH"
split(tmpspecials, SPECIALS, ":")
unlink(ENVCACHE)
diff --git a/src/core/ChangeLog b/src/core/ChangeLog
index 0ac157a..5d0754a 100644
--- a/src/core/ChangeLog
+++ b/src/core/ChangeLog
@@ -2,6 +2,77 @@
# Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2
# $Header$
+20 Sep 2005 Martin Schlemmer <azarah@gentoo.org>
+
+ * parse.c: Hopefully handle interrupted reads/writes properly.
+
+13 Sep 2005 Martin Schlemmer <azarah@gentoo.org>
+
+ * parse.c: Cleanup the pipe usage and naming in generate_stage2() for
+ better readibility.
+
+ * parse.c: Remove unused tmp_pid from generate_stage2(), also fixing
+ waitpid() not getting called.
+
+ * parse.c: Make sure we do not close the pipes twice if the child
+ returns with error exit status.
+
+ * parse.c: Remove label 'cont_do_read' in favour of just a simple break.
+ No need to jump to the error label if the child did not exit cleanly,
+ as we already cleaned up.
+
+ * parse.c: Cleanup parse_cache(). Do not parse MTIME - we have it
+ already.
+
+07 Sep 2005 Martin Schlemmer <azarah@gentoo.org>
+
+ * debug.h
+ * depend.c
+ * misc.c
+ * misc.h
+ * parse.c
+ * simple-regex.c
+ * simple-regex.h: Misc style and other cleanups.
+
+ * TODO: New file.
+
+06 Sep 2005 Martin Schlemmer <azarah@gentoo.org>
+
+ * parse.c
+ * misc.c: Try to cleanup error handling a bit (debug messages, return
+ value, etc).
+
+ * parse.c: Fix output of write_legacy_stage3() after removing the
+ parallel dependency type.
+
+ * Makefile: Do not enable bounds checking with DEBUG=1.
+
+ * misc.h: Add MIN/MAX macro's.
+
+ * parse.c: Cleanup and merge parse_print_*() functions. Move need(),
+ etc functions to after sourcing of script, else we run into issues
+ with net.* scripts that redefine them. Better checking if scripts
+ have issues or not.
+
+ * parse.c: Use poll() rather than select() and some other cleanups.
+
+ * parse.c: Remove the waitpid() call in the read/write loop of our
+ generate_stage2(), as its very slow on amd64.
+
+ * parse.c: Remove some redundent variables and other cleanups.
+
+ * parse.c: Reset tmp_count between writing and reading.
+
+ * depend.c: Also add mtime for 'net' service if we need to add it.
+
+05 Sep 2005 Martin Schlemmer <azarah@gentoo.org>
+
+ * parse.c: Make sure field in parse_cache() is not used uninitialized.
+
+ * misc.h: Remove the unused COUNT_CHAR_* macro's.
+
+ * depend.c: Add missing debugging info.
+
26 Jul 2005 Martin Schlemmer <azarah@gentoo.org>
* depend.c
diff --git a/src/core/Makefile b/src/core/Makefile
index 1e9c050..0b4c713 100644
--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -54,9 +54,11 @@ cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
ifeq ($(DEBUG),1)
override CFLAGS += -ggdb3
- override CFLAGS += $(call cc-option, -fbounds-checking, -pipe)
EXTRA_CFLAGS += -DRC_DEBUG
endif
+ifeq ($(BOUNDS),1)
+ override CFLAGS += $(call cc-option, -fbounds-checking, -pipe)
+endif
$(DEPSCAN): $(OBJS) $(DEPSCAN).o
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $^
diff --git a/src/core/TODO b/src/core/TODO
new file mode 100644
index 0000000..57c0d66
--- /dev/null
+++ b/src/core/TODO
@@ -0,0 +1,11 @@
+Shortlist of cleanups to think about at some stage:
+===================================================
+* Make error handling (and thus especially touching errno) more consistent.
+* I assumed that most malloc() implementations set errno on failure, but
+ for klibc for example, that is not true .. create a malloc wrapper to
+ make sure errno=ENOMEM on failure.
+* Split generate_stage2() and co to handle a function at a time if not too
+ slow .. this will enable us to use less memory.
+* Think about using linked lists to the actual dependencies, rather than
+ string lists for service_info_t->depend_info. This might need a lot of
+ rework, but could also safe us some memory, and lower trashing.
diff --git a/src/core/debug.h b/src/core/debug.h
index bc40038..997e92f 100644
--- a/src/core/debug.h
+++ b/src/core/debug.h
@@ -30,7 +30,7 @@
do { \
int old_errno = errno; \
fprintf(stderr, "DEBUG(1): in %s, function %s(), line %i:\n", __FILE__, \
- __FUNCTION__, __LINE__); \
+ __FUNCTION__, __LINE__); \
fprintf(stderr, "DEBUG(2): " _format, ## _arg); \
errno = old_errno; \
if (0 != errno) { \
@@ -48,7 +48,7 @@
/* if ((0 != errno) && (ESPIPE != errno)) { */ \
if (0 != errno) { \
fprintf(stderr, "DEBUG(1): in %s, function %s(), line %i:\n", \
- __FILE__, __FUNCTION__, __LINE__); \
+ __FILE__, __FUNCTION__, __LINE__); \
fprintf(stderr, "DEBUG(2): " _format, ## _arg); \
errno = old_errno; \
perror("DEBUG(3)"); \
@@ -62,7 +62,7 @@
do { \
int old_errno = errno; \
fprintf(stderr, "ERROR: file '%s', function '%s', line %i.\n", \
- __FILE__, __FUNCTION__, __LINE__); \
+ __FILE__, __FUNCTION__, __LINE__); \
errno = old_errno; \
if (0 != errno) \
perror("ERROR"); \
diff --git a/src/core/depend.c b/src/core/depend.c
index 8fc6056..4946326 100644
--- a/src/core/depend.c
+++ b/src/core/depend.c
@@ -51,7 +51,8 @@ char *service_type_names[] = {
int __service_resolve_dependency(char *servicename, char *dependency, service_type_t type);
-service_info_t *service_get_info(char *servicename) {
+service_info_t *service_get_info(char *servicename)
+{
service_info_t *info;
if ((NULL == servicename) || (0 == strlen(servicename))) {
@@ -72,7 +73,8 @@ service_info_t *service_get_info(char *servicename) {
return NULL;
}
-int service_add(char *servicename) {
+int service_add(char *servicename)
+{
service_info_t *info;
service_info_t *sorted;
int count;
@@ -120,13 +122,16 @@ int service_add(char *servicename) {
return -1;
}
-int service_is_dependency(char *servicename, char *dependency, service_type_t type) {
+int service_is_dependency(char *servicename, char *dependency, service_type_t type)
+{
service_info_t *info;
char *service;
int count = 0;
- if ((NULL == servicename) || (0 == strlen(servicename)) ||
- (NULL == dependency) || (0 == strlen(dependency))) {
+ if ((NULL == servicename)
+ || (0 == strlen(servicename))
+ || (NULL == dependency)
+ || (0 == strlen(dependency))) {
DBG_MSG("Invalid argument passed!\n");
return -1;
}
@@ -144,12 +149,15 @@ int service_is_dependency(char *servicename, char *dependency, service_type_t ty
return -1;
}
-int service_add_dependency(char *servicename, char *dependency, service_type_t type) {
+int service_add_dependency(char *servicename, char *dependency, service_type_t type)
+{
service_info_t *info;
char *tmp_buf;
- if ((NULL == servicename) || (0 == strlen(servicename)) ||
- (NULL == dependency) || (0 == strlen(dependency))) {
+ if ((NULL == servicename)
+ || (0 == strlen(servicename))
+ || (NULL == dependency)
+ || (0 == strlen(dependency))) {
DBG_MSG("Invalid argument passed!\n");
return -1;
}
@@ -159,7 +167,7 @@ int service_add_dependency(char *servicename, char *dependency, service_type_t t
/* Do not add duplicates */
if (-1 == service_is_dependency(servicename, dependency, type)) {
DBG_MSG("Adding dependency '%s' of service '%s', type '%s'.\n",
- dependency, servicename, service_type_names[type]);
+ dependency, servicename, service_type_names[type]);
tmp_buf = strndup(dependency, strlen(dependency));
if (NULL == tmp_buf) {
@@ -170,8 +178,7 @@ int service_add_dependency(char *servicename, char *dependency, service_type_t t
STRING_LIST_ADD_SORT(info->depend_info[type], tmp_buf, error);
} else {
DBG_MSG("Duplicate dependency '%s' for service '%s', type '%s'!\n",
- dependency, servicename,
- service_type_names[type]);
+ dependency, servicename, service_type_names[type]);
/* Rather do not fail here, as we add a lot of doubles
* during resolving of dependencies */
}
@@ -185,11 +192,14 @@ error:
return -1;
}
-int service_del_dependency(char *servicename, char *dependency, service_type_t type) {
+int service_del_dependency(char *servicename, char *dependency, service_type_t type)
+{
service_info_t *info;
- if ((NULL == servicename) || (0 == strlen(servicename)) ||
- (NULL == dependency) || (0 == strlen(dependency))) {
+ if ((NULL == servicename)
+ || (0 == strlen(servicename))
+ || (NULL == dependency)
+ || (0 == strlen(dependency))) {
DBG_MSG("Invalid argument passed!\n");
return -1;
}
@@ -202,7 +212,7 @@ int service_del_dependency(char *servicename, char *dependency, service_type_t t
info = service_get_info(servicename);
if (NULL != info) {
DBG_MSG("Removing dependency '%s' of service '%s', type '%s'.\n",
- dependency , servicename, service_type_names[type]);
+ dependency , servicename, service_type_names[type]);
STRING_LIST_DEL(info->depend_info[type], dependency, error);
return 0;
@@ -214,7 +224,8 @@ error:
return -1;
}
-service_info_t *service_get_virtual(char *virtual) {
+service_info_t *service_get_virtual(char *virtual)
+{
service_info_t *info;
if ((NULL == virtual) || (0 == strlen(virtual))) {
@@ -235,18 +246,21 @@ service_info_t *service_get_virtual(char *virtual) {
return NULL;
}
-int service_add_virtual(char *servicename, char* virtual) {
+int service_add_virtual(char *servicename, char* virtual)
+{
service_info_t *info;
- if ((NULL == servicename) || (0 == strlen(servicename)) ||
- (NULL == virtual ) || (0 == strlen(virtual))) {
+ if ((NULL == servicename)
+ || (0 == strlen(servicename))
+ || (NULL == virtual )
+ || (0 == strlen(virtual))) {
DBG_MSG("Invalid argument passed!\n");
return -1;
}
if (NULL != service_get_info(virtual)) {
EERROR(" Cannot add provide '%s', as a service with the same name exists!\n",
- virtual);
+ virtual);
/* Do not fail here as we do have a service that resolves
* the virtual */
}
@@ -255,7 +269,7 @@ int service_add_virtual(char *servicename, char* virtual) {
if (NULL != info) {
/* We cannot have more than one service Providing a virtual */
EWARN(" Service '%s' already provides '%s'!;\n",
- info->name, virtual);
+ info->name, virtual);
EWARN(" Not adding service '%s'...\n", servicename);
/* Do not fail here as we do have a service that resolves
* the virtual */
@@ -263,7 +277,7 @@ int service_add_virtual(char *servicename, char* virtual) {
info = service_get_info(servicename);
if (NULL != info) {
DBG_MSG("Adding virtual '%s' of service '%s'.\n",
- virtual, servicename);
+ virtual, servicename);
info->provide = strndup(virtual, strlen(virtual));
if (NULL == info->provide) {
@@ -279,7 +293,8 @@ int service_add_virtual(char *servicename, char* virtual) {
return 0;
}
-int service_set_mtime(char *servicename, time_t mtime) {
+int service_set_mtime(char *servicename, time_t mtime)
+{
service_info_t *info;
if ((NULL == servicename) || (0 == strlen(servicename))) {
@@ -290,7 +305,7 @@ int service_set_mtime(char *servicename, time_t mtime) {
info = service_get_info(servicename);
if (NULL != info) {
DBG_MSG("Setting mtime '%li' of service '%s'.\n",
- mtime, servicename);
+ mtime, servicename);
info->mtime = mtime;
@@ -302,12 +317,15 @@ int service_set_mtime(char *servicename, time_t mtime) {
return -1;
}
-int __service_resolve_dependency(char *servicename, char *dependency, service_type_t type) {
+int __service_resolve_dependency(char *servicename, char *dependency, service_type_t type)
+{
service_info_t *info;
int retval;
- if ((NULL == servicename) || (0 == strlen(servicename)) ||
- (NULL == dependency) || (0 == strlen(dependency))) {
+ if ((NULL == servicename)
+ || (0 == strlen(servicename))
+ || (NULL == dependency)
+ || (0 == strlen(dependency))) {
DBG_MSG("Invalid argument passed!\n");
return -1;
}
@@ -319,7 +337,7 @@ int __service_resolve_dependency(char *servicename, char *dependency, service_ty
}
DBG_MSG("Checking dependency '%s' of service '%s', type '%s'.\n",
- dependency, servicename, service_type_names[type]);
+ dependency, servicename, service_type_names[type]);
/* If there are no existing service 'dependency', try to resolve
* possible virtual services */
@@ -328,8 +346,8 @@ int __service_resolve_dependency(char *servicename, char *dependency, service_ty
info = service_get_virtual(dependency);
if (NULL != info) {
DBG_MSG("Virtual '%s' -> '%s' for service '%s', type '%s'.\n",
- dependency, info->name, servicename,
- service_type_names[type]);
+ dependency, info->name, servicename,
+ service_type_names[type]);
retval = service_del_dependency(servicename, dependency, type);
if (-1 == retval) {
@@ -352,7 +370,7 @@ int __service_resolve_dependency(char *servicename, char *dependency, service_ty
if (NULL == info) {
if ((type == NEED) || (type == NEED_ME)) {
EWARN(" Can't find service '%s' needed by '%s'; continuing...\n",
- dependency, servicename);
+ dependency, servicename);
retval = service_add_dependency(servicename, dependency, BROKEN);
if (-1 == retval) {
@@ -379,19 +397,22 @@ int __service_resolve_dependency(char *servicename, char *dependency, service_ty
/* Dont work too well with the '*' before and after */
if ((type != BEFORE) && (type != AFTER))
EWARN(" Service '%s' can't depend on itself; continuing...\n",
- servicename);
+ servicename);
/* Delete invalid entry */
goto remove;
}
/* Currently only these depend/order types are supported */
- if ((type == NEED) || (type == USE) || (type == BEFORE) || (type == AFTER)) {
+ if ((type == NEED)
+ || (type == USE)
+ || (type == BEFORE)
+ || (type == AFTER)) {
if (type == BEFORE) {
/* NEED and USE override BEFORE
* ('servicename' BEFORE 'dependency') */
- if ((0 == service_is_dependency(servicename, dependency, NEED)) ||
- (0 == service_is_dependency(servicename, dependency, USE))) {
+ if ((0 == service_is_dependency(servicename, dependency, NEED))
+ || (0 == service_is_dependency(servicename, dependency, USE))) {
/* Delete invalid entry */
goto remove;
}
@@ -400,8 +421,8 @@ int __service_resolve_dependency(char *servicename, char *dependency, service_ty
if (type == AFTER) {
/* NEED and USE override AFTER
* ('servicename' AFTER 'dependency') */
- if ((0 == service_is_dependency(dependency, servicename, NEED)) ||
- (0 == service_is_dependency(dependency, servicename, USE))) {
+ if ((0 == service_is_dependency(dependency, servicename, NEED))
+ || (0 == service_is_dependency(dependency, servicename, USE))) {
/* Delete invalid entry */
goto remove;
}
@@ -410,9 +431,9 @@ int __service_resolve_dependency(char *servicename, char *dependency, service_ty
/* We do not want to add circular dependencies ... */
if (0 == service_is_dependency(dependency, servicename, type)) {
EWARN(" Services '%s' and '%s' have circular\n",
- servicename, dependency);
+ servicename, dependency);
EWARN(" dependency of type '%s'; continuing...\n",
- service_type_names[type]);
+ service_type_names[type]);
/* For now remove this dependency */
goto remove;
@@ -472,7 +493,8 @@ remove:
return 0;
}
-int service_resolve_dependencies(void) {
+int service_resolve_dependencies(void)
+{
service_info_t *info;
char *service;
char *next = NULL;
@@ -480,8 +502,11 @@ int service_resolve_dependencies(void) {
/* Add our 'net' service */
if (NULL == service_get_info("net")) {
- if (-1 == service_add("net"))
+ if (-1 == service_add("net")) {
+ DBG_MSG("Failed to add virtual!\n");
return -1;
+ }
+ service_set_mtime("net", 0);
}
/* Calculate all virtuals */
diff --git a/src/core/misc.c b/src/core/misc.c
index 3f1035f..c589143 100644
--- a/src/core/misc.c
+++ b/src/core/misc.c
@@ -37,10 +37,13 @@
#include "debug.h"
#include "misc.h"
-char *memrepchr(char **str, char old, char new, size_t size) {
+char *memrepchr(char **str, char old, char new, size_t size)
+{
char *str_p;
- if ((NULL == str) || (NULL == *str) || (0 == strlen(*str))) {
+ if ((NULL == str)
+ || (NULL == *str)
+ || (0 == strlen(*str))) {
DBG_MSG("Invalid argument passed!\n");
errno = EINVAL;
return NULL;
@@ -56,12 +59,15 @@ char *memrepchr(char **str, char old, char new, size_t size) {
return *str;
}
-char *strcatpaths(const char *pathname1, const char *pathname2) {
+char *strcatpaths(const char *pathname1, const char *pathname2)
+{
char *new_path = NULL;
int lenght;
- if ((NULL == pathname1) || (0 == strlen(pathname1)) ||
- (NULL == pathname2) || (0 == strlen(pathname2))) {
+ if ((NULL == pathname1)
+ || (0 == strlen(pathname1))
+ || (NULL == pathname2)
+ || (0 == strlen(pathname2))) {
DBG_MSG("Invalid argument passed!\n");
errno = EINVAL;
return NULL;
@@ -85,7 +91,8 @@ char *strcatpaths(const char *pathname1, const char *pathname2) {
return new_path;
}
-char *strndup(const char *str, size_t size) {
+char *strndup(const char *str, size_t size)
+{
char *new_str = NULL;
size_t len;
@@ -96,7 +103,7 @@ char *strndup(const char *str, size_t size) {
}
/* Check lenght of str without breaching the size limit */
- for (len = 0;(len < size) && ('\0' != str[len]);len++);
+ for (len = 0; (len < size) && ('\0' != str[len]); len++);
new_str = malloc(len + 1);
if (NULL == new_str) {
@@ -110,7 +117,8 @@ char *strndup(const char *str, size_t size) {
return (char *)memcpy(new_str, str, len);
}
-char *gbasename(const char *path) {
+char *gbasename(const char *path)
+{
char *new_path = NULL;
if ((NULL == path) || (0 == strlen(path))) {
@@ -125,7 +133,8 @@ char *gbasename(const char *path) {
}
-int exists(const char *pathname) {
+int exists(const char *pathname)
+{
struct stat buf;
int retval;
@@ -144,7 +153,8 @@ int exists(const char *pathname) {
return 0;
}
-int is_file(const char *pathname, int follow_link) {
+int is_file(const char *pathname, int follow_link)
+{
struct stat buf;
int retval;
@@ -163,7 +173,8 @@ int is_file(const char *pathname, int follow_link) {
return 0;
}
-int is_link(const char *pathname) {
+int is_link(const char *pathname)
+{
struct stat buf;
int retval;
@@ -182,7 +193,8 @@ int is_link(const char *pathname) {
return 0;
}
-int is_dir(const char *pathname, int follow_link) {
+int is_dir(const char *pathname, int follow_link)
+{
struct stat buf;
int retval;
@@ -201,7 +213,8 @@ int is_dir(const char *pathname, int follow_link) {
return 0;
}
-time_t get_mtime(const char *pathname, int follow_link) {
+time_t get_mtime(const char *pathname, int follow_link)
+{
struct stat buf;
int retval;
@@ -221,7 +234,8 @@ time_t get_mtime(const char *pathname, int follow_link) {
}
#ifdef __KLIBC__
-int remove(const char *pathname) {
+int remove(const char *pathname)
+{
int retval;
if ((NULL == pathname) || (0 == strlen(pathname))) {
@@ -230,7 +244,7 @@ int remove(const char *pathname) {
return -1;
}
- if (is_dir(pathname, 0))
+ if (1 == is_dir(pathname, 0))
retval = rmdir(pathname);
else
retval = unlink(pathname);
@@ -239,7 +253,8 @@ int remove(const char *pathname) {
}
#endif
-int mktree(const char *pathname, mode_t mode) {
+int mktree(const char *pathname, mode_t mode)
+{
char *temp_name = NULL;
char *temp_token = NULL;
char *token_p;
@@ -284,14 +299,14 @@ int mktree(const char *pathname, mode_t mode) {
/* If it does not exist, create the dir. If it does exit,
* but is not a directory, we will catch it below. */
- if (!exists(temp_name)) {
+ if (1 != exists(temp_name)) {
retval = mkdir(temp_name, mode);
if (-1 == retval) {
DBG_MSG("Failed to create directory!\n");
goto error;
}
/* Not a directory or symlink pointing to a directory */
- } else if (!is_dir(temp_name, 1)) {
+ } else if (1 != is_dir(temp_name, 1)) {
DBG_MSG("Component in pathname is not a directory!\n");
errno = ENOTDIR;
goto error;
@@ -315,7 +330,8 @@ error:
return -1;
}
-int rmtree(const char *pathname) {
+int rmtree(const char *pathname)
+{
char **dirlist = NULL;
int i = 0;
@@ -325,7 +341,7 @@ int rmtree(const char *pathname) {
return -1;
}
- if (!exists(pathname)) {
+ if (1 != exists(pathname)) {
DBG_MSG("'%s' does not exists!\n", pathname);
errno = ENOENT;
return -1;
@@ -333,18 +349,14 @@ int rmtree(const char *pathname) {
dirlist = ls_dir(pathname, 1);
if ((NULL == dirlist) && (0 != errno)) {
- /* If errno = ENOENT and the directory exists, then it means
- * it is empty, so we should not error out */
- if (ENOENT != errno) {
- DBG_MSG("Could not get listing for '%s'!\n", pathname);
- return -1;
- }
+ DBG_MSG("Could not get listing for '%s'!\n", pathname);
+ return -1;
}
while ((NULL != dirlist) && (NULL != dirlist[i])) {
/* If it is a directory, call rmtree() again with
* it as argument */
- if (is_dir(dirlist[i], 0)) {
+ if (1 == is_dir(dirlist[i], 0)) {
if (-1 == rmtree(dirlist[i])) {
DBG_MSG("Failed to delete sub directory!\n");
goto error;
@@ -353,7 +365,7 @@ int rmtree(const char *pathname) {
/* Now actually remove it. Note that if it was a directory,
* it should already be removed by above rmtree() call */
- if ((exists(dirlist[i]) && (-1 == remove(dirlist[i])))) {
+ if ((1 == exists(dirlist[i]) && (-1 == remove(dirlist[i])))) {
DBG_MSG("Failed to remove '%s'!\n", dirlist[i]);
goto error;
}
@@ -375,7 +387,8 @@ error:
return -1;
}
-char **ls_dir(const char *pathname, int hidden) {
+char **ls_dir(const char *pathname, int hidden)
+{
DIR *dirfd;
struct dirent *dir_entry;
char **dirlist = NULL;
@@ -417,7 +430,6 @@ char **ls_dir(const char *pathname, int hidden) {
tmp_p = strcatpaths(pathname, d_name);
if (NULL == tmp_p) {
DBG_MSG("Failed to allocate buffer!\n");
- /* errno = ENOMEM */
goto error;
}
@@ -425,11 +437,8 @@ char **ls_dir(const char *pathname, int hidden) {
}
} while (NULL != dir_entry);
- if ((NULL == dirlist) || (NULL == dirlist[0])) {
+ if ((NULL == dirlist) || (NULL == dirlist[0]))
DBG_MSG("Directory is empty.\n");
- errno = ENOENT;
- goto error;
- }
closedir(dirfd);
@@ -452,7 +461,8 @@ error:
/* This handles simple 'entry="bar"' type variables. If it is more complex
* ('entry="$(pwd)"' or such), it will obviously not work, but current behaviour
* should be fine for the type of variables we want. */
-char *get_cnf_entry(const char *pathname, const char *entry) {
+char *get_cnf_entry(const char *pathname, const char *entry)
+{
char *buf = NULL;
char *tmp_buf = NULL;
char *tmp_p;
@@ -463,15 +473,17 @@ char *get_cnf_entry(const char *pathname, const char *entry) {
int current = 0;
- if ((NULL == pathname) || (0 == strlen(pathname)) ||
- (NULL == entry) || (0 == strlen(entry))) {
+ if ((NULL == pathname)
+ || (0 == strlen(pathname))
+ || (NULL == entry)
+ || (0 == strlen(entry))) {
DBG_MSG("Invalid argument passed!\n");
errno = EINVAL;
return NULL;
}
/* If it is not a file or symlink pointing to a file, bail */
- if (!is_file(pathname, 1)) {
+ if (1 != is_file(pathname, 1)) {
DBG_MSG("Given pathname is not a file or do not exist!\n");
/* FIXME: Might need to set this to something better? */
errno = ENOENT;
@@ -531,9 +543,10 @@ char *get_cnf_entry(const char *pathname, const char *entry) {
free(value);
value = strndup(token, strlen(token));
- if (NULL == value)
- /* errno = ENOMEM */
+ if (NULL == value) {
+ DBG_MSG("Failed to allocate temporary buffer!\n");
goto error;
+ }
/* We do not break, as there might be more than one entry
* defined, and as bash uses the last, so should we */
@@ -549,11 +562,8 @@ _continue:
}
- if (NULL == value) {
+ if (NULL == value)
DBG_MSG("Failed to get value for config entry '%s'!\n", entry);
- errno = ENOMSG;
- goto error;
- }
file_unmap(buf, lenght);
diff --git a/src/core/misc.h b/src/core/misc.h
index 441a976..400e580 100644
--- a/src/core/misc.h
+++ b/src/core/misc.h
@@ -50,29 +50,21 @@
errno = old_errno; \
} while (0)
+/* Min/Max macro's */
+#ifdef MAX
+# undef MAX
+#endif
+#define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
+#ifdef MIN
+# undef MIN
+#endif
+#define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a))
+
/* Return true if filename '_name' ends in '_ext' */
#define CHECK_FILE_EXTENSION(_name, _ext) \
- (strlen(_name) > strlen(_ext) && \
- 0 == strncmp(&_name[strlen(_name) - strlen(_ext)], \
- _ext, strlen(_ext)))
-
-/* For each '_char' in '_string', inc '_count' */
-#define COUNT_CHAR_UP(_string, _char, _count) \
- do { \
- int _i; \
- for (_i = 0;_i < strlen(_string);_i++) \
- if (_string[_i] == _char) \
- _count++; \
- } while (0)
-
-/* For each '_char' in '_string', dec '_count' */
-#define COUNT_CHAR_DN(_string, _char, _count) \
- do { \
- int _i; \
- for (_i = 0;_i < strlen(_string);_i++) \
- if (_string[_i] == _char) \
- _count--; \
- } while (0)
+ ((strlen(_name) > strlen(_ext)) \
+ && (0 == strncmp(&(_name[strlen(_name) - strlen(_ext)]), \
+ _ext, strlen(_ext))))
/* Add a new item to a string list. If the pointer to the list is NULL,
* allocate enough memory for the amount of entries needed. Ditto for
@@ -162,8 +154,9 @@
#define STRING_LIST_DEL(_string_list, _item, _error) \
do { \
int _i = 0; \
- if ((NULL == _item) || (0 == strlen(_item)) || \
- (NULL == _string_list)) { \
+ if ((NULL == _item) \
+ || (0 == strlen(_item)) \
+ || (NULL == _string_list)) { \
DBG_MSG("Invalid argument passed!\n"); \
errno = EINVAL; \
goto _error; \
@@ -202,30 +195,31 @@
* from using it if not absolutely needed. The major difference to above,
* is that it should be safe from having the item removed from under you. */
#define STRING_LIST_FOR_EACH_SAFE(_string_list, _pos, _next, _counter) \
- if ((NULL != _string_list) && (0 == (_counter = 0))) \
+ if ((NULL != _string_list) \
+ && (0 == (_counter = 0))) \
/* First part of the while checks if this is the
* first loop, and if so setup _pos and _next
* and increment _counter */ \
- while ((((0 == _counter) && \
- (NULL != (_pos = _string_list[_counter])) && \
- (_pos != (_next = _string_list[++_counter]))) || \
+ while ((((0 == _counter) \
+ && (NULL != (_pos = _string_list[_counter])) \
+ && (_pos != (_next = _string_list[++_counter]))) \
/* Second part is when it is not the first loop
* and _pos was not removed from under us. We
* just increment _counter, and setup _pos and
* _next */ \
- ((0 != _counter) && \
- (_pos == _string_list[_counter-1]) && \
- (_next == _string_list[_counter]) && \
- (NULL != (_pos = _string_list[_counter])) && \
- (_pos != (_next = _string_list[++_counter]))) || \
+ || ((0 != _counter) \
+ && (_pos == _string_list[_counter-1]) \
+ && (_next == _string_list[_counter]) \
+ && (NULL != (_pos = _string_list[_counter])) \
+ && (_pos != (_next = _string_list[++_counter]))) \
/* Last part is when _pos was removed from under
* us. We basically just setup _pos and _next,
* but leave _counter alone */ \
- ((0 != _counter) && \
- (_pos != _string_list[_counter-1]) && \
- (_next == _string_list[_counter-1]) && \
- (NULL != (_pos = _string_list[_counter-1])) && \
- (_pos != (_next = _string_list[_counter])))))
+ || ((0 != _counter) \
+ && (_pos != _string_list[_counter-1]) \
+ && (_next == _string_list[_counter-1]) \
+ && (NULL != (_pos = _string_list[_counter-1])) \
+ && (_pos != (_next = _string_list[_counter])))))
/* Just free the whole string list */
#define STRING_LIST_FREE(_string_list) \
diff --git a/src/core/parse.c b/src/core/parse.c
index 35926fc..b36cb54 100644
--- a/src/core/parse.c
+++ b/src/core/parse.c
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <sys/poll.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
@@ -42,13 +43,23 @@
#include "parse.h"
#include "simple-regex.h"
-#define READ_PIPE 0
-#define WRITE_PIPE 1
+#define READ_PIPE 0
+#define WRITE_PIPE 1
-#define PARSE_BUFFER_SIZE 256
+/* _pipe[0] is used to send data to the parent (thus the parent only use the
+ * read pipe, and the child uses the write pipe)
+ * _pipe[1] is used to send data to the child (thus the child only use the read
+ * pipe, and the parent uses the write pipe)
+ */
+#define PARENT_READ_PIPE(_pipe) (_pipe[0][READ_PIPE])
+#define PARENT_WRITE_PIPE(_pipe) (_pipe[1][WRITE_PIPE])
+#define CHILD_READ_PIPE(_pipe) (_pipe[1][READ_PIPE])
+#define CHILD_WRITE_PIPE(_pipe) (_pipe[0][WRITE_PIPE])
+
+#define PARSE_BUFFER_SIZE 256
-#define OUTPUT_MAX_LINE_LENGHT 256
-#define OUTPUT_BUFFER_SIZE (60 * 1024)
+#define OUTPUT_MAX_LINE_LENGHT 256
+#define OUTPUT_BUFFER_SIZE (60 * 1024)
/* void PRINT_TO_BUFFER(char **_buf, int _count, label _error, format) */
#define PRINT_TO_BUFFER(_buf, _count, _error, _output...) \
@@ -67,14 +78,14 @@
LIST_HEAD(rcscript_list);
-size_t parse_rcscript(char *scriptname, time_t mtime, char **data, size_t index);
+size_t parse_rcscript(char *scriptname, char **data, size_t index);
size_t parse_print_start(char **data, size_t index);
-size_t parse_print_header(char *scriptname, time_t mtime, char **data, size_t index);
+size_t parse_print_header(char *scriptname, char **data, size_t index);
size_t parse_print_body(char *scriptname, char **data, size_t index);
-size_t parse_print_end(char **data, size_t index);
-int get_rcscripts(void) {
+int get_rcscripts(void)
+{
rcscript_info_t *info;
char **file_list = NULL;
char *rcscript;
@@ -89,17 +100,16 @@ int get_rcscripts(void) {
STRING_LIST_FOR_EACH(file_list, rcscript, count) {
/* Is it a file? */
- if ((!is_file(rcscript, 1)) ||
+ if (!(is_file(rcscript, 1))
/* Do not process scripts, source or backup files. */
- (CHECK_FILE_EXTENSION(rcscript, ".c")) ||
- (CHECK_FILE_EXTENSION(rcscript, ".bak")) ||
- (CHECK_FILE_EXTENSION(rcscript, "~")))
- {
+ || (CHECK_FILE_EXTENSION(rcscript, ".c"))
+ || (CHECK_FILE_EXTENSION(rcscript, ".bak"))
+ || (CHECK_FILE_EXTENSION(rcscript, "~"))) {
DBG_MSG("'%s' is not a valid rc-script!\n",
- gbasename(rcscript));
+ gbasename(rcscript));
} else {
DBG_MSG("Adding rc-script '%s' to list.\n",
- gbasename(rcscript));
+ gbasename(rcscript));
info = malloc(sizeof(rcscript_info_t));
if (NULL == info) {
@@ -118,14 +128,13 @@ int get_rcscripts(void) {
info->mtime = get_mtime(rcscript, 1);
if (0 == info->mtime) {
DBG_MSG("Failed to get modification time for '%s'!\n",
- rcscript);
+ rcscript);
/* We do not care if it fails - we will pick up
* later if there is a problem with the file */
}
/* File name for the conf.d config file (if any) */
- confd_file = strcatpaths(CONFD_DIR_NAME,
- gbasename(rcscript));
+ confd_file = strcatpaths(CONFD_DIR_NAME, gbasename(rcscript));
if (NULL == confd_file) {
DBG_MSG("Failed to allocate temporary buffer!\n");
goto loop_error;
@@ -136,7 +145,7 @@ int get_rcscripts(void) {
info->confd_mtime = get_mtime(confd_file, 1);
if (0 == info->confd_mtime) {
DBG_MSG("Failed to get modification time for '%s'!\n",
- confd_file);
+ confd_file);
/* We do not care that it fails, as not all
* rc-scripts will have conf.d config files */
}
@@ -157,7 +166,7 @@ loop_error:
}
/* Final check if we have some entries */
- if (NULL == file_list[0]) {
+ if ((NULL == file_list) || (NULL == file_list[0])) {
DBG_MSG("No rc-scripts to parse!\n");
errno = ENOENT;
goto error;
@@ -175,7 +184,8 @@ error:
/* Returns 0 if we do not need to regen the cache file, else -1 with
* errno set if something went wrong */
-int check_rcscripts_mtime(char *cachefile) {
+int check_rcscripts_mtime(char *cachefile)
+{
rcscript_info_t *info;
time_t cache_mtime;
time_t rc_conf_mtime;
@@ -190,7 +200,7 @@ int check_rcscripts_mtime(char *cachefile) {
cache_mtime = get_mtime(cachefile, 1);
if (0 == cache_mtime) {
DBG_MSG("Could not get modification time for cache file '%s'!\n",
- cachefile);
+ cachefile);
return -1;
}
@@ -198,24 +208,24 @@ int check_rcscripts_mtime(char *cachefile) {
rc_conf_mtime = get_mtime(RC_CONF_FILE_NAME, 1);
if (rc_conf_mtime > cache_mtime) {
DBG_MSG("'%s' have a later modification time than '%s'.\n",
- RC_CONF_FILE_NAME, cachefile);
+ RC_CONF_FILE_NAME, cachefile);
return -1;
}
/* Get and compare mtime for RC_CONFD_FILE_NAME with that of cachefile */
rc_confd_mtime = get_mtime(RC_CONFD_FILE_NAME, 1);
if (rc_confd_mtime > cache_mtime) {
DBG_MSG("'%s' have a later modification time than '%s'.\n",
- RC_CONFD_FILE_NAME, cachefile);
+ RC_CONFD_FILE_NAME, cachefile);
return -1;
}
/* Get and compare mtime for each rc-script and its conf.d config file
* with that of cachefile */
list_for_each_entry(info, &rcscript_list, node) {
- if ((info->mtime > cache_mtime) ||
- (info->confd_mtime > cache_mtime)) {
+ if ((info->mtime > cache_mtime)
+ || (info->confd_mtime > cache_mtime)) {
DBG_MSG("'%s' have a later modification time than '%s'.\n",
- info->filename, cachefile);
+ info->filename, cachefile);
return -1;
}
}
@@ -224,7 +234,8 @@ int check_rcscripts_mtime(char *cachefile) {
}
/* Return count on success, -1 on error. If it was critical, errno will be set. */
-size_t parse_rcscript(char *scriptname, time_t mtime, char **data, size_t index) {
+size_t parse_rcscript(char *scriptname, char **data, size_t index)
+{
regex_data_t tmp_data;
char *buf = NULL;
char *tmp_buf = NULL;
@@ -241,14 +252,14 @@ size_t parse_rcscript(char *scriptname, time_t mtime, char **data, size_t index)
if (-1 == file_map(scriptname, &buf, &lenght)) {
DBG_MSG("Could not open '%s' for reading!\n",
- gbasename(scriptname));
+ gbasename(scriptname));
return -1;
}
while (current < lenght) {
count = buf_get_line(buf, lenght, current);
- tmp_buf = strndup(&buf[current], count);
+ tmp_buf = strndup(&(buf[current]), count);
if (NULL == tmp_buf) {
DBG_MSG("Failed to allocate temporary buffer!\n");
goto error;
@@ -257,25 +268,23 @@ size_t parse_rcscript(char *scriptname, time_t mtime, char **data, size_t index)
if (0 == current) {
/* Check if it starts with '#!/sbin/runscript' */
DO_REGEX(tmp_data, tmp_buf,
- "[ \t]*#![ \t]*/sbin/runscript[ \t]*.*", error);
+ "[ \t]*#![ \t]*/sbin/runscript[ \t]*.*", error);
if (REGEX_FULL_MATCH != tmp_data.match) {
DBG_MSG("'%s' is not a valid rc-script!\n",
- gbasename(scriptname));
- errno = 0;
+ gbasename(scriptname));
goto error;
}
/* We do not want rc-scripts ending in '.sh' */
if (CHECK_FILE_EXTENSION(scriptname, ".sh")) {
EWARN("'%s' is invalid (should not end with '.sh')!\n",
- gbasename(scriptname));
- errno = 0;
+ gbasename(scriptname));
goto error;
}
DBG_MSG("Parsing '%s'.\n", gbasename(scriptname));
write_count = parse_print_header(gbasename(scriptname),
- mtime, data, write_count);
+ data, write_count);
if (-1 == write_count) {
DBG_MSG("Failed to call parse_print_header()!\n");
goto error;
@@ -295,24 +304,12 @@ size_t parse_rcscript(char *scriptname, time_t mtime, char **data, size_t index)
DBG_MSG("Got 'depend()' function.\n");
write_count = parse_print_body(gbasename(scriptname),
- data, write_count);
+ data, write_count);
if (-1 == write_count) {
DBG_MSG("Failed to call parse_print_body()!\n");
goto error;
}
- /* Need to have the 'source', as parse_cache() checks for
- * second arg */
- PRINT_TO_BUFFER(data, write_count, error,
- " . \"%s\" >/dev/null 2>&1 || echo \"FAILED source\"\n",
- scriptname);
-
- write_count = parse_print_end(data, write_count);
- if (-1 == write_count) {
- DBG_MSG("Failed to call parse_print_end()!\n");
- goto error;
- }
-
/* Make sure this is the last loop */
current += lenght;
goto _continue;
@@ -340,7 +337,8 @@ error:
}
-size_t generate_stage1(char **data) {
+size_t generate_stage1(char **data)
+{
rcscript_info_t *info;
size_t write_count = 0;
size_t tmp_count;
@@ -352,10 +350,10 @@ size_t generate_stage1(char **data) {
}
list_for_each_entry(info, &rcscript_list, node) {
- tmp_count = parse_rcscript(info->filename, info->mtime, data, write_count);
+ tmp_count = parse_rcscript(info->filename, data, write_count);
if (-1 == tmp_count) {
DBG_MSG("Failed to parse '%s'!\n",
- gbasename(info->filename));
+ gbasename(info->filename));
/* If 'errno' is set, it is critical (hopefully) */
if (0 != errno)
@@ -369,36 +367,29 @@ size_t generate_stage1(char **data) {
}
/* Empty signal handler for SIGPIPE */
-static void sig_handler(int signum) {
+static void sig_handler(int signum)
+{
return;
}
/* Returns data's lenght on success, else -1 on error. */
-size_t generate_stage2(char **data) {
- /* parent_pfds is used to send data to the parent
- * (thus the parent only use the read pipe, and the
- * child uses the write pipe)
- */
- int parent_pfds[2];
- /* child_pfds is used to send data to the child
- * (thus the child only use the read pipe, and the
- * parent uses the write pipe)
- */
- int child_pfds[2];
+size_t generate_stage2(char **data)
+{
+ int pipe_fds[2][2] = { { 0, 0 }, { 0, 0 } };
pid_t child_pid;
size_t write_count = 0;
int old_errno = 0;
/* Pipe to send data to parent */
- if (-1 == pipe(parent_pfds)) {
- DBG_MSG("Failed to open 'parent_pfds' pipe!\n");
+ if (-1 == pipe(pipe_fds[0])) {
+ DBG_MSG("Failed to open pipe!\n");
goto error;
}
- /* Pipe to send data to childd */
- if (-1 == pipe(child_pfds)) {
- DBG_MSG("Failed to open 'child_pfds' pipe!\n");
+ /* Pipe to send data to child */
+ if (-1 == pipe(pipe_fds[1])) {
+ DBG_MSG("Failed to open pipe!\n");
/* Close parent_pfds */
- goto error_c_parent;
+ goto error;
}
/* Zero data */
@@ -408,7 +399,7 @@ size_t generate_stage2(char **data) {
if (-1 == child_pid) {
DBG_MSG("Failed to fork()!\n");
/* Close all pipes */
- goto error_c_all;
+ goto error;
}
if (0 == child_pid) {
/***
@@ -424,13 +415,13 @@ size_t generate_stage2(char **data) {
};
/* Close the sides of the pipes we do not use */
- close(child_pfds[WRITE_PIPE]); /* Only used for reading */
- close(parent_pfds[READ_PIPE]); /* Only used for writing */
+ close(PARENT_WRITE_PIPE(pipe_fds));
+ close(PARENT_READ_PIPE(pipe_fds));
/* dup2 child side read pipe to STDIN */
- dup2(child_pfds[READ_PIPE], STDIN_FILENO);
+ dup2(CHILD_READ_PIPE(pipe_fds), STDIN_FILENO);
/* dup2 child side write pipe to STDOUT */
- dup2(parent_pfds[WRITE_PIPE], STDOUT_FILENO);
+ dup2(CHILD_WRITE_PIPE(pipe_fds), STDOUT_FILENO);
/* We need to be in INITD_DIR_NAME for 'before'/'after' '*' to work */
if (-1 == chdir(INITD_DIR_NAME)) {
@@ -449,23 +440,12 @@ size_t generate_stage2(char **data) {
struct sigaction act_new;
struct sigaction act_old;
- struct timeval tv;
-#if defined(USE_WRITE_SELECT)
- fd_set write_fds;
-#endif
- fd_set read_fds;
+ struct pollfd poll_fds[2];
char buf[PARSE_BUFFER_SIZE+1];
char *stage1_data = NULL;
size_t stage1_write_count = 0;
size_t stage1_written = 0;
-#if defined(USE_WRITE_SELECT)
- int max_write_fds = child_pfds[WRITE_PIPE] + 1;
-#endif
- int max_read_fds = parent_pfds[READ_PIPE] + 1;
int status = 0;
- int read_count;
- int closed_write_pipe = 0;
- int tmp_pid = 0;
DBG_MSG("Child pid = %i\n", child_pid);
@@ -480,20 +460,22 @@ size_t generate_stage2(char **data) {
sigaction(SIGPIPE, &act_new, &act_old);
/* Close the sides of the pipes we do not use */
- close(parent_pfds[WRITE_PIPE]); /* Only used for reading */
- close(child_pfds[READ_PIPE]); /* Only used for writing */
+ close(CHILD_WRITE_PIPE(pipe_fds));
+ CHILD_WRITE_PIPE(pipe_fds) = 0;
+ close(CHILD_READ_PIPE(pipe_fds));
+ CHILD_READ_PIPE(pipe_fds) = 0;
stage1_data = malloc(OUTPUT_BUFFER_SIZE + 1);
if (NULL == stage1_data) {
DBG_MSG("Failed to allocate buffer!\n");
- goto error_c_p_side;
+ goto error;
}
/* Pipe parse_rcscripts() to bash */
stage1_write_count = generate_stage1(&stage1_data);
if (-1 == stage1_write_count) {
DBG_MSG("Failed to generate stage1!\n");
- goto error_c_p_side;
+ goto error;
}
#if 0
@@ -502,94 +484,96 @@ size_t generate_stage2(char **data) {
close(tmp_fd);
#endif
- /* Do setup for select() */
- tv.tv_sec = 0; /* We do not want to wait for select() */
- tv.tv_usec = 0; /* Same thing here */
-#if defined(USE_WRITE_SELECT)
- FD_ZERO(&write_fds);
- FD_SET(child_pfds[WRITE_PIPE], &write_fds);
-#endif
- FD_ZERO(&read_fds);
- FD_SET(parent_pfds[READ_PIPE], &read_fds);
-
do {
-#if defined(USE_WRITE_SELECT)
- fd_set wwrite_fds = write_fds;
-#endif
- fd_set wread_fds = read_fds;
int tmp_count = 0;
-#if defined(USE_WRITE_SELECT)
int do_write = 0;
-#endif
int do_read = 0;
-
- /* Check if we can read from parent_pfds[READ_PIPE] */
- select(max_read_fds, &wread_fds, NULL, NULL, &tv);
- do_read = FD_ISSET(parent_pfds[READ_PIPE], &wread_fds);
- /* While there is data to be written */
+ /* Check if we can write or read */
+ poll_fds[WRITE_PIPE].fd = PARENT_WRITE_PIPE(pipe_fds);
+ poll_fds[WRITE_PIPE].events = POLLOUT;
+ poll_fds[READ_PIPE].fd = PARENT_READ_PIPE(pipe_fds);
+ poll_fds[READ_PIPE].events = POLLIN | POLLPRI;
if (stage1_written < stage1_write_count) {
-#if defined(USE_WRITE_SELECT)
- /* Check if we can write */
- select(max_write_fds, NULL, &wwrite_fds,
- NULL, &tv);
- do_write = FD_ISSET(child_pfds[WRITE_PIPE],
- &wwrite_fds);
+ poll(poll_fds, 2, -1);
+ if (poll_fds[WRITE_PIPE].revents & POLLOUT)
+ do_write = 1;
+ } else {
+ poll(&(poll_fds[READ_PIPE]), 1, -1);
+ }
+ if ((poll_fds[READ_PIPE].revents & POLLIN)
+ || (poll_fds[READ_PIPE].revents & POLLPRI))
+ do_read = 1;
+ do {
/* If we can write, or there is nothing to
* read, keep feeding the write pipe */
- if (do_write || !do_read) {
-#else
- if (!do_read) {
-#endif
- tmp_count = write(child_pfds[WRITE_PIPE],
- &stage1_data[stage1_written],
- strlen(&stage1_data[stage1_written]));
- if (-1 == tmp_count) {
- DBG_MSG("Error writing to child_pfds[WRITE_PIPE]!\n");
- goto failed;
- }
- /* What was written before, plus what
- * we wrote now as well as the ending
- * '\0' of the line */
- stage1_written += tmp_count + 1;
-
- /* Close the write pipe if we done
- * writing to get a EOF signaled to
- * bash */
- if (stage1_written >= stage1_write_count) {
- closed_write_pipe = 1;
- close(child_pfds[WRITE_PIPE]);
- }
+ if ((stage1_written >= stage1_write_count)
+ || (1 == do_read)
+ || (1 != do_write))
+ break;
+
+ tmp_count = write(PARENT_WRITE_PIPE(pipe_fds),
+ &stage1_data[stage1_written],
+ strlen(&stage1_data[stage1_written]));
+ if ((-1 == tmp_count) && (EINTR != errno)) {
+ DBG_MSG("Error writing to PARENT_WRITE_PIPE!\n");
+ goto failed;
}
- }
+ /* We were interrupted, try to write again */
+ if (-1 == tmp_count) {
+ errno = 0;
+ /* Make sure we retry */
+ tmp_count = 1;
+ continue;
+ }
+ /* What was written before, plus what
+ * we wrote now as well as the ending
+ * '\0' of the line */
+ stage1_written += tmp_count + 1;
- if (do_read) {
- read_count = read(parent_pfds[READ_PIPE], buf,
- PARSE_BUFFER_SIZE);
- if (-1 == read_count) {
- DBG_MSG("Error reading parent_pfds[READ_PIPE]!\n");
+ /* Close the write pipe if we done
+ * writing to get a EOF signaled to
+ * bash */
+ if (stage1_written >= stage1_write_count) {
+ close(PARENT_WRITE_PIPE(pipe_fds));
+ PARENT_WRITE_PIPE(pipe_fds) = 0;
+ }
+ } while ((tmp_count > 0) && (stage1_written < stage1_write_count));
+
+ /* Reset tmp_count for below read loop */
+ tmp_count = 0;
+
+ do {
+ char *tmp_p;
+
+ if (1 != do_read)
+ continue;
+
+ tmp_count = read(PARENT_READ_PIPE(pipe_fds), buf,
+ PARSE_BUFFER_SIZE);
+ if ((-1 == tmp_count) && (EINTR != errno)) {
+ DBG_MSG("Error reading PARENT_READ_PIPE!\n");
goto failed;
}
- if (read_count > 0) {
- char *tmp_p;
-
- tmp_p = realloc(*data, write_count +
- read_count);
- if (NULL == tmp_p) {
- DBG_MSG("Failed to allocate buffer!\n");
- goto failed;
- }
-
- memcpy(&tmp_p[write_count], buf,
- read_count);
-
- *data = tmp_p;
- write_count += read_count;
+ /* We were interrupted, try to read again */
+ if ((-1 == tmp_count) || (0 == tmp_count)) {
+ errno = 0;
+ continue;
}
- }
- tmp_pid = waitpid(child_pid, &status, WNOHANG);
- } while (0 == tmp_pid);
+
+ tmp_p = realloc(*data, write_count + tmp_count);
+ if (NULL == tmp_p) {
+ DBG_MSG("Failed to allocate buffer!\n");
+ goto failed;
+ }
+
+ memcpy(&tmp_p[write_count], buf, tmp_count);
+
+ *data = tmp_p;
+ write_count += tmp_count;
+ } while (tmp_count > 0);
+ } while (!(poll_fds[READ_PIPE].revents & POLLHUP));
failed:
/* Set old_errno to disable child exit code checking below */
@@ -598,62 +582,51 @@ failed:
free(stage1_data);
- if (0 == closed_write_pipe)
- close(child_pfds[WRITE_PIPE]);
- close(parent_pfds[READ_PIPE]);
+ if (0 != PARENT_WRITE_PIPE(pipe_fds))
+ close(PARENT_WRITE_PIPE(pipe_fds));
+ close(PARENT_READ_PIPE(pipe_fds));
/* Restore the old signal handler for SIGPIPE */
sigaction(SIGPIPE, &act_old, NULL);
- if (tmp_pid != child_pid)
- /* Wait for bash to finish */
- waitpid(child_pid, &status, 0);
+ /* Wait for bash to finish */
+ waitpid(child_pid, &status, 0);
/* If old_errno is set, we had an error in the read loop, so do
* not worry about the child's exit code */
if (0 == old_errno) {
if ((!WIFEXITED(status)) || (0 != WEXITSTATUS(status))) {
DBG_MSG("Bash failed with status 0x%x!\n", status);
- goto error;
+ return -1;
}
} else {
/* Right, we had an error, so set errno, and exit */
errno = old_errno;
- goto error;
+ return -1;
}
}
return write_count;
/* Close parent side pipes */
-error_c_p_side:
- old_errno = errno;
- close(child_pfds[WRITE_PIPE]);
- close(parent_pfds[READ_PIPE]);
- /* close() might have changed it */
- errno = old_errno;
- goto error;
-
+error:
/* Close all pipes */
-error_c_all:
old_errno = errno;
- close(child_pfds[READ_PIPE]);
- close(child_pfds[WRITE_PIPE]);
+ if (0 != CHILD_READ_PIPE(pipe_fds))
+ close(CHILD_READ_PIPE(pipe_fds));
+ if (0 != CHILD_WRITE_PIPE(pipe_fds))
+ close(CHILD_WRITE_PIPE(pipe_fds));
+ if (0 != PARENT_READ_PIPE(pipe_fds))
+ close(PARENT_READ_PIPE(pipe_fds));
+ if (0 != PARENT_WRITE_PIPE(pipe_fds))
+ close(PARENT_WRITE_PIPE(pipe_fds));
/* close() might have changed it */
errno = old_errno;
- /* Only close parent's pipes */
-error_c_parent:
- old_errno = errno;
- close(parent_pfds[READ_PIPE]);
- close(parent_pfds[WRITE_PIPE]);
- /* close() might have changed it */
- errno = old_errno;
-
-error:
return -1;
}
-int write_legacy_stage3(FILE *output) {
+int write_legacy_stage3(FILE *output)
+{
service_info_t *info;
char *service;
int count;
@@ -690,18 +663,14 @@ int write_legacy_stage3(FILE *output) {
index = 1;
list_for_each_entry(info, &service_info_list, node) {
-#if 0
- /* Make it easier to compare old depscan.sh output and this
- * output as it puts 'net' right in the middle */
- if (0 == strcmp("net", info->name))
- continue;
-#endif
- fprintf(output, "RC_DEPEND_TREE[%i]=\"%s\"\n", index*11, info->name);
+ fprintf(output, "RC_DEPEND_TREE[%i]=\"%s\"\n",
+ index * 10, info->name);
for (i = 0;i <= BROKEN;i++) {
dep_count = 0;
- fprintf(output, "RC_DEPEND_TREE[%i+%i]=", (index * 11), (i + 2));
+ fprintf(output, "RC_DEPEND_TREE[%i+%i]=",
+ (index * 10), (i + 2));
STRING_LIST_FOR_EACH(info->depend_info[i], service, count) {
if (0 == dep_count)
@@ -718,11 +687,8 @@ int write_legacy_stage3(FILE *output) {
fprintf(output, "\n");
}
- fprintf(output, "RC_DEPEND_TREE[%i+9]=", index*11);
- fprintf(output, "\n");
-
- fprintf(output, "RC_DEPEND_TREE[%i+10]=\"%li\"\n\n", index*11,
- info->mtime);
+ fprintf(output, "RC_DEPEND_TREE[%i+9]=\"%li\"\n\n",
+ index * 10, info->mtime);
index++;
}
@@ -740,9 +706,11 @@ int write_legacy_stage3(FILE *output) {
return 0;
}
-int parse_cache(const char *data, size_t lenght) {
+int parse_cache(const char *data, size_t lenght)
+{
service_info_t *info;
service_type_t type = ALL_SERVICE_TYPE_T;
+ rcscript_info_t *rs_info;
char *tmp_buf = NULL;
char *rc_name = NULL;
char *tmp_p;
@@ -761,7 +729,7 @@ int parse_cache(const char *data, size_t lenght) {
while (current < lenght) {
count = buf_get_line((char *)data, lenght, current);
- tmp_buf = strndup(&data[current], count);
+ tmp_buf = strndup(&(data[current]), count);
if (NULL == tmp_buf) {
DBG_MSG("Failed to allocate temporary buffer!\n");
goto error;
@@ -776,9 +744,11 @@ int parse_cache(const char *data, size_t lenght) {
token = strsep(&tmp_p, " ");
/* FIELD name empty/bogus? */
- if ((NULL == token) || (0 == strlen(token)) ||
+ if ((NULL == token)
+ || (0 == strlen(token))
/* We got an empty FIELD value */
- (NULL == tmp_p) || (0 == strlen(tmp_p))) {
+ || (NULL == tmp_p)
+ || (0 == strlen(tmp_p))) {
DBG_MSG("Parsing stopped due to short read!\n");
errno = EMSGSIZE;
goto error;
@@ -790,8 +760,7 @@ int parse_cache(const char *data, size_t lenght) {
/* Add the service to the list, and initialize all data */
retval = service_add(tmp_p);
if (-1 == retval) {
- DBG_MSG("Failed to add %s to service list!\n",
- tmp_p);
+ DBG_MSG("Failed to add %s to service list!\n", tmp_p);
goto error;
}
@@ -811,46 +780,25 @@ int parse_cache(const char *data, size_t lenght) {
goto error;
}
- if (0 == strcmp(token, FIELD_FAILED)) {
- EWARN("'%s' has syntax errors, please correct!\n", rc_name);
- /* FIXME: Need to think about what to do syntax BROKEN
- * services */
- retval = service_add_dependency(rc_name, rc_name, BROKEN);
- if (-1 == retval) {
- DBG_MSG("Failed to add dependency '%s' to service '%s', type '%s'!\n",
- token, rc_name, field);
- goto error;
- }
- goto _continue;
- }
-
- if (0 == strcmp(token, FIELD_NEED)) {
+ if (0 == strcmp(token, FIELD_NEED))
type = NEED;
- goto have_dep_field;
- }
-
- if (0 == strcmp(token, FIELD_USE)) {
+ else if (0 == strcmp(token, FIELD_USE))
type = USE;
- goto have_dep_field;
- }
-
- if (0 == strcmp(token, FIELD_BEFORE)) {
+ else if (0 == strcmp(token, FIELD_BEFORE))
type = BEFORE;
- goto have_dep_field;
- }
-
- if (0 == strcmp(token, FIELD_AFTER)) {
+ else if (0 == strcmp(token, FIELD_AFTER))
type = AFTER;
- goto have_dep_field;
- }
-
- if (0 == strcmp(token, FIELD_PROVIDE)) {
+ else if (0 == strcmp(token, FIELD_PROVIDE))
type = PROVIDE;
- goto have_dep_field;
+ else if (0 == strcmp(token, FIELD_FAILED)) {
+ type = BROKEN;
+
+ /* FIXME: Need to think about what to do syntax BROKEN
+ * services */
+ EWARN("'%s' has syntax errors, please correct!\n", rc_name);
}
if (type < ALL_SERVICE_TYPE_T) {
-have_dep_field:
/* Get the first value *
* As the values are passed to a bash function, and we
* then use 'echo $*' to parse them, they should only
@@ -862,12 +810,12 @@ have_dep_field:
while (NULL != token) {
DBG_MSG("Field = '%s', service = '%s', value = '%s'\n",
- field, rc_name, token);
+ field, rc_name, token);
retval = service_add_dependency(rc_name, token, type);
if (-1 == retval) {
DBG_MSG("Failed to add dependency '%s' to service '%s', type '%s'!\n",
- token, rc_name, field);
+ token, rc_name, field);
goto error;
}
@@ -878,32 +826,6 @@ have_dep_field:
goto _continue;
}
- if (0 == strcmp(token, FIELD_MTIME)) {
- time_t mtime = 0;
-
- /* Just use the first value, and ignore the rest */
- token = strsep(&tmp_p, " ");
-
- if (NULL != token)
- mtime = atoi(token);
-
- retval = service_set_mtime(rc_name, mtime);
- if (-1 == retval) {
- DBG_MSG("Failed to set mtime for service '%s'!\n",
- rc_name);
- goto error;
- }
-
- /* Some debugging in case we have some corruption or
- * other issues */
- token = strsep(&tmp_p, " ");
- if (NULL != token)
- DBG_MSG("Too many falues for field '%s'!\n",
- FIELD_MTIME);
-
- goto _continue;
- }
-
/* Fall through */
DBG_MSG("Unknown FIELD in data!\n");
@@ -915,6 +837,20 @@ _continue:
* across loops */
}
+ /* Set the mtimes
+ * FIXME: Can drop this when we no longer need write_legacy_stage3() */
+ list_for_each_entry(rs_info, &rcscript_list, node) {
+ rc_name = gbasename(rs_info->filename);
+ if (NULL == service_get_info(rc_name))
+ continue;
+
+ retval = service_set_mtime(rc_name, rs_info->mtime);
+ if (-1 == retval) {
+ DBG_MSG("Failed to set mtime for service '%s'!\n", rc_name);
+ return -1;
+ }
+ }
+
return 0;
error:
@@ -923,27 +859,16 @@ error:
return -1;
}
-size_t parse_print_start(char **data, size_t index) {
+size_t parse_print_start(char **data, size_t index)
+{
size_t write_count = index;
- PRINT_TO_BUFFER(data, write_count, error, ". /sbin/functions.sh\n");
- PRINT_TO_BUFFER(data, write_count, error, "[ -e /etc/rc.conf ] && . /etc/rc.conf\n\n");
-// PRINT_TO_BUFFER(data, write_count, error, "set -e\n\n");
- PRINT_TO_BUFFER(data, write_count, error, "need() {\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -n \"$*\" ] && echo \"NEED $*\"; return 0\n");
- PRINT_TO_BUFFER(data, write_count, error, "}\n\n");
- PRINT_TO_BUFFER(data, write_count, error, "use() {\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -n \"$*\" ] && echo \"USE $*\"; return 0\n");
- PRINT_TO_BUFFER(data, write_count, error, "}\n\n");
- PRINT_TO_BUFFER(data, write_count, error, "before() {\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -n \"$*\" ] && echo \"BEFORE $*\"; return 0\n");
- PRINT_TO_BUFFER(data, write_count, error, "}\n\n");
- PRINT_TO_BUFFER(data, write_count, error, "after() {\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -n \"$*\" ] && echo \"AFTER $*\"; return 0\n");
- PRINT_TO_BUFFER(data, write_count, error, "}\n\n");
- PRINT_TO_BUFFER(data, write_count, error, "provide() {\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -n \"$*\" ] && echo \"PROVIDE $*\"; return 0\n");
- PRINT_TO_BUFFER(data, write_count, error, "}\n\n");
+ PRINT_TO_BUFFER(data, write_count, error,
+ ". /sbin/functions.sh\n"
+ "[ -e /etc/rc.conf ] && . /etc/rc.conf\n"
+ "\n"
+ /* "set -e\n" */
+ "\n");
return write_count;
@@ -951,13 +876,17 @@ error:
return -1;
}
-size_t parse_print_header(char *scriptname, time_t mtime, char **data, size_t index) {
+size_t parse_print_header(char *scriptname, char **data, size_t index)
+{
size_t write_count = index;
- PRINT_TO_BUFFER(data, write_count, error, "#*** %s ***\n\n", scriptname);
- PRINT_TO_BUFFER(data, write_count, error, "myservice=\"%s\"\n", scriptname);
- PRINT_TO_BUFFER(data, write_count, error, "echo \"RCSCRIPT ${myservice}\"\n\n");
- PRINT_TO_BUFFER(data, write_count, error, "echo \"MTIME %li\"\n\n", mtime);
+ PRINT_TO_BUFFER(data, write_count, error,
+ "#*** %s ***\n"
+ "\n"
+ "myservice=\"%s\"\n"
+ "echo \"RCSCRIPT ${myservice}\"\n"
+ "\n",
+ scriptname, scriptname);
return write_count;
@@ -965,7 +894,8 @@ error:
return -1;
}
-size_t parse_print_body(char *scriptname, char **data, size_t index) {
+size_t parse_print_body(char *scriptname, char **data, size_t index)
+{
size_t write_count = index;
char *tmp_buf = NULL;
char *tmp_ptr;
@@ -997,33 +927,51 @@ size_t parse_print_body(char *scriptname, char **data, size_t index) {
if (NULL == ext)
ext = tmp_ptr;
- PRINT_TO_BUFFER(data, write_count, error, "\n");
- PRINT_TO_BUFFER(data, write_count, error, " # Get settings for rc-script ...\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -e \"/etc/conf.d/${myservice}\" ] && \\\n");
- PRINT_TO_BUFFER(data, write_count, error, " . \"/etc/conf.d/${myservice}\"\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ -e /etc/conf.d/net ] && \\\n");
- PRINT_TO_BUFFER(data, write_count, error, " [ \"%s\" = \"net\" ] && \\\n", base);
- PRINT_TO_BUFFER(data, write_count, error, " [ \"%s\" != \"${myservice}\" ] && \\\n", ext);
- PRINT_TO_BUFFER(data, write_count, error, " . /etc/conf.d/net\n");
- PRINT_TO_BUFFER(data, write_count, error, " depend() {\n");
- PRINT_TO_BUFFER(data, write_count, error, " return 0\n");
- PRINT_TO_BUFFER(data, write_count, error, " }\n\n");
- PRINT_TO_BUFFER(data, write_count, error, " # Actual depend() function ...\n");
-
- free(tmp_buf);
-
- return write_count;
-
-error:
- return -1;
-}
-
-size_t parse_print_end(char **data, size_t index) {
- size_t write_count = index;
-
- PRINT_TO_BUFFER(data, write_count, error, "\n");
- PRINT_TO_BUFFER(data, write_count, error, " depend\n");
- PRINT_TO_BUFFER(data, write_count, error, "\n\n");
+ PRINT_TO_BUFFER(data, write_count, error,
+ "\n"
+ "(\n"
+ " # Get settings for rc-script ...\n"
+ " [ -e \"/etc/conf.d/${myservice}\" ] && \\\n"
+ " . \"/etc/conf.d/${myservice}\"\n"
+ " [ -e /etc/conf.d/net ] && \\\n"
+ " [ \"%s\" = \"net\" ] && \\\n"
+ " [ \"%s\" != \"${myservice}\" ] && \\\n"
+ " . /etc/conf.d/net\n"
+ " depend() {\n"
+ " return 0\n"
+ " }\n"
+ " \n"
+ " # Actual depend() function ...\n"
+ " (\n"
+ " set -e\n"
+ " . \"/etc/init.d/%s\" >/dev/null 2>&1\n"
+ " set +e\n"
+ " \n"
+ " need() {\n"
+ " [ \"$#\" -gt 0 ] && echo \"NEED $*\"; return 0\n"
+ " }\n"
+ " \n"
+ " use() {\n"
+ " [ \"$#\" -gt 0 ] && echo \"USE $*\"; return 0\n"
+ " }\n"
+ " \n"
+ " before() {\n"
+ " [ \"$#\" -gt 0 ] && echo \"BEFORE $*\"; return 0\n"
+ " }\n"
+ " \n"
+ " after() {\n"
+ " [ \"$#\" -gt 0 ] && echo \"AFTER $*\"; return 0\n"
+ " }\n"
+ " \n"
+ " provide() {\n"
+ " [ \"$#\" -gt 0 ] && echo \"PROVIDE $*\"; return 0\n"
+ " }\n"
+ " \n"
+ " depend\n"
+ " ) || echo \"FAILED ${myservice}\"\n"
+ ")\n"
+ "\n\n",
+ base, ext, scriptname);
return write_count;
diff --git a/src/core/parse.h b/src/core/parse.h
index 895fc6b..f00d835 100644
--- a/src/core/parse.h
+++ b/src/core/parse.h
@@ -45,7 +45,6 @@
#define FIELD_BEFORE "BEFORE"
#define FIELD_AFTER "AFTER"
#define FIELD_PROVIDE "PROVIDE"
-#define FIELD_MTIME "MTIME"
#define FIELD_FAILED "FAILED"
typedef struct {
diff --git a/src/core/simple-regex.c b/src/core/simple-regex.c
index 385f1f4..a5a9234 100644
--- a/src/core/simple-regex.c
+++ b/src/core/simple-regex.c
@@ -75,13 +75,13 @@
/* Macro to check if a regex_data_t pointer is valid */
#define CHECK_REGEX_DATA_P(_regex_data, _on_error) \
do { \
- if ((NULL == _regex_data) || \
- (NULL == _regex_data->data) || \
+ if ((NULL == _regex_data) \
+ || (NULL == _regex_data->data) \
/* We do not check for this, as it might still \
* provide a match ('*' or '?' wildcard) */ \
- /* (0 == strlen(_regex_data->data)) || */ \
- (NULL == _regex_data->regex) || \
- (0 == strlen(_regex_data->regex))) {\
+ /* || (0 == strlen(_regex_data->data)) */ \
+ || (NULL == _regex_data->regex) \
+ || (0 == strlen(_regex_data->regex))) {\
DBG_MSG("Invalid argument passed!\n"); \
goto _on_error; \
} \
@@ -112,7 +112,8 @@ int __match(regex_data_t *regex_data);
*
*/
-size_t get_word(const char *regex, char **r_word) {
+size_t get_word(const char *regex, char **r_word)
+{
char *r_list;
char *tmp_p;
size_t count = 0;
@@ -137,7 +138,7 @@ size_t get_word(const char *regex, char **r_word) {
case '+':
case '?':
/* If its a wildcard, backup one step */
- *--tmp_p = '\0';
+ *(--tmp_p) = '\0';
count--;
return count;
case '[':
@@ -170,7 +171,8 @@ error:
return -1;
}
-int match_word(regex_data_t *regex_data) {
+int match_word(regex_data_t *regex_data)
+{
char *data_p = regex_data->data;
char *r_word = NULL, *r_word_p;
size_t count = 0;
@@ -187,7 +189,7 @@ int match_word(regex_data_t *regex_data) {
while ((strlen(data_p) > 0) && (strlen(r_word_p) > 0 )) {
/* If 'r_word' is not 100% part of 'string', we do not have
* a match. If its a '.', it matches no matter what. */
- if ((data_p[0] != r_word_p[0]) && (r_word_p[0] != '.')) {
+ if ((data_p[0] != r_word_p[0]) && ('.' != r_word_p[0])) {
count = 0;
goto exit;
}
@@ -227,21 +229,26 @@ error:
return -1;
}
-size_t get_list_size(const char *regex) {
+size_t get_list_size(const char *regex)
+{
size_t count = 0;
/* NULL string means we do not have a list */
- if ((NULL == regex) || (0 == strlen(regex)) || (regex[0] != '[')) {
+ if ((NULL == regex)
+ || (0 == strlen(regex))
+ || ('[' != regex[0])) {
DBG_MSG("Invalid argument passed!\n");
return 0;
}
regex++;
- while ((strlen(regex) > 0) && (regex[0] != ']')) {
+ while ((strlen(regex) > 0) && (']' != regex[0])) {
/* We have a sequence (x-y) */
- if ((regex[0] == '-') && (regex[1] != ']') &&
- (strlen(regex) >= 2) && (regex[-1] < regex[1]))
+ if (('-' == regex[0])
+ && (']' != regex[1])
+ && (strlen(regex) >= 2)
+ && (regex[-1] < regex[1]))
{
/* Add current + diff in sequence */
count += regex[1] - regex[-1];
@@ -256,7 +263,8 @@ size_t get_list_size(const char *regex) {
return count;
}
-size_t get_list(const char *regex, char **r_list) {
+size_t get_list(const char *regex, char **r_list)
+{
char *tmp_buf = NULL;
size_t count = 0;
size_t size;
@@ -270,7 +278,7 @@ size_t get_list(const char *regex, char **r_list) {
/* Bail if we do not have a list. Do not add debugging, as
* it is very noisy (used a lot when we call match_list() in
* __match() and match() to test for list matching) */
- if (regex[0] != '[')
+ if ('[' != regex[0])
return 0;
size = get_list_size(regex);
@@ -291,12 +299,12 @@ size_t get_list(const char *regex, char **r_list) {
regex++;
count++;
- while ((strlen(regex) > 0) && (regex[0] != ']')) {
+ while ((strlen(regex) > 0) && (']' != regex[0])) {
/* We have a sequence (x-y) */
- if ((regex[0] == '-') && (regex[1] != ']') &&
- (strlen(regex) >= 2) && (regex[-1] < regex[1]))
- {
-
+ if (('-' == regex[0])
+ && (']' != regex[1])
+ && (strlen(regex) >= 2)
+ && (regex[-1] < regex[1])) {
/* Fill in missing chars in sequence */
while (tmp_buf[-1] < regex[1]) {
tmp_buf[0] = (char)(tmp_buf[-1] + 1);
@@ -317,7 +325,7 @@ size_t get_list(const char *regex, char **r_list) {
count++;
/* We do not have a list as it does not end in ']' */
- if (regex[0] != ']') {
+ if (']' != regex[0]) {
count = 0;
free(*r_list);
}
@@ -327,7 +335,8 @@ size_t get_list(const char *regex, char **r_list) {
/* If the first is the '^' character, everything but the list is matched
* NOTE: We only evaluate _ONE_ data character at a time!! */
-int __match_list(regex_data_t *regex_data) {
+int __match_list(regex_data_t *regex_data)
+{
regex_data_t tmp_data;
char *data_p = regex_data->data;
char *list_p = regex_data->regex;
@@ -338,7 +347,7 @@ int __match_list(regex_data_t *regex_data) {
CHECK_REGEX_DATA_P(regex_data, failed);
- if (list_p[0] == '^') {
+ if ('^' == list_p[0]) {
/* We need to invert the match */
invert = 1;
/* Make sure '^' is not part of our list */
@@ -401,7 +410,8 @@ error:
return -1;
}
-int match_list(regex_data_t *regex_data) {
+int match_list(regex_data_t *regex_data)
+{
regex_data_t tmp_data;
char *data_p = regex_data->data;
char *list_p = regex_data->regex;
@@ -464,7 +474,8 @@ error:
return -1;
}
-size_t get_wildcard(const char *regex, char *r_wildcard) {
+size_t get_wildcard(const char *regex, char *r_wildcard)
+{
/* NULL regex means we do not have a wildcard */
if ((NULL == regex) || (0 == strlen(regex))) {
DBG_MSG("Invalid argument passed!\n");
@@ -488,7 +499,8 @@ size_t get_wildcard(const char *regex, char *r_wildcard) {
return strlen(r_wildcard);
}
-int __match_wildcard(regex_data_t *regex_data, int (*match_func)(regex_data_t *regex_data), const char *regex) {
+int __match_wildcard(regex_data_t *regex_data, int (*match_func)(regex_data_t *regex_data), const char *regex)
+{
regex_data_t tmp_data;
char *data_p = regex_data->data;
char *wildcard_p = regex_data->regex;
@@ -525,9 +537,10 @@ int __match_wildcard(regex_data_t *regex_data, int (*match_func)(regex_data_t *r
/* If we have at least one match for '+', or none
* for '*' or '?', check if we have a word or list match.
* We do this because a word weights more than a wildcard */
- if ((strlen(wildcard_p) > 2) && ((count > 0) ||
- (r_wildcard[1] == '*') || (r_wildcard[1] == '?')))
- {
+ if ((strlen(wildcard_p) > 2)
+ && ((count > 0)
+ || ('*' == r_wildcard[1])
+ || ('?' == r_wildcard[1]))) {
regex_data_t tmp_data2;
#if 0
printf("data_p = %s, wildcard_p = %s\n", data_p, wildcard_p);
@@ -539,9 +552,9 @@ int __match_wildcard(regex_data_t *regex_data, int (*match_func)(regex_data_t *r
goto error;
if (/* '.' might be a special case ... */
- /* (wildcard_p[2] != '.') && */
- (REGEX_MATCH(tmp_data2) &&
- (REGEX_FULL_MATCH == tmp_data2.match))) {
+ /* ('.' != wildcard_p[2]) && */
+ ((REGEX_MATCH(tmp_data2))
+ && (REGEX_FULL_MATCH == tmp_data2.match))) {
goto exit;
}
}
@@ -557,7 +570,7 @@ int __match_wildcard(regex_data_t *regex_data, int (*match_func)(regex_data_t *r
goto error;
}
/* Only once for '?' */
- } while ((REGEX_MATCH(tmp_data)) && (r_wildcard[1] != '?'));
+ } while ((REGEX_MATCH(tmp_data)) && ('?' != r_wildcard[1]));
break;
default:
@@ -589,7 +602,8 @@ error:
return -1;
}
-int match_wildcard(regex_data_t *regex_data) {
+int match_wildcard(regex_data_t *regex_data)
+{
regex_data_t tmp_data;
char *data_p = regex_data->data;
char *wildcard_p = regex_data->regex;
@@ -639,7 +653,8 @@ error:
return -1;
}
-int __match(regex_data_t *regex_data) {
+int __match(regex_data_t *regex_data)
+{
regex_data_t tmp_data;
char *data_p = regex_data->data;
char *regex_p = regex_data->regex;
@@ -686,8 +701,8 @@ match:
match = 1;
/* Check that we do not go out of bounds */
- if (((data_p - regex_data->data) > strlen(regex_data->data)) ||
- ((regex_p - regex_data->regex) > strlen(regex_data->regex)))
+ if (((data_p - regex_data->data) > strlen(regex_data->data))
+ || ((regex_p - regex_data->regex) > strlen(regex_data->regex)))
goto failed;
}
@@ -727,7 +742,8 @@ error:
return -1;
}
-int match(regex_data_t *regex_data) {
+int match(regex_data_t *regex_data)
+{
regex_data_t tmp_data;
char *data_p = regex_data->data;
char *regex_p;
@@ -747,13 +763,13 @@ int match(regex_data_t *regex_data) {
regex_p = tmp_buf;
/* Should we only match from the start? */
- if (regex_p[0] == '^') {
+ if ('^' == regex_p[0]) {
regex_p++;
from_start = 1;
}
/* Should we match up to the end? */
- if (regex_p[strlen(regex_p) - 1] == '$') {
+ if ('$' == regex_p[strlen(regex_p) - 1]) {
regex_p[strlen(regex_p) - 1] = '\0';
to_end = 1;
}
@@ -763,8 +779,9 @@ int match(regex_data_t *regex_data) {
retval = __match(&tmp_data);
if (-1 == retval)
goto error;
- } while ((strlen(data_p++) > 0) &&
- (!REGEX_MATCH(tmp_data)) && (0 == from_start));
+ } while ((strlen(data_p++) > 0)
+ && (!REGEX_MATCH(tmp_data))
+ && (0 == from_start));
/* Compensate for above extra inc */
data_p--;
@@ -777,8 +794,8 @@ int match(regex_data_t *regex_data) {
goto failed;
}
- if ((data_p == regex_data->data) &&
- (tmp_data.match == REGEX_FULL_MATCH))
+ if ((data_p == regex_data->data)
+ && (tmp_data.match == REGEX_FULL_MATCH))
regex_data->match = REGEX_FULL_MATCH;
else
regex_data->match = REGEX_PARTIAL_MATCH;
@@ -808,47 +825,3 @@ error:
return -1;
}
-#if 0
-int main() {
- regex_data_t tmp_data;
- FILE *rcscript;
- char regex[] = "^[ \t]*[d-p]+d[ \t]*(+)[ \t]*{$";
- char tempstr[255];
- int retval;
-
- rcscript = fopen("acpid", "r");
- if (NULL == rcscript) {
- printf("%s", "Error opening file!");
- return 1;
- }
-
- while (0 != fgets(tempstr, 254, rcscript)) {
- if (tempstr[strlen(tempstr) - 1] == '\n')
- tempstr[strlen(tempstr) - 1] = '\0';
-
- FILL_REGEX_DATA(tmp_data, tempstr, regex);
- retval = match(&tmp_data);
- if (-1 != retval) {
- if (REGEX_MATCH(tmp_data)) {
- printf("*** string = '%s' ***\n", tempstr);
- printf("*** regex = '%s' ***\n", regex);
-
- if (REGEX_FULL_MATCH == tmp_data.match)
- printf("match (full): '%s', %i\n", tmp_data.where, tmp_data.count);
- else
- printf("match: '%s', %i\n", tmp_data.where, tmp_data.count);
-
- } else {
- printf("%s", "No match\n");
- }
- } else {
- printf("%s", "Error during match\n");
- }
- }
-
- fclose(rcscript);
-
- return 0;
-}
-#endif
-
diff --git a/src/core/simple-regex.h b/src/core/simple-regex.h
index affa312..ad91a58 100644
--- a/src/core/simple-regex.h
+++ b/src/core/simple-regex.h
@@ -48,13 +48,13 @@
/* Evaluate to true if we have some kind of match */
#define REGEX_MATCH(_regex_data) \
- ((REGEX_FULL_MATCH == _regex_data.match) || \
- (REGEX_PARTIAL_MATCH == _regex_data.match))
+ ((REGEX_FULL_MATCH == _regex_data.match) \
+ || (REGEX_PARTIAL_MATCH == _regex_data.match))
/* Same as above, but for use when _regex_data is a pointer */
#define REGEX_MATCH_P(_regex_data) \
- ((REGEX_FULL_MATCH == _regex_data->match) || \
- (REGEX_PARTIAL_MATCH == _regex_data->match))
+ ((REGEX_FULL_MATCH == _regex_data->match) \
+ || (REGEX_PARTIAL_MATCH == _regex_data->match))
typedef struct {
char *data; /* String to perform regex operation on */
diff --git a/src/env_whitelist b/src/env_whitelist
index 00ea17a..c52f9ec 100644
--- a/src/env_whitelist
+++ b/src/env_whitelist
@@ -16,6 +16,7 @@ IN_HOTPLUG
SHELL
USER
HOME
+TERM
# From /sbin/init
PATH
diff --git a/src/runscript.c b/src/runscript.c
index 61b43bf..73e41a0 100644
--- a/src/runscript.c
+++ b/src/runscript.c
@@ -213,7 +213,8 @@ int main(int argc, char *argv[]) {
char *caller = argv[1];
int new = 1;
- myargs[0] = "runscript";
+ /* Need to be /bin/bash, else BASH is invalid */
+ myargs[0] = "/bin/bash";
while (argv[new] != 0) {
myargs[new] = argv[new];
new++;
diff --git a/src/start-stop-daemon.c b/src/start-stop-daemon.c
index 315164f..8be9d23 100644
--- a/src/start-stop-daemon.c
+++ b/src/start-stop-daemon.c
@@ -18,23 +18,9 @@
* and Andreas Schuldei <andreas@schuldei.org>
*
* Changes by Ian Jackson: added --retry (and associated rearrangements).
- *
- * Modified for Gentoo rc-scripts by Donny Davies <woodchip@gentoo.org>:
- * I removed the BSD/Hurd/OtherOS stuff, added #include <stddef.h>
- * and stuck in a #define VERSION "1.9.18". Now it compiles without
- * the whole automake/config.h dance.
- *
- * Updated by Aron Griffis <agriffis@gentoo.org>:
- * Fetched updates from Debian's dpkg-1.10.20, including fix for
- * Gentoo bug 22686 (start-stop-daemon in baselayout doesn't allow
- * altered nicelevel).
- * Updated by Kito <kito@gentoo.org>:
- * Add support for Darwin, additional patches from opendarwin.org
- * fix for Gentoo bug 72145 from eldad@gentoo.org
*/
-#define VERSION "1.10.20"
-#include <stddef.h>
+#define VERSION "1.13.11+gentoo"
#define NONRETURNPRINTFFORMAT(x, y) \
__attribute__((noreturn, format(printf, x, y)))
@@ -75,7 +61,7 @@
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>
-
+
#include <err.h>
#include <kvm.h>
#include <limits.h>
@@ -107,6 +93,8 @@
#include <assert.h>
#include <ctype.h>
+#include <stddef.h>
+
#include "headers.h"
#ifdef HURD_IHASH_H
@@ -129,7 +117,7 @@ static const char *userspec = NULL;
static char *changeuser = NULL;
static const char *changegroup = NULL;
static char *changeroot = NULL;
-static const char *changedir = NULL;
+static const char *changedir = "/";
static const char *cmdname = NULL;
static char *execname = NULL;
static char *startas = NULL;
@@ -141,7 +129,7 @@ static int nicelevel = 0;
static struct stat exec_stat;
#if defined(OSHURD)
-static struct proc_stat_list *procset;
+static struct proc_stat_list *procset = NULL;
#endif
@@ -202,18 +190,18 @@ static void badusage(const char *msg);
typedef long tvselector(const struct timeval*);
static long tvselector_sec(const struct timeval *tv) { return tv->tv_sec; }
static long tvselector_usec(const struct timeval *tv) { return tv->tv_usec; }
-#define TVCALC_ELEM(result, expr, sec, adj) \
-{ \
- const long TVADJUST = adj; \
- long (*const TVELEM)(const struct timeval*) = tvselector_##sec; \
- (result).tv_##sec = (expr); \
+#define TVCALC_ELEM(result, expr, sec, adj) \
+{ \
+ const long TVADJUST = adj; \
+ long (*const TVELEM)(const struct timeval*) = tvselector_##sec; \
+ (result).tv_##sec = (expr); \
}
-#define TVCALC(result,expr) \
-do { \
- TVCALC_ELEM(result, expr, sec, (-1)); \
- TVCALC_ELEM(result, expr, usec, (+1000000)); \
- (result).tv_sec += (result).tv_usec / 1000000; \
- (result).tv_usec %= 1000000; \
+#define TVCALC(result,expr) \
+do { \
+ TVCALC_ELEM(result, expr, sec, (-1)); \
+ TVCALC_ELEM(result, expr, usec, (+1000000)); \
+ (result).tv_sec += (result).tv_usec / 1000000; \
+ (result).tv_usec %= 1000000; \
} while(0)
@@ -226,7 +214,7 @@ fatal(const char *format, ...)
va_start(arglist, format);
vfprintf(stderr, format, arglist);
va_end(arglist);
- putc('\n', stderr);
+ fprintf(stderr, " (%s)\n", strerror (errno));
exit(2);
}
@@ -466,34 +454,34 @@ static void
parse_options(int argc, char * const *argv)
{
static struct option longopts[] = {
- { "help", 0, NULL, 'H'},
- { "stop", 0, NULL, 'K'},
- { "start", 0, NULL, 'S'},
- { "version", 0, NULL, 'V'},
- { "startas", 1, NULL, 'a'},
- { "name", 1, NULL, 'n'},
- { "oknodo", 0, NULL, 'o'},
- { "pidfile", 1, NULL, 'p'},
- { "quiet", 0, NULL, 'q'},
- { "signal", 1, NULL, 's'},
- { "test", 0, NULL, 't'},
- { "user", 1, NULL, 'u'},
- { "group", 1, NULL, 'g'},
- { "chroot", 1, NULL, 'r'},
- { "verbose", 0, NULL, 'v'},
- { "exec", 1, NULL, 'x'},
- { "chuid", 1, NULL, 'c'},
- { "nicelevel", 1, NULL, 'N'},
+ { "help", 0, NULL, 'H'},
+ { "stop", 0, NULL, 'K'},
+ { "start", 0, NULL, 'S'},
+ { "version", 0, NULL, 'V'},
+ { "startas", 1, NULL, 'a'},
+ { "name", 1, NULL, 'n'},
+ { "oknodo", 0, NULL, 'o'},
+ { "pidfile", 1, NULL, 'p'},
+ { "quiet", 0, NULL, 'q'},
+ { "signal", 1, NULL, 's'},
+ { "test", 0, NULL, 't'},
+ { "user", 1, NULL, 'u'},
+ { "group", 1, NULL, 'g'},
+ { "chroot", 1, NULL, 'r'},
+ { "verbose", 0, NULL, 'v'},
+ { "exec", 1, NULL, 'x'},
+ { "chuid", 1, NULL, 'c'},
+ { "nicelevel", 1, NULL, 'N'},
{ "background", 0, NULL, 'b'},
{ "make-pidfile", 0, NULL, 'm'},
- { "retry", 1, NULL, 'R'},
+ { "retry", 1, NULL, 'R'},
{ "chdir", 1, NULL, 'd'},
- { NULL, 0, NULL, 0}
+ { NULL, 0, NULL, 0}
};
int c;
for (;;) {
- c = getopt_long(argc, argv, "HKSV:a:n:op:qr:s:tu:vx:c:N:bmR:g:d:",
+ c = getopt_long(argc, argv, "HKSVa:n:op:qr:s:tu:vx:c:N:bmR:g:d:",
longopts, (int *) 0);
if (c == -1)
break;
@@ -657,36 +645,70 @@ pid_is_cmd(pid_t pid, const char *name)
#if defined(OSHURD)
+static void
+init_procset(void)
+{
+ struct ps_context *context;
+ error_t err;
+
+ err = ps_context_create(getproc(), &context);
+ if (err)
+ error(1, err, "ps_context_create");
+
+ err = proc_stat_list_create(context, &procset);
+ if (err)
+ error(1, err, "proc_stat_list_create");
+
+ err = proc_stat_list_add_all(procset, 0, 0);
+ if (err)
+ error(1, err, "proc_stat_list_add_all");
+}
+
+static struct proc_stat *
+get_proc_stat (pid_t pid, ps_flags_t flags)
+{
+ struct proc_stat *ps;
+ ps_flags_t wanted_flags = PSTAT_PID | flags;
+
+ if (!procset)
+ init_procset();
+
+ ps = proc_stat_list_pid_proc_stat(procset, pid);
+ if (!ps)
+ return NULL;
+ if (proc_stat_set_flags(ps, wanted_flags))
+ return NULL;
+ if ((proc_stat_flags(ps) & wanted_flags) != wanted_flags)
+ return NULL;
+
+ return ps;
+}
+
static int
pid_is_user(pid_t pid, uid_t uid)
{
- struct stat sb;
- char buf[32];
- struct proc_stat *pstat;
+ struct proc_stat *ps;
- sprintf(buf, "/proc/%d", pid);
- if (stat(buf, &sb) != 0)
- return 0;
- return (sb.st_uid == uid);
- pstat = proc_stat_list_pid_proc_stat (procset, pid);
- if (pstat == NULL)
- fatal ("Error getting process information: NULL proc_stat struct");
- proc_stat_set_flags (pstat, PSTAT_PID | PSTAT_OWNER_UID);
- return (pstat->owner_uid == uid);
+ ps = get_proc_stat(pid, PSTAT_OWNER_UID);
+ return ps && proc_stat_owner_uid(ps) == uid;
}
static int
pid_is_cmd(pid_t pid, const char *name)
{
- struct proc_stat *pstat;
- pstat = proc_stat_list_pid_proc_stat (procset, pid);
- if (pstat == NULL)
- fatal ("Error getting process information: NULL proc_stat struct");
- proc_stat_set_flags (pstat, PSTAT_PID | PSTAT_ARGS);
- return (!strcmp (name, pstat->args));
+ struct proc_stat *ps;
+
+ ps = get_proc_stat(pid, PSTAT_ARGS);
+ return ps && !strcmp(proc_stat_args(ps), name);
}
-#endif /* OSHURD */
+static int
+pid_is_running(pid_t pid)
+{
+ return get_proc_stat(pid, 0) != NULL;
+}
+
+#else /* !OSHURD */
static int
pid_is_running(pid_t pid)
@@ -704,6 +726,8 @@ pid_is_running(pid_t pid)
return 1;
}
+#endif /* OSHURD */
+
static void
check(pid_t pid)
{
@@ -711,7 +735,7 @@ check(pid_t pid)
if (execname && !pid_is_exec(pid, &exec_stat))
return;
#elif defined(OSHURD) || defined(OSFreeBSD) || defined(OSNetBSD) || defined(OSDarwin)
- /* I will try this to see if it works */
+ /* I will try this to see if it works */
if (execname && !pid_is_cmd(pid, execname))
return;
#endif
@@ -771,98 +795,92 @@ do_procinit(void)
#if defined(OSHURD)
-error_t
-check_all(void *ptr)
+static int
+check_proc_stat (struct proc_stat *ps)
{
- struct proc_stat *pstat = ptr;
-
- check(pstat->pid);
+ check(ps->pid);
return 0;
}
static void
do_procinit(void)
{
- struct ps_context *context;
- error_t err;
-
- err = ps_context_create(getproc(), &context);
- if (err)
- error(1, err, "ps_context_create");
-
- err = proc_stat_list_create(context, &procset);
- if (err)
- error(1, err, "proc_stat_list_create");
+ if (!procset)
+ init_procset();
- err = proc_stat_list_add_all(procset, 0, 0);
- if (err)
- error(1, err, "proc_stat_list_add_all");
-
- /* Check all pids */
- ihash_iterate(context->procs, check_all);
+ proc_stat_list_for_each (procset, check_proc_stat);
}
#endif /* OSHURD */
#if defined(OSOpenBSD) || defined(OSFreeBSD) || defined(OSNetBSD)
+
+# if defined(OSNetBSD)
+# define _KINFO_PROC2 kinfo_proc2
+# define _GET_KINFO_UID(kp) (kp->p_ruid)
+# define _GET_KINFO_COMM(kp) (kp->p_comm)
+# else
+# define _KINFO_PROC2 kinfo_proc
+# define _GET_KINFO_UID(kp) (kp->ki_ruid)
+# define _GET_KINFO_COMM(kp) (kp->ki_comm)
+# endif
+
static int
pid_is_cmd(pid_t pid, const char *name)
{
- kvm_t *kd;
- int nentries, argv_len=0;
- struct kinfo_proc *kp;
- char errbuf[_POSIX2_LINE_MAX], buf[_POSIX2_LINE_MAX];
+ kvm_t *kd;
+ int nentries, argv_len=0;
+ struct kinfo_proc *kp;
+ char errbuf[_POSIX2_LINE_MAX], buf[_POSIX2_LINE_MAX];
char **pid_argv_p;
char *start_argv_0_p, *end_argv_0_p;
-
-
- kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
- if (kd == 0)
- errx(1, "%s", errbuf);
- if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &nentries)) == 0)
- errx(1, "%s", kvm_geterr(kd));
+
+ kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
+ if (kd == 0)
+ errx(1, "%s", errbuf);
+ if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &nentries)) == 0)
+ errx(1, "%s", kvm_geterr(kd));
if ((pid_argv_p = kvm_getargv(kd, kp, argv_len)) == 0)
- errx(1, "%s", kvm_geterr(kd));
+ errx(1, "%s", kvm_geterr(kd));
start_argv_0_p = *pid_argv_p;
/* find and compare string */
-
+
/* find end of argv[0] then copy and cut of str there. */
- if ((end_argv_0_p = strchr(*pid_argv_p, ' ')) == 0 )
- /* There seems to be no space, so we have the command
- * allready in its desired form. */
- start_argv_0_p = *pid_argv_p;
+ if ((end_argv_0_p = strchr(*pid_argv_p, ' ')) == 0 )
+ /* There seems to be no space, so we have the command
+ * allready in its desired form. */
+ start_argv_0_p = *pid_argv_p;
else {
- /* Tests indicate that this never happens, since
- * kvm_getargv itselfe cuts of tailing stuff. This is
- * not what the manpage says, however. */
- strncpy(buf, *pid_argv_p, (end_argv_0_p - start_argv_0_p));
- buf[(end_argv_0_p - start_argv_0_p) + 1] = '\0';
- start_argv_0_p = buf;
+ /* Tests indicate that this never happens, since
+ * kvm_getargv itselfe cuts of tailing stuff. This is
+ * not what the manpage says, however. */
+ strncpy(buf, *pid_argv_p, (end_argv_0_p - start_argv_0_p));
+ buf[(end_argv_0_p - start_argv_0_p) + 1] = '\0';
+ start_argv_0_p = buf;
}
-
+
if (strlen(name) != strlen(start_argv_0_p))
- return 0;
- return (strcmp(name, start_argv_0_p) == 0) ? 1 : 0;
+ return 0;
+ return (strcmp(name, start_argv_0_p) == 0) ? 1 : 0;
}
-
+
static int
pid_is_user(pid_t pid, uid_t uid)
{
kvm_t *kd;
int nentries; /* Value not used */
uid_t proc_uid;
- struct kinfo_proc *kp;
+ struct _KINFO_PROC2 *kp;
char errbuf[_POSIX2_LINE_MAX];
-
kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
if (kd == 0)
errx(1, "%s", errbuf);
if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &nentries)) == 0)
errx(1, "%s", kvm_geterr(kd));
- if (kp->ki_ruid )
- kvm_read(kd, (u_long)&(kp->ki_ruid),
+ if (_GET_KINFO_UID(kp))
+ kvm_read(kd, (u_long)&(_GET_KINFO_UID(kp)),
&proc_uid, sizeof(uid_t));
else
return 0;
@@ -874,7 +892,7 @@ pid_is_exec(pid_t pid, const char *name)
{
kvm_t *kd;
int nentries;
- struct kinfo_proc *kp;
+ struct _KINFO_PROC2 *kp;
char errbuf[_POSIX2_LINE_MAX], *pidexec;
kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
@@ -882,7 +900,7 @@ pid_is_exec(pid_t pid, const char *name)
errx(1, "%s", errbuf);
if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &nentries)) == 0)
errx(1, "%s", kvm_geterr(kd));
- pidexec = kp->ki_comm;
+ pidexec = _GET_KINFO_COMM(kp);
if (strlen(name) != strlen(pidexec))
return 0;
return (strcmp(name, pidexec) == 0) ? 1 : 0;
@@ -921,7 +939,7 @@ pid_is_cmd(pid_t pid, const char *name)
int mib[4];
size_t size;
struct kinfo_proc ki;
-
+
size = sizeof(ki);
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
@@ -939,7 +957,7 @@ do_procinit(void)
size_t size;
int nprocs, ret, i;
struct kinfo_proc *procs = NULL, *newprocs;
-
+
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL;
@@ -969,6 +987,7 @@ do_procinit(void)
}
}
#endif /* OSDarwin */
+
#if defined(OShpux)
static int
pid_is_user(pid_t pid, uid_t uid)
@@ -1009,9 +1028,9 @@ do_procinit(void)
int idx = 0;
while ((count = pstat_getproc(pst, sizeof(pst[0]), 10, idx)) > 0) {
- for (i = 0; i < count; i++)
+ for (i = 0; i < count; i++)
check(pst[i].pst_pid);
- idx = pst[count - 1].pst_idx + 1;
+ idx = pst[count - 1].pst_idx + 1;
}
}
#endif /* OShpux */
@@ -1021,7 +1040,7 @@ static void
do_findprocs(void)
{
clear(&found);
-
+
if (pidfile)
do_pidfile(pidfile);
else
@@ -1034,15 +1053,15 @@ do_stop(int signal_nr, int quietmode, int *n_killed, int *n_notkilled, int retry
{
struct pid_list *p;
- do_findprocs();
-
- *n_killed = 0;
- *n_notkilled = 0;
-
- if (!found)
- return;
-
- clear(&killed);
+ do_findprocs();
+
+ *n_killed = 0;
+ *n_notkilled = 0;
+
+ if (!found)
+ return;
+
+ clear(&killed);
for (p = found; p; p = p->next) {
if (testmode) {
@@ -1051,21 +1070,21 @@ do_stop(int signal_nr, int quietmode, int *n_killed, int *n_notkilled, int retry
(*n_killed)++;
} else if (kill(p->pid, signal_nr) == 0) {
push(&killed, p->pid);
- (*n_killed)++;
+ (*n_killed)++;
} else {
printf("%s: warning: failed to kill %d: %s\n",
progname, p->pid, strerror(errno));
- (*n_notkilled)++;
+ (*n_notkilled)++;
}
}
if (quietmode < 0 && killed) {
- printf("Stopped %s (pid", what_stop);
+ printf("Stopped %s (pid", what_stop);
for (p = killed; p; p = p->next)
printf(" %d", p->pid);
- putchar(')');
- if (retry_nr > 0)
- printf(", retry #%d", retry_nr);
- printf(".\n");
+ putchar(')');
+ if (retry_nr > 0)
+ printf(", retry #%d", retry_nr);
+ printf(".\n");
}
}
@@ -1181,7 +1200,7 @@ run_stop_schedule(void)
if (interval.tv_sec == 0 &&
interval.tv_usec <= MIN_POLL_INTERVAL)
- interval.tv_usec = MIN_POLL_INTERVAL;
+ interval.tv_usec = MIN_POLL_INTERVAL;
r = select(0,0,0,0,&interval);
if (r < 0 && errno != EINTR)
@@ -1215,7 +1234,6 @@ x_finished:
}
-int main(int argc, char **argv) NONRETURNING;
int
main(int argc, char **argv)
{
@@ -1295,7 +1313,7 @@ main(int argc, char **argv)
if (background) { /* ok, we need to detach this process */
int i;
if (quietmode < 0)
- printf("Detatching to start %s...", startas);
+ printf("Detaching to start %s...", startas);
i = fork();
if (i<0) {
fatal("Unable to fork.\n");
@@ -1333,11 +1351,11 @@ main(int argc, char **argv)
if (chroot(changeroot) < 0)
fatal("Unable to chroot() to %s", changeroot);
}
- if (changedir != NULL && chdir(changedir) < 0)
+ if (chdir(changedir) < 0)
fatal("Unable to chdir() to %s", changedir);
if (changeuser != NULL) {
- if (setgid(runas_gid))
- fatal("Unable to set gid to %d", runas_gid);
+ if (setgid(runas_gid))
+ fatal("Unable to set gid to %d", runas_gid);
if (initgroups(changeuser, runas_gid))
fatal("Unable to set initgroups() with gid %d", runas_gid);
if (setuid(runas_uid))
@@ -1372,4 +1390,3 @@ main(int argc, char **argv)
execv(startas, argv);
fatal("Unable to start %s: %s", startas, strerror(errno));
}
-