openpkg/rc

Thu, 04 Oct 2012 20:30:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 04 Oct 2012 20:30:05 +0200
changeset 715
c10fb90893b9
parent 469
65414bdd541c
permissions
-rw-r--r--

Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.

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

mercurial