/[baselayout]/trunk/sbin/functions.sh
Gentoo

Contents of /trunk/sbin/functions.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 484 - (show annotations) (download) (as text)
Wed Apr 21 17:09:18 2004 UTC (15 years, 1 month ago) by vapier
File MIME type: text/x-sh
File size: 15745 byte(s)
update copyright years

1 # Copyright 1999-2004 Gentoo Technologies, Inc.
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
29 # Should we use color?
30 RC_NOCOLOR="no"
31
32
33 #
34 # Default values for rc system
35 #
36 RC_TTY_NUMBER=11
37 RC_NET_STRICT_CHECKING="no"
38 RC_PARALLEL_STARTUP="no"
39 RC_USE_CONFIG_PROFILE="yes"
40
41 # Override defaults with user settings ...
42 [ -f /etc/conf.d/rc ] && source /etc/conf.d/rc
43
44
45 # void get_bootconfig()
46 #
47 # Get the BOOTLEVEL and SOFTLEVEL by setting
48 # 'bootlevel' and 'softlevel' via kernel
49 # parameters.
50 #
51 get_bootconfig() {
52 local copt=
53 local newbootlevel=
54 local newsoftlevel=
55
56 for copt in $(< /proc/cmdline)
57 do
58 case "${copt%=*}" in
59 "bootlevel")
60 newbootlevel="${copt##*=}"
61 ;;
62 "softlevel")
63 newsoftlevel="${copt##*=}"
64 ;;
65 esac
66 done
67
68 if [ -n "${newbootlevel}" ]
69 then
70 export BOOTLEVEL="${newbootlevel}"
71 else
72 export BOOTLEVEL="boot"
73 fi
74
75 if [ -n "${newsoftlevel}" ]
76 then
77 export DEFAULTLEVEL="${newsoftlevel}"
78 else
79 export DEFAULTLEVEL="default"
80 fi
81
82 return 0
83 }
84
85 setup_defaultlevels() {
86 get_bootconfig
87
88 if get_bootparam "noconfigprofile"
89 then
90 export RC_USE_CONFIG_PROFILE="no"
91
92 elif get_bootparam "configprofile"
93 then
94 export RC_USE_CONFIG_PROFILE="yes"
95 fi
96
97 if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -n "${DEFAULTLEVEL}" ] && \
98 [ -d "/etc/runlevels/${BOOTLEVEL}.${DEFAULTLEVEL}" -o \
99 -L "/etc/runlevels/${BOOTLEVEL}.${DEFAULTLEVEL}" ]
100 then
101 export BOOTLEVEL="${BOOTLEVEL}.${DEFAULTLEVEL}"
102 fi
103
104 if [ -z "${SOFTLEVEL}" ]
105 then
106 if [ -f "${svcdir}/softlevel" ]
107 then
108 export SOFTLEVEL="$(< ${svcdir}/softlevel)"
109 else
110 export SOFTLEVEL="${BOOTLEVEL}"
111 fi
112 fi
113
114 return 0
115 }
116
117 #
118 # void splash_init (void)
119 #
120 splash_init() {
121 pb_init=0
122 pb_count=0
123 pb_scripts=0
124 pb_rate=0
125
126 if [ ! -x /sbin/splash ] || \
127 [ -e /proc/version -a ! -e /proc/splash ]
128 then
129 return 0
130 fi
131
132 if [ -f /etc/conf.d/bootsplash.conf ]
133 then
134 . /etc/conf.d/bootsplash.conf
135 if [ -n "${PROGRESS_SYSINIT_RATE}" ]
136 then
137 rate=$((65535*${PROGRESS_SYSINIT_RATE}/100))
138 fi
139 fi
140
141 if [ "${RUNLEVEL}" = "S" ]
142 then
143 pb_scripts=5
144 pb_rate=16383
145 [ -n "${rate}" ] && pb_rate="${rate}"
146 fi
147
148 export pb_init pb_count pb_scripts pb_rate
149 }
150
151 #
152 # void splash_calc (void)
153 #
154 splash_calc() {
155 pb_runs=($(dolisting "/etc/runlevels/${SOFTLEVEL}/"))
156 pb_runb=($(dolisting "/etc/runlevels/${BOOTLEVEL}/"))
157 pb_scripts=${#pb_runs[*]}
158 pb_boot=${#pb_runb[*]}
159
160 [ ! -e /proc/splash -o ! -x /sbin/splash ] && return 0
161
162 if [ -f /etc/conf.d/bootsplash.conf ]
163 then
164 . /etc/conf.d/bootsplash.conf
165
166 if [ -n "${PROGRESS_SYSINIT_RATE}" ]
167 then
168 init_rate=$((65535*${PROGRESS_SYSINIT_RATE}/100))
169 fi
170
171 if [ -n "${PROGRESS_BOOT_RATE}" ]
172 then
173 boot_rate=$((65535*${PROGRESS_BOOT_RATE}/100))
174 fi
175 fi
176
177 # In runlevel boot we have 5 already started scripts
178 #
179 if [ "${RUNLEVEL}" = "S" -a "${SOFTLEVEL}" = "boot" ]
180 then
181 pb_started=($(dolisting "${svcdir}/started/"))
182 pb_scripts=$((${pb_boot} - ${#pb_started[*]}))
183 pb_init=16383
184 pb_rate=26213
185 pb_count=0
186 if [ -n "${init_rate}" -a -n "${boot_rate}" ]
187 then
188 pb_init="${init_rate}"
189 pb_rate=$((${init_rate} + ${boot_rate}))
190 fi
191 elif [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
192 then
193 pb_started=($(dolisting "${svcdir}/started/"))
194 pb_scripts=${#pb_started[*]}
195 pb_rate=65534
196 else
197 pb_init=26213
198 pb_rate=65534
199 if [ -n "${init_rate}" -a -n "${boot_rate}" ]
200 then
201 pb_init=$((${init_rate} + ${boot_rate}))
202 fi
203 fi
204
205 echo "pb_init=${pb_init}" > "${svcdir}/progress"
206 echo "pb_rate=${pb_rate}" >> "${svcdir}/progress"
207 echo "pb_count=${pb_count}" >> "${svcdir}/progress"
208 echo "pb_scripts=${pb_scripts}" >> "${svcdir}/progress"
209 }
210
211 #
212 # void splash_update (char *fsstate, char *myscript, char *action)
213 #
214 splash_update() {
215 local fsstate="$1"
216 local myscript="$2"
217 local action="$3"
218
219 [ ! -e /proc/splash -o ! -x /sbin/splash ] && return 0
220
221 if [ "${fsstate}" = "inline" ]
222 then
223 /sbin/splash "${myscript}" "${action}"
224 pb_count=$((${pb_count} + 1))
225
226 # Only needed for splash_debug()
227 pb_execed="${pb_execed} ${myscript:-inline}"
228 else
229 # Update only runlevel scripts, no dependancies (only true for startup)
230 if [ ! -L "${svcdir}/softscripts/${myscript}" ]
231 then
232 [ "${SOFTLEVEL}" != "reboot" -a \
233 "${SOFTLEVEL}" != "shutdown" ] && return
234 fi
235 # Source the current progress bar state
236 [ -f "${svcdir}/progress" ] && source "${svcdir}/progress"
237
238 # Do not update an already executed script
239 for x in ${pb_execed}
240 do
241 [ "${x}" = "${myscript}" ] && return
242 done
243
244 /sbin/splash "${myscript}" "${action}"
245 pb_count=$((${pb_count} + 1))
246
247 echo "pb_init=${pb_init}" > "${svcdir}/progress"
248 echo "pb_rate=${pb_rate}" >> "${svcdir}/progress"
249 echo "pb_count=${pb_count}" >> "${svcdir}/progress"
250 echo "pb_scripts=${pb_scripts}" >> "${svcdir}/progress"
251 echo "pb_execed=\"${pb_execed} ${myscript}\"" >> "${svcdir}/progress"
252 fi
253 }
254
255 #
256 # void splash_debug (char *softlevel)
257 #
258 splash_debug() {
259 local softlevel="$1"
260
261 [ ! -e /proc/splash -o ! -x /sbin/splash ] && return 0
262
263 if [ -f /etc/conf.d/bootsplash.conf ]
264 then
265 source /etc/conf.d/bootsplash.conf
266
267 [ "${BOOTSPLASH_DEBUG}" = "yes" -a -n "${softlevel}" ] || return
268
269 if [ -f "${svcdir}/progress" ]
270 then
271 cat "${svcdir}/progress" > "/var/log/bootsplash.${softlevel}"
272 else
273 echo "pb_init=${pb_init}" > "/var/log/bootsplash.${softlevel}"
274 echo "pb_rate=${pb_rate}" >> "/var/log/bootsplash.${softlevel}"
275 echo "pb_count=${pb_count}" >> "/var/log/bootsplash.${softlevel}"
276 echo "pb_scripts=${pb_scripts}" >> "/var/log/bootsplash.${softlevel}"
277 echo "pb_execed=\"${pb_execed}\"" >> "/var/log/bootsplash.${softlevel}"
278 fi
279 fi
280 }
281
282 update_splash_wrappers() {
283 if [ -x /sbin/splash ] && \
284 ([ ! -e /proc/version ] || \
285 [ -e /proc/version -a -e /proc/splash ])
286 then
287 rc_splash() {
288 /sbin/splash $*
289 }
290 rc_splash_init() {
291 splash_init $*
292 }
293 rc_splash_calc() {
294 splash_calc $*
295 }
296 rc_splash_update() {
297 splash_update $*
298 }
299 rc_splash_debug() {
300 splash_debug $*
301 }
302 else
303 rc_splash() {
304 return 0
305 }
306 rc_splash_init() {
307 return 0
308 }
309 rc_splash_calc() {
310 return 0
311 }
312 rc_splash_update() {
313 return 0
314 }
315 rc_splash_debug() {
316 return 0
317 }
318 fi
319
320 export rc_splash rc_splash_init rc_splash_calc \
321 rc_splash_update rc_splash_debug
322 }
323
324 # void esyslog(char* priority, char* tag, char* message)
325 #
326 # use the system logger to log a message
327 #
328 esyslog() {
329 local pri=
330 local tag=
331
332 if [ -x /usr/bin/logger ]
333 then
334 pri="$1"
335 tag="$2"
336
337 shift 2
338 [ -z "$*" ] && return 0
339
340 /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
341 fi
342
343 return 0
344 }
345
346 # void einfo(char* message)
347 #
348 # show an informative message (with a newline)
349 #
350 einfo() {
351 if [ "${RC_QUIET_STDOUT}" != "yes" ]
352 then
353 echo -e " ${GOOD}*${NORMAL} ${*}"
354 fi
355
356 return 0
357 }
358
359 # void einfon(char* message)
360 #
361 # show an informative message (without a newline)
362 #
363 einfon() {
364 if [ "${RC_QUIET_STDOUT}" != "yes" ]
365 then
366 echo -ne " ${GOOD}*${NORMAL} ${*}"
367 fi
368
369 return 0
370 }
371
372 # void ewarn(char* message)
373 #
374 # show a warning message + log it
375 #
376 ewarn() {
377 if [ "${RC_QUIET_STDOUT}" = "yes" ]
378 then
379 echo " ${*}"
380 else
381 echo -e " ${WARN}*${NORMAL} ${*}"
382 fi
383
384 # Log warnings to system log
385 esyslog "daemon.warning" "rc-scripts" "${*}"
386
387 return 0
388 }
389
390 # void eerror(char* message)
391 #
392 # show an error message + log it
393 #
394 eerror() {
395 if [ "${RC_QUIET_STDOUT}" = "yes" ]
396 then
397 echo " ${*}" >/dev/stderr
398 else
399 echo -e " ${BAD}*${NORMAL} ${*}"
400 fi
401
402 # Log errors to system log
403 esyslog "daemon.err" "rc-scripts" "${*}"
404
405 return 0
406 }
407
408 # void ebegin(char* message)
409 #
410 # show a message indicating the start of a process
411 #
412 ebegin() {
413 if [ "${RC_QUIET_STDOUT}" != "yes" ]
414 then
415 if [ "${RC_NOCOLOR}" = "yes" ]
416 then
417 echo -ne " ${GOOD}*${NORMAL} ${*}..."
418 else
419 echo -e " ${GOOD}*${NORMAL} ${*}..."
420 fi
421 fi
422
423 return 0
424 }
425
426 # void eend(int error, char* errstr)
427 #
428 # indicate the completion of process
429 # if error, show errstr via eerror
430 #
431 eend() {
432 local retval=
433
434 if [ "$#" -eq 0 ] || ([ -n "$1" ] && [ "$1" -eq 0 ])
435 then
436 if [ "${RC_QUIET_STDOUT}" != "yes" ]
437 then
438 echo -e "${ENDCOL} ${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
439 fi
440 else
441 retval="$1"
442
443 rc_splash "stop" &>/dev/null &
444
445 if [ "$#" -ge 2 ]
446 then
447 shift
448 eerror "${*}"
449 fi
450 if [ "${RC_QUIET_STDOUT}" != "yes" ]
451 then
452 echo -e "${ENDCOL} ${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
453 # extra spacing makes it easier to read
454 echo
455 fi
456 return ${retval}
457 fi
458
459 return 0
460 }
461
462 # void ewend(int error, char *warnstr)
463 #
464 # indicate the completion of process
465 # if error, show warnstr via ewarn
466 #
467 ewend() {
468 local retval=
469
470 if [ "$#" -eq 0 ] || ([ -n "$1" ] && [ "$1" -eq 0 ])
471 then
472 if [ "${RC_QUIET_STDOUT}" != "yes" ]
473 then
474 echo -e "${ENDCOL} ${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
475 fi
476 else
477 retval="$1"
478 if [ "$#" -ge 2 ]
479 then
480 shift
481 ewarn "${*}"
482 fi
483 if [ "${RC_QUIET_STDOUT}" != "yes" ]
484 then
485 echo -e "${ENDCOL} ${BRACKET}[ ${WARN}!!${BRACKET} ]${NORMAL}"
486 # extra spacing makes it easier to read
487 echo
488 fi
489 return "${retval}"
490 fi
491
492 return 0
493 }
494
495 # bool wrap_rcscript(full_path_and_name_of_rc-script)
496 #
497 # check to see if a given rc-script has syntax errors
498 # zero == no errors
499 # nonzero == errors
500 #
501 wrap_rcscript() {
502 local retval=1
503 local myservice="${1##*/}"
504
505 ( echo "function test_script() {" ; cat "$1"; echo "}" ) \
506 > "${svcdir}/${myservice}-$$"
507
508 if source "${svcdir}/${myservice}-$$" &> /dev/null
509 then
510 test_script &> /dev/null
511 retval=0
512 fi
513 rm -f "${svcdir}/${myservice}-$$"
514
515 return "${retval}"
516 }
517
518 # char *KV_major(string)
519 #
520 # Return the Major version part of given kernel version.
521 #
522 KV_major() {
523 local KV=
524
525 [ -z "$1" ] && return 1
526
527 KV="$(echo "$1" | \
528 awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
529 echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $1 }'
530
531 return 0
532 }
533
534 # char *KV_minor(string)
535 #
536 # Return the Minor version part of given kernel version.
537 #
538 KV_minor() {
539 local KV=
540
541 [ -z "$1" ] && return 1
542
543 KV="$(echo "$1" | \
544 awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
545 echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $2 }'
546
547 return 0
548 }
549
550 # char *KV_micro(string)
551 #
552 # Return the Micro version part of given kernel version.
553 #
554 KV_micro() {
555 local KV=
556
557 [ -z "$1" ] && return 1
558
559 KV="$(echo "$1" | \
560 awk '{ tmp = $0; gsub(/^[0-9\.]*/, "", tmp); sub(tmp, ""); print }')"
561 echo "${KV}" | awk -- 'BEGIN { FS = "." } { print $3 }'
562
563 return 0
564 }
565
566 # int KV_to_int(string)
567 #
568 # Convert a string type kernel version (2.4.0) to an int (132096)
569 # for easy compairing or versions ...
570 #
571 KV_to_int() {
572 local KV_MAJOR=
573 local KV_MINOR=
574 local KV_MICRO=
575 local KV_int=
576
577 [ -z "$1" ] && return 1
578
579 KV_MAJOR="$(KV_major "$1")"
580 KV_MINOR="$(KV_minor "$1")"
581 KV_MICRO="$(KV_micro "$1")"
582 KV_int="$((KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO))"
583
584 # We make version 2.2.0 the minimum version we will handle as
585 # a sanity check ... if its less, we fail ...
586 if [ "${KV_int}" -ge 131584 ]
587 then
588 echo "${KV_int}"
589
590 return 0
591 fi
592
593 return 1
594 }
595
596 # int get_KV()
597 #
598 # return the kernel version (major, minor and micro concated) as an integer
599 #
600 get_KV() {
601 local KV="$(uname -r)"
602
603 echo "$(KV_to_int "${KV}")"
604
605 return $?
606 }
607
608 # bool get_bootparam(param)
609 #
610 # return 0 if gentoo=param was passed to the kernel
611 #
612 # EXAMPLE: if get_bootparam "nodevfs" ; then ....
613 #
614 get_bootparam() {
615 local x=
616 local copt=
617 local parms=
618 local retval=1
619
620 [ ! -e "/proc/cmdline" ] && return 1
621
622 for copt in $(< /proc/cmdline)
623 do
624 if [ "${copt%=*}" = "gentoo" ]
625 then
626 params="$(gawk -v PARAMS="${copt##*=}" '
627 BEGIN {
628 split(PARAMS, nodes, ",")
629 for (x in nodes)
630 print nodes[x]
631 }')"
632
633 # Parse gentoo option
634 for x in ${params}
635 do
636 if [ "${x}" = "$1" ]
637 then
638 # echo "YES"
639 retval=0
640 fi
641 done
642 fi
643 done
644
645 return ${retval}
646 }
647
648 # Safer way to list the contents of a directory,
649 # as it do not have the "empty dir bug".
650 #
651 # char *dolisting(param)
652 #
653 # print a list of the directory contents
654 #
655 # NOTE: quote the params if they contain globs.
656 # also, error checking is not that extensive ...
657 #
658 dolisting() {
659 local x=
660 local y=
661 local tmpstr=
662 local mylist=
663 local mypath="${*}"
664
665 if [ "${mypath%/\*}" != "${mypath}" ]
666 then
667 mypath="${mypath%/\*}"
668 fi
669
670 for x in ${mypath}
671 do
672 [ ! -e "${x}" ] && continue
673
674 if [ ! -d "${x}" ] && ( [ -L "${x}" -o -f "${x}" ] )
675 then
676 mylist="${mylist} $(ls "${x}" 2> /dev/null)"
677 else
678 [ "${x%/}" != "${x}" ] && x="${x%/}"
679
680 cd "${x}"; tmpstr="$(ls)"
681
682 for y in ${tmpstr}
683 do
684 mylist="${mylist} ${x}/${y}"
685 done
686 fi
687 done
688
689 echo "${mylist}"
690 }
691
692 # void save_options(char *option, char *optstring)
693 #
694 # save the settings ("optstring") for "option"
695 #
696 save_options() {
697 local myopts="$1"
698
699 shift
700 if [ ! -d "${svcdir}/options/${myservice}" ]
701 then
702 mkdir -p -m 0755 "${svcdir}/options/${myservice}"
703 fi
704
705 echo "$*" > "${svcdir}/options/${myservice}/${myopts}"
706
707 return 0
708 }
709
710 # char *get_options(char *option)
711 #
712 # get the "optstring" for "option" that was saved
713 # by calling the save_options function
714 #
715 get_options() {
716 if [ -f "${svcdir}/options/${myservice}/$1" ]
717 then
718 echo "$(< ${svcdir}/options/${myservice}/$1)"
719 fi
720
721 return 0
722 }
723
724 # char *add_suffix(char * configfile)
725 #
726 # Returns a config file name with the softlevel suffix
727 # appended to it. For use with multi-config services.
728 add_suffix() {
729 if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -e "$1.${DEFAULTLEVEL}" ]
730 then
731 echo "$1.${DEFAULTLEVEL}"
732 else
733 echo "$1"
734 fi
735
736 return 0
737 }
738
739 getcols() {
740 echo "$2"
741 }
742
743 if [ -z "${EBUILD}" ]
744 then
745 # Setup a basic $PATH. Just add system default to existing.
746 # This should solve both /sbin and /usr/sbin not present when
747 # doing 'su -c foo', or for something like: PATH= rcscript start
748 PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:${PATH}"
749
750 if [ "$(/sbin/consoletype 2> /dev/null)" = "serial" ]
751 then
752 # We do not want colors on serial terminals
753 RC_NOCOLOR="yes"
754 fi
755
756 for arg in $*
757 do
758 case "${arg}" in
759 # Lastly check if the user disabled it with --nocolor argument
760 --nocolor)
761 RC_NOCOLOR="yes"
762 ;;
763 esac
764 done
765
766 if [ -e "/proc/cmdline" ]
767 then
768 setup_defaultlevels
769 fi
770
771 update_splash_wrappers
772 else
773 # Should we use colors ?
774 if [ "${*/depend}" = "$*" ]
775 then
776 # Check user pref in portage
777 RC_NOCOLOR="$(portageq envvar NOCOLOR 2>/dev/null)"
778
779 [ "${RC_NOCOLOR}" = "true" ] && RC_NOCOLOR="yes"
780 else
781 # We do not want colors or stty to run during emerge depend
782 RC_NOCOLOR="yes"
783 fi
784 fi
785
786 if [ "${RC_NOCOLOR}" = "yes" ]
787 then
788 COLS="25 80"
789 ENDCOL=
790
791 GOOD=
792 WARN=
793 BAD=
794 NORMAL=
795 HILITE=
796 BRACKET=
797
798 if [ -n "${EBUILD}" ] && [ "${*/depend}" = "$*" ]
799 then
800 stty cols 80 &>/dev/null
801 stty rows 25 &>/dev/null
802 fi
803 else
804 COLS="`stty size 2> /dev/null`"
805 COLS="`getcols ${COLS}`"
806 COLS=$((${COLS} - 7))
807 ENDCOL=$'\e[A\e['${COLS}'G' # Now, ${ENDCOL} will move us to the end of the
808 # column; irregardless of character width
809
810 GOOD=$'\e[32;01m'
811 WARN=$'\e[33;01m'
812 BAD=$'\e[31;01m'
813 NORMAL=$'\e[0m'
814 HILITE=$'\e[36;01m'
815 BRACKET=$'\e[34;01m'
816 fi
817
818
819 # vim:ts=4

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.20