]> git.pld-linux.org Git - projects/rc-scripts.git/blob - rc.d/init.d/functions
315f7a2396896868d53c3df571404b9ee2e1986b
[projects/rc-scripts.git] / rc.d / init.d / functions
1 # functions     This file contains functions to be used by most or all
2 #               shell scripts in the /etc/init.d directory.
3 #
4 # $Id: functions,v 1.64 2001/05/15 16:03:38 baggins Exp $
5 #
6 # Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
7 # Hacked by:    Greg Galloway and Marc Ewing
8 # Modified for PLD by:
9 #               Marek Obuchowicz <elephant@pld.org.pl>
10 #               Arkadiusz Mi¶kiewicz <misiek@pld.org.pl> 
11 #               Micha³ Kochanowicz <mkochano@pld.org.pl>
12
13 # First set up a default search path.
14 export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"
15
16 # Set defaults
17 INIT_COL=67
18
19 # Source configuration if available - may override default values
20 [ -r /etc/sysconfig/system ] && . /etc/sysconfig/system
21
22 [ -z "$COLUMNS" ] && COLUMNS=80
23
24 # Colors workaround
25 termput() 
26 {
27         if [ ! -d /usr/share/terminfo ] || \
28              [ ! -x /usr/bin/tput -a ! -x /bin/tput ]; then
29                 case "$1" in
30                   hpa)
31                         echo -ne "\033[$(($2+1))G"
32                         ;;
33                   cuu*)
34                         echo -ne "\033[${2}A"
35                         ;;
36                   el)
37                         echo -ne "\033[0K"
38                         ;;
39                   setaf)
40                         is_yes "$COLOR_INIT" && echo -ne "\033[0;3${2}m"
41                         ;;
42                   op)
43                         termput setaf 9
44                         ;;
45                   esac
46         else
47                 tput "$@"
48         fi
49 }
50
51 # printf equivalent
52 printf_()
53 {
54         typeset text m
55         text="$1" ;
56         shift ;
57         if [ $# -gt 0 ]; then
58                 m="$1";
59                 shift;
60                 while [ $# -gt 0 ]; do
61                         m="$m\",\"$1" ;
62                         shift ;
63                 done
64         fi
65         awk "BEGIN {printf \"$text\", \"$m\"; }"
66 }
67                             
68 # National language support function
69 nls()
70 {
71         typeset msg_echo old_nls_domain text message
72         msg_echo='\n'
73         old_nls_domain="$NLS_DOMAIN"
74         # parse command line
75         # don't use -o instead || here - this will broke ksh --misiek
76         while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
77                 case "$1" in
78                         --nls-domain)
79                                 shift
80                                 NLS_DOMAIN="$1"
81                                 shift
82                                 ;;
83                         -n)
84                                 msg_echo=''
85                                 shift
86                                 ;;
87                 esac
88         done
89         message="$1"
90         shift
91         # empty message, so we return --misiek
92         if [ -z "$message" ]; then
93                 NLS_DOMAIN="$old_nls_domain"
94                 echo -en "$msg_echo"
95                 return
96         fi
97                         
98         if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
99                 text=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${NLS_DOMAIN:-rc-scripts}" "$message")
100                 printf_ "$text" "$@"
101         else
102                 printf_ "$message" "$@"
103         fi
104         
105         echo -en "$msg_echo"
106         NLS_DOMAIN="$old_nls_domain"
107 }
108
109 msg_network_down()
110 {
111         nls "ERROR: Networking is down. %s can't be run." "$1"
112 }
113
114 msg_starting()
115 {
116         show "Starting %s service" "$1"
117 }
118
119 msg_already_running()
120 {
121         nls "%s service is already running." "$1"
122 }
123
124 msg_stopping()
125 {
126         show "Stopping %s service" "$1"
127 }
128
129 msg_not_running()
130 {
131         nls "%s service is not running." "$1"
132 }
133
134 msg_reloading()
135 {
136         show "Reloading %s service" "$1"
137 }
138
139 msg_usage()
140 {
141         nls "Usage: %s" "$*"
142 }
143
144 # Some functions to handle PLD-style messages
145 show() 
146 {       
147         typeset text
148         text=$(nls "$@")
149         echo -n "$text"
150         awk "BEGIN { for (j=length(\"$text\"); j<$INIT_COL; j++) printf \".\" }"
151 }
152
153 # Displays message in square brackests ("[ DONE ]"). Takes two arguments.
154 # First is the text to display, second is color number to use (argument to
155 # tput setaf). If second argument is not given, default (2, green) will be
156 # used).
157 progress()
158 {
159         typeset COLOR
160         if [ -n "$2" ]; then COLOR="$2"; else COLOR="2"; fi
161         deltext
162         echo -n "$(termput setaf 6)[$(termput setaf "$COLOR") $(nls --nls-domain rc-scripts "$1") $(termput setaf 6)]$(termput op)"
163 }
164
165 busy() 
166 {
167         progress "BUSY" 5
168 }
169
170 ok() 
171 {
172         progress "DONE"
173         echo
174 }
175
176 started()
177 {
178         progress "WORK"
179         echo
180 }
181
182 fail() 
183 {
184         progress "FAIL" 1
185         echo
186         return 1
187 }
188
189 died() 
190 {
191         progress "DIED" 1
192         echo
193         return 1
194 }
195
196 deltext() 
197 {
198         termput hpa $INIT_COL
199 }
200
201 # Usage run_cmd Message command_to_run
202 run_cmd()
203 {
204         typeset exit_code errors message force_err
205         typeset -i force_err=0
206         typeset -i exit_code=0
207         case "$1" in
208                 -a)
209                         force_err=1
210                         shift
211                         ;;
212         esac
213         message=$1
214         show "$message"; busy
215         shift
216         if errors=$(HOME=/tmp TMPDIR=/tmp initlog -c "$*" 2>&1); then
217                 ok
218                 log_success "$1 $message"
219         else
220                 fail
221                 log_failed "$1 $message"
222                 exit_code=1
223         fi
224         [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors"
225         return $exit_code
226 }
227
228 # A function to start a program (now it's usefull on read-only filesystem too)
229 daemon() 
230 {
231         typeset errors="" prog=""
232         typeset -i exit_code=0
233         [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
234         # Test syntax. Don't use -o instead || here - this will broke ksh --misiek
235         while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
236                 case $1 in
237                 '')     msg_usage " daemon [--user user] [+/-nicelevel] {program}"
238                         return 1
239                         ;;
240                 --check)
241                         # for compatibility with redhat/mandrake
242                         nls "warning: --check option is ignored!"
243                         shift
244                         shift
245                         ;;
246                 --user)
247                         shift
248                         prog="/bin/su $1 -c"
249                         shift
250                         ;;
251                 -*|+*) SERVICE_RUN_NICE_LEVEL=$1
252                         shift;;
253                 esac
254         done
255         prog="$prog "$*""
256
257         # make sure it doesn't core dump anywhere; while this could mask
258         # problems with the daemon, it also closes some security problems
259         ulimit -c 0
260
261         # And start it up.
262         busy
263         if errors=$(HOME=/tmp TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} initlog -c "$prog" 2>&1); then
264                 log_success "$1 startup"
265                 ok
266         else
267                 exit_code=1
268                 fail
269                 log_failed "$1 startup"
270                 [ -n "$errors" ] && echo "$errors"
271         fi
272         return $exit_code
273 }
274
275 # A function to stop a program.
276 killproc() 
277 {
278         typeset notset killlevel base pid
279         # Test syntax.
280         if [ $# = 0 ]; then
281                 msg_usage " killproc {program} [signal]"
282                 return 1
283         fi
284
285         busy
286         
287         typeset -i notset=0
288         # check for second arg to be kill level
289         if [ -n "$2" ] ; then
290                 killlevel=$2
291         else
292                 notset=1
293                 killlevel="-9"
294         fi
295
296         # Save basename.
297         base=$(basename $1)
298
299         # Find pid.
300         pid=$(pidofproc $base)
301
302         # Kill it.
303         if [ -n "$pid" ] ; then
304                 if [ "$notset" = "1" ] ; then
305                         if ps h $pid>/dev/null 2>&1; then
306                                 # TERM first, then KILL if not dead
307                                 kill -TERM $pid >/dev/null 2>&1
308                                 usleep 100000
309                                 if ps h $pid >/dev/null 2>&1 ; then
310                                         sleep 1
311                                         if ps h $pid >/dev/null 2>&1 ; then
312                                                 sleep 3
313                                                 if ps h $pid >/dev/null 2>&1 ; then
314                                                         kill -KILL $pid >/dev/null 2>&1
315                                                 fi
316                                         fi
317                                 fi
318                                 if (ps h $pid >/dev/null 2>&1); then
319                                    fail
320                                    log_failed "$1 shutdown"
321                                 else
322                                    ok
323                                    log_success "$1 shutdown"
324                                 fi
325                         else
326                                 died
327                                 log_failed "$1 shutdown"
328                         fi
329                 # use specified level only
330                 else
331                         if ps h $pid >/dev/null 2>&1; then
332                                 if (kill $killlevel $pid); then
333                                    ok
334                                    log_success "$1 shutdown"
335                                 else
336                                    fail
337                                    log_failed "$1 shutdown"
338                                 fi
339                         else
340                                 died
341                                 log_failed "$1 shutdown"
342                         fi
343                 fi
344         else
345                 died
346                 log_failed "$1 shutdown"
347         fi
348
349         # Remove pid file if any.
350         if [ "$notset" = "1" ]; then
351                 rm -f /var/run/$base.pid
352         fi
353 }
354
355 # A function to find the pid of a program.
356 pidofproc() 
357 {
358         typeset pid
359         # Test syntax.
360         if [ $# = 0 ] ; then
361                 msg_usage " pidofproc {program}"
362                 return 1
363         fi
364
365         # First try "/var/run/*.pid" files
366         if [ -f /var/run/$1.pid ] ; then
367                 pid=$(head -1 /var/run/$1.pid)
368                 if [ -n "$pid" ] ; then
369                         echo $pid
370                         return 0
371                 fi
372         fi
373
374         # Next try "pidof"
375         pid=$(pidof -o $$ -o $PPID -o %PPID -x $1)
376         if [ -n "$pid" ] ; then
377                 echo $pid
378                 return 0
379         fi
380
381         # Finally try to extract it from ps
382         ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
383                            { if ((prog == $5) || (("(" prog ")") == $5) ||
384                              (("[" prog "]") == $5) ||
385                            ((prog ":") == $5)) { print $1 ; exit 0 } }' $1
386 }
387
388 status() 
389 {
390         # Test syntax.
391         if [ $# = 0 ] ; then
392                 msg_usage " status {subsys} [{daemon}]"
393                 return 1
394         fi
395
396         subsys=$1
397         daemon=${2:-$subsys}
398
399         # First try "pidof"
400         pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
401         if [ -n "$pid" ] ; then
402                 nls "%s (pid %s) is running..." "$daemon" "$pid"
403                 return 0
404         else
405                 pid=`ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
406                            { if ((prog == $5) || (("(" prog ")") == $5) ||
407                              (("[" prog "]") == $5) ||
408                            ((prog ":") == $5)) { print $1 ; exit 0 } }' $1`
409                 if [ "$pid" != "" ] ; then
410                         nls "%s (pid %s) is running..." "$daemon" "$pid"
411                         return 0
412                 fi
413         fi
414
415         # Next try "/var/run/*.pid" files
416         if [ -f /var/run/$daemon.pid ] ; then
417                 pid=$(head -1 /var/run/$1.pid)
418                 if [ -n "$pid" ] ; then
419                         nls "%s dead but pid file exists" "$1"
420                         return 1
421                 fi
422         fi
423         # See if /var/lock/subsys/$subsys exists
424         if [ -f /var/lock/subsys/$subsys ]; then
425                 nls "%s dead but subsys locked" "$daemon"
426                 return 2
427         fi
428         nls "%s is stopped" "$subsys"
429         return 3
430 }
431
432 # Confirm whether we really want to run this service
433 confirm() {
434         typeset answer
435         nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
436         read answer
437         case $answer in
438                 y|Y|t|T|j|J|"")
439                         return 0
440                 ;;
441                 c|C|k|K|w|W)
442                         return 2
443                 ;;
444                 n|N)
445                         return 1
446                 ;;
447                 *)
448                         confirm $1
449                         return $?
450                 ;;
451         esac
452 }
453
454 is_yes()
455 {
456         # Test syntax   
457         if [ $# = 0 ] ; then
458                 msg_usage " is_yes {value}"
459                 return 2
460         fi
461
462         # Check value
463         case "$1" in
464                 yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
465                         # true returns zero
466                         return 0
467                 ;;
468                 *)
469                         # false returns one
470                         return 1
471                 ;;
472         esac
473 }
474
475 is_no()
476 {
477         # Test syntax
478         if [ $# = 0 ] ; then
479                 msg_usage " is_no {value}"
480                 return 2
481         fi
482
483         # It's important that is_no() should always return logical
484         # negation of is_yes(). Really ALWAYS. --misiek
485         # NOTE: This means that passing value which mean neither "yes" nor
486         # "no" will return "true", beacause it does not mean "yes". Weird,
487         # isn't it? :) --mkochano
488         if is_yes "$1" ; then
489                 return 1
490         else
491                 return 0
492         fi
493 }
494
495 # module is needed (ie. is requested, is available and isn't loaded already)
496 is_module()
497 {
498         # module name without .o at end
499         if ! (lsmod | grep -q "$1"); then
500                 if (ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.o"); then
501                         # true
502                         return 0
503                 fi
504         fi
505         # false
506         return 1
507 }
508
509 _modprobe()
510 {
511         typeset parsed single die args foo result
512         parsed=no
513         while is_no "$parsed" ; do
514                 case "$1" in
515                         "single")
516                                 single=yes
517                                 shift
518                                 ;;
519                         "die")
520                                 die=yes
521                                 shift
522                                 ;;
523                         -*)
524                                 args="$args $1"
525                                 shift
526                                 ;;
527                         *)
528                                 parsed=yes
529                                 ;;
530                 esac
531         done
532         if is_yes "${single}" ; then
533                 foo="$@"
534                 show "Loading %s kernel module(s)" "$foo"
535                 busy
536         fi
537         if [ -x /sbin/modprobe ] ; then
538                 /sbin/modprobe -s $args "$@"
539                 result=$?
540         else
541                 deltext ; fail
542                 result=1
543         fi
544         if is_yes "${single}" ; then
545                 deltext
546                 if [ $result == "0" ] ; then
547                         is_yes "$single" && ok
548                 else
549                         fail
550                         if is_yes "$die" ; then
551                                 nls "Could not load %s kernel module(s)" "$@"
552                                 exit 1
553                         fi
554                 fi
555         fi
556 }
557
558 log_success ()
559 {
560         initlog -n $0 -s "$1 $2" -e 1
561 }
562
563 log_failed ()
564 {
565         initlog -n $0 -s "$1 $2" -e 2
566 }
567
568 # RedHat/Mandrake specific functions
569 action () { STRING=$1; shift; run_cmd "$STRING" "$*"; }
570 success () { return 0; }
571 failure () { return 1; }
572
573 # TO BE REMOVED SOON. --misiek
574 msg_Network_Down () { msg_network_down "$*"; }
575 msg_Already_Running () { msg_already_running "$*"; }
576 msg_Not_Running () { msg_not_running "$*"; }
577 msg_Usage () { msg_usage "$*"; }
578
579 # This must be last line !
580 # vi:syntax=sh:tw=78:ts=8:sw=4
This page took 0.09159 seconds and 3 git commands to generate.