Tue, 29 Mar 2011 20:04:34 +0200
Rework package yet again, correcting and introducing new buildconf logic:
Conditionally disable bootstrap stage comparison correctly, correct
english grammar, better find system as(1) and ld(1), indotruce detailed
optimization option messages, more completely guess cpu types, allow
profiled bootstrapping without a preinstalled GCC because many other
compilers have long since implemented 64-bit arithmetic, instruct make
to build sequentially (not in sparallel) when building a profiled
bootstrap as GCC online documents recommend, and generally improve
comment blocks.
The single most important correction in this changeset relates to the
GCC changed optimization policy since at least GCC 4.5, in which -march
is always passed and not always correctly guessed. In the case of this
package, allowing GCC to guess the architecture leads to wild build
errors at various subcomponents (zlib, libgcc, libiberty...) and
bootstrap stages. It seems quite platform specific, and the safest
approach to correcting this seems to be explicitly always specifying the
-march argument when bootstrapping GCC. Because the best choice 'native'
is not available when bootstrapping using a foreign (non GCC) compiler,
a guess is made according to rpmmacros l_platform in that case.
It is questionable as to whether these recent optimization changes
on the part of GCC or this package are compatible with each other,
or if either are complete or correct at all. At least applying these
corrections allows this package to build again in most cases test.
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 |