]> git.pld-linux.org Git - projects/rc-scripts.git/blob - rc.d/init.d/functions
Revert few pzurowski changes since they are broken even after fixing syntax.
[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$
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-linux.org>
10 #               Arkadiusz Mi¶kiewicz <misiek@pld-linux.org>
11 #               Micha³ Kochanowicz <mkochano@pld-linux.org>
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 is_yes()
25 {
26         # Test syntax
27         if [ $# = 0 ] ; then
28                 msg_usage " is_yes {value}"
29                 return 2
30         fi
31
32         # Check value
33         case "$1" in
34           yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
35                 # true returns zero
36                 return 0
37                 ;;
38           *)
39                 # false returns one
40                 return 1
41                 ;;
42         esac
43 }
44
45 is_no()
46 {
47         # Test syntax
48         if [ $# = 0 ] ; then
49                 msg_usage " is_no {value}"
50                 return 2
51         fi
52
53         case "$1" in
54           no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
55                 # true returns zero
56                 return 0
57                 ;;
58           *)
59                 # false returns one
60                 return 1
61                 ;;
62         esac
63 }
64
65 if is_yes "$FASTRC"; then
66         INIT_DOTS=$(awk "BEGIN{for(\$i=0;\$i<$INIT_COL;\$i++)printf(\".\");}")
67         initlog()
68         {
69                 RESULT=0
70                 while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
71                         case $1 in
72                                 -c)
73                                         shift
74                                         $1
75                                         RESULT=$?
76                                         break
77                                         ;;
78                                  *)
79                                         shift
80                                         ;;
81                         esac
82                 done
83                 return $RESULT
84         }
85 fi
86
87 kernelver()
88 {
89         awk '{split($3,v,"."); printf("%03d%03d%03d\n", v[1],v[2],v[3]);}' /proc/version
90 }
91
92 kernelverser()
93 {
94         awk '{split($3,v,"."); printf("%03d%03d\n", v[1],v[2]);}' /proc/version
95 }
96
97 kernelvermser()
98 {
99         awk '{split($3,v,"."); printf("%03d\n", v[1]);}' /proc/version
100 }
101
102 # Colors workaround
103 termput()
104 {
105         if is_yes "$FASTRC" || [ ! -d /usr/share/terminfo ] || \
106            [ ! -x /usr/bin/tput -a ! -x /bin/tput ]; then
107                 case "$1" in
108                   hpa)
109                         echo -ne "\033[$(($2+1))G"
110                         ;;
111                   cuu*)
112                         echo -ne "\033[${2}A"
113                         ;;
114                   el)
115                         echo -ne "\033[0K"
116                         ;;
117                   setaf)
118                         is_yes "$COLOR_INIT" && echo -ne "\033[0;3${2}m"
119                         ;;
120                   op)
121                         termput setaf 9
122                         ;;
123                 esac
124         else
125                 # check if we are on proper terminal
126                 tput longname > /dev/null 2>&1 || return
127
128                 case "$1" in
129                   hpa | cuu* | el)
130                         tput "$@"
131                         ;;
132                   setaf)
133                         is_yes "$COLOR_INIT" && tput "$@"
134                         ;;
135                   op)
136                         tput setaf 9
137                         ;;
138                 esac
139         fi
140 }
141
142 # printf equivalent
143 printf_()
144 {
145         typeset text m
146         text="$1" ;
147         shift ;
148         if [ $# -gt 0 ]; then
149                 m="$1";
150                 shift;
151                 while [ $# -gt 0 ]; do
152                         m="$m\",\"$1" ;
153                         shift ;
154                 done
155         fi
156         awk "BEGIN {printf \"$text\", \"$m\"; }"
157 }
158
159 # National language support function
160 nls()
161 {
162         typeset msg_echo old_nls_domain text message
163         msg_echo='\n'
164         old_nls_domain="$NLS_DOMAIN"
165         # parse command line
166         # don't use -o instead || here - this will break ksh --misiek
167         while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
168                 case "$1" in
169                   --nls-domain)
170                         shift
171                         NLS_DOMAIN="$1"
172                         shift
173                         ;;
174                   -n)
175                         msg_echo=''
176                         shift
177                         ;;
178                 esac
179         done
180         message="$1"
181         shift
182         # empty message, so we return --misiek
183         if [ -z "$message" ]; then
184                 NLS_DOMAIN="$old_nls_domain"
185                 echo -en "$msg_echo"
186                 return
187         fi
188
189         if is_yes "$FASTRC"; then
190                 printf "$message" "$@"
191         elif [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
192                 text=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${NLS_DOMAIN:-rc-scripts}" "$message")
193                 printf_ "$text" "$@"
194         else
195                 printf_ "$message" "$@"
196         fi
197
198         echo -en "$msg_echo"
199         NLS_DOMAIN="$old_nls_domain"
200 }
201
202 rc_splash()
203 {
204         typeset action
205
206         action="$1"
207
208         if ! is_no "$BOOT_SPLASH"; then
209                 [ -x /bin/splash ] && /bin/splash "$action"
210         fi
211
212         : $((progress++))
213 }
214
215 msg_network_down()
216 {
217         nls "ERROR: Networking is down. %s can't be run." "$1" >&2
218 }
219
220 msg_starting()
221 {
222         show "Starting %s service" "$1"
223 }
224
225 msg_already_running()
226 {
227         nls "%s service is already running." "$1"
228 }
229
230 msg_stopping()
231 {
232         show "Stopping %s service" "$1"
233 }
234
235 msg_not_running()
236 {
237         nls "%s service is not running." "$1"
238 }
239
240 msg_reloading()
241 {
242         show "Reloading %s service" "$1"
243 }
244
245 msg_usage()
246 {
247         nls "Usage: %s" "$*"
248 }
249
250 # Some functions to handle PLD-style messages
251 show()
252 {
253         typeset text
254
255         if is_yes "$FASTRC"; then
256                 echo -n "$INIT_DOTS"
257                 termput hpa 0
258                 printf "$@"
259                 termput hpa $INIT_COL
260         else
261                 text=$(nls "$@")
262                 echo -n "$text"
263                 awk "BEGIN { for (j=length(\"$text\"); j<$INIT_COL; j++) printf \".\" }"
264         fi
265 }
266
267 # Displays message in square brackests ("[ DONE ]"). Takes two arguments.
268 # First is the text to display, second is color number to use (argument to
269 # tput setaf). If second argument is not given, default (2, green) will be
270 # used).
271 progress()
272 {
273         typeset COLOR
274         if [ -n "$2" ]; then COLOR="$2"; else COLOR="2"; fi
275         deltext
276         echo -n "$(termput setaf 6)[$(termput setaf "$COLOR") $(nls --nls-domain rc-scripts "$1") $(termput setaf 6)]$(termput op)"
277 }
278
279 busy()
280 {
281         progress "BUSY" 5
282 }
283
284 ok()
285 {
286         progress "DONE"
287         echo
288 }
289
290 started()
291 {
292         progress "WORK"
293         echo
294 }
295
296 fail()
297 {
298         progress "FAIL" 1
299         echo
300         return 1
301 }
302
303 died()
304 {
305         progress "DIED" 1
306         echo
307         return 1
308 }
309
310 deltext()
311 {
312         termput hpa $INIT_COL
313 }
314
315 # Check if $pid (could be plural) are running
316 checkpid()
317 {
318         while [ "$1" ]; do
319                 [ -d "/proc/$1" ] && return 0
320                 shift
321         done
322         return 1
323 }
324
325 # Usage run_cmd Message command_to_run
326 run_cmd()
327 {
328         typeset exit_code errors message force_err
329         typeset -i force_err=0
330         typeset -i exit_code=0
331         case "$1" in
332           -a)
333                 force_err=1
334                 shift
335                 ;;
336         esac
337         message=$1
338         show "$message"; busy
339         shift
340         if errors=$(HOME=/tmp TMPDIR=/tmp initlog -c "$*" 2>&1); then
341                 ok
342                 log_success "$1 $message"
343         else
344                 fail
345                 log_failed "$1 $message"
346                 exit_code=1
347         fi
348         [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors"
349         return $exit_code
350 }
351
352 # A function to start a program (now it's useful on read-only filesystem too)
353 daemon()
354 {
355         typeset errors="" prog="" limits=""
356         typeset -i exit_code=0
357         [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
358         # "-u unlimited" (-p for ksh) to make sure daemons will be able to fork.
359         # "-c 0" to make sure it doesn't core dump anywhere; while this could mask
360         # problems with the daemon, it also closes some security problems.
361         # Users' limits are set via pam_limits.
362         [ -z "$DEFAULT_SERVICE_LIMITS" ] && DEFAULT_SERVICE_LIMITS_HARD="-u unlimited -c 0"
363         # Test syntax. Don't use -o instead || here - this will break ksh --misiek
364         while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
365                 case $1 in
366                   '')
367                         msg_usage " daemon [--user user] [+/-nicelevel] {program}"
368                         return 2
369                         ;;
370                   --check)
371                         # for compatibility with redhat/mandrake
372                         nls "warning: --check option is ignored!"
373                         shift
374                         shift
375                         ;;
376                   --user)
377                         shift
378                         [ "$1" != "root" ] && prog="/bin/su $1 -c \""
379                         shift
380                         ;;
381                   -*|+*) SERVICE_RUN_NICE_LEVEL=$1
382                         shift;;
383                 esac
384         done
385         # If command to execute ends with quotation mark, add remaining
386         # arguments and close quotation.
387         if [ "$prog" != "${prog%\"}" ]; then
388                 prog="$prog $*\""
389         else
390                 prog="$prog $*"
391         fi
392
393         if [ -n "$KSH_VERSION" ]; then
394                 limits="`echo ${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS} | awk '/-Su/ {sub(/-Su/,"-Sp");} /-Hu/ {sub(/-Hu/,"-Hp");} /-u/ {sub(/-u/,"-p");} {print;}'`"
395         elif [ -n "$ZSH_VERSION" ]; then
396                 limits="${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}"
397         elif [ -n "$BASH_VERSION" ]; then
398                 limits="${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}"
399 #       elif [ -n "`$SH -c 'echo ${.sh.version}' 2>/dev/null`" ]; then
400         fi
401         while echo "$limits" | grep -q '[^ ]'; do
402                 ulimit `echo ${limits} | sed -e 's/^ *\(-[^-]*\)\(-.*\)\?$/\1/'`
403                 limits="`echo ${limits} | sed -e 's/^ *\(-[^-]*\)\(-.*\)\?$/\2/'`"
404         done
405
406         # And start it up.
407         busy
408         if errors=$(USER=root HOME=/tmp TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} initlog -c "$prog" 2>&1); then
409                 log_success "$1 startup"
410                 ok
411         else
412                 exit_code=1
413                 fail
414                 log_failed "$1 startup"
415                 [ -n "$errors" ] && echo "$errors"
416         fi
417         return $exit_code
418 }
419
420 # A function to stop a program.
421 killproc()
422 {
423         typeset notset killlevel base pid result
424         # Test syntax.
425         if [ $# = 0 ]; then
426                 msg_usage " killproc {program} [signal]"
427                 return 2
428         fi
429
430         busy
431
432         typeset -i notset=0
433         # check for second arg to be kill level
434         if [ -n "$2" ] ; then
435                 killlevel=$2
436         else
437                 notset=1
438                 killlevel="-9"
439         fi
440
441         # Save basename.
442         base=$(basename "$1")
443
444         # Find pid.
445         pid=$(pidofproc "$1")
446         [ -z "$pid" ] && pid=$(pidofproc "$base")
447
448         # Kill it.
449         if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1 ; then
450                 if [ "$notset" = "1" ] ; then
451                         if checkpid $pid 2>&1; then
452                                 # TERM first, then KILL if not dead
453                                 kill -TERM $pid
454                                 usleep 100000
455                                 if checkpid $pid && sleep 1 &&
456                                         checkpid $pid && sleep 3 &&
457                                         checkpid $pid; then
458                                         kill -KILL $pid
459                                         usleep 100000
460                                 fi
461                         fi
462                         checkpid $pid
463                         result=$?
464                         if [ "$result" -eq 0 ]; then
465                                 fail
466                                 log_failed "$1 shutdown"
467                         else
468                                 ok
469                                 log_success "$1 shutdown"
470                         fi
471                         result=$(( ! $result ))
472                 else
473                         # use specified level only
474                         if checkpid $pid > /dev/null 2>&1; then
475                                 kill $killlevel $pid
476                                 result=$?
477                                 if [ "$result" -eq 0 ]; then
478                                         ok
479                                         log_success "$1 got $killlevel"
480                                 else
481                                         result=7
482                                         fail
483                                         log_failed "$1 didn't get $killlevel"
484                                 fi
485                         else
486                                 result=7
487                                 died
488                                 log_failed "$1 shutdown"
489                         fi
490                 fi
491         else
492                 died
493                 log_failed "$1 shutdown"
494                 result=7
495         fi
496
497         # Remove pid file if any.
498         if [ "$notset" = "1" ]; then
499                 rm -f /var/run/${base}.pid
500         fi
501
502         return $result
503 }
504
505 # A function to find the pid of a program.
506 pidofproc()
507 {
508         typeset pid base
509         base=$(basename "$1")
510
511         # Test syntax.
512         if [ $# = 0 ] ; then
513                 msg_usage " pidofproc {program}"
514                 return 2
515         fi
516
517         # First try "/var/run/*.pid" files
518         if [ -f /var/run/${base}.pid ] ; then
519                 typeset line p pid
520                 pid=
521                 read line < /var/run/${base}.pid
522                 for p in $line; do
523                         [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p"
524                 done
525                 if [ -n "$pid" ]; then
526                         echo $pid
527                         return 0
528                 fi
529         fi
530
531         # Next try "pidof"
532         pidof -o $$ -o $PPID -o %PPID -x "$1"
533 }
534
535 status()
536 {
537         typeset base pid subsys daemon
538         subsys=$1
539         daemon=${2:-$subsys}
540         base=$(basename $daemon)
541
542         # Test syntax.
543         if [ $# = 0 ] ; then
544                 msg_usage " status {subsys} [{daemon}]"
545                 return 2
546         fi
547
548         # First try "pidof"
549         pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
550
551         if [ "$pid" != "" ]; then
552                 nls "%s (pid %s) is running..." "$daemon" "$pid"
553                 return 0
554 #       else
555 #               pid=`ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
556 #                    { if ((prog == $5) || (("(" prog ")") == $5) ||
557 #                         (("[" prog "]") == $5) ||
558 #                         ((prog ":") == $5)) { print $1 ; exit 0 } }' $1`
559 #               if [ "$pid" != "" ]; then
560 #                       nls "%s (pid %s) is running..." "$daemon" "$pid"
561 #                       return 0
562 #               fi
563         fi
564
565         # Next try "/var/run/*.pid" files
566         if [ -f /var/run/${base}.pid ]; then
567                 read pid < /var/run/${base}.pid
568                 if [ "$pid" != "" ]; then
569                         nls "%s dead but pid file exists" "$subsys"
570                         return 1
571                 fi
572         fi
573
574         # See if /var/lock/subsys/$subsys exists
575         if [ -f /var/lock/subsys/$subsys ]; then
576                 nls "%s dead but subsys locked" "$subsys"
577                 return 2
578         fi
579         nls "%s is stopped" "$subsys"
580         return 3
581 }
582
583 # Confirm whether we really want to run this service
584 confirm() {
585         typeset answer
586         nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
587         read answer
588         case $answer in
589           y|Y|t|T|j|J|"")
590                 return 0
591                 ;;
592           c|C|k|K|w|W)
593                 return 2
594                 ;;
595           n|N)
596                 return 1
597                 ;;
598           *)
599                 confirm $1
600                 return $?
601                 ;;
602         esac
603 }
604
605 # module is needed (ie. is requested, is available and isn't loaded already)
606 is_module()
607 {
608         # module name without .o at end
609         if ! (lsmod | grep -q "$1"); then
610                 if (ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"); then
611                         # true
612                         return 0
613                 fi
614         fi
615         # false
616         return 1
617 }
618
619 _modprobe()
620 {
621         typeset parsed single die args foo result
622         parsed=no
623         while is_no "$parsed" ; do
624                 case "$1" in
625                   "single")
626                         single=yes
627                         shift
628                         ;;
629                   "die")
630                         die=yes
631                         shift
632                         ;;
633                   -*)
634                         args="$args $1"
635                         shift
636                         ;;
637                   *)
638                         parsed=yes
639                         ;;
640                 esac
641         done
642         if is_yes "${single}" ; then
643                 foo="$@"
644                 show "Loading %s kernel module(s)" "$foo"
645                 busy
646         fi
647         if [ -x /sbin/modprobe ] ; then
648                 /sbin/modprobe -s $args "$@"
649                 result=$?
650         else
651                 deltext ; fail
652                 result=1
653         fi
654         if is_yes "${single}" ; then
655                 deltext
656                 if [ $result == "0" ] ; then
657                         is_yes "$single" && ok
658                 else
659                         fail
660                         if is_yes "$die" ; then
661                                 nls "Could not load %s kernel module(s)" "$@"
662                                 exit 1
663                         fi
664                 fi
665         fi
666 }
667
668 log_success ()
669 {
670         initlog -n $0 -s "$1 $2" -e 1
671 }
672
673 log_failed ()
674 {
675         initlog -n $0 -s "$1 $2" -e 2
676 }
677
678 # RedHat/Mandrake specific functions
679 action () { STRING=$1; shift; run_cmd "$STRING" "$*"; }
680 success () { return 0; }
681 failure () { return 1; }
682
683 # TO BE REMOVED IN AC. --ankry
684 msg_Network_Down () { msg_network_down "$*"; }
685 msg_Already_Running () { msg_already_running "$*"; }
686 msg_Not_Running () { msg_not_running "$*"; }
687 msg_Usage () { msg_usage "$*"; }
688
689 #/*
690 # * Local variables:
691 # * mode: sh
692 # * indent-tabs-mode: notnil
693 # * End:
694 # *
695 # */
696 # vi: syntax=sh:shiftwidth=8:
This page took 0.137355 seconds and 4 git commands to generate.