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

# Content
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 to supplement builtins
21 : ${SYSV_PRI=1} # give sysv scripts priority over lmainit facilities?
22 : ${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 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 done
545 }
546
547 . /etc/rc.values
548
549 ((SYSV_FAC)) && scan_sysv_facs
550
551 :
552
553