252 lines
5.1 KiB
Bash
Executable File
252 lines
5.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# vim:noexpandtab
|
|
|
|
# Common functionality for the hooks.
|
|
|
|
# If a variable is set to true, yes, 1, or is simply set with no value,
|
|
# return 0, otherwise return 1.
|
|
is_set()
|
|
{
|
|
case ${1-UNSET} in
|
|
true|yes|TRUE|YES|on|ON|1) return 0;;
|
|
false|FALSE|no|NO|off|OFF|0) return 1;;
|
|
*) return 2;;
|
|
esac
|
|
}
|
|
|
|
# for great debugging!
|
|
is_set "${PM_DEBUG}" && set -x
|
|
|
|
|
|
# try to take the lock. Fail if we cannot get it.
|
|
try_lock()
|
|
{
|
|
# $1 = file to use as lockfile
|
|
local lock="${LOCKDIR}/${1##*/}"
|
|
|
|
# make sure the directory where the lockfile should be exists
|
|
mkdir -p "${LOCKDIR}"
|
|
touch "${lock}"
|
|
exec 3<"${lock}"
|
|
flock -x -n 3 || return 1
|
|
return 0
|
|
}
|
|
|
|
# spin waiting for the lock with optional timeout.
|
|
# return once we have it, or the timeout has expired
|
|
spin_lock()
|
|
{
|
|
# $1 = lockfile
|
|
# $2 = optional timeout (default is 60 secs)
|
|
local lock="${LOCKDIR}/${1##*/}"
|
|
local timeout="${2:-60}"
|
|
|
|
mkdir -p "${LOCKDIR}"
|
|
touch "${lock}"
|
|
exec 3<"${lock}"
|
|
flock -x -w "${timeout}" 3 || return 1
|
|
return 0
|
|
}
|
|
|
|
# release the lock
|
|
release_lock()
|
|
{
|
|
# $1 = lockfile
|
|
local lock="${LOCKDIR}/${1##*/}"
|
|
rm -f "${lock}"
|
|
return $?
|
|
}
|
|
|
|
command_exists()
|
|
{
|
|
# $1 = command to test for. It can be an executable in the path,
|
|
# a shell function, or a shell builtin.
|
|
type "$1" >/dev/null 2>&1
|
|
return $?
|
|
}
|
|
|
|
get_power_status()
|
|
{
|
|
on_ac_power
|
|
case "$?" in
|
|
"0") echo "ac" ;;
|
|
"1") echo "battery" ;;
|
|
"255") echo "error"
|
|
return 1
|
|
;;
|
|
esac
|
|
return 0
|
|
}
|
|
|
|
# TODO: Module loading and unloading is Linux-specific.
|
|
# Look into modularizing this into an os-specific set of support routines.
|
|
_rmmod()
|
|
{
|
|
if modprobe -r "$1"; then
|
|
touch "${STORAGEDIR}/module:$1"
|
|
return 0
|
|
else
|
|
log "# could not unload '$1', usage count was $2"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# this recursively unloads the given modules and all that depend on it
|
|
# first parameter is the module to be unloaded
|
|
modunload()
|
|
{
|
|
local MOD D C USED MODS I
|
|
local UNL="$(echo $1 |tr - _)" RET=1
|
|
|
|
while read MOD D C USED D; do
|
|
[ "$MOD" = "$UNL" ] || continue
|
|
if [ "$USED" = "-" ]; then
|
|
# no dependent modules, just try to remove this one.
|
|
_rmmod "$MOD" $C
|
|
RET=$?
|
|
else
|
|
# modules depend on this one. try to remove them first.
|
|
MODS=",${USED%,}"
|
|
while [ -n "${MODS}" ]; do
|
|
# try to unload the last one first
|
|
MOD="${MODS##*,}"
|
|
modunload $MOD && RET=0
|
|
# prune the last one from the list
|
|
MODS="${MODS%,*}"
|
|
done
|
|
# if we unloaded at least one module, then let's
|
|
# try again!
|
|
[ $RET -eq 0 ] && modunload $MOD
|
|
RET=$?
|
|
fi
|
|
return $RET
|
|
done < /proc/modules
|
|
# if we came this far, there was nothing to do,
|
|
# the module is no longer loaded.
|
|
return 0
|
|
}
|
|
|
|
# reload all the modules in no particular order.
|
|
# modprobe should take care of loading prerequisites for us.
|
|
modreload()
|
|
{
|
|
for x in "${STORAGEDIR}"/module:* ; do
|
|
[ -O "${x}" ] || continue
|
|
modprobe "${x##*:}" >/dev/null 2>&1 || \
|
|
log "Could not reload module ${x##*:}."
|
|
|
|
done
|
|
}
|
|
|
|
# If the service command is not provided by the OS, we will fall back to
|
|
# ${PM_UTILS_LIBDIR)/bin/service.
|
|
|
|
stopservice()
|
|
{
|
|
if [ -x "/etc/init.d/$1" ]
|
|
then
|
|
touch "${STORAGEDIR}/service:$1"
|
|
invoke-rc.d "$1" stop
|
|
fi
|
|
}
|
|
|
|
restartservice()
|
|
{
|
|
[ -O "${STORAGEDIR}/service:$1" ] && invoke-rc.d "$1" start
|
|
}
|
|
|
|
# Disable a hook.
|
|
disablehook()
|
|
{
|
|
# $1 = name of hook to disable.
|
|
# $2 = optional comment.
|
|
echo "${2:-${0##*/}}" > "${STORAGEDIR}/disable_hook:${1##*/}"
|
|
}
|
|
|
|
# Save an arbitrary piece of state for later use.
|
|
# If called with just one argument, it reads stdin and saves it to a file.
|
|
# If called with 2 arguments, it saves $2 to a file.
|
|
savestate()
|
|
{
|
|
# $1 = name of state to save
|
|
# $2 (optional) State to save. If omitted, save stdin.
|
|
if [ -n "$2" ]; then
|
|
echo "$2" > "${STORAGEDIR}/state:$1"
|
|
else
|
|
cat > "${STORAGEDIR}/state:$1"
|
|
fi
|
|
}
|
|
|
|
# Check to see of a piece of state exists.
|
|
state_exists()
|
|
{
|
|
# $1 = name of state
|
|
[ -O "${STORAGEDIR}/state:$1" ]
|
|
}
|
|
|
|
# Output previously saved state to stdout.
|
|
restorestate()
|
|
{
|
|
# $1 = name of state
|
|
state_exists "$1" && cat "${STORAGEDIR}/state:$1"
|
|
}
|
|
|
|
# Inhibit suspend/resume and running any more hooks.
|
|
# Any parameters passed ti this function will be saved in the inhibit file.
|
|
inhibit()
|
|
{
|
|
echo "$*" > "$INHIBIT"
|
|
}
|
|
|
|
# Are we inhibited?
|
|
inhibited()
|
|
{
|
|
[ -f "$INHIBIT" ]
|
|
}
|
|
|
|
# If we were told by the user to ignore some parameters from HAL.
|
|
# remove parameters from our list
|
|
remove_parameters() {
|
|
local p
|
|
if [ "$1" = "all" ]; then
|
|
echo '' > "$PARAMETERS.new"
|
|
else
|
|
echo '' >"$PARAMETERS.rm"
|
|
for p in "$@"; do
|
|
echo "$p" >> "$PARAMETERS.rm"
|
|
done
|
|
# let grep do the dirty work.
|
|
grep -vxFf "$PARAMETERS.rm" "$PARAMETERS" > "$PARAMETERS.new"
|
|
fi
|
|
cp -f "$PARAMETERS.new" "$PARAMETERS"
|
|
}
|
|
|
|
# Add a parameter to our commandline parameters.
|
|
add_parameters() {
|
|
remove_parameters "$@" # no dups, please.
|
|
for x in "$@"; do
|
|
echo "$x" >>"$PARAMETERS"
|
|
done
|
|
}
|
|
|
|
# Get our commandline parameters
|
|
get_parameters() {
|
|
cat "$PARAMETERS"
|
|
}
|
|
|
|
# check to see if a single parameter exists
|
|
has_parameter()
|
|
{
|
|
for p in $(get_parameters); do
|
|
[ "$p" = "$1" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Like regular dbus-send, but returns $NA if the command fails for any reason.
|
|
dbus_send ()
|
|
{
|
|
command dbus-send "$@" 2>/dev/null || return $NA
|
|
}
|
|
|