ossp-pkg/due/.due/due.root.sh
##
## OSSP due - Dynamic User Environment
## Copyright (c) 1994-2004 Ralf S. Engelschall <rse@engelschall.com>
## Copyright (c) 1994-2004 The OSSP Project <http://www.ossp.org/>
##
## This file is part of OSSP due, a dynamic user environment
## which can found at http://www.ossp.org/pkg/tool/due/
##
## Permission to use, copy, modify, and distribute this software for
## any purpose with or without fee is hereby granted, provided that
## the above copyright notice and this permission notice appear in all
## copies.
##
## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
##
## due.root.sh: DUE module for root command execution
##
# generate shell script for re-evaluation of command arguments
# input: foo 'bar baz' quux (3 args)
# output: "foo \"bar baz\" quux" (1 arg)
function _arg2sh () {
local opt_e=no
local opt_t=no
local opt
OPTIND=1
while getopts et opt; do
case ${opt} in
e ) opt_e=yes ;;
t ) opt_t=yes ;;
esac
done
shift $(($OPTIND - 1))
local cmd=""
local arg
for arg in "$@"; do
# NOTICE: there are three(!) escaping layers here:
# - escape layer 1: backticks (`..xx..`)
# - escape layer 2: quotes ('..xx..')
# - escape layer 3: sed regex (s;..xx..;..xx..;)
local orig=$arg
if [ ${opt_e} = yes ]; then
arg=`echo "@${arg}" | sed -e 's;^@;;' -e 's;\\\\;\\\\\\\\;g' -e 's;\\(["]\\);\\\\\\1;g'`
elif [ ${opt_t} = yes ]; then
arg=`echo "@${arg}" | sed -e 's;^@;;' -e 's;\\\\;\\\\\\\\;g' -e 's;\\(["!\$\`]\\);\\\\\\1;g'`
fi
local quote=no
if [ "${arg}" != "${orig}" ]; then
quote=yes
else
quote=`echo "@${arg}" | sed -e 's;^@.*[ ].*\$;yes;' -e 's;^@.*;no;'`
fi
if [ ${quote} = yes ]; then
arg=`echo "@${arg}" |\
sed -e 's;^@\([A-Z][A-Z0-9_]*\)=\(.*\)$;\1="\2";' \
-e 's;^@\(.*\)$;"\1";'`
fi
cmd="${cmd}${cmd:+ }${arg}"
done
printf "%s" "${cmd}" # intentionally not echo(1)
}
# generate shell script for re-evaluation of environment variables
# input: PATH HOME (2 args)
# output: "PATH=\"...\"; HOME=\"...\"" (1 arg)
function _env2sh () {
local cmd=""
local arg
for arg in "$@"; do
local val
eval "val=\"\$${arg}\""
# NOTICE: there are three(!) escaping layers here, too.
val=`echo "@${val}" | sed -e 's;^@;;' -e 's;\\\\;\\\\\\\\;g' -e 's;\\(["!\$\`]\\);\\\\\\1;g'`
cmd="${cmd}${cmd:+; }${arg}=\"${val}\""
done
printf "%s" "${cmd}" # intentionally not echo(1)
}
# smart dealing with temporary root privileges
function root () {
# default operation
if [ $# -eq 0 ]; then
set -- -i
fi
# parse command line options
local opt_i=no # interactive shell
local opt_l=no # last command-line
local opt_e=no # remote expansion mode
local opt
OPTIND=1
while getopts ileh opt; do
case ${opt} in
i ) opt_i=yes ;;
l ) opt_l=yes ;;
e ) opt_e=yes ;;
h ) echo "root:Usage: root [-h] [-l] [-e] command"; return 0 ;;
? ) echo "root:Error: invalid command line"; return 1 ;;
esac
done
shift $(($OPTIND - 1))
# determine action(s)
local prolog=":"
local epilog=":"
local command
if [ ${opt_i} = yes ]; then
# enter interactive session with root privileges
local xtermcontrol=`find_tool xtermcontrol xtermcolors`
if [ -n "${xtermcontrol}" ]; then
prolog="${xtermcontrol} --cursor='#cc3333'"
epilog="${xtermcontrol} --cursor='#000000'"
command="PS1=\"\\[\\e[31;1m\\]\\u\\[\\e[0m\\]@\\h:\\w\\n\\\\\\$ \"; export PS1"
fi
command="${command}${command:+; }exec ${SHELL} --norc --noprofile"
elif [ ${opt_l} = yes -a ${opt_e} = yes ]; then
eval "set -- $(builtin history 2 | sed -n -e '1p' | cut -c8-)"
command=$(_arg2sh -e -- "$@")
elif [ ${opt_l} = yes ]; then
# execute last command-line with root privileges
command=$(builtin history 2 | sed -n -e '1p' | cut -c8-)
elif [ ${opt_e} = yes ]; then
# execute given command-line with root privileges (expansion mode)
command=$(_arg2sh -e -- "$@")
else
# execute given command-line with root privileges (transparent mode)
command=$(_arg2sh -t -- "$@")
fi
# generate action command
local cmd=$(_env2sh ${ROOT_ENV:-PATH MANPATH INFOPATH LD_LIBRARY_PATH TERM HOME EDITOR PAGER LOGNAME USER})
cmd="${cmd}; cd ${PWD} && ${command}"
cmd=$(_arg2sh -t -- "${cmd}")
eval ${prolog}; ssh -t -q -x root@${HOSTNAME} ${SHELL} -c "${cmd}"; rv=$?; eval ${epilog}
# exit with return value of remote command
return $rv
}