ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/lmainit/syslib.sh
Revision: 1.1
Committed: Sat Dec 7 21:49:49 2002 UTC (21 years, 5 months ago) by root
Content type: application/x-sh
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #/bin/bash
2    
3     # $syslib mustn't contain spaces (shell language limitation)
4    
5     [ -e /proc/progress ] && echo 110 >/proc/progress
6    
7     PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin"
8    
9     : ${syslib:=/etc/rc.d} # currently hardcoded in facility
10     : ${facdir:=$syslib/fac}
11    
12     VERSION=1.1
13     VENDOR_STRING="lma-init $VERSION"
14    
15     : ${CONSOLE:=/dev/console} # default console
16     : ${SUTIMEOUT:=20} # default sulogin timeout (see fatal)
17     : ${RCDIR:=/etc} # where SYSVINIT-style rcX.d files are located
18     : ${SYSVINIT:=0} # defaults for SYSV_EXEC and SYSV_FAC
19     : ${SYSV_EXEC=$SYSVINIT} # execute sysv-scripts in $RCDIR/rc?.d/[SK][0-9][0-9]*
20     : ${SYSV_FAC=$SYSVINIT} # scripts in $RCDIR/init.d/* are used overwrite builtins
21     : ${COALESCE:=1}
22     : ${SULOGIN:=sulogin}
23     : ${SINGLESTEP:=0}
24    
25     shopt -s extglob
26    
27     # load additional commands
28     enable -f $syslib/lmainit.so console setsid winsize renamefunc usleep str2hex
29    
30     color_r() {
31     r="[$1m"
32     }
33    
34     tgoto_r() {
35     r="[$(($1+1));$(($2+1))H"
36     }
37    
38     setscrreg_r() {
39     r="[$(($1+1));$(($2+1))r"
40     }
41    
42     tgoto() { tgoto_r "$@"; echo -n "$r"; }
43     color() { color_r "$@"; echo -n "$r"; }
44    
45     clear=""
46     clreol=""
47     delline=""
48     save_cursor="7"
49     restore_cursor="8"
50    
51     reset() {
52     echo -n "c"
53     }
54    
55     initscreen() {
56     eval $(winsize)
57     }
58    
59     declare -a fac_args
60    
61     find_facility() {
62     local fac_mode="${1:0:1}"
63     local fac="${1:1}"
64     local args arg i
65     fac_name="${fac%%::*}"
66     local ref="fac_${fac_name}_desc"
67     if [ -z "${!ref}" ]; then
68     # try to load the facility
69     if [ -r "$facdir/$fac_name.fac" ] ; then
70     . "$facdir/$fac_name.fac"
71     fi
72     fi
73     if [ -n "${!ref}" ]; then
74     case "$fac" in
75     *::* ) args="${fac#*::}" ;;
76     * ) args="" ;;
77     esac
78     IFS=: eval 'fac_args=($args)'
79     set -- "${fac_args[@]}"
80     eval fac_desc="\"${!ref}\""
81     if [ "$fac_mode" == "+" ]; then
82     fac_mode="start"
83     else
84     fac_mode="stop"
85     fi
86     fac_run="fac_${fac_name}_${fac_mode} \"\${fac_args[@]}\""
87     return 0
88     else
89     fac_desc="$fac_name: no such facility"
90     fac_run=false
91     return 1
92     fi
93     }
94    
95     #############################################################################
96     # Shamelessly stolen from the bash distribution.
97     # This is ugly code, and I believe my version would have been faster.
98     # Arrogance is a pity.
99     # But my version would definitely be much shorter!
100    
101     # usage: reverse arrayname
102     reverse()
103     {
104     local -a R
105     local -i i
106     local rlen temp
107    
108     # make r a copy of the array whose name is passed as an arg
109     eval R=\( \"\$\{$1\[@\]\}\" \)
110    
111     # reverse R
112     rlen=${#R[@]}
113    
114     for ((i=0; i < rlen/2; i++ ))
115     do
116     temp=${R[i]}
117     R[i]=${R[rlen-i-1]}
118     R[rlen-i-1]=$temp
119     done
120    
121     # and assign R back to array whose name is passed as an arg
122     eval $1=\( \"\$\{R\[@\]\}\" \)
123     }
124    
125     #############################################################################
126    
127     declare -i _cnt
128    
129     # start a facility definition
130     def() {
131     _name="$1"; shift
132     _desc="$*"
133    
134     end() {
135     renamefunc start "fac_${_name}_start"
136     renamefunc stop "fac_${_name}_stop"
137     eval fac_${_name}_desc='"$_desc"'
138    
139     unset end enddef desc _name _desc
140     }
141     enddef() { end; }
142    
143     desc() {
144     _desc="$*"
145     }
146    
147     start() { :; }
148     stop() { :; }
149     }
150    
151     # start a facility sequence
152     defseq() {
153     _cnt=0
154    
155     eval '
156     fac_'$1'_seq=()
157    
158     add() {
159     fac_'$1'_seq[_cnt++]="$1"
160     }
161    
162     fac_'$1'_desc="$2"
163     fac_'$1'_start() {
164     for fac in "${fac_'$1'_seq[@]}"; do
165     if [ "${fac:0:1}" != "-" ]; then
166     find_facility "+${fac#+}"
167     eval "$fac_run"
168     fi
169     done
170     }
171     fac_'$1'_stop() {
172     for fac in "${fac_'$1'_seq[@]}"; do
173     if [ "${fac:0:1}" != "+" ]; then
174     find_facility "-${fac#-}"
175     eval "$fac_run"
176     fi
177     done
178     }
179     '
180    
181     end() {
182     unset add end _cnt
183     }
184     }
185    
186     defrl() {
187     _cnt=0
188    
189     eval '
190     add() {
191     _rl_'$1'[_cnt++]="$1"
192     }
193     '
194    
195     end() {
196     unset add end _cnt
197     }
198     }
199    
200     # define an alias (name, description, alias)
201     defalias() {
202     # this was a major speed bottleneck,
203     # now it's just a readability bottleneck
204     eval '
205     fac_'$1'_desc="$2"
206     fac_'$1'_alias="$3"
207     fac_'$1'_start() {
208     find_facility "+$fac_'$1'_alias"
209     eval "$fac_run"
210     }
211     fac_'$1'_stop() {
212     find_facility "-$fac_'$1'_alias"
213     eval "$fac_run"
214     }
215     '
216     }
217    
218     #############################################################################
219    
220     fatal() {
221     echo "$@"
222     echo "you have $SUTIMEOUT seconds to log-in as root, otherwise booting will continue"
223     $SULOGIN -t $SUTIMEOUT
224     }
225    
226     # evaluate command and, if exit-status is non-zero,
227     # ask the user wether she wants to log-in (by starting sulogin)
228     safe_eval() {
229     if ! ( "$@" ); then
230     fatal "an error occured while running '$@'"
231     fi
232     }
233    
234     daemonize() {
235     {
236     cd /
237     setsid
238     exec "$@"
239     exit 127
240     } &
241     }
242    
243     kill_pidfile() {
244     local signal="$1"
245     local path="$2"
246     local pidfile="$3"
247     local pid
248     if [ -n "$pidfile" -a -r "$pidfile" ]; then
249     read pid <"$pidfile"
250     fi
251     if ((pid>0)); then
252     kill -$signal $pid || echo "$path: pidfile exists, but no process found"
253     elif [ -n "$path" ]; then
254     [ -n "$pidfile" ] && echo "$path: unable to find pidfile, trying killall instead"
255     killall -$signal "$path"
256     fi
257     }
258    
259     declare -a facilities
260    
261     _get_facilities() {
262     local RL="$1"
263     local mode="$2"
264     local i=0 j
265    
266     local omode="-"; [ $mode == "-" ] && omode="+"
267    
268     local -a facs
269     eval facs=(\"\${_rl_$RL[@]}\")
270     for fac in "${facs[@]}"; do
271     if [ "$fac" == "${fac#$omode}" ]; then # facilities not prefixed with OMODE are also o.k.
272     fac="${fac#$mode}" # facilities prefixed with the MODE are o.k.
273     if [ "$fac" == "${fac#@}" ]; then
274     j=${#facilities[@]}
275     facilities[j]="$mode$fac"
276     else
277     _get_facilities "${fac#@}" "$mode"
278     fi
279     fi
280     done
281     }
282    
283     new_facilities() {
284     facilities=()
285     }
286    
287     declare -i _sysvfac_cnt=0
288    
289     add_facilities() {
290     _get_facilities "$1" "$2"
291    
292     # optionally check for sysv facilities
293     if ((SYSV_EXEC)); then
294     local prefix=S fac j
295     [[ "$2" == "-" ]] && prefix=K
296     local -a sysvfac
297     prefix="$RCDIR/rc$1.d/$prefix[0-9][0-9]"
298     for scr in $prefix*; do
299     if [ -x "$scr" ]; then
300     fac="_sysvfac$_sysvfac_cnt"
301     eval "fac_${fac}_desc"='"${scr#$prefix}"'
302     eval "
303     fac_${fac}_start() {
304     \"$scr\" start
305     }
306     fac_${fac}_stop() {
307     \"$scr\" stop
308     }
309     "
310     sysvfac[_sysvfac_cnt++]="$2$fac"
311     fi
312     done
313     [[ "$2" == "-" ]] && reverse sysvfac
314     facilities=("${facilities[@]}" "${sysvfac[@]}")
315     fi
316     }
317    
318     rev_facilities() {
319     reverse facilities
320     }
321    
322     # check facilities for dupes ("-mysqld +mysqld" and remove them both)
323     coalesce_facilities() {
324     local -a _facilities
325    
326     _facilities=("${facilities[@]}")
327     facilities=()
328    
329     # pass 1, find dupes
330     for fac in "${_facilities[@]}"; do
331     if [ "${fac:0:1}" == "-" ]; then
332     eval local off_$(str2hex "${fac:1}")=1
333     elif eval '(($'off_$(str2hex "${fac:1}")'))'; then
334     eval local ignore_$(str2hex "${fac:1}")=1
335     fi
336     done
337    
338     # pass 2, copy all unique facility changes
339     local -i cnt=0
340     for fac in "${_facilities[@]}"; do
341     if ! eval '(($'ignore_$(str2hex "${fac:1}")'))'; then
342     facilities[cnt++]="$fac"
343     fi
344     done
345     }
346    
347     # gay penguin
348     pengo1_r() {
349     r="\
350      . .
351       
352           
353           
354         
355       \`----' 
356       ...... 
357       ........ 
358       ......... 
359       ......... 
360       ..........
361       ..........
362       ........ 
363       ........ 
364       ........
365        ......  "
366     }
367    
368     # fat penguin
369     pengo2_r() {
370     r="\
371     #######################
372     #######################
373     ##########O#O##########
374     #######################
375     #######################
376     #######################
377     #######################
378     #######################
379     #######################
380     #######################
381     #######################
382     #######################"
383     }
384    
385     #
386     # title:
387     # ---(VENDOR_STRING)------------------(TITLE)--------------------------------
388     # or
389     # ----------------------------------(TITLE)----------------------------------
390    
391     _bars="------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
392    
393     show_title () {
394     local opt="$1"
395     local -i offs=0
396    
397     tgoto 0 0
398     color 37
399     echo -n "${_bars:0:$cols}"
400    
401     if [ -n "$VENDOR_STRING" ] ; then
402     offs=$(((${#VENDOR_STRING})+6))
403     tgoto 0 3
404     echo -n "("
405     color 33
406     echo -n "$VENDOR_STRING"
407     color 37
408     echo -n ")"
409     color 33
410     fi
411     tgoto 0 $(((cols-offs-${#opt})/2+offs))
412     echo -n "("
413     color 33
414     echo -n "$opt"
415     color 37
416     echo -n ")"
417     color 36
418     }
419    
420     #< w1 >< w2 >
421     ##################################^
422     # pengo title #h1
423     # pengo #
424     # pengo x1 #
425     # xn #v
426     #________________________________#
427     # #
428     ##################################
429     run_facilities() {
430     local title="$1"
431    
432     ((COALESCE)) && coalesce_facilities
433    
434     ((DRY_RUN)) || console "$CONSOLE"
435     initscreen
436    
437     local -i nfac=${#facilities[@]}
438     local -i h1=rows/3
439     local -i w1=PENGUIN?24:0
440     local -i w2=cols-w1
441     local -i y n wfac
442     local pengo
443    
444     color "31;44;1"; local C_error="$r"
445     color "36;44;1"; local C_fac="$r"
446     color "33"; local C_desc="$r"
447     color "37"; local C_text="$r"
448    
449     tgoto_r 1 0; pengo="$r"
450    
451     ((h1>nfac+2)) && h1=nfac+2
452     if ((PENGUIN==1)); then
453     ((h1<18)) && h1=18
454     pengo1_r; pengo="$pengo$r"
455     elif ((PENGUIN==2)); then
456     ((h1<14)) && h1=14
457     pengo2_r; pengo="$pengo$r"
458     fi
459    
460     pengo="$pengo$C_fac"
461    
462     echo -n "$C_fac$fac$clear"
463     show_title "$title"
464     echo -n "$pengo"
465    
466     wfac=h1-1
467     if ((wfac>nfac)); then
468     wfac=nfac
469     fi
470     for((y=0; y<wfac; y++)); do
471     find_facility "${facilities[y]}"
472     tgoto_r $((y+1)) $w1
473     echo -n "$r [ ] $fac_desc"
474     done
475    
476     tgoto $((h1-1)) 0
477     color "37"
478     echo -n ${_bars:0:$cols}
479     color "36"
480    
481     y=0 n=0
482     setscrreg_r $h1 $((rows-1)); echo -n "$r"
483     tgoto $((rows-1)) 0
484    
485     setscrreg_r 1 $((h1-2)); local scrollup="$r"
486     tgoto_r 1 0; scrollup="$scrollup$r$delline"
487     ((SLOW_TERMINAL)) || scrollup="$scrollup$pengo$C_fac"
488     setscrreg_r $h1 $((rows-1)); scrollup="$scrollup$r"
489     tgoto_r $((rows-1)) 0; scrollup="$scrollup$r"
490    
491     for fac in "${facilities[@]}"; do
492     find_facility "${facilities[n++]}"
493     if ((y<h1-2)); then
494     y=y+1
495     else
496     echo -n "$scrollup"
497     fi
498     tgoto_r $y $w1
499     echo "$save_cursor${r} [*] $fac_desc$restore_cursor[ $C_desc$fac_desc$C_fac ]$clreol$C_text"
500     unset ERR
501     ((DRY_RUN)) || eval "$fac_run"
502     tgoto_r $y $((w1+2))
503     if [ -z "$ERR" ]; then
504     echo -n "$C_fac$save_cursor${r}X$restore_cursor"
505     else
506     echo -n "$C_error$save_cursor${r}*$restore_cursor$ERR$C_fac"
507     fi
508     if ((SINGLESTEP)); then
509     stty -echo
510     echo -n "${C_error}singlestepping, please press enter to continue... $C_fac"
511     read r
512     stty echo
513     echo -n " $clreol"
514     fi
515     done
516    
517     setscrreg_r 0 $((rows-1)); echo -n "$r"
518     if ((RESET)); then
519     reset
520     else
521     tgoto $((rows-1)) 0
522     fi
523     }
524    
525     # scan sysv-facilities by name in $RCDIR/init.d/* and
526     # create real facilities from them
527     scan_sysv_facs() {
528     for path in $RCDIR/init.d/*; do
529     local fac=${path#$RCDIR/init.d/}
530     fac=${fac//[^a-zA-Z0-9_]/_}
531     eval "fac_${fac}_desc"='"$path"'
532     eval "
533     fac_${fac}_start() {
534     \"$path\" start
535     }
536     fac_${fac}_stop() {
537     \"$path\" stop
538     }
539     "
540     done
541     }
542    
543     . /etc/rc.values
544    
545     ((SYSV_FAC)) && scan_sysv_facs
546    
547     :
548    
549