openpkg/rc

Sun, 29 May 2011 16:29:06 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sun, 29 May 2011 16:29:06 +0200
changeset 344
e33c1efbd60f
child 427
71503088f51b
permissions
-rw-r--r--

Update, correct, improve build configuration and packaging logic.
Update to new version of vendor software, bump copyright date, remove implicit
gcc dependency, add comments for Trolltech bug tracking, correct enforced
dynamic library linkage, and install mysterious process stub binary.

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

mercurial