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

# 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 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