#!/bin/sh # vim:noexpandtab # Common functionality for the hooks. # for great debugging! [ "${PM_DEBUG}" = "true" ] && 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 # make sure it is ours first.i 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() { RETVAL=0 on_ac_power case "$?" in "0") echo "ac" ;; "1") echo "battery" ;; "255") echo "error" RETVAL=1 ;; esac return $RETVAL } _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. modreload() { for x in "${STORAGEDIR}"/module:* ; do [ -O "${x}" ] && modprobe "${x##*:}" >/dev/null 2>&1 done } if ! command_exists service; then service() { if [ -x "/etc/init.d/$1" ]; then svc="$1" shift "/etc/init.d/$svc" "$@" else log "$1" $": unrecognized service" 1>&2 return 1 fi } fi stopservice() { if service "$1" status 2>/dev/null | grep -c -q running; then touch "${STORAGEDIR}/service:$1" service "$1" stop fi } restartservice() { [ -O "${STORAGEDIR}/service:$1" ] && service "$1" start } disablehook() { echo "${2:-${0$$*/}}" > "${STORAGEDIR}/disable_hook:${1##*/}" } savestate() { if [ -n "$2" ]; then echo "$2" > "${STORAGEDIR}/state:$1" else cat > "${STORAGEDIR}/state:$1" fi } state_exists() { [ -O "${STORAGEDIR}/state:$1" ] } restorestate() { state_exists "$1" && cat "${STORAGEDIR}/state:$1" }