summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/rc-update')
-rwxr-xr-xsbin/rc-update191
1 files changed, 131 insertions, 60 deletions
diff --git a/sbin/rc-update b/sbin/rc-update
index 3f9a980..a1864a9 100755
--- a/sbin/rc-update
+++ b/sbin/rc-update
@@ -3,69 +3,80 @@
# Distributed under the terms of the GNU General Public License v2
source /sbin/functions.sh
+esyslog() { :; }
+
+argv0=${0##*/}
usage() {
cat << FOO
-usage: rc-update -a|add script runlevel2 [runlevel2 ...]
- rc-update -d|del script [runlevel1 ...]
- rc-update -s|show [runlevel1 ...]
+usage: ${argv0} -a|add script runlevel1 [runlevel2 ...]
+ ${argv0} -d|del script [runlevel1 ...]
+ ${argv0} -s|show [runlevel1 ...]
examples:
- # rc-update add net.eth0 default
+ # ${argv0} add net.eth0 default
Adds the net.eth0 script (in /etc/init.d) to the "default" runlevel.
- # rc-update del sysklogd
+ # ${argv0} del sysklogd
Deletes the sysklogd script from all runlevels. The original script
is not deleted, just any symlinks to the script in /etc/runlevels/*.
- # rc-update del net.eth2 default wumpus
+ # ${argv0} del net.eth2 default wumpus
Delete the net.eth2 script from the default and wumpus runlevels.
All other runlevels are unaffected. Again, the net.eth2 script
residing in /etc/init.d is not deleted, just any symlinks in
/etc/runlevels/default and /etc/runlevels/wumpus.
- # rc-update show
+ # ${argv0} show
Show all the available scripts and list at which runlevels they
will execute.
FOO
- exit 1
+ exit ${1:-0}
}
add() {
+ local ret=0
local x=
local myscript=
- if [[ $# -lt 3 ]] ; then
- eerror "$0: at least two arguments expected after \"$1\"."
+ if [[ $# -lt 2 ]] ; then
+ eerror "Usage: ${argv0} add <script> runlevel1 [runlevel2 ...]" 1>&2
exit 1
fi
- shift
- myscript="$1"
+
+ [[ ${quiet} -gt 0 ]] && exec 2> /dev/null
+
+ myscript=$1
if [[ ! -e ${ROOT}/etc/init.d/${myscript} ]] ; then
- eerror "$0: '${ROOT}/etc/init.d/${myscript}' not found; aborting."
+ eerror "${argv0}: '${ROOT}etc/init.d/${myscript}' not found; aborting" 1>&2
exit 1
fi
shift
for x in $* ; do
- if [[ ! -e ${ROOT}/etc/runlevels/${x} ]] ; then
- ewarn "runlevel ${x} not found; skipping"
+ if [[ ! -e ${ROOT}etc/runlevels/${x} ]] ; then
+ ewarn "runlevel '${x}' not found; skipping" 1>&2
+ ((++ret))
continue
fi
- if [[ -L ${ROOT}/etc/runlevels/${x}/${myscript} ]] ; then
- ewarn "${myscript} already installed in runlevel ${x}; skipping"
+ if [[ -L ${ROOT}etc/runlevels/${x}/${myscript} ]] ; then
+ ewarn "${myscript} already installed in runlevel '${x}'; skipping" 1>&2
continue
fi
- if [[ ! -x ${ROOT}/etc/init.d/${myscript} ]] ; then
- ewarn "${myscript} not executable; skipping"
+ if [[ ! -x ${ROOT}etc/init.d/${myscript} ]] ; then
+ ewarn "${myscript} not executable; skipping" 1>&2
+ ((++ret))
continue
fi
- ln -snf "/etc/init.d/${myscript}" "${ROOT}/etc/runlevels/${x}/${myscript}"
+ ln -snf "/etc/init.d/${myscript}" "${ROOT}etc/runlevels/${x}/${myscript}"
if [[ $? -ne 0 ]] ; then
- eerror "$0: failed to add ${myscript} to ${x}."
- exit 1
+ eerror "${argv0}: failed to add '${myscript}' to '${x}'" 1>&2
+ ((++ret))
+ continue
fi
einfo "${myscript} added to runlevel ${x}"
done
+
+ return ${ret}
}
del() {
@@ -74,30 +85,39 @@ del() {
local myscript=
local remlevels=
- if [[ $# -lt 2 ]] ; then
- eerror "$0: at least one argument expected after \"$1\"."
+ if [[ $# -lt 1 ]] ; then
+ eerror "Usage: ${argv0} del <script> [runlevel1 ...]" 1>&2
exit 1
fi
- shift
+
+ [[ ${quiet} -gt 0 ]] && exec 2> /dev/null
+
myscript=$1
shift
if [[ $# -eq 0 ]] ; then
- mylevels=$(cd "${ROOT}"/etc/runlevels/; ls)
+ mylevels=$(cd "${ROOT}"etc/runlevels/; ls)
else
mylevels="$*"
fi
remlevels=""
for x in ${mylevels} ; do
- if [[ -L ${ROOT}/etc/runlevels/${x}/${myscript} ]] ; then
- rm -f "${ROOT}/etc/runlevels/${x}/${myscript}"
- remlevels="${remlevels} ${x}"
+ # -e will return false for broken symlinks so we need the extra -L
+ [[ ! -L ${ROOT}etc/runlevels/${x}/${myscript} ]] && \
+ [[ ! -e ${ROOT}etc/runlevels/${x}/${myscript} ]] && continue
+
+ remlevels="${remlevels} ${x}"
+ if [[ ! -L ${ROOT}etc/runlevels/${x}/${myscript} ]] ; then
+ ewarn "Removing invalid init.d script: '${ROOT}etc/runlevels/${x}/${myscript}'" 1>&2
fi
+ rm -f "${ROOT}etc/runlevels/${x}/${myscript}"
+ ((ret+=$?))
done
if [[ -z ${remlevels} ]] ; then
- einfo "${myscript} not found in any of the specified runlevels."
- else
- einfo "${myscript} removed from the following runlevels:${remlevels}"
+ ewarn "'${myscript}' not found in any of the specified runlevels" 1>&2
+ elif [[ ${quiet} -eq 0 ]] ; then
+ einfo "'${myscript}' removed from the following runlevels:${remlevels}"
fi
+ return ${ret}
}
show() {
@@ -106,62 +126,113 @@ show() {
local mylevels=
local myscripts=
- shift
+ shopt -s nullglob
if [[ $# -eq 0 ]] ; then
- mylevels=$(cd "${ROOT}"/etc/runlevels/; ls)
+ mylevels=$(cd "${ROOT}"etc/runlevels/; ls)
else
mylevels="$*"
+ # verify runlevels provided by user
+ for y in ${mylevels} ; do
+ [[ ! -d ${ROOT}etc/runlevels/${y} ]] && ewarn "Runlevel doesn't exist: ${y}"
+ done
fi
- myscripts=$(cd "${ROOT}"/etc/init.d; ls)
+ myscripts=$(cd "${ROOT}"etc/init.d; ls)
+
+ # Sanity check to make sure everything is kosher ...
+ for x in $(find "${ROOT}"etc/runlevels -xtype l) ; do
+ ewarn "Broken runlevel entry: ${x}"
+ done
+ for x in $(find "${ROOT}"etc/runlevels ! -type l -a ! -type d) ; do
+ ewarn "Invalid runlevel entry: ${x}"
+ done
for x in ${myscripts} ; do
- if [[ ${x%%.sh} = "${x}" ]] ; then
- printf "%20s | " ${x:0:19}
+ # skip *.sh scripts as they are helpers, not init.d scripts
+ [[ ${x} == *.sh ]] && continue
+
+ # unless we are running in verbose mode, don't display scripts
+ # that aren't in any runlevels that we are examining
+ if [[ ${verbose} -eq 0 ]] ; then
+ local found_it=0
for y in ${mylevels} ; do
- if [[ -L ${ROOT}/etc/runlevels/${y}/${x} ]] ; then
- echo -n "${y} "
- else
- printf "%${#y}s " " "
+ if [[ -L ${ROOT}etc/runlevels/${y}/${x} ]] ; then
+ found_it=1
+ break
fi
done
- echo ""
+ [[ ${found_it} -eq 0 ]] && continue
fi
+
+ # ok, let's show this script already !
+ printf "%20s | " ${x:0:19}
+ for y in ${mylevels} ; do
+ if [[ -L ${ROOT}etc/runlevels/${y}/${x} ]] ; then
+ echo -n "${y} "
+ else
+ printf "%${#y}s " " "
+ fi
+ done
+ echo ""
done
}
check_is_root() {
if [[ ${EUID} -ne 0 ]] ; then
- eerror "$0: must be root."
+ eerror "${argv0}: must be root to complete this operation" 1>&2
exit 1
fi
}
-if [[ $# -lt 1 ]] ; then
- usage
- exit 1
-fi
+export ROOT=${ROOT%/}/
+[[ ${ROOT} != "/" ]] && einfo "Working with files in root ${ROOT} ..."
-if [[ -n ${ROOT} ]] ; then
- [[ ${ROOT:0-1} == "/" ]] && export ROOT=${ROOT:0:${#ROOT}-1}
- einfo "Working with files in root ${ROOT} ..."
-fi
+verbose=0
+quiet=0
+action=""
+opts=""
+check_root=0
+
+[[ ${RC_VERBOSE} == "yes" ]] && ((++verbose))
-case "$1" in
+while [[ -n $* ]] ; do
+ case "$1" in
add|-a)
- check_is_root
- add "$@"
+ check_root=1
+ action="add"
;;
del|delete|-d)
- check_is_root
- del "$@"
+ check_root=1
+ action="del"
;;
show|-s)
- show "$@"
+ action="show"
+ ;;
+ help|-h|--help)
+ usage 0
+ ;;
+ verbose|-v|--verbose)
+ ((++verbose))
+ ;;
+ quiet|-q|--quiet)
+ ((++quiet))
+ ;;
+ -*)
+ echo -e "${argv0}: Unknown option $1\n" 1>&2
+ usage 1
;;
*)
- usage
- exit 1
+ opts="${opts} $1"
;;
-esac
+ esac
+ shift
+done
+
+if [[ -z ${action} ]] ; then
+ eerror "${argv0}: gimme something to do!" 1>&2
+ exit 1
+fi
+
+[[ ${check_root} -eq 1 ]] && check_is_root
+${action} ${opts}
# vim:ts=4