openpkg/rc

Wed, 14 Jan 2009 15:59:12 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 14 Jan 2009 15:59:12 +0100
changeset 86
78e7deb1d6ab
child 427
71503088f51b
permissions
-rw-r--r--

Correct and improve many buildconf and code logic blocks. In particular:
1. Document potential problems building with current binutils releases.
2. Document the flawed webkit and explain its temporary exclusion.
3. Document the edition of Qt which is built and installed.
4. Remove the Solaris x11_supdir logic as it is no longer found.
5. Correct several .pr[io] files including QMAKE_CXXFLAGS and INCPATH,
which previously caused preexisting Qt installations to deliver
erroneous old include and library logic instead of relying on
that of the currently building package. -I/opkg/include is now
placed at the end of the compile statements.
6. Don't trust the QMAKE_[INC|LIB]DIR_X11 identifiers in qmake.conf.
7. Allow more 64-bit builds and more properly identify the platform.
8. Place plugins (which are shared objects) in lib instead of share.
9. Build components as plugins when possible if with_shared is enabled.
10. Translate German text to English to be more consistent.
11. Instead of removing the pkgconfig directory of with_shared builds,
place it in a child directory useful for shared building.
12. Document the nonstandard shared build directory structure,
including using the hidden pkgconfig directory (PKG_CONFIG_PATH.)
13. Change %doc to specify files rather than directories in the RPM DB.

michael@13 1 #!@l_prefix@/lib/openpkg/bash --noprofile
michael@13 2 ##
michael@13 3 ## rc -- OpenPKG Run-Command Processor
michael@13 4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/>
michael@13 5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/>
michael@13 6 ##
michael@13 7 ## Permission to use, copy, modify, and distribute this software for
michael@13 8 ## any purpose with or without fee is hereby granted, provided that
michael@13 9 ## the above copyright notice and this permission notice appear in all
michael@13 10 ## copies.
michael@13 11 ##
michael@13 12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
michael@13 13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
michael@13 14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
michael@13 15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
michael@13 16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@13 17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@13 18 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
michael@13 19 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@13 20 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@13 21 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@13 22 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@13 23 ## SUCH DAMAGE.
michael@13 24 ##
michael@13 25
michael@13 26 ##
michael@13 27 ## configuration
michael@13 28 ##
michael@13 29
michael@13 30 # program name, version and date
michael@13 31 progname="rc"
michael@13 32 progvers="1.2.0"
michael@13 33 progdate="28-Jul-2003"
michael@13 34
michael@13 35 # path to OpenPKG instance
michael@13 36 prefix="@l_prefix@"
michael@13 37
michael@13 38 # path to GNU bash and GNU shtool
michael@13 39 bash="$prefix/lib/openpkg/bash"
michael@13 40 shtool="$prefix/lib/openpkg/shtool"
michael@13 41
michael@13 42 # path to rc.d, rc.conf and rc.func
michael@13 43 rcdir="$prefix/etc/rc.d"
michael@13 44 rcconf="$prefix/etc/rc.conf"
michael@13 45 rcfunc="$prefix/etc/rc.func"
michael@13 46
michael@13 47 # helper variables
michael@13 48 NL="
michael@13 49 "
michael@13 50
michael@13 51 ##
michael@13 52 ## command line option parsing
michael@13 53 ##
michael@13 54
michael@13 55 # default parameters
michael@13 56 silent=0
michael@13 57 verbose=0
michael@13 58 debug=0
michael@13 59 help=0
michael@13 60 keep=0
michael@13 61 print=0
michael@13 62 eval=0
michael@13 63 config=0
michael@13 64 query=0
michael@13 65
michael@13 66 # iterate over argument line
michael@13 67 while [ $# -gt 0 ]; do
michael@13 68 opt=$1
michael@13 69 case $opt in
michael@13 70 -*=*) arg=${opt/-*=/} ;;
michael@13 71 *) arg='' ;;
michael@13 72 esac
michael@13 73 case $opt in
michael@13 74 -s|--silent ) silent=1 ;;
michael@13 75 -v|--verbose ) verbose=1 ;;
michael@13 76 -d|--debug ) debug=1 ;;
michael@13 77 -h|--help ) help="Usage" ;;
michael@13 78 -k|--keep ) keep=1 ;;
michael@13 79 -p|--print ) print=1 ;;
michael@13 80 -e|--eval ) eval=1 ;;
michael@13 81 -c|--config ) config=1 ;;
michael@13 82 -q|--query ) query=1 ;;
michael@13 83 -* ) help="Invalid option \`$opt'"; break ;;
michael@13 84 * ) break ;;
michael@13 85 esac
michael@13 86 shift
michael@13 87 done
michael@13 88
michael@13 89 # display error or usage message
michael@13 90 if [ ".$help" != .0 ]; then
michael@13 91 if [ ".$help" != ".Usage" ]; then
michael@13 92 echo "$progname:ERROR: $help" 1>&2
michael@13 93 fi
michael@13 94 echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-k|--keep] [-h|--help]" 1>&2
michael@13 95 echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query]" 1>&2
michael@13 96 echo " <package> <command> [<command> ...]" 1>&2
michael@13 97 if [ ".$help" != ".Usage" ]; then
michael@13 98 exit 1
michael@13 99 else
michael@13 100 exit 0
michael@13 101 fi
michael@13 102 fi
michael@13 103
michael@13 104 # determine a reasonable default silent/verbose situation in case
michael@13 105 # nothing was explicitly specified or a conflicting situation was
michael@13 106 # specified. Else is silent either disabled by default or was
michael@13 107 # explicitly enabled.
michael@13 108 if [ $silent -eq $verbose ]; then
michael@13 109 if [ -t 2 ]; then
michael@13 110 # stdout connected to a terminal device, so no need to be silent
michael@13 111 silent=0
michael@13 112 else
michael@13 113 # stdout NOT connected to a terminal device, so be silent
michael@13 114 silent=1
michael@13 115 fi
michael@13 116 fi
michael@13 117
michael@13 118 # extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc)
michael@13 119 PATH_ORIG="$PATH"
michael@13 120 PATH="$prefix/bin:$PATH"
michael@13 121 PATH="$prefix/sbin:$PATH"
michael@13 122 PATH="$prefix/lib/openpkg:$PATH"
michael@13 123
michael@13 124 # establish secure temporary directory
michael@13 125 i=0
michael@13 126 while [ $i -lt 10 ]; do
michael@13 127 tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$"
michael@13 128 (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break
michael@13 129 i=$(($i + 1))
michael@13 130 sleep 1
michael@13 131 done
michael@13 132 if [ $i -eq 10 ]; then
michael@13 133 echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2
michael@13 134 exit 1
michael@13 135 fi
michael@13 136 declare -r tmpdir
michael@13 137 trap "trap - EXIT INT ABRT QUIT TERM; rm -rf $tmpdir >/dev/null 2>&1 || true" EXIT INT ABRT QUIT TERM
michael@13 138
michael@13 139 # determine reasonable temporary files
michael@13 140 tmpfile="$tmpdir/rc.tmp"
michael@13 141 outfile="$tmpdir/rc.out"
michael@13 142 errfile="$tmpdir/rc.err"
michael@13 143 allfile="$tmpdir/rc.all"
michael@13 144
michael@13 145 # handle --query option
michael@13 146 if [ ".$query" = .1 ]; then
michael@13 147 # suck in all %config sections of all scripts
michael@13 148 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf)
michael@13 149 touch $tmpfile
michael@13 150 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 151 echo ". $rcconf" >>$tmpfile
michael@13 152 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
michael@13 153 for s_name in $scripts; do
michael@13 154 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 155 done
michael@13 156 . $tmpfile
michael@13 157
michael@13 158 # apply override values to get effective values
michael@13 159 . $rcconf
michael@13 160
michael@13 161 # display variable value
michael@13 162 for var in $*; do
michael@13 163 eval "echo \${$var}"
michael@13 164 done
michael@13 165
michael@13 166 # stop processing immediately
michael@13 167 exit 0
michael@13 168 fi
michael@13 169
michael@13 170 # handle --config option
michael@13 171 if [ ".$config" = .1 ]; then
michael@13 172 # suck in all %config sections of all scripts
michael@13 173 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf)
michael@13 174 touch $tmpfile
michael@13 175 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 176 echo ". $rcconf" >>$tmpfile
michael@13 177 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
michael@13 178 for s_name in $scripts; do
michael@13 179 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 180 done
michael@13 181 . $tmpfile
michael@13 182
michael@13 183 # remember default values
michael@13 184 vars=""
michael@13 185 OIFS="$IFS"; IFS="$NL"
michael@13 186 for assign in `egrep '[ ]*[a-zA-Z_][a-zA-Z_0-9]*=' $tmpfile | sort`; do
michael@13 187 var=`echo "$assign" | sed -e 's;^[ ]*\([a-zA-Z_][a-zA-Z_0-9]*\)=.*;\1;'`
michael@13 188 vars="$vars $var"
michael@13 189 eval "${var}_def=\"\$$var\""
michael@13 190 done
michael@13 191 IFS="$OIFS"
michael@13 192
michael@13 193 # apply override values to get effective values
michael@13 194 . $rcconf
michael@13 195
michael@13 196 # determine how to print in bold mode in case output
michael@13 197 # is connected to a terminal device
michael@13 198 if [ -t 1 ]; then
michael@13 199 begin_bold=`$shtool echo -e '%B'`
michael@13 200 end_bold=`$shtool echo -e '%b'`
michael@13 201 else
michael@13 202 begin_bold=""
michael@13 203 end_bold=""
michael@13 204 fi
michael@13 205
michael@13 206 # iterate over all variables and display name, default and effective value
michael@13 207 echo "${begin_bold}Configuration Variable Effective Value Default Value${end_bold}"
michael@13 208 echo "------------------------ ------------------------- -- -------------------------"
michael@13 209 for var in . $vars; do
michael@13 210 test ".$var" = .. && continue
michael@13 211 eval "val=\"\$$var\""
michael@13 212 eval "def=\"\$${var}_def\""
michael@13 213 tag="!="
michael@13 214 begin="$begin_bold"
michael@13 215 end="$end_bold"
michael@13 216 if [ ".$val" = ".$def" ]; then
michael@13 217 tag="=="
michael@13 218 begin=""
michael@13 219 end=""
michael@13 220 fi
michael@13 221 printf "%s%-24s %-25s %s %-25s%s\n" "$begin" "$var" "\"$val\"" "$tag" "\"$def\"" "$end"
michael@13 222 done
michael@13 223
michael@13 224 # stop processing immediately
michael@13 225 exit 0
michael@13 226 fi
michael@13 227
michael@13 228 # determine script(s) to use and make sure they exist
michael@13 229 if [ $# -lt 1 ]; then
michael@13 230 echo "openpkg:rc:ERROR: no package and command(s) specified" 1>&2
michael@13 231 exit 1
michael@13 232 fi
michael@13 233 if [ $# -lt 2 ]; then
michael@13 234 echo "openpkg:rc:ERROR: no command(s) specified for package" 1>&2
michael@13 235 exit 1
michael@13 236 fi
michael@13 237 scripts="${1/*rc./}"
michael@13 238 shift
michael@13 239 isall=0
michael@13 240 if [ ".$scripts" = ".all" ]; then
michael@13 241 isall=1
michael@13 242 . $rcconf
michael@13 243 if [ ".$openpkg_runall" != . ]; then
michael@13 244 # backward compatibility only
michael@13 245 echo "openpkg:rc:WARNING: variable \"openpkg_runall\" was renamed to \"openpkg_rc_all\"." 1>&2
michael@13 246 echo "openpkg:rc:WARNING: value of deprecated variable \"openpkg_runall\" taken over for compatibility." 1>&2
michael@13 247 echo "openpkg:rc:WARNING: please update your local configuration in \"$rcconf\"." 1>&2
michael@13 248 openpkg_rc_all="$openpkg_runall"
michael@13 249 fi
michael@13 250 case "$openpkg_rc_all" in
michael@13 251 [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;;
michael@13 252 esac
michael@13 253 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
michael@13 254 else
michael@13 255 if [ ! -f "$rcdir/rc.$scripts" ]; then
michael@13 256 echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2
michael@13 257 exit 1
michael@13 258 fi
michael@13 259 fi
michael@13 260
michael@13 261 # determine current run-time user
michael@13 262 user=`(id -un) 2>/dev/null ||\
michael@13 263 (id | sed -e 's;^[^(]*(\([^)]*\)).*;\1;') 2>/dev/null ||\
michael@13 264 (whoami) 2>/dev/null ||\
michael@13 265 (who am i | cut "-d " -f1) 2>/dev/null ||\
michael@13 266 echo ${LOGNAME:-${USER}}`
michael@13 267 if [ ".$user" = . ]; then
michael@13 268 echo "openpkg:rc:ERROR: unable to determine current username" 1>&2
michael@13 269 exit 1
michael@13 270 fi
michael@13 271
michael@13 272 # iterate over the specified commands
michael@13 273 rv=0
michael@13 274 cmds="$*"
michael@13 275 for cmd in $cmds; do
michael@13 276 # create "all outputs" file for execution operation (i.e. not --print and --eval)
michael@13 277 if [ ".$print" = .0 -a ".$eval" = .0 ]; then
michael@13 278 rm -f $allfile
michael@13 279 touch $allfile
michael@13 280 fi
michael@13 281
michael@13 282 # find scripts which contain the command and determine
michael@13 283 # their individual user/priority settings
michael@13 284 list=''
michael@13 285 for s_name in $scripts; do
michael@13 286 enable=yes
michael@13 287
michael@13 288 # check for upgraded package with unresolved configuration file conflicts
michael@13 289 if [ -d "$prefix/etc/$s_name" -a ".$eval" != .1 ]; then
michael@13 290 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
michael@13 291 case "$cmd" in
michael@13 292 start|restart ) type="ERROR" ;;
michael@13 293 * ) type="WARNING" ;;
michael@13 294 esac
michael@13 295 echo "openpkg:rc:${type}: package \"$s_name\" has unresolved configuration file conflicts" 1>&2
michael@13 296 echo "openpkg:rc:${type}: indicated by \"*.rpm(new|orig|save)\" files in or below the" 1>&2
michael@13 297 echo "openpkg:rc:${type}: directory \"$prefix/etc/$s_name\". Please resolve first!" 1>&2
michael@13 298 if [ ".$type" = .ERROR ]; then
michael@13 299 continue
michael@13 300 fi
michael@13 301 fi
michael@13 302 fi
michael@13 303
michael@13 304 # check whether command exists in script at all
michael@13 305 cmdline=`grep "^%$cmd" $rcdir/rc.$s_name | sed -e "s;^%$cmd[^ ].*;;"`
michael@13 306 if [ ".$cmdline" != . ]; then
michael@13 307 # parse local command options
michael@13 308 cmdopts=`echo "$cmdline" | sed -e "s;^%$cmd *;;"`
michael@13 309 s_user=$user
michael@13 310 s_prio=500
michael@13 311 s_output=no
michael@13 312 set -- $cmdopts
michael@13 313 prev=''
michael@13 314 for opt
michael@13 315 do
michael@13 316 if [ ".$prev" != . ]; then
michael@13 317 opt="$prev$opt"
michael@13 318 prev=''
michael@13 319 fi
michael@13 320 case $opt in
michael@13 321 -*=* ) arg=${opt/-*=/} ;;
michael@13 322 -[a-zA-Z]* ) arg=${opt/-[a-zA-Z0-9]/} ;;
michael@13 323 *) arg='' ;;
michael@13 324 esac
michael@13 325 case $opt in
michael@13 326 -u|-p ) prev=$opt ;;
michael@13 327 -e|--enable ) enable=yes ;;
michael@13 328 -d|--disable ) enable=no ;;
michael@13 329 -o|--output ) s_output=yes ;;
michael@13 330 -u*|--user=* ) s_user=$arg ;;
michael@13 331 -p*|--prio=* ) s_prio=$arg ;;
michael@13 332 * ) echo "openpkg:rc:WARNING: invalid local option \"$opt\" in \"$rcdir/rc.$s_name:%$cmd\""; break ;;
michael@13 333 esac
michael@13 334 shift
michael@13 335 done
michael@13 336
michael@13 337 # sanity check: is operation supported by current environment?
michael@13 338 if [ ".$s_user" != ".$user" -a ".$user" != ".root" -a ".$print" = .0 ]; then
michael@13 339 echo "openpkg:rc:ERROR: $s_name:%$cmd: require root privileges to run as user \"$s_user\"" 1>&2
michael@13 340 exit 1
michael@13 341 fi
michael@13 342
michael@13 343 # skip this script if script is disabled
michael@13 344 if [ ".$enable" != .yes ]; then
michael@13 345 continue
michael@13 346 fi
michael@13 347
michael@13 348 # accumulate the determined information
michael@13 349 list="$list,$s_prio:$s_name:$s_user:$s_output"
michael@13 350 else
michael@13 351 # command not found in script
michael@13 352 if [ ".$isall" = .0 ]; then
michael@13 353 echo "openpkg:rc:ERROR: $s_name: command \"$cmd\" not found" 1>&2
michael@13 354 exit 1
michael@13 355 fi
michael@13 356 fi
michael@13 357 done
michael@13 358
michael@13 359 # if operating on all scripts, complain if a non-standard command
michael@13 360 # was used and it was not found in any(!) script at all. The
michael@13 361 # standard commands are accepted to perform no operation if no
michael@13 362 # packages are currently installed which provide such commands.
michael@13 363 if [ ".$list" = . -a ".$isall" = .1 ]; then
michael@13 364 case "$cmd" in
michael@13 365 start|stop|monthly|weekly|daily|hourly|quarterly )
michael@13 366 ;;
michael@13 367 * )
michael@13 368 echo "openpkg:rc:ERROR: command \"$cmd\" not found in any script" 1>&2
michael@13 369 rv=1
michael@13 370 break
michael@13 371 ;;
michael@13 372 esac
michael@13 373 fi
michael@13 374
michael@13 375 # generate global (loop invariant) header for script in case of
michael@13 376 # --print and --eval (for the execution approach we cannot do
michael@13 377 # this, because there a new script is generated from scratch for
michael@13 378 # each package.
michael@13 379 if [ ".$print" = .1 -o ".$eval" = .1 ]; then
michael@13 380 rm -f $tmpfile
michael@13 381 touch $tmpfile
michael@13 382
michael@13 383 # generate: optionally enable shell debugging
michael@13 384 if [ ".$debug" = .1 ]; then
michael@13 385 echo "set -x" >>$tmpfile
michael@13 386 fi
michael@13 387
michael@13 388 # generate: inclusion of the run-command helper functions
michael@13 389 echo ". $rcfunc" >>$tmpfile
michael@13 390
michael@13 391 # generate: all %config sections of all(!) scripts. We cannot
michael@13 392 # just include those which have the current command in it
michael@13 393 # because by design all command scripts see the %config
michael@13 394 # section of all(!) scripts. Because of $openpkg_rc_def the
michael@13 395 # variable, we place the %config section of "openpkg" to the front.
michael@13 396 # And we have to extra pre-include the rc.conf to allow
michael@13 397 # rc.conf to override the default of $openpkg_rc_def, too.
michael@13 398 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 399 echo ". $rcconf" >>$tmpfile
michael@13 400 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
michael@13 401 for l_name in $l_scripts; do
michael@13 402 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 403 done
michael@13 404
michael@13 405 # generate: inclusion of the application of override variables
michael@13 406 echo ". $rcconf" >>$tmpfile
michael@13 407
michael@13 408 # for --eval redirect stderr and stdout (but remember stdout)
michael@13 409 # (let stderr pass unfiltered in case of debug mode)
michael@13 410 if [ ".$eval" = .1 ]; then
michael@13 411 if [ ".$debug" = .1 ]; then
michael@13 412 echo "exec 3<&1- 1>/dev/null" >>$tmpfile
michael@13 413 else
michael@13 414 echo "exec 3<&1- 1>/dev/null 2>/dev/null" >>$tmpfile
michael@13 415 fi
michael@13 416 fi
michael@13 417 fi
michael@13 418
michael@13 419 # iterate over all packages (in priority order!) where the command
michael@13 420 # was found in order to execute, print, or evaluate their scripts
michael@13 421 verbose_pos=0
michael@13 422 for entry in `echo $list | tr ',' '\012' | sort -n`; do
michael@13 423 [ ".$entry" = . ] && continue
michael@13 424
michael@13 425 # re-determine the script name, script and whether to print output
michael@13 426 eval `echo $entry | sed -e 's%^[0-9]*:\(.*\):\(.*\):\(.*\)$%s_name="\1"; s_user="\2"; s_output="\3";%'`
michael@13 427
michael@13 428 # display verbose progress message parts
michael@13 429 if [ ".$print" = .0 -a ".$eval" = .0 -a ".$silent" = .0 ]; then
michael@13 430 # line break if we already have output more than 70
michael@13 431 # characters (notice that usually already more characters
michael@13 432 # where printed, because of the name of the last script)
michael@13 433 if [ $verbose_pos -gt 70 ]; then
michael@13 434 verbose_pos=0
michael@13 435 echo "" 1>&2
michael@13 436 fi
michael@13 437
michael@13 438 # display verbose message parts: prefix (on first), separator and package
michael@13 439 if [ $verbose_pos -eq 0 ]; then
michael@13 440 output=$(printf "OpenPKG: %s: " "$cmd")
michael@13 441 echo -n "$output" 1>&2
michael@13 442 verbose_pos=$(($verbose_pos + ${#output}))
michael@13 443 output_prefix=""
michael@13 444 else
michael@13 445 output_prefix=", "
michael@13 446 fi
michael@13 447 output=$(printf "%s%s" "$output_prefix" "$s_name")
michael@13 448 echo -n "$output" 1>&2
michael@13 449 verbose_pos=$(($verbose_pos + ${#output}))
michael@13 450 fi
michael@13 451
michael@13 452 # now operate on the particular script
michael@13 453 if [ ".$print" = .1 ]; then
michael@13 454 # special case: under --print we just add the %common and
michael@13 455 # command scripts to the generated output script and do
michael@13 456 # not execute anything at this point.
michael@13 457 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
michael@13 458 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
michael@13 459 elif [ ".$eval" = .1 ]; then
michael@13 460 # special case: under --eval we just add the %common and
michael@13 461 # command scripts to the generated output script and do
michael@13 462 # not execute anything at this point. Additionally, we
michael@13 463 # emulate a real sub-shell environment.
michael@13 464 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
michael@13 465 echo "while [ 1 ]; do" >>$tmpfile
michael@13 466 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' \
michael@13 467 -e 's/^exit[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)exit[^;]*/\1break 99/g' \
michael@13 468 -e 's/^return[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)return[^;]*/\1break 99/g'
michael@13 469 echo "break" >>$tmpfile
michael@13 470 echo "done" >>$tmpfile
michael@13 471 else
michael@13 472 # the regular case of executing the command script directly
michael@13 473
michael@13 474 # prepare temporary files
michael@13 475 rm -f $tmpfile $outfile $errfile
michael@13 476 (umask 077; touch $tmpfile $outfile $errfile)
michael@13 477
michael@13 478 # generate: optionally enable shell debugging
michael@13 479 if [ ".$debug" = .1 ]; then
michael@13 480 echo "set -x" >>$tmpfile
michael@13 481 fi
michael@13 482
michael@13 483 # generate: inclusion of the run-command helper functions
michael@13 484 echo ". $rcfunc" >>$tmpfile
michael@13 485
michael@13 486 # generate: all %config sections of all(!) scripts. We cannot
michael@13 487 # just include those which have the current command in it
michael@13 488 # because by design all command scripts see the %config
michael@13 489 # section of all(!) scripts. Because of $openpkg_rc_def the
michael@13 490 # variable, we place the %config section of "openpkg" to the front.
michael@13 491 # And we have to extra pre-include the rc.conf to allow
michael@13 492 # rc.conf to override the default of $openpkg_rc_def, too.
michael@13 493 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 494 echo ". $rcconf" >>$tmpfile
michael@13 495 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
michael@13 496 for l_name in $l_scripts; do
michael@13 497 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
michael@13 498 done
michael@13 499
michael@13 500 # generate: inclusion of the application of override variables
michael@13 501 echo ". $rcconf" >>$tmpfile
michael@13 502
michael@13 503 # generate: %common section and particular command section
michael@13 504 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
michael@13 505 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
michael@13 506
michael@13 507 # execute the generated script with GNU Bash
michael@13 508 if [ ".$user" != ".$s_user" ]; then
michael@13 509 # execute as different user
michael@13 510 if [ ".$verbose" = .1 ]; then
michael@13 511 echo "openpkg:rc:NOTICE: $prefix:$s_name:%$cmd: executing as user $s_user"
michael@13 512 fi
michael@13 513 if [ ".$user" = ".@l_susr@" -a ".@l_susr@" = ".root" ]; then
michael@13 514 chown $s_user $tmpfile
michael@13 515 if [ ".$debug" = .1 ]; then
michael@13 516 su - $s_user -c "PATH=\"$PATH\"; $bash $tmpfile" >$outfile
michael@13 517 rc=$?
michael@13 518 else
michael@13 519 su - $s_user -c "PATH=\"$PATH\"; $bash $tmpfile" >$outfile 2>$errfile
michael@13 520 rc=$?
michael@13 521 fi
michael@13 522 elif [ ".@l_susr@" != ".root" ]; then
michael@13 523 # do not complain if we would not have any chance
michael@13 524 # at all to switch the user because we are running
michael@13 525 # in a non-privileged instance. Else we would just
michael@13 526 # trash the mailbox of the user receiving the
michael@13 527 # output of periodic run-commands.
michael@13 528 rc=0
michael@13 529 else
michael@13 530 echo "openpkg:rc:WARNING: $prefix:$s_name:%$cmd: require root privileges to run as user \"$s_user\"" 1>&2
michael@13 531 rc=1
michael@13 532 fi
michael@13 533 else
michael@13 534 # execute as current user
michael@13 535 if [ ".$verbose" = .1 ]; then
michael@13 536 echo "openpkg:rc:NOTICE: $prefix:$s_name:%$cmd: executing as user $user"
michael@13 537 fi
michael@13 538 if [ ".$debug" = .1 ]; then
michael@13 539 $bash $tmpfile >$outfile
michael@13 540 rc=$?
michael@13 541 else
michael@13 542 $bash $tmpfile >$outfile 2>$errfile
michael@13 543 rc=$?
michael@13 544 fi
michael@13 545 fi
michael@13 546 if [ $rc -ne 0 ]; then
michael@13 547 if [ ".$silent" = .0 ]; then
michael@13 548 # indicate failure of execution on verbose message line
michael@13 549 echo ":FAILED" 1>&2
michael@13 550 verbose_pos=0
michael@13 551 fi
michael@13 552 # give details of execution failure
michael@13 553 ( echo "openpkg:rc:WARNING: $prefix:$s_name:%$cmd: failed with return code $rc"
michael@13 554 if [ ".`cat $outfile $errfile`" != . ]; then
michael@13 555 echo "openpkg:rc:NOTICE: output from stdout/stderr is following:"
michael@13 556 echo "+----------------------------------------------------------------------"
michael@13 557 cat $outfile $errfile | sed -e 's;^;| ;'
michael@13 558 echo "+----------------------------------------------------------------------"
michael@13 559 else
michael@13 560 echo "openpkg:rc:NOTICE: no output occurred on stdout/stderr"
michael@13 561 fi
michael@13 562 ) 1>&2
michael@13 563
michael@13 564 # enforce global return value
michael@13 565 rv=1
michael@13 566 else
michael@13 567 # give details of execution success in case verbose operation is requested
michael@13 568 if [ ".$verbose" = .1 ]; then
michael@13 569 ( echo "openpkg:rc:NOTICE: $prefix:$s_name:%$cmd: succeeded with return code $rc"
michael@13 570 if [ ".`cat $outfile $errfile`" != . ]; then
michael@13 571 echo "openpkg:rc:NOTICE: output from stdout/stderr is following:"
michael@13 572 echo "+----------------------------------------------------------------------"
michael@13 573 cat $outfile $errfile | sed -e 's;^;| ;'
michael@13 574 echo "+----------------------------------------------------------------------"
michael@13 575 else
michael@13 576 echo "openpkg:rc:NOTICE: no output occurred on stdout/stderr"
michael@13 577 fi
michael@13 578 ) 1>&2
michael@13 579 fi
michael@13 580 if [ ".$s_output" = .yes ]; then
michael@13 581 # accumulate script output for later display
michael@13 582 cat $outfile >>$allfile
michael@13 583 fi
michael@13 584 fi
michael@13 585 fi
michael@13 586 done
michael@13 587
michael@13 588 # post-processing for each command
michael@13 589 if [ ".$print" = .1 ]; then
michael@13 590 # for --print just print the resulting script to stdout
michael@13 591 cat $tmpfile
michael@13 592 elif [ ".$eval" = .1 ]; then
michael@13 593 # finish generation of temporary script by restoring stdout
michael@13 594 # and printing the exported environment variables into a format
michael@13 595 # suitable for evaluation by the callers shell.
michael@13 596 echo "exec 1<&3-" >>$tmpfile
michael@13 597 echo "unset PWD SHLVL" >>$tmpfile
michael@13 598 echo "env |\\" >>$tmpfile
michael@13 599 echo "egrep '^[A-Z_][A-Z0-9_]*=.' |\\" >>$tmpfile
michael@13 600 echo "sed -e '/^_=/d' -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g' \\" >>$tmpfile
michael@13 601 case $SHELL in
michael@13 602 csh|*/csh|tcsh|*/tcsh )
michael@13 603 echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/setenv \\1 \"\\2\"/'" >>$tmpfile
michael@13 604 ;;
michael@13 605 * )
michael@13 606 echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/\\1=\"\\2\"; export \\1/'" >>$tmpfile
michael@13 607 ;;
michael@13 608 esac
michael@13 609
michael@13 610 # prepare temporary files
michael@13 611 rm -f $outfile $errfile
michael@13 612 touch $outfile $errfile
michael@13 613
michael@13 614 # now replace temporary script with its output
michael@13 615 # by executing it and capturing its output
michael@13 616 # (let stderr pass unfiltered in case of debug mode)
michael@13 617 if [ ".$debug" = .1 ]; then
michael@13 618 env -i \
michael@13 619 HOME="$HOME" \
michael@13 620 USER="$USER" \
michael@13 621 LOGNAME="$LOGNAME" \
michael@13 622 TERM="$TERM" \
michael@13 623 PATH="$PATH_ORIG" \
michael@13 624 MANPATH="$MANPATH" \
michael@13 625 INFOPATH="$INFOPATH" \
michael@13 626 LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
michael@13 627 $bash --norc --noprofile --posix \
michael@13 628 $tmpfile >$outfile
michael@13 629 else
michael@13 630 env -i \
michael@13 631 HOME="$HOME" \
michael@13 632 USER="$USER" \
michael@13 633 LOGNAME="$LOGNAME" \
michael@13 634 TERM="$TERM" \
michael@13 635 PATH="$PATH_ORIG" \
michael@13 636 MANPATH="$MANPATH" \
michael@13 637 INFOPATH="$INFOPATH" \
michael@13 638 LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
michael@13 639 $bash --norc --noprofile --posix \
michael@13 640 $tmpfile >$outfile 2>/dev/null
michael@13 641 fi
michael@13 642 cp $outfile $tmpfile
michael@13 643
michael@13 644 # for --eval we cannot just print the resulting script because
michael@13 645 # not all Bourne-Shell implementations like to "eval" large
michael@13 646 # multi-line outputs. Hence we output a little one-liner which
michael@13 647 # "sources" the script instead and cleans up.
michael@13 648 case $SHELL in
michael@13 649 csh|*/csh|tcsh|*/tcsh )
michael@13 650 echo "source $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
michael@13 651 ;;
michael@13 652 * )
michael@13 653 echo ". $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
michael@13 654 ;;
michael@13 655 esac
michael@13 656 else
michael@13 657 # for the execution situation just make sure we
michael@13 658 # terminate the verbose message output.
michael@13 659 if [ ".$silent" = .0 -a $verbose_pos -gt 0 ]; then
michael@13 660 echo "." 1>&2
michael@13 661 fi
michael@13 662
michael@13 663 # additionally, if a script wants its output to be displayed,
michael@13 664 # now do it. In case there was no such request, do not bother
michael@13 665 # -- we then just output an empty file and so can avoid an
michael@13 666 # extra test surrounding the next command.
michael@13 667 cat $allfile
michael@13 668 fi
michael@13 669 done
michael@13 670
michael@13 671 # cleanup temporary files except the result script in
michael@13 672 # case of --eval (which is then removed by the caller).
michael@13 673 # keep those files for debugging purposes if requested.
michael@13 674 if [ ".$keep" = .0 ]; then
michael@13 675 rm -f $outfile $errfile $allfile >/dev/null 2>&1 || true
michael@13 676 if [ ".$eval" = .0 ]; then
michael@13 677 rm -f $tmpfile >/dev/null 2>&1 || true
michael@13 678 rm -rf $tmpdir >/dev/null 2>&1 || true
michael@13 679 fi
michael@13 680 fi
michael@13 681
michael@13 682 # now clean the exit trap and exit with the global return value
michael@13 683 # indicating to the caller whether all scripts were executed
michael@13 684 # successfully or at least one failed.
michael@13 685 trap - EXIT
michael@13 686 exit $rv
michael@13 687

mercurial