3 #Copyright (c) 2001 Matthias S. Benkmann
4 #licensed under the GNU General Public License (GPL) Version 2
6 runlevel_prefix
="runlevel."
12 telinit help displays this help text
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.
30 telinit <service> start
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
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
70 -*) initctl
-n "$@" ;; #if switch is specified, use normal need
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
86 for service
in $servicelist
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 ;;
103 #unlike get_inittab_entry in telinit, this function returns all words for an
104 #entry with more than one word after the "="
107 expr "`echo ; cat $INIT_ROOT/etc/inittab ; echo`" : $
'.*\n[ \r\t]*'${1}$
'[ \r\t]*=*[ \r\t]*''\('$
'[^\n]*''\).*'
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
!
123 if [ $# -lt 2 ]; then exit 1; fi
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" ];
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
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
147 if [ ! -e "$INIT_D/$target" ]; then
148 echo -n 1>&2 "No valid runlevel in parameter list: "
150 shift 1 #remove start
152 echo -n 1>&2 "No valid runlevel in bootprog parameter list: "
153 eval set -- $bootprog_entry
159 need
"$target" || exit_if_fatal_error
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
!
175 ########################################################
177 ########################################################
178 if [ $# == 1 -o "$2" == "help" -o "$2" == "--help" ]; then
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"
200 exec $scriptpath "$@"
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" ];
211 else target
=$runlevel_prefix$2$runlevel_suffix
214 if [ ! -e "$INIT_D/$target" ]; then
215 echo 1>&2 Illegal runlevel
: "$2"
221 if [ ! -d "$INIT_D/$1" ]; then return; fi
223 for f
in $INIT_D/$1/* ; do
225 make_dir_list
${f##*/}
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
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
245 need
-r "$rollback_target" || exit_if_fatal_error
246 need
"$target" || exit_if_fatal_error