openpkg/rc

Tue, 31 Jul 2012 09:20:53 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 31 Jul 2012 09:20:53 +0200
changeset 421
3285b64e3857
child 427
71503088f51b
permissions
-rw-r--r--

Import package vendor original specs for necessary manipulations.

     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