1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/openpkg/rc Tue Jan 06 23:40:39 2009 +0100 1.3 @@ -0,0 +1,687 @@ 1.4 +#!@l_prefix@/lib/openpkg/bash --noprofile 1.5 +## 1.6 +## rc -- OpenPKG Run-Command Processor 1.7 +## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/> 1.8 +## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/> 1.9 +## 1.10 +## Permission to use, copy, modify, and distribute this software for 1.11 +## any purpose with or without fee is hereby granted, provided that 1.12 +## the above copyright notice and this permission notice appear in all 1.13 +## copies. 1.14 +## 1.15 +## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 1.16 +## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1.17 +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.18 +## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR 1.19 +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.20 +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.21 +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 1.22 +## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1.23 +## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 1.24 +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 1.25 +## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.26 +## SUCH DAMAGE. 1.27 +## 1.28 + 1.29 +## 1.30 +## configuration 1.31 +## 1.32 + 1.33 +# program name, version and date 1.34 +progname="rc" 1.35 +progvers="1.2.0" 1.36 +progdate="28-Jul-2003" 1.37 + 1.38 +# path to OpenPKG instance 1.39 +prefix="@l_prefix@" 1.40 + 1.41 +# path to GNU bash and GNU shtool 1.42 +bash="$prefix/lib/openpkg/bash" 1.43 +shtool="$prefix/lib/openpkg/shtool" 1.44 + 1.45 +# path to rc.d, rc.conf and rc.func 1.46 +rcdir="$prefix/etc/rc.d" 1.47 +rcconf="$prefix/etc/rc.conf" 1.48 +rcfunc="$prefix/etc/rc.func" 1.49 + 1.50 +# helper variables 1.51 +NL=" 1.52 +" 1.53 + 1.54 +## 1.55 +## command line option parsing 1.56 +## 1.57 + 1.58 +# default parameters 1.59 +silent=0 1.60 +verbose=0 1.61 +debug=0 1.62 +help=0 1.63 +keep=0 1.64 +print=0 1.65 +eval=0 1.66 +config=0 1.67 +query=0 1.68 + 1.69 +# iterate over argument line 1.70 +while [ $# -gt 0 ]; do 1.71 + opt=$1 1.72 + case $opt in 1.73 + -*=*) arg=${opt/-*=/} ;; 1.74 + *) arg='' ;; 1.75 + esac 1.76 + case $opt in 1.77 + -s|--silent ) silent=1 ;; 1.78 + -v|--verbose ) verbose=1 ;; 1.79 + -d|--debug ) debug=1 ;; 1.80 + -h|--help ) help="Usage" ;; 1.81 + -k|--keep ) keep=1 ;; 1.82 + -p|--print ) print=1 ;; 1.83 + -e|--eval ) eval=1 ;; 1.84 + -c|--config ) config=1 ;; 1.85 + -q|--query ) query=1 ;; 1.86 + -* ) help="Invalid option \`$opt'"; break ;; 1.87 + * ) break ;; 1.88 + esac 1.89 + shift 1.90 +done 1.91 + 1.92 +# display error or usage message 1.93 +if [ ".$help" != .0 ]; then 1.94 + if [ ".$help" != ".Usage" ]; then 1.95 + echo "$progname:ERROR: $help" 1>&2 1.96 + fi 1.97 + echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-k|--keep] [-h|--help]" 1>&2 1.98 + echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query]" 1>&2 1.99 + echo " <package> <command> [<command> ...]" 1>&2 1.100 + if [ ".$help" != ".Usage" ]; then 1.101 + exit 1 1.102 + else 1.103 + exit 0 1.104 + fi 1.105 +fi 1.106 + 1.107 +# determine a reasonable default silent/verbose situation in case 1.108 +# nothing was explicitly specified or a conflicting situation was 1.109 +# specified. Else is silent either disabled by default or was 1.110 +# explicitly enabled. 1.111 +if [ $silent -eq $verbose ]; then 1.112 + if [ -t 2 ]; then 1.113 + # stdout connected to a terminal device, so no need to be silent 1.114 + silent=0 1.115 + else 1.116 + # stdout NOT connected to a terminal device, so be silent 1.117 + silent=1 1.118 + fi 1.119 +fi 1.120 + 1.121 +# extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc) 1.122 +PATH_ORIG="$PATH" 1.123 +PATH="$prefix/bin:$PATH" 1.124 +PATH="$prefix/sbin:$PATH" 1.125 +PATH="$prefix/lib/openpkg:$PATH" 1.126 + 1.127 +# establish secure temporary directory 1.128 +i=0 1.129 +while [ $i -lt 10 ]; do 1.130 + tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$" 1.131 + (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break 1.132 + i=$(($i + 1)) 1.133 + sleep 1 1.134 +done 1.135 +if [ $i -eq 10 ]; then 1.136 + echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2 1.137 + exit 1 1.138 +fi 1.139 +declare -r tmpdir 1.140 +trap "trap - EXIT INT ABRT QUIT TERM; rm -rf $tmpdir >/dev/null 2>&1 || true" EXIT INT ABRT QUIT TERM 1.141 + 1.142 +# determine reasonable temporary files 1.143 +tmpfile="$tmpdir/rc.tmp" 1.144 +outfile="$tmpdir/rc.out" 1.145 +errfile="$tmpdir/rc.err" 1.146 +allfile="$tmpdir/rc.all" 1.147 + 1.148 +# handle --query option 1.149 +if [ ".$query" = .1 ]; then 1.150 + # suck in all %config sections of all scripts 1.151 + # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) 1.152 + touch $tmpfile 1.153 + sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.154 + echo ". $rcconf" >>$tmpfile 1.155 + scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 1.156 + for s_name in $scripts; do 1.157 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.158 + done 1.159 + . $tmpfile 1.160 + 1.161 + # apply override values to get effective values 1.162 + . $rcconf 1.163 + 1.164 + # display variable value 1.165 + for var in $*; do 1.166 + eval "echo \${$var}" 1.167 + done 1.168 + 1.169 + # stop processing immediately 1.170 + exit 0 1.171 +fi 1.172 + 1.173 +# handle --config option 1.174 +if [ ".$config" = .1 ]; then 1.175 + # suck in all %config sections of all scripts 1.176 + # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) 1.177 + touch $tmpfile 1.178 + sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.179 + echo ". $rcconf" >>$tmpfile 1.180 + scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 1.181 + for s_name in $scripts; do 1.182 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.183 + done 1.184 + . $tmpfile 1.185 + 1.186 + # remember default values 1.187 + vars="" 1.188 + OIFS="$IFS"; IFS="$NL" 1.189 + for assign in `egrep '[ ]*[a-zA-Z_][a-zA-Z_0-9]*=' $tmpfile | sort`; do 1.190 + var=`echo "$assign" | sed -e 's;^[ ]*\([a-zA-Z_][a-zA-Z_0-9]*\)=.*;\1;'` 1.191 + vars="$vars $var" 1.192 + eval "${var}_def=\"\$$var\"" 1.193 + done 1.194 + IFS="$OIFS" 1.195 + 1.196 + # apply override values to get effective values 1.197 + . $rcconf 1.198 + 1.199 + # determine how to print in bold mode in case output 1.200 + # is connected to a terminal device 1.201 + if [ -t 1 ]; then 1.202 + begin_bold=`$shtool echo -e '%B'` 1.203 + end_bold=`$shtool echo -e '%b'` 1.204 + else 1.205 + begin_bold="" 1.206 + end_bold="" 1.207 + fi 1.208 + 1.209 + # iterate over all variables and display name, default and effective value 1.210 + echo "${begin_bold}Configuration Variable Effective Value Default Value${end_bold}" 1.211 + echo "------------------------ ------------------------- -- -------------------------" 1.212 + for var in . $vars; do 1.213 + test ".$var" = .. && continue 1.214 + eval "val=\"\$$var\"" 1.215 + eval "def=\"\$${var}_def\"" 1.216 + tag="!=" 1.217 + begin="$begin_bold" 1.218 + end="$end_bold" 1.219 + if [ ".$val" = ".$def" ]; then 1.220 + tag="==" 1.221 + begin="" 1.222 + end="" 1.223 + fi 1.224 + printf "%s%-24s %-25s %s %-25s%s\n" "$begin" "$var" "\"$val\"" "$tag" "\"$def\"" "$end" 1.225 + done 1.226 + 1.227 + # stop processing immediately 1.228 + exit 0 1.229 +fi 1.230 + 1.231 +# determine script(s) to use and make sure they exist 1.232 +if [ $# -lt 1 ]; then 1.233 + echo "openpkg:rc:ERROR: no package and command(s) specified" 1>&2 1.234 + exit 1 1.235 +fi 1.236 +if [ $# -lt 2 ]; then 1.237 + echo "openpkg:rc:ERROR: no command(s) specified for package" 1>&2 1.238 + exit 1 1.239 +fi 1.240 +scripts="${1/*rc./}" 1.241 +shift 1.242 +isall=0 1.243 +if [ ".$scripts" = ".all" ]; then 1.244 + isall=1 1.245 + . $rcconf 1.246 + if [ ".$openpkg_runall" != . ]; then 1.247 + # backward compatibility only 1.248 + echo "openpkg:rc:WARNING: variable \"openpkg_runall\" was renamed to \"openpkg_rc_all\"." 1>&2 1.249 + echo "openpkg:rc:WARNING: value of deprecated variable \"openpkg_runall\" taken over for compatibility." 1>&2 1.250 + echo "openpkg:rc:WARNING: please update your local configuration in \"$rcconf\"." 1>&2 1.251 + openpkg_rc_all="$openpkg_runall" 1.252 + fi 1.253 + case "$openpkg_rc_all" in 1.254 + [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;; 1.255 + esac 1.256 + scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"` 1.257 +else 1.258 + if [ ! -f "$rcdir/rc.$scripts" ]; then 1.259 + echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2 1.260 + exit 1 1.261 + fi 1.262 +fi 1.263 + 1.264 +# determine current run-time user 1.265 +user=`(id -un) 2>/dev/null ||\ 1.266 + (id | sed -e 's;^[^(]*(\([^)]*\)).*;\1;') 2>/dev/null ||\ 1.267 + (whoami) 2>/dev/null ||\ 1.268 + (who am i | cut "-d " -f1) 2>/dev/null ||\ 1.269 + echo ${LOGNAME:-${USER}}` 1.270 +if [ ".$user" = . ]; then 1.271 + echo "openpkg:rc:ERROR: unable to determine current username" 1>&2 1.272 + exit 1 1.273 +fi 1.274 + 1.275 +# iterate over the specified commands 1.276 +rv=0 1.277 +cmds="$*" 1.278 +for cmd in $cmds; do 1.279 + # create "all outputs" file for execution operation (i.e. not --print and --eval) 1.280 + if [ ".$print" = .0 -a ".$eval" = .0 ]; then 1.281 + rm -f $allfile 1.282 + touch $allfile 1.283 + fi 1.284 + 1.285 + # find scripts which contain the command and determine 1.286 + # their individual user/priority settings 1.287 + list='' 1.288 + for s_name in $scripts; do 1.289 + enable=yes 1.290 + 1.291 + # check for upgraded package with unresolved configuration file conflicts 1.292 + if [ -d "$prefix/etc/$s_name" -a ".$eval" != .1 ]; then 1.293 + if [ ".`(find $prefix/etc/$s_name -type f -print; find $prefix/etc/$s_name -type l -print) 2>/dev/null | egrep -v '.*/\.(snap|snapshot)/.*' | egrep '.*\.rpm(new|orig|save)$'`" != . ]; then 1.294 + case "$cmd" in 1.295 + start|restart ) type="ERROR" ;; 1.296 + * ) type="WARNING" ;; 1.297 + esac 1.298 + echo "openpkg:rc:${type}: package \"$s_name\" has unresolved configuration file conflicts" 1>&2 1.299 + echo "openpkg:rc:${type}: indicated by \"*.rpm(new|orig|save)\" files in or below the" 1>&2 1.300 + echo "openpkg:rc:${type}: directory \"$prefix/etc/$s_name\". Please resolve first!" 1>&2 1.301 + if [ ".$type" = .ERROR ]; then 1.302 + continue 1.303 + fi 1.304 + fi 1.305 + fi 1.306 + 1.307 + # check whether command exists in script at all 1.308 + cmdline=`grep "^%$cmd" $rcdir/rc.$s_name | sed -e "s;^%$cmd[^ ].*;;"` 1.309 + if [ ".$cmdline" != . ]; then 1.310 + # parse local command options 1.311 + cmdopts=`echo "$cmdline" | sed -e "s;^%$cmd *;;"` 1.312 + s_user=$user 1.313 + s_prio=500 1.314 + s_output=no 1.315 + set -- $cmdopts 1.316 + prev='' 1.317 + for opt 1.318 + do 1.319 + if [ ".$prev" != . ]; then 1.320 + opt="$prev$opt" 1.321 + prev='' 1.322 + fi 1.323 + case $opt in 1.324 + -*=* ) arg=${opt/-*=/} ;; 1.325 + -[a-zA-Z]* ) arg=${opt/-[a-zA-Z0-9]/} ;; 1.326 + *) arg='' ;; 1.327 + esac 1.328 + case $opt in 1.329 + -u|-p ) prev=$opt ;; 1.330 + -e|--enable ) enable=yes ;; 1.331 + -d|--disable ) enable=no ;; 1.332 + -o|--output ) s_output=yes ;; 1.333 + -u*|--user=* ) s_user=$arg ;; 1.334 + -p*|--prio=* ) s_prio=$arg ;; 1.335 + * ) echo "openpkg:rc:WARNING: invalid local option \"$opt\" in \"$rcdir/rc.$s_name:%$cmd\""; break ;; 1.336 + esac 1.337 + shift 1.338 + done 1.339 + 1.340 + # sanity check: is operation supported by current environment? 1.341 + if [ ".$s_user" != ".$user" -a ".$user" != ".root" -a ".$print" = .0 ]; then 1.342 + echo "openpkg:rc:ERROR: $s_name:%$cmd: require root privileges to run as user \"$s_user\"" 1>&2 1.343 + exit 1 1.344 + fi 1.345 + 1.346 + # skip this script if script is disabled 1.347 + if [ ".$enable" != .yes ]; then 1.348 + continue 1.349 + fi 1.350 + 1.351 + # accumulate the determined information 1.352 + list="$list,$s_prio:$s_name:$s_user:$s_output" 1.353 + else 1.354 + # command not found in script 1.355 + if [ ".$isall" = .0 ]; then 1.356 + echo "openpkg:rc:ERROR: $s_name: command \"$cmd\" not found" 1>&2 1.357 + exit 1 1.358 + fi 1.359 + fi 1.360 + done 1.361 + 1.362 + # if operating on all scripts, complain if a non-standard command 1.363 + # was used and it was not found in any(!) script at all. The 1.364 + # standard commands are accepted to perform no operation if no 1.365 + # packages are currently installed which provide such commands. 1.366 + if [ ".$list" = . -a ".$isall" = .1 ]; then 1.367 + case "$cmd" in 1.368 + start|stop|monthly|weekly|daily|hourly|quarterly ) 1.369 + ;; 1.370 + * ) 1.371 + echo "openpkg:rc:ERROR: command \"$cmd\" not found in any script" 1>&2 1.372 + rv=1 1.373 + break 1.374 + ;; 1.375 + esac 1.376 + fi 1.377 + 1.378 + # generate global (loop invariant) header for script in case of 1.379 + # --print and --eval (for the execution approach we cannot do 1.380 + # this, because there a new script is generated from scratch for 1.381 + # each package. 1.382 + if [ ".$print" = .1 -o ".$eval" = .1 ]; then 1.383 + rm -f $tmpfile 1.384 + touch $tmpfile 1.385 + 1.386 + # generate: optionally enable shell debugging 1.387 + if [ ".$debug" = .1 ]; then 1.388 + echo "set -x" >>$tmpfile 1.389 + fi 1.390 + 1.391 + # generate: inclusion of the run-command helper functions 1.392 + echo ". $rcfunc" >>$tmpfile 1.393 + 1.394 + # generate: all %config sections of all(!) scripts. We cannot 1.395 + # just include those which have the current command in it 1.396 + # because by design all command scripts see the %config 1.397 + # section of all(!) scripts. Because of $openpkg_rc_def the 1.398 + # variable, we place the %config section of "openpkg" to the front. 1.399 + # And we have to extra pre-include the rc.conf to allow 1.400 + # rc.conf to override the default of $openpkg_rc_def, too. 1.401 + sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.402 + echo ". $rcconf" >>$tmpfile 1.403 + l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 1.404 + for l_name in $l_scripts; do 1.405 + sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.406 + done 1.407 + 1.408 + # generate: inclusion of the application of override variables 1.409 + echo ". $rcconf" >>$tmpfile 1.410 + 1.411 + # for --eval redirect stderr and stdout (but remember stdout) 1.412 + # (let stderr pass unfiltered in case of debug mode) 1.413 + if [ ".$eval" = .1 ]; then 1.414 + if [ ".$debug" = .1 ]; then 1.415 + echo "exec 3<&1- 1>/dev/null" >>$tmpfile 1.416 + else 1.417 + echo "exec 3<&1- 1>/dev/null 2>/dev/null" >>$tmpfile 1.418 + fi 1.419 + fi 1.420 + fi 1.421 + 1.422 + # iterate over all packages (in priority order!) where the command 1.423 + # was found in order to execute, print, or evaluate their scripts 1.424 + verbose_pos=0 1.425 + for entry in `echo $list | tr ',' '\012' | sort -n`; do 1.426 + [ ".$entry" = . ] && continue 1.427 + 1.428 + # re-determine the script name, script and whether to print output 1.429 + eval `echo $entry | sed -e 's%^[0-9]*:\(.*\):\(.*\):\(.*\)$%s_name="\1"; s_user="\2"; s_output="\3";%'` 1.430 + 1.431 + # display verbose progress message parts 1.432 + if [ ".$print" = .0 -a ".$eval" = .0 -a ".$silent" = .0 ]; then 1.433 + # line break if we already have output more than 70 1.434 + # characters (notice that usually already more characters 1.435 + # where printed, because of the name of the last script) 1.436 + if [ $verbose_pos -gt 70 ]; then 1.437 + verbose_pos=0 1.438 + echo "" 1>&2 1.439 + fi 1.440 + 1.441 + # display verbose message parts: prefix (on first), separator and package 1.442 + if [ $verbose_pos -eq 0 ]; then 1.443 + output=$(printf "OpenPKG: %s: " "$cmd") 1.444 + echo -n "$output" 1>&2 1.445 + verbose_pos=$(($verbose_pos + ${#output})) 1.446 + output_prefix="" 1.447 + else 1.448 + output_prefix=", " 1.449 + fi 1.450 + output=$(printf "%s%s" "$output_prefix" "$s_name") 1.451 + echo -n "$output" 1>&2 1.452 + verbose_pos=$(($verbose_pos + ${#output})) 1.453 + fi 1.454 + 1.455 + # now operate on the particular script 1.456 + if [ ".$print" = .1 ]; then 1.457 + # special case: under --print we just add the %common and 1.458 + # command scripts to the generated output script and do 1.459 + # not execute anything at this point. 1.460 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d' 1.461 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' 1.462 + elif [ ".$eval" = .1 ]; then 1.463 + # special case: under --eval we just add the %common and 1.464 + # command scripts to the generated output script and do 1.465 + # not execute anything at this point. Additionally, we 1.466 + # emulate a real sub-shell environment. 1.467 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d' 1.468 + echo "while [ 1 ]; do" >>$tmpfile 1.469 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' \ 1.470 + -e 's/^exit[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)exit[^;]*/\1break 99/g' \ 1.471 + -e 's/^return[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)return[^;]*/\1break 99/g' 1.472 + echo "break" >>$tmpfile 1.473 + echo "done" >>$tmpfile 1.474 + else 1.475 + # the regular case of executing the command script directly 1.476 + 1.477 + # prepare temporary files 1.478 + rm -f $tmpfile $outfile $errfile 1.479 + (umask 077; touch $tmpfile $outfile $errfile) 1.480 + 1.481 + # generate: optionally enable shell debugging 1.482 + if [ ".$debug" = .1 ]; then 1.483 + echo "set -x" >>$tmpfile 1.484 + fi 1.485 + 1.486 + # generate: inclusion of the run-command helper functions 1.487 + echo ". $rcfunc" >>$tmpfile 1.488 + 1.489 + # generate: all %config sections of all(!) scripts. We cannot 1.490 + # just include those which have the current command in it 1.491 + # because by design all command scripts see the %config 1.492 + # section of all(!) scripts. Because of $openpkg_rc_def the 1.493 + # variable, we place the %config section of "openpkg" to the front. 1.494 + # And we have to extra pre-include the rc.conf to allow 1.495 + # rc.conf to override the default of $openpkg_rc_def, too. 1.496 + sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.497 + echo ". $rcconf" >>$tmpfile 1.498 + l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 1.499 + for l_name in $l_scripts; do 1.500 + sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 1.501 + done 1.502 + 1.503 + # generate: inclusion of the application of override variables 1.504 + echo ". $rcconf" >>$tmpfile 1.505 + 1.506 + # generate: %common section and particular command section 1.507 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d' 1.508 + sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' 1.509 + 1.510 + # execute the generated script with GNU Bash 1.511 + if [ ".$user" != ".$s_user" ]; then 1.512 + # execute as different user 1.513 + if [ ".$verbose" = .1 ]; then 1.514 + echo "openpkg:rc:NOTICE: $prefix:$s_name:%$cmd: executing as user $s_user" 1.515 + fi 1.516 + if [ ".$user" = ".@l_susr@" -a ".@l_susr@" = ".root" ]; then 1.517 + chown $s_user $tmpfile 1.518 + if [ ".$debug" = .1 ]; then 1.519 + su - $s_user -c "PATH=\"$PATH\"; $bash $tmpfile" >$outfile 1.520 + rc=$? 1.521 + else 1.522 + su - $s_user -c "PATH=\"$PATH\"; $bash $tmpfile" >$outfile 2>$errfile 1.523 + rc=$? 1.524 + fi 1.525 + elif [ ".@l_susr@" != ".root" ]; then 1.526 + # do not complain if we would not have any chance 1.527 + # at all to switch the user because we are running 1.528 + # in a non-privileged instance. Else we would just 1.529 + # trash the mailbox of the user receiving the 1.530 + # output of periodic run-commands. 1.531 + rc=0 1.532 + else 1.533 + echo "openpkg:rc:WARNING: $prefix:$s_name:%$cmd: require root privileges to run as user \"$s_user\"" 1>&2 1.534 + rc=1 1.535 + fi 1.536 + else 1.537 + # execute as current user 1.538 + if [ ".$verbose" = .1 ]; then 1.539 + echo "openpkg:rc:NOTICE: $prefix:$s_name:%$cmd: executing as user $user" 1.540 + fi 1.541 + if [ ".$debug" = .1 ]; then 1.542 + $bash $tmpfile >$outfile 1.543 + rc=$? 1.544 + else 1.545 + $bash $tmpfile >$outfile 2>$errfile 1.546 + rc=$? 1.547 + fi 1.548 + fi 1.549 + if [ $rc -ne 0 ]; then 1.550 + if [ ".$silent" = .0 ]; then 1.551 + # indicate failure of execution on verbose message line 1.552 + echo ":FAILED" 1>&2 1.553 + verbose_pos=0 1.554 + fi 1.555 + # give details of execution failure 1.556 + ( echo "openpkg:rc:WARNING: $prefix:$s_name:%$cmd: failed with return code $rc" 1.557 + if [ ".`cat $outfile $errfile`" != . ]; then 1.558 + echo "openpkg:rc:NOTICE: output from stdout/stderr is following:" 1.559 + echo "+----------------------------------------------------------------------" 1.560 + cat $outfile $errfile | sed -e 's;^;| ;' 1.561 + echo "+----------------------------------------------------------------------" 1.562 + else 1.563 + echo "openpkg:rc:NOTICE: no output occurred on stdout/stderr" 1.564 + fi 1.565 + ) 1>&2 1.566 + 1.567 + # enforce global return value 1.568 + rv=1 1.569 + else 1.570 + # give details of execution success in case verbose operation is requested 1.571 + if [ ".$verbose" = .1 ]; then 1.572 + ( echo "openpkg:rc:NOTICE: $prefix:$s_name:%$cmd: succeeded with return code $rc" 1.573 + if [ ".`cat $outfile $errfile`" != . ]; then 1.574 + echo "openpkg:rc:NOTICE: output from stdout/stderr is following:" 1.575 + echo "+----------------------------------------------------------------------" 1.576 + cat $outfile $errfile | sed -e 's;^;| ;' 1.577 + echo "+----------------------------------------------------------------------" 1.578 + else 1.579 + echo "openpkg:rc:NOTICE: no output occurred on stdout/stderr" 1.580 + fi 1.581 + ) 1>&2 1.582 + fi 1.583 + if [ ".$s_output" = .yes ]; then 1.584 + # accumulate script output for later display 1.585 + cat $outfile >>$allfile 1.586 + fi 1.587 + fi 1.588 + fi 1.589 + done 1.590 + 1.591 + # post-processing for each command 1.592 + if [ ".$print" = .1 ]; then 1.593 + # for --print just print the resulting script to stdout 1.594 + cat $tmpfile 1.595 + elif [ ".$eval" = .1 ]; then 1.596 + # finish generation of temporary script by restoring stdout 1.597 + # and printing the exported environment variables into a format 1.598 + # suitable for evaluation by the callers shell. 1.599 + echo "exec 1<&3-" >>$tmpfile 1.600 + echo "unset PWD SHLVL" >>$tmpfile 1.601 + echo "env |\\" >>$tmpfile 1.602 + echo "egrep '^[A-Z_][A-Z0-9_]*=.' |\\" >>$tmpfile 1.603 + echo "sed -e '/^_=/d' -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g' \\" >>$tmpfile 1.604 + case $SHELL in 1.605 + csh|*/csh|tcsh|*/tcsh ) 1.606 + echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/setenv \\1 \"\\2\"/'" >>$tmpfile 1.607 + ;; 1.608 + * ) 1.609 + echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/\\1=\"\\2\"; export \\1/'" >>$tmpfile 1.610 + ;; 1.611 + esac 1.612 + 1.613 + # prepare temporary files 1.614 + rm -f $outfile $errfile 1.615 + touch $outfile $errfile 1.616 + 1.617 + # now replace temporary script with its output 1.618 + # by executing it and capturing its output 1.619 + # (let stderr pass unfiltered in case of debug mode) 1.620 + if [ ".$debug" = .1 ]; then 1.621 + env -i \ 1.622 + HOME="$HOME" \ 1.623 + USER="$USER" \ 1.624 + LOGNAME="$LOGNAME" \ 1.625 + TERM="$TERM" \ 1.626 + PATH="$PATH_ORIG" \ 1.627 + MANPATH="$MANPATH" \ 1.628 + INFOPATH="$INFOPATH" \ 1.629 + LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \ 1.630 + $bash --norc --noprofile --posix \ 1.631 + $tmpfile >$outfile 1.632 + else 1.633 + env -i \ 1.634 + HOME="$HOME" \ 1.635 + USER="$USER" \ 1.636 + LOGNAME="$LOGNAME" \ 1.637 + TERM="$TERM" \ 1.638 + PATH="$PATH_ORIG" \ 1.639 + MANPATH="$MANPATH" \ 1.640 + INFOPATH="$INFOPATH" \ 1.641 + LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \ 1.642 + $bash --norc --noprofile --posix \ 1.643 + $tmpfile >$outfile 2>/dev/null 1.644 + fi 1.645 + cp $outfile $tmpfile 1.646 + 1.647 + # for --eval we cannot just print the resulting script because 1.648 + # not all Bourne-Shell implementations like to "eval" large 1.649 + # multi-line outputs. Hence we output a little one-liner which 1.650 + # "sources" the script instead and cleans up. 1.651 + case $SHELL in 1.652 + csh|*/csh|tcsh|*/tcsh ) 1.653 + echo "source $tmpfile; rm -rf $tmpdir 2>/dev/null || true" 1.654 + ;; 1.655 + * ) 1.656 + echo ". $tmpfile; rm -rf $tmpdir 2>/dev/null || true" 1.657 + ;; 1.658 + esac 1.659 + else 1.660 + # for the execution situation just make sure we 1.661 + # terminate the verbose message output. 1.662 + if [ ".$silent" = .0 -a $verbose_pos -gt 0 ]; then 1.663 + echo "." 1>&2 1.664 + fi 1.665 + 1.666 + # additionally, if a script wants its output to be displayed, 1.667 + # now do it. In case there was no such request, do not bother 1.668 + # -- we then just output an empty file and so can avoid an 1.669 + # extra test surrounding the next command. 1.670 + cat $allfile 1.671 + fi 1.672 +done 1.673 + 1.674 +# cleanup temporary files except the result script in 1.675 +# case of --eval (which is then removed by the caller). 1.676 +# keep those files for debugging purposes if requested. 1.677 +if [ ".$keep" = .0 ]; then 1.678 + rm -f $outfile $errfile $allfile >/dev/null 2>&1 || true 1.679 + if [ ".$eval" = .0 ]; then 1.680 + rm -f $tmpfile >/dev/null 2>&1 || true 1.681 + rm -rf $tmpdir >/dev/null 2>&1 || true 1.682 + fi 1.683 +fi 1.684 + 1.685 +# now clean the exit trap and exit with the global return value 1.686 +# indicating to the caller whether all scripts were executed 1.687 +# successfully or at least one failed. 1.688 +trap - EXIT 1.689 +exit $rv 1.690 +