* Merged newxml into HEAD
[linux_from_scratch.git] / bootscripts / contrib / new-boot-0.2 / sbin / init.d / rc
blobbded375bc2dd3d036cd6704ae799af0bd2f2754d
1 #!/bin/sh
3 #Copyright (c) 2001 Matthias S. Benkmann
4 #licensed under the GNU General Public License (GPL) Version 2
6 runlevel_prefix="runlevel."
7 runlevel_suffix=""
9 HELP_TEXT='
10 telinit invocations:
12 telinit help displays this help text
14 telinit <num>
15 or
16 telinit '"${runlevel_prefix}<num>${runlevel_suffix}"\
17 ' will go up or down to runlevel <num>
19 telinit single will bring the system to maintenance mode
21 telinit <service> <params>
22 will call <service> with arguments <params>,
23 e.g. telinit logging status
24 You should prefer this method over calling boot
25 scripts directly because telinit makes sure the
26 environment is set up similar to that created by init
27 when it starts boot scripts.
29 NOTE: If you call
30 telinit <service> start
31 or
32 telinit <service> stop
33 you will bypass the dependency management system,
34 i.e. the script will be started or stopped
35 without init knowing about it.
36 Read initctl(8) to understand all the
37 implications of this.
42 #locate and source functions script
43 source `PATH=$INIT_D/:${0%/*}/:${0%/*/*}/:${0%/*/*/*}/ type -p functions`
45 #block SIGHUP in case the script is called over a modem line that disconnects
46 # (or someone closes his xterm after calling the script, or ...)
47 #block SIGINT to prevent nervous users from Ctrl-C'ing us
48 #block SIGQUIT to prevent users from Ctrl-\'ing us.
49 #block SIGTSTP to prevent users from Ctrl-Z'ing us.
50 #We use ":" rather than "" because the latter would be inherited by processes
51 # such as fsck that we start (SIG_IGN is inherited) while the former is not.
52 # This means that with ":" the scripts called by rc can be interrupted. It's
53 # just the rc script that you can't interrupt. Usually a user would only want
54 # to interrupt a certain script but if he presses the keys at the wrong time,
55 # he might hit rc by accident.
56 trap ":" SIGHUP SIGINT SIGQUIT SIGTSTP
59 remove_trailing_slash()
61 i=${1%/} #cut off trailing slash
62 i=${i:-/} #if string is now empty put it back
63 echo $i
66 needdir()
68 case "z$1" in
69 z) return 0 ;;
70 -*) initctl -n "$@" ;; #if switch is specified, use normal need
71 esac
73 dir=$1
74 dir=${1##[^/]*} #dir="" if $1 is not an absolute path, else dir=$1
75 dir=${dir:-$INIT_D/$1} #if dir="" (i.e. $1 not abs.) then dir=$INIT_D/$1
76 dir=`remove_trailing_slash $dir`
77 #dir is a non-empty absolute path without a trailing slash now.
79 #test if $dir is a directory, if not try using normal need on input
80 test -d $dir || { initctl -n "$@"; return $? ; }
82 servicelist=`echo $dir/*` #list of all services in $dir
83 if [ "$servicelist" = $dir'/*' ]; then return 0; fi #if list is empty then return
85 errcode=0
86 for service in $servicelist
88 case $service in
89 *~) ;; #do not run backup files
91 #strip pathname (see comment at top) and +
92 #return immediately if error because + services are essential
93 */+*) initctl -n ${service##*/+} || return 1 ;;
95 #strip pathname (see comment at top)
96 *) initctl -n ${service##*/} || errcode=2 ;;
97 esac
98 done
100 return $errcode
103 #unlike get_inittab_entry in telinit, this function returns all words for an
104 #entry with more than one word after the "="
105 get_inittab_entry2()
107 expr "`echo ; cat $INIT_ROOT/etc/inittab ; echo`" : $'.*\n[ \r\t]*'${1}$'[ \r\t]*=*[ \r\t]*''\('$'[^\n]*''\).*'
110 case "$1" in
111 start-dir)
112 if [ $# -lt 2 ]; then exit 1; fi
114 needdir $2 || exit_if_fatal_error
116 rl=${2##*$runlevel_prefix}
117 rl=${rl%$runlevel_suffix}
118 echo -n Runlevel $rl reached!
119 print_status success
122 start)
123 if [ $# -lt 2 ]; then exit 1; fi
125 parameters="$@"
127 for (( i=0; $i<2 ; i=$i+1 )); do
128 while [ $# -ge 2 ]; do
129 #target could be a script (e.g. "single") rather than a runlevel num
130 if [ -e "$INIT_D/$2" ];
131 then target=$2
132 else target=$runlevel_prefix$2$runlevel_suffix
135 if [ -e "$INIT_D/$target" ]; then break 2; fi
137 #if $target not found, try the next parameter
138 shift 1;
139 done
141 #we didn't find a valid runlevel in the parameter list, so we try
142 #the default setting from inittab
143 bootprog_entry="`get_inittab_entry2 bootprog`"
144 eval set -- $bootprog_entry
145 done
147 if [ ! -e "$INIT_D/$target" ]; then
148 echo -n 1>&2 "No valid runlevel in parameter list: "
149 set -- $parameters
150 shift 1 #remove start
151 echo 1>&2 "$@"
152 echo -n 1>&2 "No valid runlevel in bootprog parameter list: "
153 eval set -- $bootprog_entry
154 shift 1 #remove rc
155 echo 1>&2 "$@"
156 exit 1
159 need "$target" || exit_if_fatal_error
162 stop-dir)
163 if [ $# -lt 2 ]; then exit 1; fi
165 rl=${2##*$runlevel_prefix}
166 rl=${rl%$runlevel_suffix}
167 echo -n Runlevel $rl going down!
168 print_status success
171 stop)
174 telinit)
175 ########################################################
176 # telinit help
177 ########################################################
178 if [ $# == 1 -o "$2" == "help" -o "$2" == "--help" ]; then
179 echo "$HELP_TEXT"
180 exit 0
183 ########################################################
184 # telinit <service> <params>
185 ########################################################
186 if [ $# -gt 2 ]; then
187 script=`cd $INIT_D ; PATH=$INIT_PATH type -ap $2`
189 #set scriptpath="" if script is not abs. path
190 scriptpath=${script##[^/]*}
192 #set scriptpath=$INIT_D/$script if script not abs. path
193 scriptpath=${scriptpath:-$INIT_D/$script}
195 if [ ! -x "$scriptpath" -o ! -f "$scriptpath" ]; then
196 echo 1>&2 "Cannot execute $scriptpath"
197 exit 1
199 shift 2
200 exec $scriptpath "$@"
201 exit $?
204 ########################################################
205 # telinit <runlevel_name>|<num>
206 ########################################################
208 #target could be a script (e.g. "single") rather than a runlevel num
209 if [ -e "$INIT_D/$2" ];
210 then target=$2
211 else target=$runlevel_prefix$2$runlevel_suffix
214 if [ ! -e "$INIT_D/$target" ]; then
215 echo 1>&2 Illegal runlevel: "$2"
216 exit 1
219 make_dir_list()
221 if [ ! -d "$INIT_D/$1" ]; then return; fi
222 echo $1
223 for f in $INIT_D/$1/* ; do
224 f=${f##*/+}
225 make_dir_list ${f##*/}
226 done
229 #list of all directories needed by the target
230 dirlist=$target" "`make_dir_list $target`
232 cur_services=`initctl -d 2>/dev/null`
233 cur_services=`expr "$cur_services" : '.*AVAILABLE SERVICES:\(.*\)STARTING SERVICES:.*'`
235 #find the highest service in the stack of available services that is
236 #one of the needed directories; everything above this service is not
237 #part of the target runlevel
238 rollback_target=""
239 for s1 in $cur_services EnD_ofLiSt__; do
240 for s2 in $dirlist; do
241 if [ $s1 == $s2 ]; then rollback_target=$s1; break 2; fi
242 done
243 done
245 need -r "$rollback_target" || exit_if_fatal_error
246 need "$target" || exit_if_fatal_error
249 exit 1
251 esac
253 exit 0