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