diff options
-rw-r--r-- | ChangeLog | 186 | ||||
-rw-r--r-- | etc/conf.d/domainname | 21 | ||||
-rw-r--r-- | etc/conf.d/env_whitelist | 11 | ||||
-rw-r--r-- | etc/group | 7 | ||||
-rw-r--r-- | etc/passwd | 7 | ||||
-rwxr-xr-x | sbin/depscan.sh | 4 | ||||
-rwxr-xr-x | sbin/env-update.sh | 11 | ||||
-rwxr-xr-x | sbin/functions.sh | 151 | ||||
-rwxr-xr-x | sbin/init-common-post.sh | 58 | ||||
-rwxr-xr-x | sbin/init-common-pre.sh | 7 | ||||
-rwxr-xr-x | sbin/init-functions.sh | 57 | ||||
-rwxr-xr-x | sbin/init.linux.sh | 43 | ||||
-rwxr-xr-x | sbin/rc | 189 | ||||
-rwxr-xr-x | sbin/rc-daemon.sh | 13 | ||||
-rwxr-xr-x | sbin/rc-help.sh | 116 | ||||
-rwxr-xr-x | sbin/rc-services.sh | 164 | ||||
-rwxr-xr-x | sbin/runscript.sh | 32 | ||||
-rw-r--r-- | src/awk/genenviron.awk | 9 | ||||
-rw-r--r-- | src/core/ChangeLog | 71 | ||||
-rw-r--r-- | src/core/Makefile | 4 | ||||
-rw-r--r-- | src/core/TODO | 11 | ||||
-rw-r--r-- | src/core/debug.h | 6 | ||||
-rw-r--r-- | src/core/depend.c | 107 | ||||
-rw-r--r-- | src/core/misc.c | 98 | ||||
-rw-r--r-- | src/core/misc.h | 68 | ||||
-rw-r--r-- | src/core/parse.c | 600 | ||||
-rw-r--r-- | src/core/parse.h | 1 | ||||
-rw-r--r-- | src/core/simple-regex.c | 151 | ||||
-rw-r--r-- | src/core/simple-regex.h | 8 | ||||
-rw-r--r-- | src/env_whitelist | 1 | ||||
-rw-r--r-- | src/runscript.c | 3 | ||||
-rw-r--r-- | src/start-stop-daemon.c | 323 |
32 files changed, 1416 insertions, 1122 deletions
@@ -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 @@ -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: @@ -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 @@ -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)); } - |