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

Contents of /trunk/sbin/functions.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 465 - (show annotations) (download) (as text)
Sun Feb 15 20:01:09 2004 UTC (15 years, 8 months ago) by azarah
File MIME type: text/x-sh
File size: 15746 byte(s)
Add RC_TTY_NUMBER to /etc/conf.d/rc to configure how many tty devices
are used in scripts such as consolefonts, numlock, etc.  This should
close bug #39863.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.20