#!/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 # $2 (optional) content to write to the lockfile, # extra newline will be appended # make sure the directory where the lockfile should be exists mkdir -p "${LOCKDIR}" local lock="${LOCKDIR}/${1##*/}" # we use noclobber to make sure there are no race conditions (set -o noclobber; echo "${2}" > "${lock}") 2> /dev/null || 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 local elapsed=0 while ! try_lock $1; do [ "x$2" != "x" ] && [ $(( $elapsed == $2 )) -ne 0 ] && return 1 elapsed=$(($elapsed + 1)) sleep 1; done } # 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 service "$1" status 2>/dev/null | grep -q -e running -e started then touch "${STORAGEDIR}/service:$1" service "$1" stop fi } restartservice() { [ -O "${STORAGEDIR}/service:$1" ] && service "$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 }