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