/[baselayout]/branches/rc-scripts-1_6/sbin/functions.sh
Gentoo

Contents of /branches/rc-scripts-1_6/sbin/functions.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 776 - (show annotations) (download) (as text)
Fri Dec 10 15:27:45 2004 UTC (9 years, 11 months ago) by vapier
File MIME type: text/x-sh
File size: 15950 byte(s)
RC_USE_FSTAB to disable get_mount_fstab by default

1 # Copyright 1999-2004 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header$
4
5 RC_GOT_FUNCTIONS="yes"
6
7 # daemontools dir
8 SVCDIR="/var/lib/supervise"
9
10 # Check /etc/conf.d/rc for a description of these ...
11 svcdir="/var/lib/init.d"
12 svclib="/lib/rcscripts"
13 svcmount="no"
14 svcfstype="tmpfs"
15 svcsize=1024
16
17 # Different types of dependencies
18 deptypes="need use"
19 # Different types of order deps
20 ordtypes="before after"
21
22 #
23 # Internal variables
24 #
25
26 # Dont output to stdout?
27 RC_QUIET_STDOUT="no"
28 RC_VERBOSE="${RC_VERBOSE:-no}"
29
30 # Should we use color?
31 RC_NOCOLOR="${RC_NOCOLOR:-no}"
32 # Can the terminal handle endcols?
33 RC_ENDCOL="yes"
34
35 #
36 # Default values for rc system
37 #
38 RC_TTY_NUMBER=11
39 RC_NET_STRICT_CHECKING="no"
40 RC_PARALLEL_STARTUP="no"
41 RC_USE_CONFIG_PROFILE="yes"
42
43 #
44 # Default values for e-message indentation and dots
45 #
46 RC_INDENTATION=''
47 RC_DEFAULT_INDENT=3
48 #RC_DOT_PATTERN=' .'
49 RC_DOT_PATTERN=''
50
51 # Override defaults with user settings ...
52 [ -f /etc/conf.d/rc ] && source /etc/conf.d/rc
53
54 # void splash(...)
55 #
56 # Notify bootsplash/splashutils/gensplash/whatever about
57 # important events.
58 #
59 splash() {
60 return 0
61 }
62
63 # This will override the splash() function...
64 [ -f /sbin/splash-functions.sh ] && source /sbin/splash-functions.sh
65
66 # void get_bootconfig()
67 #
68 # Get the BOOTLEVEL and SOFTLEVEL by setting
69 # 'bootlevel' and 'softlevel' via kernel
70 # parameters.
71 #
72 get_bootconfig() {
73 local copt=
74 local newbootlevel=
75 local newsoftlevel=
76
77 for copt in $(< /proc/cmdline)
78 do
79 case "${copt%=*}" in
80 "bootlevel")
81 newbootlevel="${copt##*=}"
82 ;;
83 "softlevel")
84 newsoftlevel="${copt##*=}"
85 ;;
86 esac
87 done
88
89 if [ -n "${newbootlevel}" ]
90 then
91 export BOOTLEVEL="${newbootlevel}"
92 else
93 export BOOTLEVEL="boot"
94 fi
95
96 if [ -n "${newsoftlevel}" ]
97 then
98 export DEFAULTLEVEL="${newsoftlevel}"
99 else
100 export DEFAULTLEVEL="default"
101 fi
102
103 return 0
104 }
105
106 setup_defaultlevels() {
107 get_bootconfig
108
109 if get_bootparam "noconfigprofile"
110 then
111 export RC_USE_CONFIG_PROFILE="no"
112
113 elif get_bootparam "configprofile"
114 then
115 export RC_USE_CONFIG_PROFILE="yes"
116 fi
117
118 if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -n "${DEFAULTLEVEL}" ] && \
119 [ -d "/etc/runlevels/${BOOTLEVEL}.${DEFAULTLEVEL}" -o \
120 -L "/etc/runlevels/${BOOTLEVEL}.${DEFAULTLEVEL}" ]
121 then
122 export BOOTLEVEL="${BOOTLEVEL}.${DEFAULTLEVEL}"
123 fi
124
125 if [ -z "${SOFTLEVEL}" ]
126 then
127 if [ -f "${svcdir}/softlevel" ]
128 then
129 export SOFTLEVEL="$(< ${svcdir}/softlevel)"
130 else
131 export SOFTLEVEL="${BOOTLEVEL}"
132 fi
133 fi
134
135 return 0
136 }
137
138 # void get_libdir(void)
139 #
140 # prints the current libdir {lib,lib32,lib64}
141 #
142 get_libdir() {
143 if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then
144 CONF_LIBDIR="${CONF_LIBDIR_OVERRIDE}"
145 elif [ -x "/usr/bin/portageq" ] ; then
146 CONF_LIBDIR="$(/usr/bin/portageq envvar CONF_LIBDIR)"
147 fi
148 echo ${CONF_LIBDIR:=lib}
149 }
150
151 # void esyslog(char* priority, char* tag, char* message)
152 #
153 # use the system logger to log a message
154 #
155 esyslog() {
156 local pri=
157 local tag=
158
159 if [ -x /usr/bin/logger ]
160 then
161 pri="$1"
162 tag="$2"
163
164 shift 2
165 [[ -z "$*" ]] && return 0
166
167 /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
168 fi
169
170 return 0
171 }
172
173 # void eindent(int num)
174 #
175 # increase the indent used for e-commands.
176 #
177 eindent() {
178 local i=$1
179 (( i > 0 )) || (( i = RC_DEFAULT_INDENT ))
180 esetdent $(( ${#RC_INDENTATION} + i ))
181 }
182
183 # void eoutdent(int num)
184 #
185 # decrease the indent used for e-commands.
186 #
187 eoutdent() {
188 local i=$1
189 (( i > 0 )) || (( i = RC_DEFAULT_INDENT ))
190 esetdent $(( ${#RC_INDENTATION} - i ))
191 }
192
193 # void esetdent(int num)
194 #
195 # hard set the indent used for e-commands.
196 # num defaults to 0
197 #
198 esetdent() {
199 local i=$1
200 (( i < 0 )) && (( i = 0 ))
201 RC_INDENTATION=$(printf "%${i}s" '')
202 }
203
204 # void einfo(char* message)
205 #
206 # show an informative message (with a newline)
207 #
208 einfo() {
209 einfon "$*\n"
210 LAST_E_CMD=einfo
211 return 0
212 }
213
214 # void einfon(char* message)
215 #
216 # show an informative message (without a newline)
217 #
218 einfon() {
219 [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
220 [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
221 echo -ne " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
222 LAST_E_CMD=einfon
223 return 0
224 }
225
226 # void ewarn(char* message)
227 #
228 # show a warning message + log it
229 #
230 ewarn() {
231 if [[ ${RC_QUIET_STDOUT} == yes ]]; then
232 echo " $*"
233 else
234 [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
235 echo -e " ${WARN}*${NORMAL} ${RC_INDENTATION}$*"
236 fi
237
238 # Log warnings to system log
239 esyslog "daemon.warning" "rc-scripts" "$*"
240
241 LAST_E_CMD=ewarn
242 return 0
243 }
244
245 # void eerror(char* message)
246 #
247 # show an error message + log it
248 #
249 eerror() {
250 if [[ ${RC_QUIET_STDOUT} == yes ]]; then
251 echo " $*" >/dev/stderr
252 else
253 [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
254 echo -e " ${BAD}*${NORMAL} ${RC_INDENTATION}$*"
255 fi
256
257 # Log errors to system log
258 esyslog "daemon.err" "rc-scripts" "$*"
259
260 LAST_E_CMD=eerror
261 return 0
262 }
263
264 # void ebegin(char* message)
265 #
266 # show a message indicating the start of a process
267 #
268 ebegin() {
269 local msg="$*" dots spaces=${RC_DOT_PATTERN//?/ }
270 [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
271
272 if [[ -n ${RC_DOT_PATTERN} ]]; then
273 dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')
274 dots=${dots//${spaces}/${RC_DOT_PATTERN}}
275 msg="${msg}${dots}"
276 else
277 msg="${msg} ..."
278 fi
279 einfon "${msg}"
280 [[ ${RC_ENDCOL} == yes ]] && echo
281
282 LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
283 LAST_E_CMD=ebegin
284 return 0
285 }
286
287 # void _eend(int error, char *efunc, char* errstr)
288 #
289 # indicate the completion of process, called from eend/ewend
290 # if error, show errstr via efunc
291 #
292 # This function is private to functions.sh. Do not call it from a
293 # script.
294 #
295 _eend() {
296 local retval=${1:-0} efunc=${2:-eerror} msg
297 shift 2
298
299 if [[ ${retval} == 0 ]]; then
300 [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
301 msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
302 else
303 if [[ -c /dev/null ]]; then
304 rc_splash "stop" &>/dev/null &
305 else
306 rc_splash "stop" &
307 fi
308 if [[ -n "$*" ]]; then
309 ${efunc} "$*"
310 fi
311 msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
312 fi
313
314 if [[ ${RC_ENDCOL} == yes ]]; then
315 echo -e "${ENDCOL} ${msg}"
316 else
317 [[ ${LAST_E_CMD} == ebegin ]] || LAST_E_LEN=0
318 printf "%$(( COLS - LAST_E_LEN - 6 ))s%b\n" '' "${msg}"
319 fi
320
321 return ${retval}
322 }
323
324 # void eend(int error, char* errstr)
325 #
326 # indicate the completion of process
327 # if error, show errstr via eerror
328 #
329 eend() {
330 local retval=${1:-0}
331 shift
332
333 _eend ${retval} eerror "$*"
334
335 LAST_E_CMD=eend
336 return $retval
337 }
338
339 # void ewend(int error, char* errstr)
340 #
341 # indicate the completion of process
342 # if error, show errstr via ewarn
343 #
344 ewend() {
345 local retval=${1:-0}
346 shift
347
348 _eend ${retval} ewarn "$*"
349
350 LAST_E_CMD=ewend
351 return $retval
352 }
353
354 # v-e-commands honor RC_VERBOSE which defaults to no.
355 # The condition is negated so the return value will be zero.
356 veinfo() { [[ "${RC_VERBOSE}" != yes ]] || einfo "$@"; }
357 veinfon() { [[ "${RC_VERBOSE}" != yes ]] || einfon "$@"; }
358 vewarn() { [[ "${RC_VERBOSE}" != yes ]] || ewarn "$@"; }
359 veerror() { [[ "${RC_VERBOSE}" != yes ]] || eerror "$@"; }
360 vebegin() { [[ "${RC_VERBOSE}" != yes ]] || ebegin "$@"; }
361 veend() {
362 [[ "${RC_VERBOSE}" == yes ]] && { eend "$@"; return $?; }
363 return ${1:-0}
364 }
365 veend() {
366 [[ "${RC_VERBOSE}" == yes ]] && { ewend "$@"; return $?; }
367 return ${1:-0}
368 }
369
370 # bool wrap_rcscript(full_path_and_name_of_rc-script)
371 #
372 # check to see if a given rc-script has syntax errors
373 # zero == no errors
374 # nonzero == errors
375 #
376 wrap_rcscript() {
377 local retval=1
378 local myservice="${1##*/}"
379
380 ( echo "function test_script() {" ; cat "$1"; echo "}" ) \
381 > "${svcdir}/${myservice}-$$"
382
383 if source "${svcdir}/${myservice}-$$"
384 then
385 test_script
386 retval=0
387 fi
388 rm -f "${svcdir}/${myservice}-$$"
389
390 return "${retval}"
391 }
392
393 # char *KV_major(string)
394 #
395 # Return the Major version part of given kernel version.
396 #
397 KV_major() {
398 local KV=
399
400 [ -z "$1" ] && return 1
401
402 KV="$(echo "$1" | \
403 awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
404 echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $1 }'
405
406 return 0
407 }
408
409 # char *KV_minor(string)
410 #
411 # Return the Minor version part of given kernel version.
412 #
413 KV_minor() {
414 local KV=
415
416 [ -z "$1" ] && return 1
417
418 KV="$(echo "$1" | \
419 awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
420 echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $2 }'
421
422 return 0
423 }
424
425 # char *KV_micro(string)
426 #
427 # Return the Micro version part of given kernel version.
428 #
429 KV_micro() {
430 local KV=
431
432 [ -z "$1" ] && return 1
433
434 KV="$(echo "$1" | \
435 awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
436 echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $3 }'
437
438 return 0
439 }
440
441 # int KV_to_int(string)
442 #
443 # Convert a string type kernel version (2.4.0) to an int (132096)
444 # for easy compairing or versions ...
445 #
446 KV_to_int() {
447 local KV_MAJOR=
448 local KV_MINOR=
449 local KV_MICRO=
450 local KV_int=
451
452 [ -z "$1" ] && return 1
453
454 KV_MAJOR="$(KV_major "$1")"
455 KV_MINOR="$(KV_minor "$1")"
456 KV_MICRO="$(KV_micro "$1")"
457 KV_int="$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO ))"
458
459 # We make version 2.2.0 the minimum version we will handle as
460 # a sanity check ... if its less, we fail ...
461 if [ "${KV_int}" -ge 131584 ]
462 then
463 echo "${KV_int}"
464
465 return 0
466 fi
467
468 return 1
469 }
470
471 # int get_KV()
472 #
473 # return the kernel version (major, minor and micro concated) as an integer
474 #
475 get_KV() {
476 local KV="$(uname -r)"
477
478 echo "$(KV_to_int "${KV}")"
479
480 return $?
481 }
482
483 # bool get_bootparam(param)
484 #
485 # return 0 if gentoo=param was passed to the kernel
486 #
487 # EXAMPLE: if get_bootparam "nodevfs" ; then ....
488 #
489 get_bootparam() {
490 local x copt params retval=1
491
492 [ ! -r "/proc/cmdline" ] && return 1
493
494 for copt in $(< /proc/cmdline)
495 do
496 if [ "${copt%=*}" = "gentoo" ]
497 then
498 params="$(gawk -v PARAMS="${copt##*=}" '
499 BEGIN {
500 split(PARAMS, nodes, ",")
501 for (x in nodes)
502 print nodes[x]
503 }')"
504
505 # Parse gentoo option
506 for x in ${params}
507 do
508 if [ "${x}" = "$1" ]
509 then
510 # echo "YES"
511 retval=0
512 fi
513 done
514 fi
515 done
516
517 return ${retval}
518 }
519
520 # Safer way to list the contents of a directory,
521 # as it do not have the "empty dir bug".
522 #
523 # char *dolisting(param)
524 #
525 # print a list of the directory contents
526 #
527 # NOTE: quote the params if they contain globs.
528 # also, error checking is not that extensive ...
529 #
530 dolisting() {
531 local x=
532 local y=
533 local tmpstr=
534 local mylist=
535 local mypath="$*"
536
537 if [ "${mypath%/\*}" != "${mypath}" ]
538 then
539 mypath="${mypath%/\*}"
540 fi
541
542 for x in ${mypath}
543 do
544 [ ! -e "${x}" ] && continue
545
546 if [ ! -d "${x}" ] && ( [ -L "${x}" -o -f "${x}" ] )
547 then
548 mylist="${mylist} $(ls "${x}" 2> /dev/null)"
549 else
550 [ "${x%/}" != "${x}" ] && x="${x%/}"
551
552 cd "${x}"; tmpstr="$(ls)"
553
554 for y in ${tmpstr}
555 do
556 mylist="${mylist} ${x}/${y}"
557 done
558 fi
559 done
560
561 echo "${mylist}"
562 }
563
564 # void save_options(char *option, char *optstring)
565 #
566 # save the settings ("optstring") for "option"
567 #
568 save_options() {
569 local myopts="$1"
570
571 shift
572 if [ ! -d "${svcdir}/options/${myservice}" ]
573 then
574 mkdir -p -m 0755 "${svcdir}/options/${myservice}"
575 fi
576
577 echo "$*" > "${svcdir}/options/${myservice}/${myopts}"
578
579 return 0
580 }
581
582 # char *get_options(char *option)
583 #
584 # get the "optstring" for "option" that was saved
585 # by calling the save_options function
586 #
587 get_options() {
588 if [ -f "${svcdir}/options/${myservice}/$1" ]
589 then
590 echo "$(< ${svcdir}/options/${myservice}/$1)"
591 fi
592
593 return 0
594 }
595
596 # char *add_suffix(char * configfile)
597 #
598 # Returns a config file name with the softlevel suffix
599 # appended to it. For use with multi-config services.
600 add_suffix() {
601 if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -e "$1.${DEFAULTLEVEL}" ]
602 then
603 echo "$1.${DEFAULTLEVEL}"
604 else
605 echo "$1"
606 fi
607
608 return 0
609 }
610
611 # Network filesystems list for common use in rc-scripts.
612 # This variable is used in is_net_fs and other places such as
613 # localmount.
614 NET_FS_LIST="afs cifs coda ncpfs nfs nfs4 shfs smbfs"
615
616 # bool is_net_fs(path)
617 #
618 # return 0 if path is the mountpoint of a networked filesystem
619 #
620 # EXAMPLE: if is_net_fs / ; then ...
621 #
622 is_net_fs() {
623 local fstype=$(mount -o remount -fv "$1" | awk '{print $(NF-1)}')
624 [[ " ${NET_FS_LIST} " == *" ${fstype} "* ]]
625 return $?
626 }
627
628 # bool is_uml_sys()
629 #
630 # return 0 if the currently running system is User Mode Linux
631 #
632 # EXAMPLE: if is_uml_sys ; then ...
633 #
634 is_uml_sys() {
635 grep -q 'UML' /proc/cpuinfo &> /dev/null
636 return $?
637 }
638
639 # bool get_mount_fstab(path)
640 #
641 # return the parameters to pass to the mount command generated from fstab
642 #
643 # EXAMPLE: cmd=$( get_mount_fstab /proc )
644 # cmd=${cmd:--t proc none /proc}
645 # mount -n ${cmd}
646 #
647 get_mount_fstab() {
648 awk '$1 ~ "^#" { next }
649 $2 == "'$*'" { if (found++ == 0) { print "-t "$3,"-o "$4,$1,$2 } }
650 END { if (found > 1) { print "More than one entry for '$*' found in /etc/fstab!" > "/dev/stderr" } }
651 ' /etc/fstab
652 }
653
654 # bool is_older_than(reference, files/dirs to check)
655 #
656 # return 0 if any of the files/dirs are newer than
657 # the reference file
658 #
659 # EXAMPLE: if is_older_than a.out *.o ; then ...
660 is_older_than() {
661 local x=
662 local ref="$1"
663 shift
664
665 for x in "$@"
666 do
667 [[ ${x} -nt ${ref} ]] && return 0
668
669 if [[ -d ${x} ]]
670 then
671 is_older_than "${ref}" "${x}"/* && return 0
672 fi
673 done
674
675 return 1
676 }
677
678
679 ##############################################################################
680 # #
681 # This should be the last code in here, please add all functions above!! #
682 # #
683 # *** START LAST CODE *** #
684 # #
685 ##############################################################################
686
687 if [ -z "${EBUILD}" ]
688 then
689 # Setup a basic $PATH. Just add system default to existing.
690 # This should solve both /sbin and /usr/sbin not present when
691 # doing 'su -c foo', or for something like: PATH= rcscript start
692 PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:${PATH}"
693
694 if [ "$(/sbin/consoletype 2> /dev/null)" = "serial" ]
695 then
696 # We do not want colors/endcols on serial terminals
697 RC_NOCOLOR="yes"
698 RC_ENDCOL="no"
699 fi
700
701 for arg in "$@"
702 do
703 case "${arg}" in
704 # Lastly check if the user disabled it with --nocolor argument
705 --nocolor|-nc)
706 RC_NOCOLOR="yes"
707 ;;
708 esac
709 done
710
711 if [ -r "/proc/cmdline" ]
712 then
713 setup_defaultlevels
714 fi
715 else
716 # Should we use colors ?
717 if [[ $* != *depend* ]]; then
718 # Check user pref in portage
719 RC_NOCOLOR="$(portageq envvar NOCOLOR 2>/dev/null)"
720 [ "${RC_NOCOLOR}" = "true" ] && RC_NOCOLOR="yes"
721 else
722 # We do not want colors or stty to run during emerge depend
723 RC_NOCOLOR="yes"
724 RC_ENDCOL="no"
725 fi
726 fi
727
728 # Setup COLS and ENDCOL so eend can line up the [ ok ]
729 COLS=${COLUMNS:-0} # bash's internal COLUMNS variable
730 (( COLS == 0 )) && COLS=$(stty size 2>/dev/null | cut -d' ' -f2)
731 (( COLS > 0 )) || (( COLS = 80 )) # width of [ ok ] == 7
732 if [[ ${RC_ENDCOL} == yes ]]; then
733 ENDCOL=$'\e[A\e['$(( COLS - 7 ))'G'
734 else
735 ENDCOL=''
736 fi
737
738 # Setup the colors so our messages all look pretty
739 if [[ ${RC_NOCOLOR} == yes ]]; then
740 unset GOOD WARN BAD NORMAL HILITE BRACKET
741 else
742 GOOD=$'\e[32;01m'
743 WARN=$'\e[33;01m'
744 BAD=$'\e[31;01m'
745 NORMAL=$'\e[0m'
746 HILITE=$'\e[36;01m'
747 BRACKET=$'\e[34;01m'
748 fi
749
750 ##############################################################################
751 # #
752 # *** END LAST CODE *** #
753 # #
754 # This should be the last code in here, please add all functions above!! #
755 # #
756 ##############################################################################
757
758
759 # vim:ts=4

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20