Permalink
Fetching contributors…
Cannot retrieve contributors at this time
144 lines (115 sloc) 3.47 KB
#!/bin/bash
####################################################################
# Prey Core Action Functions - by Tomas Pollak (bootlog.org)
# URL: http://preyproject.com
# License: GPLv3
####################################################################
# modules can queue specific actions by calling
# add_action 'module_name' 'function_name'
add_action(){
log " ++ Queueing action for $1 module!"
if [ -z "$2" ]; then
function=1
else
function=$2
fi
actions[${#actions[*]}]="${1}=${function}"
}
# sets the running pid to the action/module name
add_running_action(){
running_actions[${#running_actions[*]}]="${1}=${2}"
}
get_action(){
get_var actions $1
}
# gets the pid of the running process
get_running_action(){
get_var running_actions $1
}
action_callback(){
until read -st 1; do
echo -n ""
done
log " -- Action finished. Running callback!"
eval '$1 $REPLY'
}
# receives the pid name, assigns it to the module name
create_pidfile_for(){
log " -- Creating pidfile for $current_module's $1..."
echo $1 > "$tmpbase/prey-action-$current_module.pid"
}
unload_action(){
log " -- Unloading $1 from memory..."
local pidfile="$tmpbase/prey-action-$1.pid"
kill -HUP -- -`cat $pidfile` &> /dev/null
}
remove_pidfile(){
local pidfile="$tmpbase/prey-action-$1.pid"
if [ -f "$pidfile" ]; then
log ' -- Removing pidfile...'
rm -f "$pidfile" 2> /dev/null
else
log " -- Pidfile doesn't exist!"
fi
}
check_running_actions(){
for pidfile in $(ls $tmpbase/prey-action-*.pid 2> /dev/null); do
if [ ! -f $pidfile ]; then
continue # just to make sure
fi
local action_name=`basename $pidfile | sed -e 's/prey-action-//' -e 's/\.pid//'`
log " -- Found PID for running action: $action_name"
local pid=$(cat $pidfile)
local actually_running=$(ps ax | grep $pid | grep -v grep > /dev/null && echo 1)
if [ -z `get_action $action_name` ]; then # action was removed from options
# log " -- Removing $action_name which was untoggled by user..."
unload_action $action_name
sleep 1
elif [ -z "$actually_running" ]; then
log " -- Not really running! PID file was just lying around."
rm -f "$pidfile"
else
add_running_action $action_name $pid
fi
done
}
action_finished(){
if [[ -n "$2" && $(get_running_action $2) == $1 ]]; then
wait $1
return_status=$?
log " -- Action $2 returned with status $return_status."
remove_pidfile $2
fi
}
run_pending_actions(){
# -b -> Cause the status of terminated background jobs to be reported immediately,
# rather than before printing the next primary prompt.
# -m job control enabled
set -bm
log "\n${bold} == Running pending actions...${bold_end}"
for action in "${actions[@]}"; do
local current_module=$(echo $action | sed 's/=.*//')
local function=$(echo $action | sed 's/.*=\(.*\)/\1/')
if [ -n "$(get_running_action $current_module)" ]; then
log " -- $current_module is already running! Skipping..."
continue
fi
set_module_paths_for $current_module
if [ "$function" != "1" ]; then # specific function requested
log " -- Running action $function from $current_module module."
eval "$function" &
else # no specific action requested, we'll assume there's a run file
log "\n${bold} == Running $current_module module!${bold_end}\n"
. "$module_path/core/run" &
fi
pid=$!
create_pidfile_for $pid
add_running_action $current_module $pid
trap 'action_finished $pid $current_module' SIGCHLD
done
wait
log " -- No pending actions left. All done!\n"
trap - SIGCHLD
cleanup
# set +bm
}