]> git.pld-linux.org Git - projects/rc-scripts.git/blob - rc.d/init.d/functions
- version 0.2.11
[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.63 2001/05/13 17:10:17 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 [ -f /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 nicelevel exit_code errors prog
232         typeset -i nicelevel=0
233         typeset -i exit_code=0
234         [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
235         # Test syntax. Don't use -o instead || here - this will broke ksh --misiek
236         while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
237                 case $1 in
238                 '')     msg_usage " daemon [--user user] [+/-nicelevel] {program}"
239                         return 1
240                         ;;
241                 --check)
242                         # for compatibility with redhat/mandrake
243                         nls "warning: --check option is ignored!"
244                         shift
245                         shift
246                         ;;
247                 --user)
248                         shift
249                         prog="/bin/su $1 -c"
250                         shift
251                         ;;
252                 -*|+*) SERVICE_RUN_NICE_LEVEL=$1
253                         shift;;
254                 esac
255         done
256         prog="$prog "$*""
257
258         # make sure it doesn't core dump anywhere; while this could mask
259         # problems with the daemon, it also closes some security problems
260         ulimit -c 0
261
262         # And start it up.
263         busy
264         if errors=$(HOME=/tmp TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} initlog -c "$prog" 2>&1); then
265                 log_success "$1 startup"
266                 ok
267         else
268                 exit_code=1
269                 fail
270                 log_failed "$1 startup"
271                 [ -n "$errors" ] && echo "$errors"
272         fi
273         return $exit_code
274 }
275
276 # A function to stop a program.
277 killproc() 
278 {
279         typeset notset killlevel base pid
280         # Test syntax.
281         if [ $# = 0 ]; then
282                 msg_usage " killproc {program} [signal]"
283                 return 1
284         fi
285
286         busy
287         
288         typeset -i notset=0
289         # check for second arg to be kill level
290         if [ -n "$2" ] ; then
291                 killlevel=$2
292         else
293                 notset=1
294                 killlevel="-9"
295         fi
296
297         # Save basename.
298         base=$(basename $1)
299
300         # Find pid.
301         pid=$(pidofproc $base)
302
303         # Kill it.
304         if [ -n "$pid" ] ; then
305                 if [ "$notset" = "1" ] ; then
306                         if ps h $pid>/dev/null 2>&1; then
307                                 # TERM first, then KILL if not dead
308                                 kill -TERM $pid >/dev/null 2>&1
309                                 usleep 100000
310                                 if ps h $pid >/dev/null 2>&1 ; then
311                                         sleep 1
312                                         if ps h $pid >/dev/null 2>&1 ; then
313                                                 sleep 3
314                                                 if ps h $pid >/dev/null 2>&1 ; then
315                                                         kill -KILL $pid >/dev/null 2>&1
316                                                 fi
317                                         fi
318                                 fi
319                                 if (ps h $pid >/dev/null 2>&1); then
320                                    fail
321                                    log_failed "$1 shutdown"
322                                 else
323                                    ok
324                                    log_success "$1 shutdown"
325                                 fi
326                         else
327                                 died
328                                 log_failed "$1 shutdown"
329                         fi
330                 # use specified level only
331                 else
332                         if ps h $pid >/dev/null 2>&1; then
333                                 if (kill $killlevel $pid); then
334                                    ok
335                                    log_success "$1 shutdown"
336                                 else
337                                    fail
338                                    log_failed "$1 shutdown"
339                                 fi
340                         else
341                                 died
342                                 log_failed "$1 shutdown"
343                         fi
344                 fi
345         else
346                 died
347                 log_failed "$1 shutdown"
348         fi
349
350         # Remove pid file if any.
351         if [ "$notset" = "1" ]; then
352                 rm -f /var/run/$base.pid
353         fi
354 }
355
356 # A function to find the pid of a program.
357 pidofproc() 
358 {
359         typeset pid
360         # Test syntax.
361         if [ $# = 0 ] ; then
362                 msg_usage " pidofproc {program}"
363                 return 1
364         fi
365
366         # First try "/var/run/*.pid" files
367         if [ -f /var/run/$1.pid ] ; then
368                 pid=$(head -1 /var/run/$1.pid)
369                 if [ -n "$pid" ] ; then
370                         echo $pid
371                         return 0
372                 fi
373         fi
374
375         # Next try "pidof"
376         pid=$(pidof -o $$ -o $PPID -o %PPID -x $1)
377         if [ -n "$pid" ] ; then
378                 echo $pid
379                 return 0
380         fi
381
382         # Finally try to extract it from ps
383         ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
384                            { if ((prog == $5) || (("(" prog ")") == $5) ||
385                              (("[" prog "]") == $5) ||
386                            ((prog ":") == $5)) { print $1 ; exit 0 } }' $1
387 }
388
389 status() 
390 {
391         # Test syntax.
392         if [ $# = 0 ] ; then
393                 msg_usage " status {subsys} [{daemon}]"
394                 return 1
395         fi
396
397         subsys=$1
398         daemon=${2:-$subsys}
399
400         # First try "pidof"
401         pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
402         if [ -n "$pid" ] ; then
403                 nls "%s (pid %s) is running..." "$daemon" "$pid"
404                 return 0
405         else
406                 pid=`ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
407                            { if ((prog == $5) || (("(" prog ")") == $5) ||
408                              (("[" prog "]") == $5) ||
409                            ((prog ":") == $5)) { print $1 ; exit 0 } }' $1`
410                 if [ "$pid" != "" ] ; then
411                         nls "%s (pid %s) is running..." "$daemon" "$pid"
412                         return 0
413                 fi
414         fi
415
416         # Next try "/var/run/*.pid" files
417         if [ -f /var/run/$daemon.pid ] ; then
418                 pid=$(head -1 /var/run/$1.pid)
419                 if [ -n "$pid" ] ; then
420                         nls "%s dead but pid file exists" "$1"
421                         return 1
422                 fi
423         fi
424         # See if /var/lock/subsys/$subsys exists
425         if [ -f /var/lock/subsys/$subsys ]; then
426                 nls "%s dead but subsys locked" "$daemon"
427                 return 2
428         fi
429         nls "%s is stopped" "$subsys"
430         return 3
431 }
432
433 # Confirm whether we really want to run this service
434 confirm() {
435         typeset answer
436         nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
437         read answer
438         case $answer in
439                 y|Y|t|T|j|J|"")
440                         return 0
441                 ;;
442                 c|C|k|K|w|W)
443                         return 2
444                 ;;
445                 n|N)
446                         return 1
447                 ;;
448                 *)
449                         confirm $1
450                         return $?
451                 ;;
452         esac
453 }
454
455 is_yes()
456 {
457         # Test syntax   
458         if [ $# = 0 ] ; then
459                 msg_usage " is_yes {value}"
460                 return 2
461         fi
462
463         # Check value
464         case "$1" in
465                 yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
466                         # true returns zero
467                         return 0
468                 ;;
469                 *)
470                         # false returns one
471                         return 1
472                 ;;
473         esac
474 }
475
476 is_no()
477 {
478         # Test syntax
479         if [ $# = 0 ] ; then
480                 msg_usage " is_no {value}"
481                 return 2
482         fi
483
484         # It's important that is_no() should always return logical
485         # negation of is_yes(). Really ALWAYS. --misiek
486         # NOTE: This means that passing value which mean neither "yes" nor
487         # "no" will return "true", beacause it does not mean "yes". Weird,
488         # isn't it? :) --mkochano
489         if is_yes "$1" ; then
490                 return 1
491         else
492                 return 0
493         fi
494 }
495
496 # module is needed (ie. is requested, is available and isn't loaded already)
497 is_module()
498 {
499         # module name without .o at end
500         if ! (lsmod | grep -q "$1"); then
501                 if (ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.o"); then
502                         # true
503                         return 0
504                 fi
505         fi
506         # false
507         return 1
508 }
509
510 _modprobe()
511 {
512         typeset parsed single die args foo result
513         parsed=no
514         while is_no "$parsed" ; do
515                 case "$1" in
516                         "single")
517                                 single=yes
518                                 shift
519                                 ;;
520                         "die")
521                                 die=yes
522                                 shift
523                                 ;;
524                         -*)
525                                 args="$args $1"
526                                 shift
527                                 ;;
528                         *)
529                                 parsed=yes
530                                 ;;
531                 esac
532         done
533         if is_yes "${single}" ; then
534                 foo="$@"
535                 show "Loading %s kernel module(s)" "$foo"
536                 busy
537         fi
538         if [ -x /sbin/modprobe ] ; then
539                 /sbin/modprobe -s $args "$@"
540                 result=$?
541         else
542                 deltext ; fail
543                 result=1
544         fi
545         if is_yes "${single}" ; then
546                 deltext
547                 if [ $result == "0" ] ; then
548                         is_yes "$single" && ok
549                 else
550                         fail
551                         if is_yes "$die" ; then
552                                 nls "Could not load %s kernel module(s)" "$@"
553                                 exit 1
554                         fi
555                 fi
556         fi
557 }
558
559 log_success ()
560 {
561         initlog -n $0 -s "$1 $2" -e 1
562 }
563
564 log_failed ()
565 {
566         initlog -n $0 -s "$1 $2" -e 2
567 }
568
569 # RedHat/Mandrake specific functions
570 action () { STRING=$1; shift; run_cmd "$STRING" "$*"; }
571 success () { return 0; }
572 failure () { return 1; }
573
574 # Will be removed in the future
575 msg_Network_Down () { msg_network_down "$*"; }
576 msg_Already_Running () { msg_already_running "$*"; }
577 msg_Not_Running () { msg_not_running "$*"; }
578 msg_Usage () { msg_usage "$*"; }
579
580 # This must be last line !
581 # vi:syntax=sh:tw=78:ts=8:sw=4
This page took 0.0712 seconds and 3 git commands to generate.