| 1 |
#!/bin/sh
|
| 2 |
|
| 3 |
# /etc/init.d/splashy-init
|
| 4 |
|
| 5 |
# Copyright 2005, 2006 Splashy Project http://alioth.debian.org/projects/splashy
|
| 6 |
# Copyright 2005, 2006 Jacobo Vilella (aka Jacobo221) <jacobo221@gmail.com>
|
| 7 |
#
|
| 8 |
# This file is part of Splashy.
|
| 9 |
#
|
| 10 |
# Splashy is free software; you can redistribute it and/or
|
| 11 |
# modify it under the terms of the GNU General Public
|
| 12 |
# License as published by the Free Software Foundation;
|
| 13 |
# either version 2 of the License, or (at your option) any
|
| 14 |
# later version.
|
| 15 |
#
|
| 16 |
# Splashy is distributed in the hope that it will be useful,
|
| 17 |
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
| 18 |
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 19 |
# See the GNU General Public License for more details.
|
| 20 |
#
|
| 21 |
# You should have received a copy of the GNU General Public
|
| 22 |
# License along with Splashy; if not, write to the Free
|
| 23 |
# Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
| 24 |
# Boston, MA 02110-1301 USA
|
| 25 |
|
| 26 |
# init script for the service splashy
|
| 27 |
# Read details about this script in the Readme.txt file
|
| 28 |
|
| 29 |
### BEGIN INIT INFO
|
| 30 |
# Provides: splashy
|
| 31 |
# Required-Start:
|
| 32 |
# Should-Start: mountvirtfs
|
| 33 |
# Required-Stop:
|
| 34 |
# Should-Stop:
|
| 35 |
# Default-Start: S 2 3 4 5
|
| 36 |
# Default-Stop: 0 2 3 4 5 6
|
| 37 |
# Short-Description: splashy daemon used for presenting a boot splash for Linux
|
| 38 |
# Description: The splashy service is used for starting a user-space boot
|
| 39 |
# splash utility that draws an image and a progress bar while the system
|
| 40 |
# is booting.
|
| 41 |
# X-UnitedLinux-Default-Enabled: yes
|
| 42 |
### END INIT INFO
|
| 43 |
|
| 44 |
# COMMENTS:
|
| 45 |
# - Debug lines easily removable: delete all lines containing "DEBUG" or "debug"
|
| 46 |
#
|
| 47 |
# TODO:
|
| 48 |
# - splashy_pgrep... must go away :)
|
| 49 |
# - Support fsck
|
| 50 |
#
|
| 51 |
# NOT TODO:
|
| 52 |
# - The script does not support filenames with spaces in /etc/rc?.d/*, but
|
| 53 |
# supporting it would add too much mess to the script and no one really
|
| 54 |
# has that
|
| 55 |
# - Determine the scripts that will be run more acuratelly by not including
|
| 56 |
# those that will not be started/stopped by an optimized rc(S) script,
|
| 57 |
# because:
|
| 58 |
# * There is no way to be sure that the optimization will happen
|
| 59 |
# * It is too CPU expensive
|
| 60 |
### END NOTES INFO
|
| 61 |
|
| 62 |
SC_NAME="${0##*/}"
|
| 63 |
NAME="splashy"
|
| 64 |
DESC="Splashy client"
|
| 65 |
|
| 66 |
# Script-only options. Do not touch unless you know what you are doing
|
| 67 |
CONFIG="/etc/default/splashy"
|
| 68 |
#CHANGE: Once splashy_config --check works, return code should tell also if the
|
| 69 |
# file does not exist, thus the $XML_CONFIG variable will be useless
|
| 70 |
XML_CONFIG="/etc/splashy/config.xml"
|
| 71 |
SC_SLEEP="0.5"
|
| 72 |
#CHANGE: Make it into config.xml? Anyway, check in config_parse
|
| 73 |
CONSOLE="/dev/vcs1"
|
| 74 |
|
| 75 |
# LSB strongly recommends not to trust $PATH
|
| 76 |
PATH=/bin:/sbin
|
| 77 |
|
| 78 |
### BEGIN MAIN FUNCTIONS
|
| 79 |
# Load LSB's functions
|
| 80 |
# Why adding this here instead of only where it is needed? LSB's init-functions
|
| 81 |
# file could run some inline commands which should be run on all init scripts
|
| 82 |
if test -r /lib/lsb/init-functions; then
|
| 83 |
. /lib/lsb/init-functions
|
| 84 |
else
|
| 85 |
# Simulate LSB functions if the real ones are not available
|
| 86 |
echo "Please install LSB init-funcitons!"
|
| 87 |
log_begin_msg() { echo $@; }
|
| 88 |
log_end_msg() { if test $1 -eq 0; then echo done; else echo failed; fi;}
|
| 89 |
log_succees_msg() { echo $@; }
|
| 90 |
log_warning_msg() { echo $@; }
|
| 91 |
log_failure_msg() { echo $@; }
|
| 92 |
fi
|
| 93 |
|
| 94 |
# Provide an interface to be able to silent commands not bothering if
|
| 95 |
# If -2 is first argument, only stderr is silenced
|
| 96 |
# If -S is first argument, command will be silenced even when /dev/null doesn't
|
| 97 |
# exist and will return true if the command had no output and false otherwise
|
| 98 |
# This only applies to the cases when no /dev/null exists
|
| 99 |
# If -s is first argument, same as when -S, but returns true/false inveresly
|
| 100 |
# Options -S and -s imply -2
|
| 101 |
# Since debug() already calls silent() do not use debug in this function
|
| 102 |
silent() {
|
| 103 |
if test "$1" = -2; then
|
| 104 |
smode=2
|
| 105 |
shift
|
| 106 |
elif test "$1" = -S; then
|
| 107 |
smode=S
|
| 108 |
shift
|
| 109 |
elif test "$1" = -s; then
|
| 110 |
smode=s
|
| 111 |
shift
|
| 112 |
fi
|
| 113 |
if test -c /dev/null; then
|
| 114 |
if test "$smode" = 2; then
|
| 115 |
"$@" 2>/dev/null
|
| 116 |
else
|
| 117 |
"$@" >/dev/null 2>&1
|
| 118 |
fi
|
| 119 |
else
|
| 120 |
if test "$smode" = S; then
|
| 121 |
"$@" 2>&1 | if read i; then false; else true; fi
|
| 122 |
elif test "$smode" = s; then
|
| 123 |
"$@" 2>&1 | if read i; then true; else false; fi
|
| 124 |
else
|
| 125 |
# Cannot silence it
|
| 126 |
"$@"
|
| 127 |
fi
|
| 128 |
fi
|
| 129 |
}
|
| 130 |
# Output debug info passed as arguments when $DEBUG is enabled
|
| 131 |
# Return 0 when debug mode is set. Return 1 otherwise
|
| 132 |
# When -S is set, it only have effect when DEBUG=2, return 1 otherwise
|
| 133 |
debug() {
|
| 134 |
debugnull=""
|
| 135 |
is_enabled $DEBUG || return 1
|
| 136 |
test "$1" = -S && if test "$DEBUG" = 2; then shift; else return 1; fi
|
| 137 |
test -w /dev/null || debugnull=" (/dev/null doesn't exist)"
|
| 138 |
if test $# -gt 0 && is_enabled "$LOG"; then # debug log
|
| 139 |
# On boot fs is ro. Buffer until it is writtable # debug log
|
| 140 |
# we cannot trust test -w # debug log
|
| 141 |
# Also, touching the file makes sure the file exists by the time
|
| 142 |
# echo >> $LOG is executed
|
| 143 |
if silent -S touch "$LOG"; then # debug log
|
| 144 |
test -n "$LOGBUFF" && # debug log
|
| 145 |
echo -e "$LOGBUFF" >> "$LOG" && # debug log
|
| 146 |
unset LOGBUFF # debug log
|
| 147 |
echo -e "$$: $*$debugnull" >> "$LOG" # debug log
|
| 148 |
else # debug log
|
| 149 |
LOGBUFF="$(echo $LOGBUFF"\n"$$: $*$debugnull)" # debug log
|
| 150 |
fi # debug log
|
| 151 |
fi # debug log
|
| 152 |
test $# -gt 0 && echo -e "=Splashy debug ($$)=: $*$debugnull"; return 0; }
|
| 153 |
export LOGBUFF # Must be exported so daemon gets the debug log from Start
|
| 154 |
|
| 155 |
# Check if $1 is a number
|
| 156 |
# It requires another number as $2 to check this. Some number which $1 can
|
| 157 |
# never be
|
| 158 |
is_number() {
|
| 159 |
silent -S test "$1" -ne "$2"
|
| 160 |
}
|
| 161 |
|
| 162 |
# Return true when $1 is an 'enable value'
|
| 163 |
is_enabled() {
|
| 164 |
local value
|
| 165 |
test $# -lt 1 && return 1
|
| 166 |
for value in "" 0 no No NO disable Disable DISABLE false False FALSE \
|
| 167 |
disabled Disabled DISABLED; do
|
| 168 |
test "$1" = "$value" && return 1
|
| 169 |
done
|
| 170 |
return 0
|
| 171 |
}
|
| 172 |
|
| 173 |
# This function shows the error message <msg> and exists with code <code>
|
| 174 |
# By default, code is 1
|
| 175 |
# error <msg> [code]
|
| 176 |
# error <code>
|
| 177 |
error() {
|
| 178 |
is_enabled "$initmsg_call" && log_end_msg 1
|
| 179 |
debug "Error(): $2"
|
| 180 |
if test $# -gt 1; then
|
| 181 |
if test $2 -eq 0; then
|
| 182 |
log_warning_msg "$1"
|
| 183 |
else
|
| 184 |
log_failure_msg "$1"
|
| 185 |
fi
|
| 186 |
exit $2
|
| 187 |
else
|
| 188 |
log_failure_msg "$1"
|
| 189 |
exit 1
|
| 190 |
fi
|
| 191 |
}
|
| 192 |
|
| 193 |
# This function just checks if, given a path patter, at least one file exists
|
| 194 |
# matching that pattern
|
| 195 |
# This is useful because ls might file in many circumstances (for example, with
|
| 196 |
# deep linked symbolic links) and test only allows a single file to be checked
|
| 197 |
file_exists() {
|
| 198 |
local file
|
| 199 |
for file in $1; do
|
| 200 |
test -e "$file" && return 0
|
| 201 |
done
|
| 202 |
return 1
|
| 203 |
}
|
| 204 |
|
| 205 |
#CHANGE: delete once --check is implemented in /sbin/splashy_config
|
| 206 |
splashy_config() {
|
| 207 |
case "$1" in
|
| 208 |
--check)
|
| 209 |
if test -r "$XML_CONFIG"; then
|
| 210 |
return 0
|
| 211 |
else
|
| 212 |
return 1
|
| 213 |
fi
|
| 214 |
;;
|
| 215 |
*)
|
| 216 |
/sbin/splashy_config "$@"
|
| 217 |
;;
|
| 218 |
esac
|
| 219 |
}
|
| 220 |
|
| 221 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 222 |
# See if the current theme in the current runlevel must have a progress bar
|
| 223 |
# The result is returned in $SET_PROGRESS and the return value is that of
|
| 224 |
# the splashy_config command
|
| 225 |
get_set_progress() {
|
| 226 |
if test "$RUNLEVEL" = 0 -o "$RUNLEVEL" = 6; then
|
| 227 |
SET_PROGRESS="$("$CONFIG_READER" --get-key \
|
| 228 |
/splashy/progressbaronshutdown)"
|
| 229 |
else
|
| 230 |
SET_PROGRESS="$("$CONFIG_READER" --get-key \
|
| 231 |
/splashy/progressbaronboot)"
|
| 232 |
fi
|
| 233 |
}
|
| 234 |
|
| 235 |
# Load options
|
| 236 |
# Export them so that subshells can read them too
|
| 237 |
config_parse() {
|
| 238 |
debug "Config parse: Starting"
|
| 239 |
# Unset all variables so that in a USR2 signal, the are all rechecked
|
| 240 |
# Do not unset FRAMEBUFFER, RUNLEVEL nor PREVLEVEL since they could be
|
| 241 |
# taken from environment variable and the script would loose their value
|
| 242 |
# Do not unset DEBUG either since some effects are unrevertable once
|
| 243 |
# the scripts started, such as server startup when DEBUG=2
|
| 244 |
unset ENABLE SERVER UPDATE_CMD CONFIG_READER SLEEP_TIME CHVT_TTY \
|
| 245 |
PIDFILE CLIENT_PIDFILE END_MATCHES LEVEL_MATCH SET_PROGRESS \
|
| 246 |
EXTERN_PROGRESS POST_EXEC_SERVICES ENABLE_INITRAMFS
|
| 247 |
# INVERT_DOWN FIFO_FILE
|
| 248 |
# Unset $prctg in case after a USR2 signal there has to be no progress
|
| 249 |
unset prctg
|
| 250 |
# If the script is run manually, get the current runlevel or exit
|
| 251 |
# Another chance that $RUNLEVEL might not be defined is in old
|
| 252 |
# init binnaries, but anyway splashy will only work on 2.6 linux
|
| 253 |
# kernels, which should be installed along with newer init versions
|
| 254 |
if test -z "$RUNLEVEL"; then
|
| 255 |
RUNLEVEL="$(silent -2 runlevel)"
|
| 256 |
test "$RUNLEVEL" = unknown &&
|
| 257 |
error "Splashy: No priviledges to determine runlevel"
|
| 258 |
# Use dd instead of cut since cut is in /usr/bin. dd spits
|
| 259 |
# stats. attempt to filter them. No matter if that filtering
|
| 260 |
# generates an error: return code is not checked and dd will
|
| 261 |
# spit messages if /dev/null doesn't exist anyway
|
| 262 |
RUNLEVEL="$(echo "$RUNLEVEL" |
|
| 263 |
dd skip=2 count=1 bs=1 2>/dev/null)"
|
| 264 |
test -z "$RUNLEVEL" &&
|
| 265 |
error "Splashy: No priviledges to determine runlevel"
|
| 266 |
fi
|
| 267 |
if test -z "$PREVLEVEL"; then
|
| 268 |
# See comment above about why using dd here
|
| 269 |
PREVLEVEL="$(silent -2 runlevel |
|
| 270 |
dd count=1 bs=1 2>/dev/null)"
|
| 271 |
test -z "$PREVLEVEL" && PREVLEVEL=N
|
| 272 |
fi
|
| 273 |
debug "Config parse: Parsing file"
|
| 274 |
# Load script configuration file
|
| 275 |
if test -r "$CONFIG"; then
|
| 276 |
. $CONFIG
|
| 277 |
else
|
| 278 |
log_warning_msg "Splashy: Missing $CONFIG. Using defaults"
|
| 279 |
fi
|
| 280 |
debug "Config parse: Config reader execution"
|
| 281 |
# Load XML configuration file
|
| 282 |
test -z "$CONFIG_READER" && CONFIG_READER="/sbin/splashy_config"
|
| 283 |
test -x "$CONFIG_READER" ||
|
| 284 |
error "Splashy: $CONFIG_READER cannot be executed"
|
| 285 |
CONFIG_READER="${CONFIG_READER##*/}" #CHANGE: delete
|
| 286 |
"$CONFIG_READER" --check ||
|
| 287 |
error "Splashy: $XML_CONFIG config file is broken"
|
| 288 |
# FIFO_FILE="$("$CONFIG_READER" --get-key /splashy/fifo)"
|
| 289 |
PIDFILE="$("$CONFIG_READER" --get-key /splashy/pid)"
|
| 290 |
get_set_progress || SET_PROGRESS=yes
|
| 291 |
debug "Config parse: Reading vars"
|
| 292 |
# Default user options
|
| 293 |
test -z "$ENABLE" && ENABLE=1
|
| 294 |
test -z "$SERVER" && SERVER="/sbin/splashy"
|
| 295 |
test -z "$UPDATE_CMD" && UPDATE_CMD="/sbin/splashy_update"
|
| 296 |
test -x "$UPDATE_CMD" || error "Splashy: $UPDATE_CMD cannot be executed"
|
| 297 |
test -z "$POST_EXEC_SERVICES" &&
|
| 298 |
POST_EXEC_SERVICES="keymap.sh console-screen.sh"
|
| 299 |
test -z "$END_MATCHES" &&
|
| 300 |
# do not include "halt reboot" since they should hold the image
|
| 301 |
END_MATCHES="^[Ss]top[Ss]plashy$ ^S[Ss]plashy[Ss]top$
|
| 302 |
^gdm$ ^kdm$ ^wdm$ ^xdm$ ^3xdm$ ^startx$"
|
| 303 |
test -z "$FRAMEBUFFER" && FRAMEBUFFER="/dev/fb0"
|
| 304 |
test -z "$SLEEP_TIME" && SLEEP_TIME=1
|
| 305 |
# test -z "$INVERT_DOWN" && INVERT_DOWN=0
|
| 306 |
# INVERT_DOWN=0 # Disable always since it is not usable (on server side)
|
| 307 |
# Support old variable names
|
| 308 |
# test -n "$spl_fifo" -a -z "$FIFO_FILE" && FIFO_FILE="$spl_fifo"
|
| 309 |
test -n "$spl_tty" -a -z "$CHVT_TTY" && CHVT_TTY="$spl_tty"
|
| 310 |
# Check configuration values
|
| 311 |
test -x "$SERVER" || error "Splashy: $SERVER cannot be executed"
|
| 312 |
# If it is a number, just detect level. But make sure it is _just_ a
|
| 313 |
# number, with no spaces
|
| 314 |
echo "$END_MATCHES" | grep '^[0-9]\+$' -q &&
|
| 315 |
test $END_MATCHES -lt 100 && LEVEL_MATCH=y
|
| 316 |
# Do not check $SLEEP_TIME with is_number(): It could be a decimal
|
| 317 |
echo "$SLEEP_TIME" | grep -E '^[0-9]+\.*[0-9]*$|[0-9]*\.*[0-9]+' -q ||
|
| 318 |
error "Splashy: Wrong SLEEP_TIME value $SLEEP_TIME"
|
| 319 |
# Check $CHVT_TTY value
|
| 320 |
if test -z "$CHVT_TTY"; then
|
| 321 |
CHVT_TTY=auto
|
| 322 |
elif ! is_number "$CHVT_TTY" -1 &&
|
| 323 |
test "$CHVT_TTY" != auto -a "$CHVT_TTY" != none; then
|
| 324 |
error "Splashy: Invalid CHVT_TTY value ($CHVT_TTY)"
|
| 325 |
fi
|
| 326 |
test "${LOG%/*}" != "$LOG" -a ! -w "${LOG%/*}" &&
|
| 327 |
error "Splashy: Cannot log to $LOG"
|
| 328 |
# Get other settings
|
| 329 |
CLIENT_PIDFILE="$PIDFILE.client"
|
| 330 |
# Don't check the existence of the PID file. It might not
|
| 331 |
# yet exist, but check that it is set
|
| 332 |
# # Same goes for the FIFO file
|
| 333 |
# test -z "$FIFO_FILE" &&
|
| 334 |
# error "Splashy: No fifo file set in $XML_CONFIG"
|
| 335 |
test -z "$PIDFILE" && error "Splashy: No pid file set in $XML_CONFIG"
|
| 336 |
# Everything was successfull, so export them and set $CONFIG_PARSED
|
| 337 |
export ENABLE SERVER UPDATE_CMD CONFIG_READER SLEEP_TIME CHVT_TTY \
|
| 338 |
PIDFILE CLIENT_PIDFILE END_MATCHES FRAMEBUFFER LEVEL_MATCH \
|
| 339 |
SET_PROGRESS RUNLEVEL PREVLEVEL EXTERN_PROGRESS LOG \
|
| 340 |
POST_EXEC_SERVICES ENABLE_INITRAMFS CONFIG_PARSED=yes \
|
| 341 |
DEBUG
|
| 342 |
# INVERT_DOWN FIFO_FILE
|
| 343 |
debug "Config parse: Done"
|
| 344 |
}
|
| 345 |
|
| 346 |
# Detect if this script is already running
|
| 347 |
# Arguments correspond to PIDs that will be ignored
|
| 348 |
# Must be called _after_ calling config_parse()
|
| 349 |
# It returns the PID(s) in variable $pid if successfull
|
| 350 |
# Beware it could return duplicate PIDs
|
| 351 |
is_client_running() {
|
| 352 |
debug "Client_run(): Parent script PIDs: $SCRIPTSPIDS"
|
| 353 |
# The sorting of the matches is from least CPU heavy to most heavy
|
| 354 |
if test -e "$CLIENT_PIDFILE"; then
|
| 355 |
pid=`cat "$CLIENT_PIDFILE"`
|
| 356 |
silent -S kill -0 $pid &&
|
| 357 |
# Make sure that it is actually splashy. On init scripts, it
|
| 358 |
# is very easy for another process to have the same pid that
|
| 359 |
# a splashy process on an earlier boot
|
| 360 |
grep -i splashy -q /proc/$pid/cmdline &&
|
| 361 |
return 0
|
| 362 |
fi
|
| 363 |
local file files ipid npid tpid
|
| 364 |
for file in "$0" /etc/rc?.d/[SK][0-9][0-9]splashy* \
|
| 365 |
/etc/init.d/*splashy*; do
|
| 366 |
files="$files $file"
|
| 367 |
done
|
| 368 |
pid="$(pidof -x $files)"
|
| 369 |
# Do not use pidof's -o option. It is broken: it will fail
|
| 370 |
# to work when the results have duplicate pids and it only
|
| 371 |
# accepts 4 -o pids
|
| 372 |
# Therefore, here is an independent and good implementation
|
| 373 |
for ipid in $pid; do
|
| 374 |
for npid in $SCRIPTSPIDS; do
|
| 375 |
test $npid -eq $ipid && continue 2
|
| 376 |
done
|
| 377 |
tpid="$tpid $ipid"
|
| 378 |
done
|
| 379 |
test -n "$tpid" && pid="$tpid"
|
| 380 |
}
|
| 381 |
|
| 382 |
# Detect if the splashy server is already running
|
| 383 |
# Must be called _after_ calling config_parse()
|
| 384 |
# It returns the PID in variable $pid if successfull. Be aware that more than
|
| 385 |
# one PID could be returned in $pid
|
| 386 |
# It uses $SERVER_PID to remember the pid (and check it) across calls
|
| 387 |
is_server_running() {
|
| 388 |
# The sorting of the matches is from least CPU heavy to most heavy
|
| 389 |
if test -n "$SERVER_PID"; then
|
| 390 |
silent -S kill -0 $SERVER_PID &&
|
| 391 |
pid="$SERVER_PID" && return 0
|
| 392 |
fi
|
| 393 |
if test -e "$PIDFILE"; then
|
| 394 |
pid=`cat "$PIDFILE"`
|
| 395 |
silent -S kill -0 $pid &&
|
| 396 |
# Update SERVER_PID so next time it is faster to check
|
| 397 |
SERVER_PID="$pid" && return 0
|
| 398 |
fi
|
| 399 |
pid="$(pidof "${SERVER##*/}")" &&
|
| 400 |
# Update SERVER_PID so next time it is faster to check
|
| 401 |
SERVER_PID="$pid" && return 0
|
| 402 |
unset pid SERVER_PID
|
| 403 |
return 1
|
| 404 |
}
|
| 405 |
|
| 406 |
# Remove the PID file and close splashy server before exitting
|
| 407 |
# This does not close the server, since that would run into a race condition
|
| 408 |
# (clean_exit calls send_command which calls clean_exit...)
|
| 409 |
clean_exit() {
|
| 410 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 411 |
silent -S rm -f "$CLIENT_PIDFILE"
|
| 412 |
debug "Clean_exit(): $1"
|
| 413 |
exit $1
|
| 414 |
}
|
| 415 |
|
| 416 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 417 |
# Sends commands to Splashy
|
| 418 |
# In case of error, exit
|
| 419 |
send_command() {
|
| 420 |
debug "send_command(): Called as $*"
|
| 421 |
# test ! -p "$FIFO_FILE" &&
|
| 422 |
# error "Splashy: FIFO file $FIFO_FILE no longer exists!"
|
| 423 |
if is_server_running; then
|
| 424 |
debug "send_command(): Sending '$*'"
|
| 425 |
# # Do not run in the background! This will wait until
|
| 426 |
# # splashy-server reads the command, so no bottle-necks
|
| 427 |
# # will happen. Also, if it is run while udev is
|
| 428 |
# # remounting /dev, running in background would fail
|
| 429 |
# # since /dev/null might not exist (and '&' needs
|
| 430 |
# # /dev/null)
|
| 431 |
# echo $* > "$FIFO_FILE" ||
|
| 432 |
# error "Splashy: Unable to send '$*' to Splashy"
|
| 433 |
# Luis Mondesi <lemsx1@gmail.com>
|
| 434 |
# We use splashy_update to send our commands to Splashy's fifo
|
| 435 |
# This command allows us to write to the FIFO without blocking
|
| 436 |
# this script (non-io block). splashy_update will report
|
| 437 |
# error codes according to the error that was encountered. If
|
| 438 |
# we encounter a recoverable error, we try at least 10 times
|
| 439 |
# before we give up on the command
|
| 440 |
#CHANGE: Is there any sense in retrying??
|
| 441 |
for i in 1 2 3 4 5 6 7 8 9 0; do
|
| 442 |
upout="$("$UPDATE_CMD" "$*" 2>&1)"
|
| 443 |
upcode="$?"
|
| 444 |
debug "splashy_update code: $upcode"
|
| 445 |
case "$upcode" in
|
| 446 |
0) break
|
| 447 |
;;
|
| 448 |
1|4) sleep 0.5
|
| 449 |
debug "FIFO failure. Delayed 0.5s"
|
| 450 |
test -n "$upout" && debug "Reason: $upout"
|
| 451 |
;;
|
| 452 |
2) debug "FIFO failure. Reason: $upout" ;;
|
| 453 |
3) debug "Update_cmd: args failure!" ;;
|
| 454 |
esac
|
| 455 |
done
|
| 456 |
else
|
| 457 |
# The server is not running anymore (user closed it)
|
| 458 |
debug "send_command(): No server"
|
| 459 |
debug ||
|
| 460 |
clean_exit 0
|
| 461 |
fi
|
| 462 |
}
|
| 463 |
|
| 464 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 465 |
# This is a hack I've come up with to see if X is running
|
| 466 |
# since there is no 'official way' of getting this information
|
| 467 |
# If there is an X running, provide the tty number of the first X screen
|
| 468 |
# It returns the result in $X_tty. If no X or no valid result is found,
|
| 469 |
# $X_tty is either unset or set to "" and return code is 1. Otherwise, return
|
| 470 |
# code is 0
|
| 471 |
get_X_tty() {
|
| 472 |
debug "get_X(): Running"
|
| 473 |
local f X_sc X_sc_lowest X_pid
|
| 474 |
# See if an X is running and, if so, get the lockfile of the
|
| 475 |
# lowest X screen
|
| 476 |
for f in /tmp/.X*-lock; do
|
| 477 |
X_sc="$(echo ${f##*/} | sed 's/\.X\([0-9]*\)-lock/\1/')"
|
| 478 |
# If the $X_sc's value is the filename, then the
|
| 479 |
# pattern wasn't found
|
| 480 |
test "${f##*/}" = "$X_sc" && unset X_sc &&
|
| 481 |
continue
|
| 482 |
# If $X_sc_lowest isn't yet set, just set it and
|
| 483 |
# continue (do not compare)
|
| 484 |
test -z "$X_sc_lowest" && X_sc_lowest=$X_sc &&
|
| 485 |
continue
|
| 486 |
test $X_sc -lt $X_sc_lowest && X_sc_lowest=$X_sc
|
| 487 |
done
|
| 488 |
# If an X was found running get it's PID
|
| 489 |
if test $X_sc_lowest; then
|
| 490 |
debug "get_X(): Xnum: $X_sc_lowest"
|
| 491 |
X_pid=`sed 's/[^0-9]*\([0-9]*\).*/\1/' \
|
| 492 |
/tmp/.X"$X_sc_lowest"-lock`
|
| 493 |
# Make sure we are getting a number. Comparing a pid
|
| 494 |
# against 0 is a safe check
|
| 495 |
if is_number "$X_pid" 0; then
|
| 496 |
# This is the most precise way, but requires
|
| 497 |
# root priviledge
|
| 498 |
if test -r /proc/$X_pid/fd; then
|
| 499 |
debug "get_X: Root"
|
| 500 |
for f in /proc/$X_pid/fd/*; do
|
| 501 |
# Search for a /dev/tty* file
|
| 502 |
# being used by the X server
|
| 503 |
X_tty="$(readlink "$f" |
|
| 504 |
grep "^/dev/tty")" &&
|
| 505 |
break
|
| 506 |
done
|
| 507 |
# See if a device was found. If so, get
|
| 508 |
# its number
|
| 509 |
if test -n "$X_tty"; then
|
| 510 |
X_tty="$(echo "$X_tty" |
|
| 511 |
sed 's/[^0-9]*\([0-9]*\)/\1/')"
|
| 512 |
# Make sure we are getting a
|
| 513 |
# number. Comparing a tty
|
| 514 |
# against a nevative number is a
|
| 515 |
# safe check
|
| 516 |
is_number "$X_tty" -1 ||
|
| 517 |
unset X_tty
|
| 518 |
fi
|
| 519 |
fi
|
| 520 |
# This method similar to `ps -aux | grep X |
|
| 521 |
# grep vt7`, but more precise (though more CPU
|
| 522 |
# expensive)
|
| 523 |
# It should be available for any user, even
|
| 524 |
# non-priviledged
|
| 525 |
# Priviledged uers may also come here if the
|
| 526 |
# other method failed
|
| 527 |
if test -z "$X_tty"; then
|
| 528 |
debug "get_X(): NoRoot"
|
| 529 |
# The reason for using "echo `cat ...` |
|
| 530 |
# tr ... | sed ...", instead of passing
|
| 531 |
# the file directly as an argument is
|
| 532 |
# that sed doesn't hande files with NULL
|
| 533 |
# characters, and cmdline has some
|
| 534 |
X_tty="$(cat /proc/$X_pid/cmdline |
|
| 535 |
tr '\000' ' ' |
|
| 536 |
sed 's/.*\ vt\([0-9]*\)[\ \x0$].*/\1/')"
|
| 537 |
# Make sure we are getting a number
|
| 538 |
# Comparing a tty against a nevative
|
| 539 |
# number is a safe check
|
| 540 |
is_number "$X_tty" -1 || unset X_tty
|
| 541 |
fi
|
| 542 |
fi
|
| 543 |
fi
|
| 544 |
debug "get_X(): X_tty: $X_tty"
|
| 545 |
test -n "$X_tty" || return 1
|
| 546 |
}
|
| 547 |
|
| 548 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 549 |
# Complete the progress bar
|
| 550 |
# $prctg is global in case a USR2 signal happened
|
| 551 |
perform_complete() {
|
| 552 |
debug "Complete: $atempts=$succeeded+$repeats/$failed"
|
| 553 |
# The progress has been completed. Complete progress and exit
|
| 554 |
if is_enabled "$SET_PROGRESS"; then
|
| 555 |
# if test "$RUNLEVEL" = 6 -o "$RUNLEVEL" = 0 &&
|
| 556 |
# is_enabled "$INVERT_DOWN"; then
|
| 557 |
# prctg=0
|
| 558 |
# else
|
| 559 |
prctg=100
|
| 560 |
# fi
|
| 561 |
# Do not update progress if it is already set to that percentage
|
| 562 |
if test "$oldprctg" != "$prctg"; then
|
| 563 |
# debug "Complete: Sending 100%: $prctg - $oldprctg"
|
| 564 |
# send_command "progress $(($prctg - $oldprctg))"
|
| 565 |
# debug && i=$(($prctg - $oldprctg))
|
| 566 |
# debug "FINAL INCREMENT: $inc_count + $i"
|
| 567 |
debug "Complete: Sending 100%: $prctg"
|
| 568 |
send_command "progress $prctg"
|
| 569 |
fi
|
| 570 |
fi
|
| 571 |
|
| 572 |
# Switch to X's terminal when not shutting down
|
| 573 |
if test "$RUNLEVEL" != 6 -a "$RUNLEVEL" != 0; then
|
| 574 |
# If a tty was set to switch in config, switch to it
|
| 575 |
# Otherwise, try to determine where X is running, or
|
| 576 |
# don't switch
|
| 577 |
if test "$CHVT_TTY" = auto; then
|
| 578 |
debug "Get tty: yes"
|
| 579 |
if get_X_tty; then
|
| 580 |
switch_tty="$X_tty"
|
| 581 |
else
|
| 582 |
debug "Get tty: no. Defaulting to 1"
|
| 583 |
switch_tty=1 # Fallback to tty1
|
| 584 |
fi
|
| 585 |
else
|
| 586 |
switch_tty="$CHVT_TTY"
|
| 587 |
fi
|
| 588 |
debug "Switch X initialized"
|
| 589 |
# If a tty is set, switch to it
|
| 590 |
# Don't use 'chvt' command: It is not a base distro command
|
| 591 |
if [ "$switch_tty" != none ]; then
|
| 592 |
debug "Switch to $switch_tty tty"
|
| 593 |
# Allow Splashy to change vt
|
| 594 |
send_command "allowchvt"
|
| 595 |
# Tell Splashy to switch vt
|
| 596 |
send_command "chvt $switch_tty"
|
| 597 |
fi
|
| 598 |
debug "Server: Exitting"
|
| 599 |
send_command "exit"
|
| 600 |
fi
|
| 601 |
# If Splashy is supposed to be running from initramfs, so any init script
|
| 602 |
# running unicode{start|stop} will be patched and must be rerun now
|
| 603 |
# Do not use "is_enabled $ENABLE_INITRAMFS" but instead check if it is
|
| 604 |
# enabled using the same check used in initramfs/hooks/splashy
|
| 605 |
if test "$ENABLE_INITRAMFS" = 1; then
|
| 606 |
debug "Initramfs enabled"
|
| 607 |
# Timeout after 10 seconds
|
| 608 |
for i in 1 2 3 4 5 6 7 8 9 0; do
|
| 609 |
# Do the same check that the init scripts do when patched
|
| 610 |
silent pidof splashy || break
|
| 611 |
done
|
| 612 |
debug "Server died"
|
| 613 |
# Even if splashy is still running, start the services. In the
|
| 614 |
# worst case it will halt the system until splashy server
|
| 615 |
# timesout which is what would have happened anyway if this code
|
| 616 |
# wasn't here
|
| 617 |
# Execute the services in the same order they should
|
| 618 |
if test "$POST_EXEC_SERVICES" = auto; then
|
| 619 |
debug "Autodetecting services to rerun"
|
| 620 |
if test "PREVLEVEL" = N; then
|
| 621 |
runlevels="S $RUNLEVEL"
|
| 622 |
else
|
| 623 |
runlevels="$RUNLEVEL"
|
| 624 |
fi
|
| 625 |
for rl in runlevels; do
|
| 626 |
for file in \
|
| 627 |
`grep -i unicode_ /etc/rc"$rl"/* -m1 | \
|
| 628 |
cut -f1 -d:`; do
|
| 629 |
debug "Rerunning $file"
|
| 630 |
test -x "$file" && "$file"
|
| 631 |
done
|
| 632 |
done
|
| 633 |
else
|
| 634 |
for file in $POST_EXEC_SERVICES; do
|
| 635 |
debug "Rerunning service $file"
|
| 636 |
test -r "/etc/init.d/$file" || continue
|
| 637 |
case "$file" in
|
| 638 |
*.sh) sh "/etc/init.d/$file" start
|
| 639 |
debug "Shell service rerun successfully"
|
| 640 |
;;
|
| 641 |
*) test -x "/etc/init.d/$file" || continue
|
| 642 |
/etc/init.d/"$file" start
|
| 643 |
debug "Binary service rerun successfully"
|
| 644 |
;;
|
| 645 |
esac
|
| 646 |
done
|
| 647 |
fi
|
| 648 |
fi
|
| 649 |
debug "Client: Exitting"
|
| 650 |
clean_exit 0
|
| 651 |
}
|
| 652 |
|
| 653 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 654 |
# Get the aproximate list of scripts that will be run for the passed
|
| 655 |
# as argument runlevel
|
| 656 |
# The list of scripts is appended to $scripts and the amount of scripts
|
| 657 |
# is summed to $nscripts
|
| 658 |
get_scripts() {
|
| 659 |
local file
|
| 660 |
# Ignore K scripts in first runlevel since boot
|
| 661 |
# Also note that $END_MATCHES applies only for start scripts
|
| 662 |
# This is because a runlevel might have a name twice (as a K and an S
|
| 663 |
# script) and it would make no sense to stop splashy at K level. Same
|
| 664 |
# would happen in name collision between runlevels S and 2 for example
|
| 665 |
if test "$PREVLEVEL" != N; then
|
| 666 |
# Make sure that at least such a file exists, otherwise we
|
| 667 |
# would get the exact literal string
|
| 668 |
file_exists "/etc/rc$1.d/K[0-9][0-9]*" &&
|
| 669 |
for file in /etc/rc"$1".d/K[0-9][0-9]*; do
|
| 670 |
scripts="$scripts$1${file##*/} "
|
| 671 |
nscripts=$(($nscripts + 1))
|
| 672 |
done
|
| 673 |
fi
|
| 674 |
# Make sure that at least such a file exists, otherwise we
|
| 675 |
# would get the exact literal string
|
| 676 |
file_exists "/etc/rc$1.d/S[0-9][0-9]*" &&
|
| 677 |
if test "$1" != S -a "$1" != s; then
|
| 678 |
local done oldlevel count var newlevel
|
| 679 |
for file in /etc/rc"$1".d/S[0-9][0-9]*; do
|
| 680 |
file="${file##*/}"
|
| 681 |
newlevel="$(printf "%.3s" "$file")"
|
| 682 |
scripts="$scripts$1$file "
|
| 683 |
if test -z "$done"; then
|
| 684 |
if test "$oldlevel" = $newlevel; then
|
| 685 |
count=$(($count + 1))
|
| 686 |
else
|
| 687 |
oldlevel=$newlevel
|
| 688 |
count=0
|
| 689 |
fi
|
| 690 |
for match in $END_MATCHES; do
|
| 691 |
test -z "$match" && continue
|
| 692 |
if is_enabled $LEVEL_MATCH; then
|
| 693 |
match="S$match*"
|
| 694 |
else
|
| 695 |
test -n "${match#*\$}" &&
|
| 696 |
match="$match*"
|
| 697 |
if test -n "${match%%^*}"; then
|
| 698 |
match="*$match"
|
| 699 |
else
|
| 700 |
match="S[0-9][0-9]$match"
|
| 701 |
fi
|
| 702 |
fi
|
| 703 |
case "$file" in
|
| 704 |
$match)
|
| 705 |
done=1
|
| 706 |
var=$(($var - $count))
|
| 707 |
debug "Get_scripts(): M: $file"
|
| 708 |
break
|
| 709 |
;;
|
| 710 |
esac
|
| 711 |
done
|
| 712 |
# Even when done, +1, because when a matching
|
| 713 |
# script is reached, it is that script that
|
| 714 |
# ends, not the one right before it
|
| 715 |
#J221: Any system wide option to check?
|
| 716 |
# Notice that this is optimized for parallel
|
| 717 |
# booting scripts. It will not be all that good
|
| 718 |
# in serial scripts booting, since all $oldlevel
|
| 719 |
# scripts are disconted and then +1, so if the
|
| 720 |
# matched script wasn't the first one, it might
|
| 721 |
# stop before it is reached
|
| 722 |
var=$(($var + 1))
|
| 723 |
fi
|
| 724 |
done
|
| 725 |
nscripts=$(($nscripts + $var))
|
| 726 |
else
|
| 727 |
for file in /etc/rc"$1".d/S[0-9][0-9]*; do
|
| 728 |
scripts="$scripts$1${file##*/} "
|
| 729 |
nscripts=$(($nscripts + 1))
|
| 730 |
done
|
| 731 |
fi
|
| 732 |
}
|
| 733 |
|
| 734 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 735 |
# Get the aproximate list of scripts that will be run in the given runlevel
|
| 736 |
# This wrapper simple adds the ability to include post-S scripts
|
| 737 |
# Notice that this will never be exact since rc(S) scripts tend to optimize
|
| 738 |
# performance by not stopping or running those services which are kept or
|
| 739 |
# or not restarted along runlevels
|
| 740 |
# The script names are returned along with the runlevel in $scripts
|
| 741 |
# The amount of scripts returned is returned in $nscripts
|
| 742 |
# It sets $target_rl when in booting S runlevel and the next runlevel is known
|
| 743 |
# It uses $target_rl_was_set to remember if $target_rl has already been set
|
| 744 |
get_scripts_wrapper() {
|
| 745 |
unset scripts nscripts
|
| 746 |
get_scripts "$1"
|
| 747 |
debug "Wrapper(): $1 = $nscripts"
|
| 748 |
# Export them now since the function might be left due to
|
| 749 |
# errors at any moment. They must be exported to be usable
|
| 750 |
# across shells
|
| 751 |
export scripts nscripts target_rl
|
| 752 |
if test "$1" = S -o "$1" = s; then
|
| 753 |
# Notice that /proc could not yet be mounted
|
| 754 |
test ! -e /proc/1 && return
|
| 755 |
# Only set it the first time we enter runlevel S
|
| 756 |
if ! is_enabled "$target_rl_was_set" &&
|
| 757 |
test "$PREVLEVEL" = N; then
|
| 758 |
target_rl="$(sed 's/init\ \[\([Ss0-9AaBbCc]\)\].*/\1/' \
|
| 759 |
/proc/1/cmdline)"
|
| 760 |
test "$target_rl" = "$(cat /proc/1/cmdline)" -o \
|
| 761 |
"$target_rl" = S -o "$target_rl" = s -o \
|
| 762 |
-z "$target_rl" &&
|
| 763 |
unset target_rl && return
|
| 764 |
get_scripts "$target_rl"
|
| 765 |
debug "Wrapper(): S + $target_rl = $nscripts"
|
| 766 |
fi
|
| 767 |
fi
|
| 768 |
}
|
| 769 |
|
| 770 |
# Start the splashy server accordingly to the runlevel we are in or going to
|
| 771 |
# It accepts "-s" as its only argument. When passed, it will not show errors nor
|
| 772 |
# exit if failure happens
|
| 773 |
# $vga will never vary during a system session so it is safe keeping it through
|
| 774 |
# USR2 signals and overwritting it
|
| 775 |
# Returns true on success
|
| 776 |
start_server() {
|
| 777 |
local server_code=0 command
|
| 778 |
if test "$RUNLEVEL" = 0 -o "$RUNLEVEL" = 6; then
|
| 779 |
debug "Server(): Run: shutdown"
|
| 780 |
command=shutdown
|
| 781 |
else
|
| 782 |
debug "Server(): Run: boot"
|
| 783 |
command=boot
|
| 784 |
fi
|
| 785 |
# # When debug option is enabled in splashy server, uncomment line below
|
| 786 |
# debug && command="--debug $command"
|
| 787 |
# We cannot rely on splashy-server writting the pid, since the
|
| 788 |
# filesystem might not be writable yet
|
| 789 |
# Notice that splashy server is silenced, so all errors must be handled
|
| 790 |
# by the script
|
| 791 |
! debug -S &&
|
| 792 |
if silent "$SERVER" $command &&
|
| 793 |
# Make sure there is only one instance running
|
| 794 |
is_server_running && is_number "$pid" 0; then
|
| 795 |
# # With incremental progress commands it is not possible to
|
| 796 |
# # restore the progress bar
|
| 797 |
# server_code=0
|
| 798 |
# Try to restore previous progress bar status if there was
|
| 799 |
if test -n "$prctg"; then
|
| 800 |
send_command "progress $prctg" || server_code=1
|
| 801 |
fi
|
| 802 |
else
|
| 803 |
server_code=1
|
| 804 |
fi
|
| 805 |
# See if the server was successfuly initiated
|
| 806 |
if test $server_code -ne 0 -a "$1" != "-s"; then
|
| 807 |
# Let's now determine the exact reason for the failure and tell
|
| 808 |
# it
|
| 809 |
echo "Splashy failed because of the following reason(s):"
|
| 810 |
test ! -e /proc/fb &&
|
| 811 |
echo " - No framebuffer kernel support is available"
|
| 812 |
! test -w "$FRAMEBUFFER" &&
|
| 813 |
echo " - Framebuffer device unwrittable ($FRAMEBUFFER)"
|
| 814 |
# # rc scripts get kernel foo=bar arguments as environment
|
| 815 |
# # variables. So check if vga= is set (this is an alternate way
|
| 816 |
# # of checking /proc/cmdline, since /proc could not yet be
|
| 817 |
# # mounted) or try to find it out
|
| 818 |
# # Grub method
|
| 819 |
# test -z "$vga" &&
|
| 820 |
# # Lilo (kernel docs) method
|
| 821 |
# vga="$(silent -2 dd count=1 bs=2 skip=295165 if=/dev/mem |
|
| 822 |
# silent -2 od -d - | head -n 1 | tr -s \ | cut -f 2 -d \ )"
|
| 823 |
# ! silent -S test "$vga" -ge 769 -a "$vga" -le 799 &&
|
| 824 |
# # Desperate detection
|
| 825 |
# # It is practically impossible to detect all possible values,
|
| 826 |
# # just run and take a look at:
|
| 827 |
# # egrep '(fix(\.|->)id.*\"|\.id[[:space:]]*=[[:space:]]*\")' \
|
| 828 |
# # -R /usr/src/linux/drivers/video/ | \
|
| 829 |
# # sed 's/.*\"\([^\"]*\)\".*/\1/'
|
| 830 |
# # ...and that's just some (most) of them
|
| 831 |
# ! silent -S grep 'VESA VGA' /proc/fb -q &&
|
| 832 |
# echo " - Kernel parameter vga= not set"
|
| 833 |
# To see if Framebuffer is usable just check that /proc/fb
|
| 834 |
# contains data (framebuffer's identification string)
|
| 835 |
# If it does, it is usable (/proc/fb never contains error
|
| 836 |
# messages, etc), if it doesn't, it is not (all framebuffer
|
| 837 |
# devices _must_ define a 'char id[16]' string
|
| 838 |
test -z "$(cat /proc/fb)" &&
|
| 839 |
echo " - Framebuffer disabled. Set vga= value in kernel"
|
| 840 |
is_server_running &&
|
| 841 |
if ! is_number "$pid" 0; then
|
| 842 |
echo " - There is more than one Splashy server running!"
|
| 843 |
else
|
| 844 |
echo " - Another Splashy server is already running"
|
| 845 |
fi
|
| 846 |
test ! -p "$("$CONFIG_READER" --get-key /splashy/fifo)" &&
|
| 847 |
echo " - FIFO file doesn't exist"
|
| 848 |
debug || # Do not fail on debug mode. Keep going
|
| 849 |
error "Failed to start Splashy server"
|
| 850 |
fi
|
| 851 |
return $server_code
|
| 852 |
}
|
| 853 |
### END MAIN FUNCTIONS
|
| 854 |
|
| 855 |
### BEGIN COMMON STUFF
|
| 856 |
# Add this pid to the list of PIDS is_client_running() should ignore and export
|
| 857 |
# it so it is readable from subshells
|
| 858 |
export SCRIPTSPIDS="$SCRIPTSPIDS $$"
|
| 859 |
|
| 860 |
# Parse the config files. Only if not parsed already
|
| 861 |
is_enabled "$CONFIG_PARSED" || config_parse
|
| 862 |
|
| 863 |
debug "Starting client: $0 ($SC_NAME)"
|
| 864 |
debug "Runlevel: $RUNLEVEL"
|
| 865 |
|
| 866 |
# This is the only way possible to have it behave appropiately in some
|
| 867 |
# circumstances, although breaking LSB
|
| 868 |
case "$SC_NAME" in
|
| 869 |
[KS][0-9][0-9][Ss]top[Ss]plashy | [KS][0-9][0-9][Ss]plashy[Ss]top)
|
| 870 |
# The capital 'S' is on purpose to know it is an init script
|
| 871 |
mode=Stop
|
| 872 |
;;
|
| 873 |
[KS][0-9][0-9]*)
|
| 874 |
if ! is_enabled "$START_RUN" && test "$1" = start -o "$1" = stop; then
|
| 875 |
# The capital 'S' is on purpose to know it is an init script
|
| 876 |
mode=Start
|
| 877 |
else
|
| 878 |
mode="$1"
|
| 879 |
fi
|
| 880 |
;;
|
| 881 |
*) mode="$1"
|
| 882 |
;;
|
| 883 |
esac
|
| 884 |
|
| 885 |
# This script should be run in start mode from a K call in all runlevels but S.
|
| 886 |
# If this is not the case, assume it is already running from a K script. It is
|
| 887 |
# necessary to run the script in all runlevels as both K and S script because
|
| 888 |
# of the reason explained in the README file under section "USER NOTES"
|
| 889 |
# Also, remove the splashy server pid file when booting the system
|
| 890 |
test "$mode" = Start && test "$RUNLEVEL" = S -o "$RUNLEVEL" = s &&
|
| 891 |
case "$SC_NAME" in
|
| 892 |
K*) error "Please do not run Splashy as a K script from runlevel S"
|
| 893 |
;;
|
| 894 |
S*) silent -S rm "$PIDFILE"
|
| 895 |
;;
|
| 896 |
esac
|
| 897 |
|
| 898 |
debug "Mode: $mode. $$"
|
| 899 |
### END COMMON STUFF
|
| 900 |
|
| 901 |
### BEGIN ACTIONS
|
| 902 |
# Behave appropiately to the command
|
| 903 |
case "$mode" in
|
| 904 |
# The start mode does initial checks before running the daemon and sets
|
| 905 |
# everything up so that the daemon can run in background as lightly as
|
| 906 |
# possible
|
| 907 |
[Ss]tart)
|
| 908 |
# We are using the initrc messages here instead of using them in the
|
| 909 |
# daemon (where they should be) because the init-functions currently
|
| 910 |
# do not support parallel running
|
| 911 |
# log_begin_msg is available since LSB 2.0, while log_daemon_msg is new
|
| 912 |
# in LSB 3.0. But we will simulate log_daemon_msg through log_begin_msg
|
| 913 |
log_begin_msg "Starting $DESC: $NAME"
|
| 914 |
# Under certain circumstances (such as when exitting) it is necessary
|
| 915 |
# to know if the log_begin_msg function was called and is waiting
|
| 916 |
# for a log_end_msg call
|
| 917 |
initmsg_call=yes
|
| 918 |
# Do not run on RUNLEVEL 1. Don't bother disabling this:
|
| 919 |
# The splashy-server checks this too and will not run on runlevel 1
|
| 920 |
test "$RUNLEVEL" = 1 && error "Splashy: Will not run in runlevel 1" 0
|
| 921 |
# Since init scripts are config files, they might be left after an
|
| 922 |
# uninstall. Check whether the binary is still present:
|
| 923 |
test ! -x "$SERVER" &&
|
| 924 |
error "Splashy: $SERVER not installed. Purge Splashy" 5
|
| 925 |
# Do not start if disabled and called as init script
|
| 926 |
! is_enabled "$ENABLE" && test "$mode" = Start &&
|
| 927 |
error "Splashy is disabled in $CONFIG" 0
|
| 928 |
# Do not run if this script is already running
|
| 929 |
# This must obviously be checked before the pid file is rewritten
|
| 930 |
# Return successful as described in LSB
|
| 931 |
is_client_running &&
|
| 932 |
# This script is run twice during almost all runlevels to avoid
|
| 933 |
# the rc script optimizations (see USER NOTES in the Readme.txt
|
| 934 |
# file), so try to give an apropiate output for each case
|
| 935 |
if test $mode = Start; then
|
| 936 |
debug "Splashy client already running"
|
| 937 |
echo " status is \"running\"."
|
| 938 |
exit 0
|
| 939 |
else
|
| 940 |
error "Splashy: Already running" 0
|
| 941 |
fi
|
| 942 |
# Perform some operations with the script name that may be necessary
|
| 943 |
# later
|
| 944 |
test $mode = Start && export NAME_FULL="$0"
|
| 945 |
debug "Start: NameFull: $NAME_FULL"
|
| 946 |
# Get the scripts here so it is done when entering daemon mode
|
| 947 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 948 |
get_scripts_wrapper "$RUNLEVEL"
|
| 949 |
# Be able to know if the script was run with start initially
|
| 950 |
export START_RUN=yes
|
| 951 |
# Try to run the server, if possible. If it fails, just ignore
|
| 952 |
# This will make splashy appear from the very first moment, with no
|
| 953 |
# scrolling text at all (almost). Thus the importance of suggestion to
|
| 954 |
# be launched after mountvirtfs
|
| 955 |
test -e /proc/1 -a -e /dev/fb0 &&
|
| 956 |
#CHANGE: Do not check for /dev/vcs1. Splashy could just be showing a
|
| 957 |
# static image while on initramfs
|
| 958 |
if test "$PREVLEVEL" = N; then
|
| 959 |
# If the system is booting, just try to start it, but don't care
|
| 960 |
# if it fails: it will be started again later
|
| 961 |
#CHANGE: When the server handles its launching errors
|
| 962 |
# correctly, remove this check and launch without -s. Otherwise
|
| 963 |
# it might be correctly launched twice (if user entered verbose)
|
| 964 |
# # Luis Mondesi <lemsx1@gmail.com>
|
| 965 |
# # When using initramfs, splashy will be running with no ability
|
| 966 |
# # to read our named pipe (fifo). We must kill it first and then
|
| 967 |
# # start it properly
|
| 968 |
# debug "PidOf says $(pidof -s splashy)."
|
| 969 |
# silent -S kill -9 $(pidof -s splashy)
|
| 970 |
# sleep 1
|
| 971 |
start_server -s
|
| 972 |
else
|
| 973 |
start_server
|
| 974 |
fi
|
| 975 |
if test $? -eq 0; then
|
| 976 |
debug "Client: Started server"
|
| 977 |
export SERVER_RUNNING=y &&
|
| 978 |
# If in extern_progress mode, splashy server started, so exit
|
| 979 |
is_enabled "$EXTERN_PROGRESS" &&
|
| 980 |
clean_exit 0
|
| 981 |
fi
|
| 982 |
# Start in background
|
| 983 |
# We assume that /dev/null exists, since this part should be run
|
| 984 |
# asynchronously
|
| 985 |
debug "Calling daemon mode"
|
| 986 |
"$0" daemon &
|
| 987 |
# If we got here, the process was successfull as far as we can report
|
| 988 |
# up to the moment
|
| 989 |
log_end_msg 0
|
| 990 |
# This isn't necessary. It is just in case someday something is added
|
| 991 |
# below, so we don't forget
|
| 992 |
unset initmsg_call
|
| 993 |
;;
|
| 994 |
# NEVER call this script in "daemon" mode directly! Let "start" call it
|
| 995 |
daemon)
|
| 996 |
is_enabled "$START_RUN" || error "Daemon mode cannot be called directly"
|
| 997 |
debug "Entering daemon mode"
|
| 998 |
### BEGIN FUNCTIONS EXCLUSIVE FOR THIS MODE
|
| 999 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 1000 |
# Set the pid file, if possible
|
| 1001 |
# It uses $pidmark_done to know if the pid file has been successfully
|
| 1002 |
# and definitely written
|
| 1003 |
set_pid_file() {
|
| 1004 |
# Don't write PID when shutting down, otherwise it would be
|
| 1005 |
# there when booting back again
|
| 1006 |
test -n "$pidmark_done" -o \
|
| 1007 |
"$RUNLEVEL" = 0 -o "$RUNLEVEL" = 6 &&
|
| 1008 |
return
|
| 1009 |
# We cannot trust in /dev/null existing
|
| 1010 |
if test -e /dev/null; then
|
| 1011 |
( echo $$ > "$CLIENT_PIDFILE" ) 2>/dev/null
|
| 1012 |
else
|
| 1013 |
echo $$ > "$CLIENT_PIDFILE"
|
| 1014 |
fi &&
|
| 1015 |
# We cannot assume that the filesystem is correctly set
|
| 1016 |
# and that it will not be remounted until runlevel S
|
| 1017 |
# has been passed
|
| 1018 |
# Notice that the order in the check below does matter
|
| 1019 |
# This function is always called after
|
| 1020 |
# progress2percentage() so it is safe to assume that if
|
| 1021 |
# $target_rl is blank, this is not first runlevel S
|
| 1022 |
if test -z "$target_rl"; then
|
| 1023 |
pidmark_done=yes
|
| 1024 |
debug "PID(): done"
|
| 1025 |
else debug "PID(): written"
|
| 1026 |
fi
|
| 1027 |
}
|
| 1028 |
|
| 1029 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 1030 |
# Get the $level (s, S or 0-9), $mode (S or K), $progress (rc
|
| 1031 |
# step) and $name (script name) currently running. Also $script is
|
| 1032 |
# the whole script's name plus it's runlevel
|
| 1033 |
# Note that the variables' values may be empty when the progress status
|
| 1034 |
# cannot be detected
|
| 1035 |
# Return true when the progress is complete. Otherwise, return false
|
| 1036 |
# It updates $RUNLEVEL acording to the runlevel it has detected
|
| 1037 |
# It uses $oldscript to remember the previous script across calls
|
| 1038 |
get_status() {
|
| 1039 |
local line
|
| 1040 |
unset script
|
| 1041 |
debug "Get_status(): oldscript: $oldscript"
|
| 1042 |
debug && atempts="$(($atempts + 1))"
|
| 1043 |
# There are two characteristics which should be studied:
|
| 1044 |
# 1. CPU usage: We don't want splashy to harm boot time too
|
| 1045 |
# much
|
| 1046 |
# 2. (Most important) Atomic: It is extremely important that
|
| 1047 |
# the delay between the /proc/*/exe listing and the reading of
|
| 1048 |
# the links is as short as possible (explained later in point
|
| 1049 |
# 4 about why can no init script be detected)
|
| 1050 |
# We can almost assure that this following command is the real
|
| 1051 |
# core of this script, so making it's CPU usage low, makes the
|
| 1052 |
# sholw script fast
|
| 1053 |
# Only search for the newest process since we are only
|
| 1054 |
# interested in processes newer than this script. If no such
|
| 1055 |
# process is found, then this script will appear, which
|
| 1056 |
# we'll ignore
|
| 1057 |
line="$(splashy_pgrep -f -n -l \
|
| 1058 |
"/rc[sS0-9AaBbCc\].d/[KS][0-9][0-9]")" &&
|
| 1059 |
test "${line%% *}" -ne $$ && script="${line#* }"
|
| 1060 |
# How to get sourced scripts progress too?
|
| 1061 |
# TheBonsai: "redefine "source" ["."] as a function" "read
|
| 1062 |
# INVOCATION section in [bash] manpage" "i mean the ENV hack"
|
| 1063 |
# Jacobo221: "reading kernel docs" "Note that [...] a trailing =
|
| 1064 |
# on the name of any parameter states that that parameter will
|
| 1065 |
# be entered as an environment variable"
|
| 1066 |
# twkm: "it is not exported, it is merely in pid 1's env"
|
| 1067 |
# (and init passes it to rc/rcS)
|
| 1068 |
#test -n "$script" && debug "Get_status(): script: $script"
|
| 1069 |
# It can happen that no rc script is detected to be running in
|
| 1070 |
# the following cases:
|
| 1071 |
# 1. /etc/boot.rc/ scripts (deprecated, but still supported) are
|
| 1072 |
# being run
|
| 1073 |
# 2. All rc scripts have been run. The stop script should have
|
| 1074 |
# been run by this time
|
| 1075 |
# 3. The status check was performed while the rc script itself
|
| 1076 |
# was iterating into another init script
|
| 1077 |
# 4. The init script that was being run while the /proc/*/exe
|
| 1078 |
# listing was performed, died before its link was read
|
| 1079 |
# No init script has been detected to be running
|
| 1080 |
if test -z "$script"; then
|
| 1081 |
debug "Get_status(): No script"
|
| 1082 |
unset progress mode level
|
| 1083 |
# See if rc scripts are being run still
|
| 1084 |
# It could happen that it was switching from
|
| 1085 |
# runlevel S to another runlevel such as 2, so it
|
| 1086 |
# would not detect any /etc/init.d/rc(S) script
|
| 1087 |
# To avoid the switching from S to X runlevel bug,
|
| 1088 |
# see if runlevel command is set. This command
|
| 1089 |
# reads the utmp file, which is set by init not
|
| 1090 |
# before switching from runlevel S. Also notice
|
| 1091 |
# it cannot be trusted much since the utmp could be
|
| 1092 |
# from a previous session or just not exist yet
|
| 1093 |
# But, this doesn't save much, since init sets utmp
|
| 1094 |
# _during_ the runlevel switching process, so the bug
|
| 1095 |
# is still there, just more difficult to suffer it
|
| 1096 |
# Notice that if /proc is unmounted _during_ the
|
| 1097 |
# script, it will complete the progress bar
|
| 1098 |
if ! silent -s splashy_pgrep -f -o "/etc/init.d/rc" &&
|
| 1099 |
test "$(silent -2 runlevel)" != unknown; then
|
| 1100 |
debug "Get_status(): No rc(S)"
|
| 1101 |
succeeded=$(($succeeded + 1))
|
| 1102 |
return 0
|
| 1103 |
else
|
| 1104 |
if test -z "$oldscript"; then
|
| 1105 |
# At least, we are at the progress were
|
| 1106 |
# this script is called from, if this is
|
| 1107 |
# an init script
|
| 1108 |
test -n "$NAME_FULL" &&
|
| 1109 |
script="$NAME_FULL"
|
| 1110 |
if test -z "$script"; then
|
| 1111 |
debug "Get_status(): No 1st" &&
|
| 1112 |
failed="$(($failed +1))"
|
| 1113 |
return 1
|
| 1114 |
fi
|
| 1115 |
debug "Get_status(): script1: $script"
|
| 1116 |
else
|
| 1117 |
debug "Get_status(): Not detected" &&
|
| 1118 |
failed="$(($failed + 1))"
|
| 1119 |
return 1
|
| 1120 |
fi
|
| 1121 |
fi
|
| 1122 |
fi
|
| 1123 |
progress=$(echo $script | sed 's/.*\/[KS]\([0-9][0-9]\).*/\1/')
|
| 1124 |
level=$(echo $script | sed 's/.*\/rc\([sS0-9AaBbCc]\).*/\1/')
|
| 1125 |
mode=$(echo $script | sed 's/.*\/\([KS]\).*/\1/')
|
| 1126 |
name="$(echo $script |
|
| 1127 |
sed 's/.*\/[KS][0-9][0-9]\([^[:space:]]*\).*/\1/')"
|
| 1128 |
script="$level$mode$progress$name"
|
| 1129 |
debug "Get_status(): Progress: $script ($level$mode$progress)"
|
| 1130 |
# If we are at the same progress that we were before, skip. We
|
| 1131 |
# avoid writting to the fifo and loosing cpu cycles in
|
| 1132 |
# framebuffer drawing
|
| 1133 |
if test "$script" = "$oldscript"; then
|
| 1134 |
unset progress mode level
|
| 1135 |
debug "Get_status(): Repeat ($oldscript)" &&
|
| 1136 |
repeats="$(($repeats + 1))"
|
| 1137 |
else
|
| 1138 |
# Update the $oldscript variable to check against it
|
| 1139 |
# on next iteration
|
| 1140 |
oldscript="$script"
|
| 1141 |
fi
|
| 1142 |
# Do not check here if the progress is complete
|
| 1143 |
# If there is no stop script, this script will detect this later
|
| 1144 |
debug "Get_status(): oldscript2: $oldscript"
|
| 1145 |
# Update runlevel
|
| 1146 |
test -n "$level" && RUNLEVEL="$level"
|
| 1147 |
return 1
|
| 1148 |
}
|
| 1149 |
|
| 1150 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 1151 |
# Convert the progress status into a percentage number to reflect in the
|
| 1152 |
# progress bar. Leave the result in the $prctg variable
|
| 1153 |
# Returns true when the progress is complete
|
| 1154 |
# Unsets $prctg if it couldn't be detected
|
| 1155 |
# It updates $PREVLEVEL when the detected level has changed
|
| 1156 |
# It uses $prevcyclerl to remember the runlevel that was used in the
|
| 1157 |
# last iteration. It also uses $oldprctg to remember the $prctg value
|
| 1158 |
# in the last call
|
| 1159 |
# When it detects the $target_rl runlevel has been passed, it unsets the
|
| 1160 |
# variable
|
| 1161 |
# It may also set target_rl_was_set when get_scripts_wrapper() failed to
|
| 1162 |
# set $target_rl
|
| 1163 |
# Notice $RUNLEVEL and $level are equivalent here (except when $level is
|
| 1164 |
# not set)
|
| 1165 |
progress2percent() {
|
| 1166 |
debug "Progress: Non-complete"
|
| 1167 |
# Set the $oldprctg now before it is modified
|
| 1168 |
oldprctg="$prctg"
|
| 1169 |
# Check if the variables have been set by get_status
|
| 1170 |
# If the variables are not set that is because the
|
| 1171 |
# percentage should not be updated
|
| 1172 |
# If only one variable is set, the others are too
|
| 1173 |
test -z "$level" && return 1
|
| 1174 |
local xscript var file
|
| 1175 |
debug "Progress: Exists"
|
| 1176 |
debug && succeeded="$(($succeeded + 1))"
|
| 1177 |
# This is the first iteration
|
| 1178 |
if test -z "$prevcyclerl"; then
|
| 1179 |
prevcyclerl="$level"
|
| 1180 |
# $target_rl_was_set is very often used in this script
|
| 1181 |
# to know when we have passed the first S runlevel. So
|
| 1182 |
# since this is the first iteration, if it isn't S, say
|
| 1183 |
# so
|
| 1184 |
test "$PREVLEVEL" != N && target_rl_was_set=yes
|
| 1185 |
fi
|
| 1186 |
# See if the runlevel changed in the last iteration. If it did,
|
| 1187 |
# update the variables
|
| 1188 |
if test "$prevcyclerl" != "$level"; then
|
| 1189 |
debug "Progress(): Runlevel $prevcyclerl -> $level"
|
| 1190 |
debug "Progress(): Target Runlevel1: $target_rl"
|
| 1191 |
debug "Progress(): Target RL set1: $target_rl_was_set"
|
| 1192 |
# Set $PREVLEVEL. Only set it when this is not a change
|
| 1193 |
# from initial S to X
|
| 1194 |
if test -n "$target_rl_was_set" -a -z "$target_rl"; then
|
| 1195 |
PREVLEVEL="$prevcyclerl"
|
| 1196 |
debug "Progress(): PREVLEVEL changed"
|
| 1197 |
# If the runlevel that goes after S has not been
|
| 1198 |
# detected, we can assume it is this one
|
| 1199 |
# Also assume it is this one whe, although $target_rl is
|
| 1200 |
# set, this other runlevel has taken its place
|
| 1201 |
elif test -z "$target_rl" -a -z "$target_rl_was_set" ||
|
| 1202 |
test -n "$target_rl" -a "$target_rl" != "$level"; then
|
| 1203 |
debug "Progress(): Hard target_rl detection"
|
| 1204 |
target_rl="$level"
|
| 1205 |
# get_scripts_wrapper() also sets $scripts and
|
| 1206 |
# other variables when it detects $target_rl
|
| 1207 |
# Since this cannot be done here, set it to
|
| 1208 |
# value 'half' so it is known later
|
| 1209 |
target_rl_was_set=half
|
| 1210 |
# Check if we have just finished running the target
|
| 1211 |
# runlevel, and if so, set things up
|
| 1212 |
elif test "$prevcyclerl" = "$target_rl"; then
|
| 1213 |
unset target_rl
|
| 1214 |
fi
|
| 1215 |
debug "Progress(): Target Runlevel2: $target_rl"
|
| 1216 |
debug "Progress(): Target RL set2: $target_rl_was_set"
|
| 1217 |
# Update the variables for the new runlevel unless they
|
| 1218 |
# are already set
|
| 1219 |
if test "$target_rl" != "$level" -o \
|
| 1220 |
"$target_rl_was_set" = half; then
|
| 1221 |
debug "Progress(): Regetting scripts"
|
| 1222 |
get_scripts_wrapper "$level"
|
| 1223 |
# Only do this operations when this is not the
|
| 1224 |
# post S runlevel
|
| 1225 |
if test "$target_rl_was_set" != half; then
|
| 1226 |
debug "Progress(): Redoing thingies"
|
| 1227 |
get_set_progress
|
| 1228 |
#CHANGE: Restart server (since it
|
| 1229 |
# does not support downgrading the
|
| 1230 |
# progress) and set apropiate command
|
| 1231 |
# (boot, shutdown) and check
|
| 1232 |
# progressbaron*. This should be removed
|
| 1233 |
# when it does
|
| 1234 |
send_command "exit"
|
| 1235 |
start_server
|
| 1236 |
fi
|
| 1237 |
# If it was 'half', it is completly set now
|
| 1238 |
test "$target_rl_was_set" = half &&
|
| 1239 |
target_rl_was_set=yes
|
| 1240 |
fi
|
| 1241 |
debug "Progress(): Target Runlevel3: $target_rl"
|
| 1242 |
debug "Progress(): Target RL set3: $target_rl_was_set"
|
| 1243 |
fi
|
| 1244 |
# Unset $prctg so that if unknown, it is not set. It cannot be
|
| 1245 |
# unset earlier since start_server() might need it
|
| 1246 |
unset prctg
|
| 1247 |
debug "Progress(): script=$script, scripts=$scripts"
|
| 1248 |
# Note that $script might be something like
|
| 1249 |
# "/bin/sh /etc/rcS.d/S01splashy"
|
| 1250 |
for file in $scripts; do
|
| 1251 |
var=$(($var + 1))
|
| 1252 |
test $file = "$script" && xscript=$var && break
|
| 1253 |
done
|
| 1254 |
if test -z "$xscript"; then
|
| 1255 |
# If the script wasn't found, ignore it. Maybe a
|
| 1256 |
# K script in runlevel S
|
| 1257 |
debug "Progress: NOT FOUND!!: $script,$scripts"
|
| 1258 |
return 1
|
| 1259 |
elif test 0"$xscript" -gt 0"$nscripts"; then
|
| 1260 |
# If we are here it is because we passed the
|
| 1261 |
# last step, so complete at once
|
| 1262 |
debug "Progress: Overflowed"
|
| 1263 |
return 0
|
| 1264 |
fi
|
| 1265 |
# Don't calculate progress if it is not going to be used
|
| 1266 |
if is_enabled "$SET_PROGRESS"; then
|
| 1267 |
# If no scripts were detected, return and keep looping
|
| 1268 |
# Do not return true (break main loop) since this could
|
| 1269 |
# be runlevel S, so there could be scripts in next
|
| 1270 |
# runlevel
|
| 1271 |
# The script is already prepared to detect when no
|
| 1272 |
# scripts are left to run, even when $nscript == 0
|
| 1273 |
# Anyway, this should never happen. If it did, it is
|
| 1274 |
# most probably a bug in the get_scripts() function
|
| 1275 |
if [ $nscripts = 0 ]; then
|
| 1276 |
debug "Progress: No scripts detected!"
|
| 1277 |
return 1
|
| 1278 |
fi
|
| 1279 |
# Notice that the calculations are all in a single
|
| 1280 |
# command and with a single division so that there is
|
| 1281 |
# little loss in integer division
|
| 1282 |
# If the next runlevel cannot be handled now (when in
|
| 1283 |
# first runlevel S), suppose S will take 75% of the time
|
| 1284 |
if test -z "$target_rl_was_set" ||
|
| 1285 |
test -n "$target_rl" -a "$target_rl" != "$level"
|
| 1286 |
then
|
| 1287 |
prctg="$(($xscript * 100 * 3 /(4 * $nscripts)))"
|
| 1288 |
debug "Progress: PrctgAlgo: S"
|
| 1289 |
# Previously the booting runlevel wasn't know but it is
|
| 1290 |
# now known, so resume from the suppose 75% progress
|
| 1291 |
elif test "$target_rl" = "$level"; then
|
| 1292 |
prctg="$(($xscript * 100 /(4 * $nscripts) +75))"
|
| 1293 |
debug "Progress: PrctgAlgo: !S"
|
| 1294 |
# Default behaviour
|
| 1295 |
else
|
| 1296 |
prctg="$(($xscript * 100 / $nscripts))"
|
| 1297 |
debug "Progress: PrctgAlgo: Other"
|
| 1298 |
fi
|
| 1299 |
# # When going down, if set in configuration, invert
|
| 1300 |
# # percentage
|
| 1301 |
# if test $RUNLEVEL = 0 -o $RUNLEVEL = 6; then
|
| 1302 |
# #debug "Progress: Now: 0 or 6"
|
| 1303 |
# if is_enabled "$INVERT_DOWN"; then
|
| 1304 |
# prctg="$((100 - $prctg))"
|
| 1305 |
# debug "Progress: Down: Inverse"
|
| 1306 |
# fi
|
| 1307 |
# fi
|
| 1308 |
fi
|
| 1309 |
test "$prevcyclerl" != "$level" && prevcyclerl="$level"
|
| 1310 |
return 1
|
| 1311 |
}
|
| 1312 |
|
| 1313 |
is_enabled "$EXTERN_PROGRESS" ||
|
| 1314 |
# This function performs signals handling
|
| 1315 |
signal_handler() {
|
| 1316 |
debug "Signal Handler: $1"
|
| 1317 |
case $1 in
|
| 1318 |
ABRT)
|
| 1319 |
clean_exit 0
|
| 1320 |
;;
|
| 1321 |
TERM)
|
| 1322 |
send_command exit
|
| 1323 |
clean_exit 0
|
| 1324 |
;;
|
| 1325 |
USR1)
|
| 1326 |
perform_complete
|
| 1327 |
;;
|
| 1328 |
USR2)
|
| 1329 |
config_parse
|
| 1330 |
start_server
|
| 1331 |
;;
|
| 1332 |
*)
|
| 1333 |
error "Signal Handler: Invalid signal $1"
|
| 1334 |
;;
|
| 1335 |
esac
|
| 1336 |
}
|
| 1337 |
### END FUNCTIONS EXCLUSIVE FOR THIS MODE
|
| 1338 |
|
| 1339 |
# If the server was already set to run (in start mode), don't attempt to
|
| 1340 |
# start it now. Otherwise, if the user had been fast enough to enter
|
| 1341 |
# verbose mode, it would splash again
|
| 1342 |
if test -z "$SERVER_RUNNING"; then
|
| 1343 |
# See if proc fs is mounted. If it isn't sleep until it is
|
| 1344 |
# Since it should be mounted pretty soon, we can safely set it
|
| 1345 |
# to wake up in very low frequencies
|
| 1346 |
# Even if we already checked if it exists, it does noharm to
|
| 1347 |
# check again
|
| 1348 |
while test ! -e /proc/1; do sleep -- $SC_SLEEP; done
|
| 1349 |
# Check also that the framebuffer device exists or wait for it
|
| 1350 |
# to be created, since some systems may rely on udev creating
|
| 1351 |
# it. But before, make sure that udev is going to run, otherwise
|
| 1352 |
# just go on and report the failure when splashy server fails
|
| 1353 |
if test ! -e "$CONSOLE" -o ! -e "$FRAMEBUFFER"; then
|
| 1354 |
# Only wait if udev is launched. Otherwise just fail
|
| 1355 |
if file_exists "/etc/rcS.d/*udev"; then
|
| 1356 |
i=0
|
| 1357 |
debug "Waiting framebuffer or console devices"
|
| 1358 |
# Cycle 90 times maximum
|
| 1359 |
while test "$i" -lt 90; do
|
| 1360 |
sleep -- $SC_SLEEP
|
| 1361 |
if test -e "$FRAMEBUFFER" -a \
|
| 1362 |
-e "$CONSOLE"; then
|
| 1363 |
fbdev_found=1
|
| 1364 |
break
|
| 1365 |
fi
|
| 1366 |
i=$(($i + 1))
|
| 1367 |
done
|
| 1368 |
fi
|
| 1369 |
test 0$fbdev_found -eq 0 && clean_exit 0
|
| 1370 |
fi
|
| 1371 |
# Run splashy-server daemon
|
| 1372 |
is_server_running
|
| 1373 |
server_status=$?
|
| 1374 |
if test $server_status -eq 0 &&
|
| 1375 |
test $RUNLEVEL != 0 -a $RUNLEVEL != 6 &&
|
| 1376 |
is_number "$pid" 0; then
|
| 1377 |
# If it is already running, we are not going down and
|
| 1378 |
# there is only one instance running, use it
|
| 1379 |
# Notice it MUST be restarted when going down. Read few
|
| 1380 |
# lines below the reason
|
| 1381 |
debug "Server: Running already"
|
| 1382 |
true
|
| 1383 |
else
|
| 1384 |
debug "Server: Not running (or nevermind)"
|
| 1385 |
# If it is already running but level is 0 or 6, or there
|
| 1386 |
# is more than one instance running, kill it (them) and
|
| 1387 |
# run it again. In the case of going down it would get
|
| 1388 |
# killed by runlevel shutdown scripts otherwise
|
| 1389 |
test $server_status -eq 0 && silent -S kill $pid
|
| 1390 |
start_server
|
| 1391 |
fi
|
| 1392 |
else debug "Client: Server was started already"
|
| 1393 |
fi
|
| 1394 |
# In extern_progress mode Splashy server must be running now, so exit
|
| 1395 |
is_enabled "$EXTERN_PROGRESS" && clean_exit 0
|
| 1396 |
# Set $prctg and $oldprctg to the initial progress value
|
| 1397 |
is_enabled "$SET_PROGRESS" && test -z "$prctg" &&
|
| 1398 |
# if test "$tlevel" = 0 -o "$tlevel" = 6 &&
|
| 1399 |
# is_enabled "$INVERT_DOWN"; then
|
| 1400 |
# prctg=100
|
| 1401 |
# # If in inverse mode, set bar to 100 from the very start since
|
| 1402 |
# # Splashy initializes it to 0%
|
| 1403 |
# send_command "progress $prctg"
|
| 1404 |
# else
|
| 1405 |
prctg=0
|
| 1406 |
# fi
|
| 1407 |
# Do not assume $oldprctg will be set later: if the process is complete
|
| 1408 |
# before it hits progress2percent(), it will never be set
|
| 1409 |
oldprctg="$prctg"
|
| 1410 |
|
| 1411 |
# Trap signals to control remotely a running instance of this script
|
| 1412 |
# There is no need to trap them before this point
|
| 1413 |
# SIGINT and SIGQUIT cannot be handled (at least by bash) here
|
| 1414 |
#LM: man bash and look for SIGNALS
|
| 1415 |
trap "signal_handler ABRT" ABRT # ctrl+c
|
| 1416 |
trap "signal_handler TERM" TERM # kill
|
| 1417 |
trap "signal_handler USR1" USR1
|
| 1418 |
trap "signal_handler USR2" USR2
|
| 1419 |
|
| 1420 |
# Now go drawing the percentage in frequencies of $SLEEP_TIME seconds
|
| 1421 |
# By the time we get here, we can expect some progress has been done
|
| 1422 |
# (otherwise /proc would not be mounted), so don't sleep initially
|
| 1423 |
debug "Progress: Start (sleep: $SLEEP_TIME)"
|
| 1424 |
until get_status || progress2percent; do
|
| 1425 |
# Write down the PID. This must be done every time it is
|
| 1426 |
# possible, since it may be deleted during the client's
|
| 1427 |
# execution (see the boot notes in the comment at the beginning
|
| 1428 |
# of the script
|
| 1429 |
# When runlevel S finishes, all mounts should be correctly done,
|
| 1430 |
# so we can assume that the pidfile is not correctly set
|
| 1431 |
set_pid_file
|
| 1432 |
if test -n "$prctg" -a "$oldprctg" != "$prctg"; then
|
| 1433 |
# # Send Splashy the percentage to increment the bar
|
| 1434 |
# i=$(($prctg - $oldprctg));debug S: $prctg-$oldprctg=$i
|
| 1435 |
# test $i -lt 0 && debug "GOSH!!!!"
|
| 1436 |
# debug && inc_count="$((${inc_count:-0} + $i))"
|
| 1437 |
# debug "Current count goes up to $inc_count"
|
| 1438 |
# send_command "progress $(($prctg - $oldprctg))"
|
| 1439 |
# Send Splashy the percentage to display
|
| 1440 |
debug "S: $prctg"
|
| 1441 |
send_command "progress $prctg"
|
| 1442 |
else debug "Progress: no progress update reported"
|
| 1443 |
fi
|
| 1444 |
debug "Progress: Next iteration"
|
| 1445 |
sleep -- $SLEEP_TIME
|
| 1446 |
done
|
| 1447 |
trap - INT USR1 USR2
|
| 1448 |
perform_complete
|
| 1449 |
;;
|
| 1450 |
|
| 1451 |
[Ss]top)
|
| 1452 |
# In extern_progress mode, just stop server
|
| 1453 |
if ! is_enabled "$EXTERN_PROGRESS" && is_client_running; then
|
| 1454 |
debug "Stop: Client $pid"
|
| 1455 |
silent -S kill -USR1 $pid
|
| 1456 |
else
|
| 1457 |
# Stop server. Only when it was impossible to stop signal the
|
| 1458 |
# client
|
| 1459 |
if is_server_running; then
|
| 1460 |
debug "Stop: Server"
|
| 1461 |
# Notice that if the config file path changed, this
|
| 1462 |
# may fail
|
| 1463 |
send_command "exit"
|
| 1464 |
else
|
| 1465 |
false
|
| 1466 |
fi
|
| 1467 |
fi
|
| 1468 |
test $? -ne 0 -a $mode = stop &&
|
| 1469 |
error "Unable to stop Splashy. Most probably it isn't running" 0
|
| 1470 |
;;
|
| 1471 |
|
| 1472 |
restart)
|
| 1473 |
# If in extern_progress mode, just restart server
|
| 1474 |
if is_enabled "$EXTERN_PROGRESS"; then
|
| 1475 |
splashy_update exit
|
| 1476 |
sleep 1
|
| 1477 |
if is_server_running; then
|
| 1478 |
for proc in $pid; do
|
| 1479 |
kill -9 $proc
|
| 1480 |
done
|
| 1481 |
fi
|
| 1482 |
start_server
|
| 1483 |
elif is_client_running; then
|
| 1484 |
debug "Restart: Client: Running"
|
| 1485 |
"$0" stop && "$0" start
|
| 1486 |
else
|
| 1487 |
debug "Restart: Server: Not running"
|
| 1488 |
"$0" start
|
| 1489 |
fi
|
| 1490 |
;;
|
| 1491 |
|
| 1492 |
try-restart | force-reload)
|
| 1493 |
# If in extern_progress mode, just restart server
|
| 1494 |
if is_enabled "$EXTERN_PROGRESS"; then
|
| 1495 |
"$0" restart
|
| 1496 |
elif is_client_running; then
|
| 1497 |
debug "Try-Restart: Yes"
|
| 1498 |
"$0" stop && "$0" start
|
| 1499 |
else
|
| 1500 |
debug "Try-Restart: No"
|
| 1501 |
exit 1
|
| 1502 |
fi
|
| 1503 |
;;
|
| 1504 |
|
| 1505 |
reload)
|
| 1506 |
# If in extern_progress mode, just restart server
|
| 1507 |
if is_enabled "$EXTERN_PROGRESS"; then
|
| 1508 |
"$0" restart
|
| 1509 |
exit 0
|
| 1510 |
fi
|
| 1511 |
# Read config again and restart server at the same point it was (since
|
| 1512 |
# this is the only way to make the server read the theme again)
|
| 1513 |
is_client_running && silent -S kill -USR2 $pid
|
| 1514 |
;;
|
| 1515 |
|
| 1516 |
status)
|
| 1517 |
|
| 1518 |
# If in extern_progress mode, just show server status
|
| 1519 |
if is_enabled "$EXTERN_PROGRESS"; then
|
| 1520 |
if is_server_running; then
|
| 1521 |
echo Running
|
| 1522 |
exit 0
|
| 1523 |
elif test -e "$PIDFILE"; then
|
| 1524 |
echo "Not running, but pid file exists"
|
| 1525 |
exit 1
|
| 1526 |
else
|
| 1527 |
echo "Not running"
|
| 1528 |
exit 3
|
| 1529 |
fi
|
| 1530 |
# Report client status only. Client should die once server dies
|
| 1531 |
elif is_client_running; then
|
| 1532 |
echo Running
|
| 1533 |
exit 0
|
| 1534 |
elif test -e "$CLIENT_PIDFILE"; then
|
| 1535 |
# Do not use error() function: this is not an error
|
| 1536 |
echo "Not running, but pid file exists"
|
| 1537 |
exit 1
|
| 1538 |
else
|
| 1539 |
# Do not use error() function: this is not an error
|
| 1540 |
echo "Not running"
|
| 1541 |
exit 3
|
| 1542 |
fi
|
| 1543 |
;;
|
| 1544 |
|
| 1545 |
*)
|
| 1546 |
# This is not an init error message, so do not use error() funciton
|
| 1547 |
echo "Usage: start|stop|status|restart|try-restart|reload|force-reload"
|
| 1548 |
test "$mode" = help && exit 0
|
| 1549 |
exit 1
|
| 1550 |
;;
|
| 1551 |
esac
|
| 1552 |
### END ACTIONS
|