#!/bin/ksh ##### if you don't have ksh, use bash ##### # # script to assist creating links in /etc/init.d # for usage, run with no arguments. # # note: generally means a 2-digit number ([0-9][0-9]) # # ari edelkind (03/07/2000) # last modified 03/08/2000) # $BASE_DIR/rc?.d are the startup directories # $INIT_DIR is the directory which contains all actual files BASE_DIR="/etc" INIT_DIR="/etc/init.d" # default link type: if $SYMBOLIC is 0, a hard link is used. DEF_SYMBOLIC=0 # default force setting: if $FORCE is 1, 'rm -f' will be executed # before linkage. DEF_FORCE=0 # default added runlevels for -k DEF_KRL=S01 # if $TESTING is 1, commands will be echoed instead of executed. TESTING=0 K_RUNLEVELS= S_RUNLEVELS= K_PRIO= S_PRIO= SYMBOLIC=$DEF_SYMBOLIC FORCE=$DEF_FORCE KRL=$DEF_KRL usage() { if [ "$DEF_SYMBOLIC" -eq 1 ]; then SLDEF="(default)" HLDEF="" else SLDEV="" HLDEF="(default)" fi if [ "$DEF_FORCE" -eq 1 ]; then YFDEF="(default)" NFDEF="" else YFDEF="" NFDEF="(default)" fi if [ ! -z "$*" ]; then echo "" echo "$*" fi echo "" echo "links init files from a file in $INIT_DIR" echo "" echo "usage: $0 [opts] <[-k] [-s] | [-p]> <-r> " echo "" echo " -k Add K to runlevels + $DEF_KRL" echo " -s Add S to runlevels" echo " -p Use priority , and auto-create S* and K*" echo " -r Runlevels to use, one level per digit (i.e. -r12)" echo " -S Use symbolic link $SLDEF" echo " -H Use hard link $HLDEF" echo " -f Remove link first $YFDEF" echo " -F Don't remove link first $NFDEF" echo " -B Use for base dir ($BASE_DIR)" echo " -I Use for init dir ($INIT_DIR)" echo " -KRL Use for added K runlevels ($DEF_KRL)" echo " -test testing only (nothing will be committed)" echo "" echo "example:" echo " $0 -k34 -s68 -r12 xinetd" echo "" exit 1 } docmd() { if [ "$TESTING" -eq 1 ]; then echo "CMD: $*" else $* fi } eh() { echo "FATAL: $*" exit 1 } wh() { echo "WARNING: $*" } for arg in $*; do case "$arg" in -k[0-9][0-9]) [ ! -z "$K_PRIO" ] && usage "$arg: -k ($K_PRIO) already given" K_PRIO=`echo $arg |sed 's/^-k//'` [ $K_PRIO -gt 00 ] || eh "$arg: priority must be greater than 0" ;; -s[0-9][0-9]) [ ! -z "$S_PRIO" ] && usage "$arg: -s ($S_PRIO) already given" S_PRIO=`echo $arg |sed 's/^-s//'` [ $S_PRIO -gt 00 ] || eh "$arg: priority must be greater than 0" ;; -p[0-9][0-9]) [ -z "$X_PRIO" ] || usage "$arg: -p ($X_PRIO) already given" [ -z "$S_PRIO" ] || usage "$arg: incompatible with -s" [ -z "$K_PRIO" ] || usage "$arg: incompatible with -k" X_PRIO=`echo $arg |sed 's/^-p//'` [ $X_PRIO -gt 00 ] || eh "$arg: priority must be greater than 0" S_PRIO=$X_PRIO K_PRIO=`expr 100 - $X_PRIO` ;; -r*) [ ! -z "$RUNLEVELS" ] && \ usage "$arg: -r ($RUNLEVELS) already given" RUNLEVELS=`echo $arg |sed 's/^-r//'` ;; -S) SYMBOLIC=1 ;; -H) SYMBOLIC=0 ;; -f) FORCE=1 ;; -F) FORCE=0 ;; -B*) BASE_DIR=`echo $arg |sed 's/^-B//'` ;; -I*) INIT_DIR=`echo $arg |sed 's/^-I//'` ;; -KRL*) KRL=`echo $arg |sed 's/^-KRL//'` ;; -test) TESTING=1 ;; *) [ ! -z "$FNAME" ] && \ usage "$arg: filename ($FNAME) already given" FNAME=$arg ;; esac done S_RUNLEVELS=$RUNLEVELS K_RUNLEVELS=$S_RUNLEVELS$KRL # separate runlevels S_RUNLEVELS="`echo $S_RUNLEVELS |sed 's/./& /g'`" K_RUNLEVELS="`echo $K_RUNLEVELS |sed 's/./& /g'`" # input sanity checks [ -z "$S_RUNLEVELS" ] && usage [ -z "$K_PRIO" -a -z "$S_PRIO" ] && usage [ -z "$FNAME" ] && usage IFNAME="$INIT_DIR/$FNAME" [ ! -f "$IFNAME" ] && eh "$IFNAME does not exist." [ ! -x "$IFNAME" ] && wh "$IFNAME is not executable." [ "$SYMBOLIC" -eq 1 ] && LNOPTS="-s" # i could consolidate the following two blocks into one function with lots # of 'eval's and shell escapes, but the resulting code, while slightly smaller, # would be evidently slower and harder to read. if [ ! -z "$S_PRIO" ]; then S_RLDONE= for level in $S_RUNLEVELS; do # don't do it more than once [ ! -z "`echo $S_RLDONE |grep $level`" ] && continue S_RLDONE="${S_RLDONE}$level" SKIPDIR=0 DIR="$BASE_DIR/rc$level.d" if [ ! -d "$DIR" ]; then wh "no such directory: $DIR (skipping)" SKIPDIR=1 elif [ ! -w "$DIR" ]; then wh "can't write to directory: $DIR (skipping)" SKIPDIR=1 fi # don't retry known problem dirs if [ "$SKIPDIR" -eq 1 ]; then S_RUNLEVELS=`echo $S_RUNLEVELS |sed s/$level//g` K_RUNLEVELS=`echo $K_RUNLEVELS |sed s/$level//g` continue fi docmd cd "$DIR" if [ $? -ne 0 ]; then wh "could not cd to $DIR" continue fi LINK="S${S_PRIO}$FNAME" [ "$FORCE" -eq 1 ] && docmd rm -f "$LINK" echo "linking $DIR/$LINK -> $IFNAME" #ln $LNOPTS "$IFNAME" "$LINK" || wh "could not link $DIR/$LINK -> $IFNAME" docmd ln $LNOPTS "$IFNAME" "$LINK" || continue done fi if [ ! -z "$K_PRIO" ]; then K_RLDONE= for level in $K_RUNLEVELS; do # don't do it more than oince [ ! -z "`echo $K_RLDONE |grep $level`" ] && continue K_RLDONE="${K_RLDONE}$level" SKIPDIR=0 DIR="$BASE_DIR/rc$level.d" if [ ! -d "$DIR" ]; then wh "no such directory: $DIR (skipping)" SKIPDIR=1 elif [ ! -w "$DIR" ]; then wh "can't write to directory: $DIR (skipping)" SKIPDIR=1 fi # don't retry known problem dirs if [ "$SKIPDIR" -eq 1 ]; then S_RUNLEVELS=`echo $S_RUNLEVELS |sed s/$level//g` K_RUNLEVELS=`echo $K_RUNLEVELS |sed s/$level//g` continue fi docmd cd "$DIR" if [ $? -ne 0 ]; then wh "could not cd to $DIR" continue fi LINK="K${K_PRIO}$FNAME" [ "$FORCE" -eq 1 ] && docmd rm -f "$LINK" echo "linking $DIR/$LINK -> $IFNAME" #ln $LNOPTS "$IFNAME" "$LINK" || wh "could not link $DIR/$LINK -> $IFNAME" docmd ln $LNOPTS "$IFNAME" "$LINK" || continue done fi