updated on Wed Jan 25 20:08:56 UTC 2012
[aur-mirror.git] / fbsplash-extras / fbsplash-extras.sh
blob208ed480d2f52eba30f5ade46cd13f4ea8b6175e
1 #!/bin/bash
3 # /etc/rc.d/functions.d/fbsplash-extras.sh #
5 # Advanced Fbsplash script for Arch Linux Initscripts #
6 # #
7 # Author: Kurt J. Bosch <kjb-temp-2009 at alpenjodel.de> #
8 # Based on the work of: Greg Helton <gt at fallendusk.org> #
9 # Thomas Baechler <thomas at archlinux.org> #
10 # Michal Januszewski <spock at gentoo.org> #
11 # and others #
12 # #
13 # Distributed under the terms of the GNU General Public License (GPL) #
15 # Don't mess if one daemon script runs another (netfs in a loop etc.)
16 (( SPLASH_RC_DAEMON )) && return 0
17 [[ $0 = /etc/rc.d/* ]] && export SPLASH_RC_DAEMON=1
19 # Set $SPLASH_XSERVICE
20 . /etc/conf.d/splash
21 . /etc/conf.d/splash-extras
23 . /sbin/fbsplash-control-functions.bash
25 stat_busy() {
26 printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} "
27 printf "${SAVE_POSITION}"
28 deltext
29 printf " ${C_OTHER}[${C_BUSY}BUSY${C_OTHER}]${C_CLEAR} "
30 SPLASH_BUSY_MSG=$1
31 (( SPLASH_RC_BKGD )) || splash_control push-message "${SPLASH_BUSY_MSG}"
32 return 0
35 stat_append() {
36 printf "${RESTORE_POSITION}"
37 printf -- "${C_MAIN}${1}${C_CLEAR}"
38 printf "${SAVE_POSITION}"
39 SPLASH_BUSY_MSG+=" $1"
40 (( SPLASH_RC_BKGD )) || splash_control push-message "${SPLASH_BUSY_MSG}"
41 return 0
44 stat_fail() {
45 deltext
46 printf " ${C_OTHER}[${C_FAIL}FAIL${C_OTHER}]${C_CLEAR} \n"
47 # Set generic failure service explicitly, write to msglog textbox, save
48 splash_control svc-error
49 splash_control log "Error $SPLASH_BUSY_MSG"
50 splash_svc fail
51 return 0
54 SPLASH_EXTRAS_WORKDIR="/run/fbsplash-extras"
56 export SPLASH_ACTION
57 export SPLASH_SVC
59 # args: [ 'start'|'stop' <service-name> | 'fail' ]
60 splash_svc() {
61 local err_file
62 if [[ $1 != fail ]]; then
63 # End previous service
64 if [[ $SPLASH_SVC ]]; then
65 err_file=${SPLASH_EXTRAS_WORKDIR}/svc_${SPLASH_ACTION}_failed-${SPLASH_SVC}
66 if [[ -f ${err_file} ]]
67 then splash_control svc_${SPLASH_ACTION}_failed "${SPLASH_SVC}"
68 elif [[ $SPLASH_ACTION = "stop" ]]
69 then splash_control svc_stopped "${SPLASH_SVC}"
70 else splash_control svc_started "${SPLASH_SVC}"
73 SPLASH_ACTION=$1
74 SPLASH_SVC=$2
76 [[ $SPLASH_SVC ]] || return 0
77 err_file=${SPLASH_EXTRAS_WORKDIR}/svc_${SPLASH_ACTION}_failed-${SPLASH_SVC}
78 case $1
79 # Mark service as failed hiding any errors in case /run unmounted
80 in fail )
81 ( mkdir -p "${SPLASH_EXTRAS_WORKDIR}" && : >| "${err_file}" ) 2>/dev/null
82 ;; start )
83 [[ $SPLASH_SVC = "$SPLASH_XSERVICE" ]] && splash_end_boot
84 ;;& start | stop )
85 # Begin new service
86 splash_control svc_${SPLASH_ACTION} "${SPLASH_SVC}"
87 # Clean up any old file (from custom pm-utils scripts etc.)
88 [[ -f $err_file ]] && rm -f "${err_file}"
89 esac
92 SPLASH_CONSOLEFONT=$CONSOLEFONT
93 case $0
94 in /etc/rc.sysinit )
95 SPLASH_ACTION="start"
96 # Deferre set_consolefont to avoid splash destruction
97 # (Also simply do this if verbose or off - avoids changing the font in the middle of boot.)
98 CONSOLEFONT=""
99 # If we have no /proc at this point, assume no initcpio was used.
100 # Let the helper parse the kernel cmdline and init the splash or console background,
101 # but don't do this always to avoid visible repaint or 'fbcondecor not supported'
102 # console message (can't be redirected).
103 [[ -f /proc/cmdline ]] || fbcondecor_helper 2 init
104 # Take over splash daemon started in initcpio or start splash ASAP
105 # Note: Devices needed like /dev/fb0 must be provided by initcpio or kernel devtmpfs.
106 add_hook sysinit_start \
107 splash_sysinit_start
108 splash_sysinit_start() {
109 mkdir -p "${SPLASH_EXTRAS_WORKDIR}"
110 # Take over initcpio splash cache tmpfs and running splash daemon if any
111 local dir mp
112 for dir in /run /dev; do
113 mp=$dir/.splash-cache
114 mountpoint -q "$mp" && break
115 mp=""
116 done
117 if [[ $mp ]]; then
118 # Provide /etc/rc.conf HOSTNAME for /etc/conf.d/splash boot message hack
119 # Use existing services list files in initcpio splash-cache
120 HOSTNAME=$HOSTNAME fbsplash-controld start early "$mp" svcs_start_fg
121 elif [[ -c /dev/fb0 ]]; then
122 splash_sysinit_start_splash
124 splash_svc start _devices
126 splash_sysinit_start_splash() {
127 splash_svclist start \
128 "${SPLASH_EXTRAS_WORKDIR}"/svcs_start_fg \
129 >|"${SPLASH_EXTRAS_WORKDIR}"/svcs_start
130 HOSTNAME=$HOSTNAME fbsplash-controld start bootup \
131 "${SPLASH_EXTRAS_WORKDIR}"/svcs_start_fg \
132 "${SPLASH_EXTRAS_WORKDIR}"/svcs_start
134 add_hook sysinit_udevsettled \
135 splash_sysinit_udevsettled
136 splash_sysinit_udevsettled() {
137 # Last chance for framebuffer module to be loaded
138 fbsplash-controld ping || splash_sysinit_start_splash
139 splash_svc start _volumes
141 add_hook sysinit_prefsck \
142 splash_sysinit_prefsck
143 splash_sysinit_prefsck() {
144 splash_svc start _filesystems
146 # Filesystem check progress
147 add_hook sysinit_prefsck splash_prefsck
148 add_hook sysinit_postfsck splash_postfsck
149 # Loop filesystem check (custom) progress
150 add_hook sysinit_prefsckloop splash_prefsck
151 add_hook sysinit_postfsckloop splash_postfsck
153 add_hook sysinit_postmount \
154 splash_sysinit_postmount
155 splash_sysinit_postmount() {
156 splash_svc start _misc
158 add_hook sysinit_end \
159 splash_sysinit_end
160 splash_sysinit_end() {
161 # Dummy service for SysV-Init 'boot' and running theme hooks
162 # May also be used for $SPLASH_XSERVICE to stop the splash at end of rc.sysinit
163 splash_svc start fbsplash-boot-dummy
165 ;; /etc/rc.multi )
166 if [[ $PREVLEVEL = N ]]; then
167 SPLASH_ACTION="start"
168 add_hook multi_start \
169 splash_multi_start
170 splash_multi_start() {
171 # Dummy service for SysV-Init 'boot' and running theme hooks
172 splash_control svc_started fbsplash-boot-dummy
175 # Stop/paint/fadeout splash if still running before enabling login / starting X
176 add_hook multi_end \
177 splash_multi_end
178 splash_multi_end() {
179 # Avoid race condition and don't change to splash VT again if X already started
180 [[ $SPLASH_XSERVICE != fbsplash-boot-dummy ]] && ck_autostart "$SPLASH_XSERVICE" || return 0
181 [[ $PREVLEVEL = N ]] && splash_end_boot
182 fbsplash-chvt
184 ;; /etc/rc.d/"$SPLASH_XSERVICE" )
185 # Stop the splash staying on or changing to the splash TTY before starting X
186 case $1
187 in start )
188 # chvt even if no splash was to stop
189 fbsplash-chvt splash || :
190 ;; stop )
191 # If not shutdown/reboot, override X change to splash VT
192 [[ $RUNLEVEL != [06] ]] && SPLASH_FGCONSOLE=$( fgconsole ) &&
193 splash_set_trap "fbsplash-chvt --wait $SPLASH_FGCONSOLE" EXIT || :
194 esac
195 ;; /etc/rc.single )
196 # On Single-user boot, drop any splash unmounting tmpfs to allow clean mkinitcpio
197 # Switch to console (on runlevel change, after Xorg was killed)
198 if [[ $PREVLEVEL = N ]]; then
199 SPLASH_ACTION="start"
200 add_hook single_start \
201 splash_single_start
202 splash_single_start() {
203 # Dummy service for SysV-Init 'boot' and running theme hooks
204 splash_control svc_start_failed fbsplash-boot-dummy
205 fbsplash-controld stop force
206 set_consolefont
207 fbsplash-chvt 1
209 elif get_pid Xorg >/dev/null; then
210 add_hook single_postkillall \
211 splash_single_postkillall
212 splash_single_postkillall() {
213 fbsplash-chvt 1
216 ;; /etc/rc.shutdown )
217 SPLASH_ACTION="stop"
218 add_hook shutdown_start \
219 splash_shutdown_start
220 splash_shutdown_start() {
221 # No deferred start on SPLASH_XSERVICE to avoid delay
222 # X should chvt to splash tty
223 mkdir -p "${SPLASH_EXTRAS_WORKDIR}"
224 splash_svclist stop \
225 "${SPLASH_EXTRAS_WORKDIR}"/svcs_stop_fg \
226 >|"${SPLASH_EXTRAS_WORKDIR}"/svcs_stop
227 local mode="shutdown"
228 [[ $RUNLEVEL = 6 ]] && mode="reboot"
229 fbsplash-controld start $mode \
230 "${SPLASH_EXTRAS_WORKDIR}"/svcs_stop_fg "" \
231 "${SPLASH_EXTRAS_WORKDIR}"/svcs_stop
232 (( $? )) && return 0
233 local file
234 for file in /run/fbsplash{,-control}d.pid; do
235 [[ -f $file ]] && add_omit_pids $( <"$file" )
236 done
238 add_hook shutdown_prekillall \
239 splash_shutdown_prekillall
240 splash_shutdown_prekillall() {
241 # Currently we don't have shutdown_preumount and don't want to store ## FIXME ##
242 # SIGTERM/SIGKILL times, which may vary depending on programs actually running,
243 # as the last two (SIGTERM takes full 5 seconds if no response from some process)
244 splash_control store
245 splash_svc stop _misc
247 add_hook shutdown_postkillall \
248 splash_shutdown_postkillall
249 splash_shutdown_postkillall() {
250 splash_svc stop _filesystems
252 # Shutdown filesystem check (custom) progress
253 add_hook shutdown_prefsck splash_prefsck
254 add_hook shutdown_postfsck splash_postfsck
256 add_hook shutdown_postumount \
257 splash_shutdown_postumount
258 splash_shutdown_postumount() {
259 splash_svc stop _volumes
261 add_hook shutdown_poweroff \
262 splash_shutdown_poweroff
263 splash_shutdown_poweroff() {
264 splash_svc
265 fbsplash-controld stop
267 esac
269 start_daemon() {
270 splash_rc_d "$1" start
272 start_daemon_bkgd() {
273 stat_bkgd "Starting $1"
274 # Don't hide errors - we wan't to see them if SPLASH_VERBOSE_ON_ERRORS=yes
275 have_daemon "$1" && ( SPLASH_SVC="" SPLASH_RC_BKGD=1 splash_rc_d "$1" start ) >/dev/null &
277 stop_daemon() {
278 splash_rc_d "$1" stop
281 # args: <daemon> start|stop
282 splash_rc_d() {
283 local action=$2
284 splash_svc "$action" "$1"
285 have_daemon "$1" && /etc/rc.d/"$1" "$action"
286 local ret=$?
287 (( ret )) && splash_svc fail
288 splash_svc
289 return $ret
292 splash_end_boot() {
293 splash_control store
294 fbsplash-controld stop
295 CONSOLEFONT=$SPLASH_CONSOLEFONT
296 set_consolefont
299 # Echo list of services relevant for icons (for theme hooks using splash_svclist_get)
300 # Write list of services relevant for progress (foreground) to given file (if any)
301 # args: 'start'|'stop' [<svcs-progress-list-file>]
302 # Note: These are also called from fbsplash-initscripts-services-get.
303 splash_svclist() {
304 local svcs_fg=${2:-/dev/null}
305 : >|"$svcs_fg" || return 1
306 # rc.sysinit/rc.shutdown Pseudo services triggered via run_hook
307 local -a pseudo_svcs=( )
308 [[ $1 = start ]] && pseudo_svcs+=( _devices )
309 pseudo_svcs+=( _volumes _filesystems _misc )
310 case $1 in
311 start )
313 start_daemon() {
314 echo "${1}"
315 echo "${1}" >>"$svcs_fg"
317 start_daemon_bkgd() {
318 echo "${1}"
320 # Internal dummy service for SysV-Init 'boot' and running theme hooks
321 # May also be used for $SPLASH_XSERVICE to stop the splash at end of rc.sysinit
322 # (start only - hidden from fbsplash-initscripts-services-get)
323 [[ $PREVLEVEL = N ]] && pseudo_svcs+=( fbsplash-boot-dummy )
324 # Code derived from /etc/rc.multi
325 for daemon in "${pseudo_svcs[@]}" "${DAEMONS[@]}"; do
326 case $daemon
327 in '!'* ) continue
328 ;; "$SPLASH_XSERVICE" | '@'"$SPLASH_XSERVICE" ) break
329 ;; '@'* ) start_daemon_bkgd "${daemon#@}"
330 ;; * ) start_daemon "$daemon"
331 esac
332 done
334 ;; stop )
336 stop_daemon() {
337 echo "${1}"
338 echo "${1}" >>"$svcs_fg"
340 stop_all_daemons
341 for (( i=${#pseudo_svcs[@]}-1; i>=0; i-- )); do
342 stop_daemon "${pseudo_svcs[i]}"
343 done
345 esac
348 # Start daemon for pushing progress info from
349 # 'fsck -C$FSCK_FD' to the splash status message line
350 splash_prefsck() {
351 # If no splash, do nothing
352 fbsplash-controld ping || return 0
353 stat_busy "Starting Splash Filesystem Check Progress Daemon"
354 fbsplash-controld fsckd start && exec {FSCK_FD}>"/run/fbsplash-fsckd.fifo"
355 (( $? == 0 )) && stat_done || stat_fail
358 splash_postfsck() {
359 # fsck seems to push progress updates asynchronously in the background
360 if [[ $FSCK_FD ]]; then
361 status "Stopping Splash Filesystem Check Progress Daemon"
362 fbsplash-controld fsckd stop
363 exec {FSCK_FD}>&-
364 unset FSCK_FD
366 # fsck failure emergency exit
367 if (( ( fsckret | fsckret_loop | 33 ) != 33 )); then
368 # Abort splash unmounting the splash cache tmpfs
369 fbsplash-controld stop force
370 fbsplash-chvt 1
374 # Function for preparing a cache (faking sysinit) for adding contents to an initrd
375 # Note: This is called from /lib/initcpio/install/fbsplash (after sourcing splash stuff)
376 splash_cache_prep_initcpio() {
377 SPLASH_MODE_REQ="silent"
378 SPLASH_PROFILE="off"
380 ( splash_cache_prep ) && [[ $spl_cachedir ]] && cd "$spl_cachedir" || exit 1
381 export PREVLEVEL=N RUNLEVEL=S
382 . /etc/rc.conf
383 CONSOLEFONT=""
384 splash_svclist start svcs_start_fg >|svcs_start
385 splash_run_hooks pre rc_init sysinit $RUNLEVEL
386 # Write a clean initial profile mainly for splash_manager -c replay
387 echo 0.00: pre rc_init sysinit $RUNLEVEL >|profile
388 exit 0
389 ) || return 1
390 # Cleanup at mkinitcpio exit
391 splash_set_trap splash_cache_cleanup_initcpio EXIT ||
392 warning "WARNING: Unable to do umount '$spl_cachedir' and cleanup at exit."
393 return 0
396 # Run remaining rc_init/rc_exit hooks for theme specific cleanup (arch-banner themes)
397 # Unmount the tmpfs
398 splash_cache_cleanup_initcpio() {
400 [[ $spl_cachedir ]] && cd "$spl_cachedir" || exit 0
401 export PREVLEVEL=N RUNLEVEL=S
402 splash_run_hooks post rc_init sysinit $RUNLEVEL
403 splash_run_hooks "pre post" rc_exit $RUNLEVEL
404 RUNLEVEL=5
405 splash_run_hooks "pre post" rc_init boot $RUNLEVEL
406 splash_run_hooks pre rc_exit $RUNLEVEL
407 umount -l "${spl_cachedir}" # splash_cache_cleanup mount --move fails silently in chroot
408 cd /
409 splash_run_hooks post rc_exit $RUNLEVEL
413 # Run theme hooks for SPLASH_THEMES
414 # args: 'pre'|'post'|'pre post' <event> [arg]...
415 splash_run_hooks() {
416 local pp=$1 event=$2 args=( "${@:3}" )
417 shift
418 local p
419 for p in $pp; do
420 local -A done=()
421 local theme
422 for theme in $SPLASH_THEMES; do
423 theme=${theme%%/*}
424 (( done[$theme] )) && continue
425 local hook=/etc/splash/$theme/scripts/${event}-$p
426 [[ -x $hook ]] && SPLASH_THEME=$theme "$hook" "${args[@]}"
427 done[$theme]=1
428 done
429 done
432 # Set a trap command
433 # args: <trap-arg> <signal-spec>...
434 splash_set_trap() {
435 local arg=$1
436 shift
437 # Don't mess with disabled signals or any
438 # quoted command strings already set, but fail
439 [[ -z $( trap -p "$@" ) ]] && trap "$arg" "$@"
442 # EOF #