/[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 877 - (show annotations) (download) (as text)
Sun Jan 30 19:32:34 2005 UTC (13 years, 10 months ago) by vapier
File MIME type: text/x-sh
File size: 15639 byte(s)
sbin/functions.sh

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 (X of X.Y.Z) kernel version
396 #
397 KV_major() {
398 [[ -z $1 ]] && return 1
399
400 local KV=$@
401 echo ${KV%%.*}
402 }
403
404 # char *KV_minor(string)
405 #
406 # Return the Minor (Y of X.Y.Z) kernel version
407 #
408 KV_minor() {
409 [[ -z $1 ]] && return 1
410
411 local KV=$@
412 KV=${KV#*.}
413 echo ${KV%%.*}
414 }
415
416 # char *KV_micro(string)
417 #
418 # Return the Micro (Z of X.Y.Z) kernel version.
419 #
420 KV_micro() {
421 [[ -z $1 ]] && return 1
422
423 local KV=$@
424 KV=${KV#*.*.}
425 echo ${KV%%[^[:digit:]]*}
426 }
427
428 # int KV_to_int(string)
429 #
430 # Convert a string type kernel version (2.4.0) to an int (132096)
431 # for easy compairing or versions ...
432 #
433 KV_to_int() {
434 [[ -z $1 ]] && return 1
435
436 local KV_MAJOR=$(KV_major "$1")
437 local KV_MINOR=$(KV_minor "$1")
438 local KV_MICRO=$(KV_micro "$1")
439 local KV_int=$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO ))
440
441 # We make version 2.2.0 the minimum version we will handle as
442 # a sanity check ... if its less, we fail ...
443 if [[ ${KV_int} -ge 131584 ]] ; then
444 echo "${KV_int}"
445 return 0
446 fi
447
448 return 1
449 }
450
451 # int get_KV()
452 #
453 # Return the kernel version (major, minor and micro concated) as an integer.
454 # Assumes X and Y of X.Y.Z are numbers. Also assumes that some leading
455 # portion of Z is a number.
456 # e.g. 2.4.25, 2.6.10, 2.6.4-rc3, 2.2.40-poop, 2.0.15+foo
457 #
458 get_KV() {
459 local KV=$(uname -r)
460
461 echo $(KV_to_int "${KV}")
462
463 return $?
464 }
465
466 # bool get_bootparam(param)
467 #
468 # return 0 if gentoo=param was passed to the kernel
469 #
470 # EXAMPLE: if get_bootparam "nodevfs" ; then ....
471 #
472 get_bootparam() {
473 local x copt params retval=1
474
475 [ ! -r "/proc/cmdline" ] && return 1
476
477 for copt in $(< /proc/cmdline)
478 do
479 if [ "${copt%=*}" = "gentoo" ]
480 then
481 params="$(gawk -v PARAMS="${copt##*=}" '
482 BEGIN {
483 split(PARAMS, nodes, ",")
484 for (x in nodes)
485 print nodes[x]
486 }')"
487
488 # Parse gentoo option
489 for x in ${params}
490 do
491 if [ "${x}" = "$1" ]
492 then
493 # echo "YES"
494 retval=0
495 fi
496 done
497 fi
498 done
499
500 return ${retval}
501 }
502
503 # Safer way to list the contents of a directory,
504 # as it do not have the "empty dir bug".
505 #
506 # char *dolisting(param)
507 #
508 # print a list of the directory contents
509 #
510 # NOTE: quote the params if they contain globs.
511 # also, error checking is not that extensive ...
512 #
513 dolisting() {
514 local x=
515 local y=
516 local tmpstr=
517 local mylist=
518 local mypath="$*"
519
520 if [ "${mypath%/\*}" != "${mypath}" ]
521 then
522 mypath="${mypath%/\*}"
523 fi
524
525 for x in ${mypath}
526 do
527 [ ! -e "${x}" ] && continue
528
529 if [ ! -d "${x}" ] && ( [ -L "${x}" -o -f "${x}" ] )
530 then
531 mylist="${mylist} $(ls "${x}" 2> /dev/null)"
532 else
533 [ "${x%/}" != "${x}" ] && x="${x%/}"
534
535 cd "${x}"; tmpstr="$(ls)"
536
537 for y in ${tmpstr}
538 do
539 mylist="${mylist} ${x}/${y}"
540 done
541 fi
542 done
543
544 echo "${mylist}"
545 }
546
547 # void save_options(char *option, char *optstring)
548 #
549 # save the settings ("optstring") for "option"
550 #
551 save_options() {
552 local myopts="$1"
553
554 shift
555 if [ ! -d "${svcdir}/options/${myservice}" ]
556 then
557 mkdir -p -m 0755 "${svcdir}/options/${myservice}"
558 fi
559
560 echo "$*" > "${svcdir}/options/${myservice}/${myopts}"
561
562 return 0
563 }
564
565 # char *get_options(char *option)
566 #
567 # get the "optstring" for "option" that was saved
568 # by calling the save_options function
569 #
570 get_options() {
571 if [ -f "${svcdir}/options/${myservice}/$1" ]
572 then
573 echo "$(< ${svcdir}/options/${myservice}/$1)"
574 fi
575
576 return 0
577 }
578
579 # char *add_suffix(char * configfile)
580 #
581 # Returns a config file name with the softlevel suffix
582 # appended to it. For use with multi-config services.
583 add_suffix() {
584 if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -e "$1.${DEFAULTLEVEL}" ]
585 then
586 echo "$1.${DEFAULTLEVEL}"
587 else
588 echo "$1"
589 fi
590
591 return 0
592 }
593
594 # Network filesystems list for common use in rc-scripts.
595 # This variable is used in is_net_fs and other places such as
596 # localmount.
597 NET_FS_LIST="afs cifs coda ncpfs nfs nfs4 shfs smbfs"
598
599 # bool is_net_fs(path)
600 #
601 # return 0 if path is the mountpoint of a networked filesystem
602 #
603 # EXAMPLE: if is_net_fs / ; then ...
604 #
605 is_net_fs() {
606 local fstype=$(mount -o remount -fv "$1" | awk '{print $(NF-1)}')
607 [[ " ${NET_FS_LIST} " == *" ${fstype} "* ]]
608 return $?
609 }
610
611 # bool is_uml_sys()
612 #
613 # return 0 if the currently running system is User Mode Linux
614 #
615 # EXAMPLE: if is_uml_sys ; then ...
616 #
617 is_uml_sys() {
618 grep -q 'UML' /proc/cpuinfo &> /dev/null
619 return $?
620 }
621
622 # bool get_mount_fstab(path)
623 #
624 # return the parameters to pass to the mount command generated from fstab
625 #
626 # EXAMPLE: cmd=$( get_mount_fstab /proc )
627 # cmd=${cmd:--t proc none /proc}
628 # mount -n ${cmd}
629 #
630 get_mount_fstab() {
631 awk '$1 ~ "^#" { next }
632 $2 == "'$*'" { if (found++ == 0) { print "-t "$3,"-o "$4,$1,$2 } }
633 END { if (found > 1) { print "More than one entry for '$*' found in /etc/fstab!" > "/dev/stderr" } }
634 ' /etc/fstab
635 }
636
637 # bool is_older_than(reference, files/dirs to check)
638 #
639 # return 0 if any of the files/dirs are newer than
640 # the reference file
641 #
642 # EXAMPLE: if is_older_than a.out *.o ; then ...
643 is_older_than() {
644 local x=
645 local ref="$1"
646 shift
647
648 for x in "$@"
649 do
650 [[ ${x} -nt ${ref} ]] && return 0
651
652 if [[ -d ${x} ]]
653 then
654 is_older_than "${ref}" "${x}"/* && return 0
655 fi
656 done
657
658 return 1
659 }
660
661
662 ##############################################################################
663 # #
664 # This should be the last code in here, please add all functions above!! #
665 # #
666 # *** START LAST CODE *** #
667 # #
668 ##############################################################################
669
670 if [ -z "${EBUILD}" ]
671 then
672 # Setup a basic $PATH. Just add system default to existing.
673 # This should solve both /sbin and /usr/sbin not present when
674 # doing 'su -c foo', or for something like: PATH= rcscript start
675 PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:${PATH}"
676
677 if [ "$(/sbin/consoletype 2> /dev/null)" = "serial" ]
678 then
679 # We do not want colors/endcols on serial terminals
680 RC_NOCOLOR="yes"
681 RC_ENDCOL="no"
682 fi
683
684 for arg in "$@"
685 do
686 case "${arg}" in
687 # Lastly check if the user disabled it with --nocolor argument
688 --nocolor|-nc)
689 RC_NOCOLOR="yes"
690 ;;
691 esac
692 done
693
694 if [ -r "/proc/cmdline" ]
695 then
696 setup_defaultlevels
697 fi
698 else
699 # Should we use colors ?
700 if [[ $* != *depend* ]]; then
701 # Check user pref in portage
702 RC_NOCOLOR="$(portageq envvar NOCOLOR 2>/dev/null)"
703 [ "${RC_NOCOLOR}" = "true" ] && RC_NOCOLOR="yes"
704 else
705 # We do not want colors or stty to run during emerge depend
706 RC_NOCOLOR="yes"
707 RC_ENDCOL="no"
708 fi
709 fi
710
711 # Setup COLS and ENDCOL so eend can line up the [ ok ]
712 COLS=${COLUMNS:-0} # bash's internal COLUMNS variable
713 (( COLS == 0 )) && COLS=$(stty size 2>/dev/null | cut -d' ' -f2)
714 (( COLS > 0 )) || (( COLS = 80 )) # width of [ ok ] == 7
715 if [[ ${RC_ENDCOL} == yes ]]; then
716 ENDCOL=$'\e[A\e['$(( COLS - 7 ))'G'
717 else
718 ENDCOL=''
719 fi
720
721 # Setup the colors so our messages all look pretty
722 if [[ ${RC_NOCOLOR} == yes ]]; then
723 unset GOOD WARN BAD NORMAL HILITE BRACKET
724 else
725 GOOD=$'\e[32;01m'
726 WARN=$'\e[33;01m'
727 BAD=$'\e[31;01m'
728 NORMAL=$'\e[0m'
729 HILITE=$'\e[36;01m'
730 BRACKET=$'\e[34;01m'
731 fi
732
733 ##############################################################################
734 # #
735 # *** END LAST CODE *** #
736 # #
737 # This should be the last code in here, please add all functions above!! #
738 # #
739 ##############################################################################
740
741
742 # vim:ts=4

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.20