openpkg/stack.sh

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
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 ##
     2 ##  OpenPKG Software Stack Generation
     3 ##  Copyright (c) 2010-2012 OpenPKG GmbH <http://openpkg.com/>
     4 ##
     5 ##  This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
     6 ##  All rights reserved. Licenses which grant limited permission to use,
     7 ##  copy, modify and distribute this software are available from the
     8 ##  OpenPKG GmbH.
     9 ##
    10 ##  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
    11 ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    12 ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    13 ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
    14 ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    15 ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    16 ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    17 ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    18 ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    19 ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    20 ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    21 ##  SUCH DAMAGE.
    22 ##
    24 #   configuration
    25 openpkg="${OPENPKG_PREFIX}/bin/openpkg"
    26 curl="${OPENPKG_PREFIX}/bin/openpkg curl"
    27 shtool="${OPENPKG_PREFIX}/lib/openpkg/shtool"
    29 ##
    30 ##  COMMAND LINE PARSING
    31 ##
    33 str_usage="[-h|--help] [-v|--verbose <level>] [-o|--output <dir>] [-D|--define <name>=<value> ...] [-u|--unversioned] [-q|--query] <name>.stk"
    34 arg_spec="1="
    35 opt_spec="h.v:o:D+u.q."
    36 opt_alias="h:help,v:verbose,o:output,D:define,u:unversioned,q:query"
    37 opt_h=no
    38 opt_v=4
    39 opt_o="."
    40 opt_D=""
    41 opt_u=no
    42 opt_q=no
    44 #   parse argument specification string
    45 eval `echo $arg_spec |\
    46       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
    48 #   parse option specification string
    49 eval `echo $opt_spec |\
    50       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
    52 #   parse option alias string
    53 eval `echo $opt_alias |\
    54       sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
    56 #   interate over argument line
    57 opt_PREV=''
    58 while [ $# -gt 0 ]; do
    59     #   special option stops processing
    60     if [ ".$1" = ".--" ]; then
    61         shift
    62         break
    63     fi
    65     #   determine option and argument
    66     opt_ARG_OK=no
    67     if [ ".$opt_PREV" != . ]; then
    68         #   merge previous seen option with argument
    69         opt_OPT="$opt_PREV"
    70         opt_ARG="$1"
    71         opt_ARG_OK=yes
    72         opt_PREV=''
    73     else
    74         #   split argument into option and argument
    75         case "$1" in
    76             --[a-zA-Z0-9]*=*)
    77                 eval `echo "x$1" |\
    78                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
    79                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
    80                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
    81                 ;;
    82             --[a-zA-Z0-9]*)
    83                 opt_OPT=`echo "x$1" | cut -c4-`
    84                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
    85                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
    86                 opt_ARG=''
    87                 ;;
    88             -[a-zA-Z0-9]*)
    89                 eval `echo "x$1" |\
    90                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
    91                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
    92                 ;;
    93             -[a-zA-Z0-9])
    94                 opt_OPT=`echo "x$1" | cut -c3-`
    95                 opt_ARG=''
    96                 ;;
    97             *)
    98                 break
    99                 ;;
   100         esac
   101     fi
   103     #   eat up option
   104     shift
   106     #   determine whether option needs an argument
   107     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
   108     if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
   109         if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
   110             opt_PREV="$opt_OPT"
   111             continue
   112         fi
   113     fi
   115     #   process option
   116     case $opt_MODE in
   117         '.' )
   118             #   boolean option
   119             eval "opt_${opt_OPT}=yes"
   120             ;;
   121         ':' )
   122             #   option with argument (multiple occurances override)
   123             eval "opt_${opt_OPT}=\"\$opt_ARG\""
   124             ;;
   125         '+' )
   126             #   option with argument (multiple occurances append)
   127             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
   128             ;;
   129         * )
   130             echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
   131             exit 1
   132             ;;
   133     esac
   134 done
   135 if [ ".$opt_PREV" != . ]; then
   136     echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
   137     exit 1
   138 fi
   140 #   process help option
   141 if [ ".$opt_h" = .yes ]; then
   142     echo "Usage: $0 $str_usage"
   143     exit 0
   144 fi
   146 #   complain about incorrect number of arguments
   147 case $arg_MODE in
   148     '=' )
   149         if [ $# -ne $arg_NUMS ]; then
   150             echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
   151             exit 1
   152         fi
   153         ;;
   154     '+' )
   155         if [ $# -lt $arg_NUMS ]; then
   156             echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
   157             exit 1
   158         fi
   159         ;;
   160 esac
   162 ##
   163 ##  HELPER FUNCTIONS
   164 ##
   166 #   helper function for graceful termination
   167 die () {
   168     echo "$0: ERROR: $*"
   169     exit 1
   170 }
   172 #   helper function for verbose messages
   173 verbose () {
   174     lvl="$1"
   175     msg="$2"
   176     if [ $opt_v -ge $lvl ]; then
   177         case "$lvl" in
   178             1 ) str_prefix="**" ;;
   179             2 ) str_prefix="++" ;;
   180             3 ) str_prefix="--" ;;
   181             4 ) str_prefix=".." ;;
   182         esac
   183         echo "${str_prefix} ${msg}"
   184     fi
   185 }
   187 #   expand macros
   188 macro_expand () {
   189     stk="$1"
   191     #   load all options and their default values
   192     options=""
   193     for option in `sed <$stk \
   194         -e "1,/^%options/d" -e '/^%/,$d' \
   195         -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' \
   196         -e 's; *[^ ]*$;;'`; do
   197         options="$options $option"
   198     done
   199     eval `sed <$stk \
   200         -e "1,/^%options/d" -e '/^%/,$d' \
   201         -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \
   202         -e 's:^\([^ ]*\) *\([^ ]*\)$:option_\1="\2";:'`
   204     #   override options with defined values
   205     for define in $opt_D; do
   206         name=`echo "$define" | sed -e 's;=.*$;;'`
   207         value=`echo "$define" | sed -e 's;^.*=;;'`
   208         eval "exists=\"\${option_${name}}\""
   209         if [ ".$exists" = . ]; then
   210             die "definition of not-existing option \"$name\""
   211         fi
   212         eval "option_${name}=\"${value}\""
   213     done
   215     #   expand macros
   216     cmd="sed"
   217     for name in $options; do
   218         eval "value=\"\${option_${name}}\""
   219         cmd="$cmd -e 's;%{[?]$name:\\([^}]*\\)};\1;g'"
   220         cmd="$cmd -e 's;%{![?]$name:\\([^}]*\\)};;g'"
   221         cmd="$cmd -e 's;%{$name};$value;g'"
   222     done
   223     cmd="$cmd -e 's;%{[?][^:}]*:[^}]*};;g'"
   224     cmd="$cmd -e 's;%{![?][^:}]*:\([^}]*\)};\1;g'"
   225     eval "$cmd"
   226 }
   228 #   extract macro-expanded header
   229 header () {
   230     stk="$1"
   231     hdr="$2"
   232     exists=`egrep "^${hdr}" $stk`
   233     if [ ".$exists" != . ]; then
   234         egrep "^${hdr}:" $stk | \
   235         sed -e 's;^[^:]*: *;;' -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \
   236         macro_expand "$stk"
   237     fi
   238 }
   240 #   extract macro-expanded section
   241 section () {
   242     stk="$1"
   243     sec="$2"
   244     exists=`egrep "^%${sec}" $stk`
   245     if [ ".$exists" != . ]; then
   246         sed <$stk \
   247             -e "1,/^%${sec}/d" -e '/^%/,$d' \
   248             -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \
   249         macro_expand "$stk"
   250     fi
   251 }
   253 ##
   254 ##  MAIN
   255 ##
   257 #   determine stack file
   258 stk="$1"
   259 shift
   261 #   support stand-alone query operation
   262 if [ ".$opt_q" = .yes ]; then
   263     name=`header "$stk" "Name"`
   264     summary=`header "$stk" "Summary"`
   265     packager=`header "$stk" "Packager"`
   266     version=`header "$stk" "Version"`
   267     release=`header "$stk" "Release"`
   268     echo "name=\"$name\";"
   269     echo "summary=\"$summary\";"
   270     echo "packager=\"$packager\";"
   271     echo "version=\"$version\";"
   272     echo "release=\"$release\";"
   273     sed <$stk \
   274         -e "1,/^%options/d" -e '/^%/,$d' \
   275         -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \
   276         -e 's:^\([^ ]*\) *\([^ ]*\)$:\1="\2";:'
   277     exit 0
   278 fi
   280 #   determine temporary directory
   281 tmpdir="${TMPDIR-/tmp}"
   283 #   provide verbose header
   284 verbose 1 "OpenPKG Software Stack Generation"
   286 #   determine information
   287 verbose 2 "determining software stack information"
   288 name=`header "$stk" "Name"`
   289 summary=`header "$stk" "Summary"`
   290 packager=`header "$stk" "Packager"`
   291 version=`header "$stk" "Version"`
   292 release=`header "$stk" "Release"`
   293 verbose 3 "Name:        $name"
   294 verbose 3 "Summary:     $summary"
   295 verbose 3 "Packager:    $packager"
   296 verbose 3 "Version:     $version"
   297 verbose 3 "Release:     $release"
   298 if [ ".$opt_u" = .yes ]; then
   299     basename="$name"
   300 else
   301     basename="$name-$version-$release"
   302 fi
   304 #   determine URLs
   305 verbose 2 "determining software stack packages"
   306 repo=`section "$stk" "repository"`
   307 verbose 3 "repository:  [URL]  $repo"
   308 $openpkg build -r "$repo" -Z -u -K -B \
   309     `section "$stk" "packages"` | \
   310     egrep "openpkg curl" | \
   311     sed -e 's;^.* \([^ ]*\) || exit.*$;\1;' \
   312         -e '/\/openpkg-[0-9].*\.src\.rpm/{h;s/\.src\.rpm$/.src.sh/;p;x}' \
   313     >$tmpdir/url.txt
   315 #   provide header
   316 verbose 2 "assembling software stack sources"
   318 #   download source packages
   319 if [ ! -d "$opt_o/$basename.src.d" ]; then
   320     verbose 3 "creating:    [DIR]  $opt_o/$basename.src.d"
   321     $shtool mkdir -p -m 755 "$opt_o/$basename.src.d"
   322 else
   323     verbose 3 "reusing:     [DIR]  $opt_o/$basename.src.d"
   324 fi
   325 for url in `cat $tmpdir/url.txt`; do
   326     url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'`
   327     if [ ! -f "$opt_o/$basename.src.d/$url_file" ]; then
   328         verbose 3 "downloading: [FILE] $opt_o/$basename.src.d/$url_file"
   329         if [ $opt_v -ge 4 ]; then
   330             $curl '-#' -L -k -o $opt_o/$basename.src.d/$url_file $url
   331         else
   332             $curl -s -L -k -o $opt_o/$basename.src.d/$url_file $url
   333         fi
   334     else
   335         verbose 3 "reusing:     [FILE] $opt_o/$basename.src.d/$url_file"
   336     fi
   337 done
   338 for path in $opt_o/$basename.src.d/*.src.sh $opt_o/$basename.src.d/*.src.rpm; do
   339     if [ ! -f "$path" ]; then
   340         continue
   341     fi
   342     path_file=`echo $path | sed -e 's;^.*/\([^/]*\)$;\1;'`
   343     found=no
   344     for url in `cat $tmpdir/url.txt`; do
   345         url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'`
   346         if [ ".$url_file" = ".$path_file" ]; then
   347             found=yes
   348             break
   349         fi
   350     done
   351     if [ ".$found" = .no ]; then
   352         verbose 3 "removing:    [FILE] $path"
   353         rm -f "$path"
   354     fi
   355 done
   356 rm -f $tmpdir/url.txt
   358 #   generate XML/RDF index for SRPM packages
   359 verbose 3 "generating:  [FILE] $opt_o/$basename.src.d/00INDEX.rdf"
   360 $openpkg index -r "OpenPKG/SRPM" \
   361     -o $opt_o/$basename.src.d/00INDEX.rdf \
   362     -i $opt_o/$basename.src.d
   364 #   generate deployment utility
   365 verbose 3 "generating:  [FILE] $opt_o/$basename.sh"; \
   366 section "$stk" "framework" >$tmpdir/framework.txt
   367 section "$stk" "prolog" >$tmpdir/prolog.txt
   368 section "$stk" "epilog" >$tmpdir/epilog.txt
   369 HAVE_PROLOG=no; if [ ".`cat $tmpdir/prolog.txt`" != . ]; then HAVE_PROLOG=yes; fi
   370 HAVE_EPILOG=no; if [ ".`cat $tmpdir/epilog.txt`" != . ]; then HAVE_EPILOG=yes; fi
   371 $openpkg build -r "$repo" -Z -u -K \
   372     `section "$stk" "packages"` | \
   373 grep -v "^#" | \
   374 grep -v "^echo" | \
   375 grep -v "^rm" | \
   376 egrep -v "^(if|fi)" | \
   377 grep -v "openpkg curl" | \
   378 grep -v "openpkg rpm -Uvh" | \
   379 sed -e 's;.*openpkg rpm ;;' \
   380     -e 's; || exit.*;;' \
   381     -e 's;--rebuild ;;' \
   382     -e 's;/.*/\([^/]*\.src\.rpm\);\1;' \
   383     -e 's;^\(.*\) \([^/]*\.src\.rpm\);\2 \1;' \
   384     -e "s;--define '\\([^ ]*\\) \\([^ ]*\\)';\\1=\\2;g" \
   385     -e 's;\.src\.rpm;;' \
   386     >$tmpdir/packages.txt
   387 sed <$0 \
   388     -e '1,/^____/d' \
   389     -e "/^CFG_FRAMEWORK=\"/r $tmpdir/framework.txt" \
   390     -e "/^CFG_PACKAGES=\"/r $tmpdir/packages.txt" \
   391     -e "s;@HAVE_PROLOG@;$HAVE_PROLOG;" \
   392     -e "/%prolog/r $tmpdir/prolog.txt" \
   393     -e "s;@HAVE_EPILOG@;$HAVE_EPILOG;" \
   394     -e "/%epilog/r $tmpdir/epilog.txt" \
   395     -e "/^## SHTOOL ##/r $shtool" \
   396     -e "s;^\\(CFG_NAME=\"\\).*\\(\"\\);\\1$name\\2;" \
   397     -e "s;^\\(CFG_SUMMARY=\"\\).*\\(\"\\);\\1$summary\\2;" \
   398     -e "s;^\\(CFG_PACKAGER=\"\\).*\\(\"\\);\\1$packager\\2;" \
   399     -e "s;^\\(CFG_VERSION=\"\\).*\\(\"\\);\\1$version\\2;" \
   400     -e "s;^\\(CFG_RELEASE=\"\\).*\\(\"\\);\\1$release\\2;" \
   401     -e "s;^\\(CFG_UNVERSIONED=\"\\).*\\(\"\\);\\1$opt_u\\2;" \
   402     >$opt_o/$basename.sh
   404 #   cleanup
   405 rm -f $tmpdir/framework.txt
   406 rm -f $tmpdir/packages.txt
   407 rm -f $tmpdir/prolog.txt
   408 rm -f $tmpdir/epilog.txt
   410 #   exit gracefully
   411 exit 0
   413 ##
   414 ##  DEPLOYMENT SCRIPT
   415 ##
   417 ______________________________________________________________________________
   418 #!/bin/sh
   419 #![OpenPKG]
   420 ##
   421 ##  OpenPKG Software Stack Deployment
   422 ##  Copyright (c) 2010-2012 OpenPKG GmbH <http://openpkg.com/>
   423 ##
   424 ##  This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
   425 ##  All rights reserved. Licenses which grant limited permission to use,
   426 ##  copy, modify and distribute this software are available from the
   427 ##  OpenPKG GmbH.
   428 ##
   429 ##  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
   430 ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   431 ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   432 ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
   433 ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   434 ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   435 ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   436 ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   437 ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   438 ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   439 ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   440 ##  SUCH DAMAGE.
   441 ##
   443 ##
   444 ##  COMMAND LINE PARSING
   445 ##
   447 str_usage="[-h|--help] [-v|--verbose <level>] [-c|--cleanup <level>] [-D|--define <name>=<value> ...] [-s|--srcdir <dir>] [-o|--outdir <dir>] [-t|--tmpdir <dir>] [-S <sudo>]"
   448 arg_spec="0="
   449 opt_spec="h.v:c:D+s:o:t:S:"
   450 opt_alias="h:help,v:verbose,c:cleanup,D:define,s:srcdir,o:outdir,t:tmpdir,S:sudo"
   451 opt_h=no
   452 opt_v=3
   453 opt_c=1
   454 opt_D=""
   455 opt_s=""
   456 opt_o=""
   457 opt_t="${TMPDIR-/tmp}"
   458 opt_S=""
   460 #   parse argument specification string
   461 eval `echo $arg_spec |\
   462       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
   464 #   parse option specification string
   465 eval `echo $opt_spec |\
   466       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
   468 #   parse option alias string
   469 eval `echo $opt_alias |\
   470       sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
   472 #   interate over argument line
   473 opt_PREV=''
   474 while [ $# -gt 0 ]; do
   475     #   special option stops processing
   476     if [ ".$1" = ".--" ]; then
   477         shift
   478         break
   479     fi
   481     #   determine option and argument
   482     opt_ARG_OK=no
   483     if [ ".$opt_PREV" != . ]; then
   484         #   merge previous seen option with argument
   485         opt_OPT="$opt_PREV"
   486         opt_ARG="$1"
   487         opt_ARG_OK=yes
   488         opt_PREV=''
   489     else
   490         #   split argument into option and argument
   491         case "$1" in
   492             --[a-zA-Z0-9]*=*)
   493                 eval `echo "x$1" |\
   494                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
   495                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
   496                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
   497                 ;;
   498             --[a-zA-Z0-9]*)
   499                 opt_OPT=`echo "x$1" | cut -c4-`
   500                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
   501                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
   502                 opt_ARG=''
   503                 ;;
   504             -[a-zA-Z0-9]*)
   505                 eval `echo "x$1" |\
   506                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
   507                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
   508                 ;;
   509             -[a-zA-Z0-9])
   510                 opt_OPT=`echo "x$1" | cut -c3-`
   511                 opt_ARG=''
   512                 ;;
   513             *)
   514                 break
   515                 ;;
   516         esac
   517     fi
   519     #   eat up option
   520     shift
   522     #   determine whether option needs an argument
   523     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
   524     if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
   525         if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
   526             opt_PREV="$opt_OPT"
   527             continue
   528         fi
   529     fi
   531     #   process option
   532     case $opt_MODE in
   533         '.' )
   534             #   boolean option
   535             eval "opt_${opt_OPT}=yes"
   536             ;;
   537         ':' )
   538             #   option with argument (multiple occurances override)
   539             eval "opt_${opt_OPT}=\"\$opt_ARG\""
   540             ;;
   541         '+' )
   542             #   option with argument (multiple occurances append)
   543             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
   544             ;;
   545         * )
   546             echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
   547             exit 1
   548             ;;
   549     esac
   550 done
   551 if [ ".$opt_PREV" != . ]; then
   552     echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
   553     exit 1
   554 fi
   556 #   process help option
   557 if [ ".$opt_h" = .yes ]; then
   558     echo "Usage: $0 $str_usage"
   559     exit 0
   560 fi
   562 #   complain about incorrect number of arguments
   563 case $arg_MODE in
   564     '=' )
   565         if [ $# -ne $arg_NUMS ]; then
   566             echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
   567             exit 1
   568         fi
   569         ;;
   570     '+' )
   571         if [ $# -lt $arg_NUMS ]; then
   572             echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
   573             exit 1
   574         fi
   575         ;;
   576 esac
   578 #   helper function for verbose messages
   579 verbose () {
   580     lvl="$1"
   581     msg="$2"
   582     if [ $opt_v -ge $lvl ]; then
   583         case "$lvl" in
   584             1 ) str_prefix="**" ;;
   585             2 ) str_prefix="++" ;;
   586             3 ) str_prefix="--" ;;
   587             4 ) str_prefix=".." ;;
   588         esac
   589         echo "${str_prefix} ${msg}"
   590     fi
   591 }
   593 #   helper function for graceful termination
   594 die () {
   595     echo "$0: ERROR: $*"
   596     exit 1
   597 }
   599 ##
   600 ##  MAIN
   601 ##
   603 #   the stack information
   604 CFG_NAME=""
   605 CFG_SUMMARY=""
   606 CFG_PACKAGER=""
   607 CFG_VERSION=""
   608 CFG_RELEASE=""
   610 #   the required OpenPKG framework parameters
   611 CFG_FRAMEWORK="
   612 "
   614 #   the required OpenPKG packages
   615 #   (in topological order and with build options resolved)
   616 CFG_PACKAGES="
   617 "
   619 #   whether unversioned output directory should be used
   620 CFG_UNVERSIONED=""
   622 #   display information
   623 verbose 1 "OpenPKG Software Stack Deployment"
   624 verbose 2 "determining information"
   626 #   parse OpenPKG framework parameters
   627 params="
   628     prefix
   629     user group
   630     susr musr rusr nusr
   631     sgrp mgrp rgrp ngrp
   632     suid muid ruid nuid
   633     sgid mgid rgid ngid
   634     tag
   635 "
   636 for param in $params; do
   637     eval "CF_$param=''"
   638 done
   639 for opt in $CFG_FRAMEWORK; do
   640     case "$opt" in
   641         --[a-zA-Z0-9-]*=* )
   642             name=`echo "$opt" | sed -e 's;^--\([^=]*\)=.*$;\1;'`
   643             value=`echo "$opt" | sed -e 's;^--[^=]*=\(.*\)$;\1;'`
   644             eval "CF_$name='$value'"
   645             ;;
   646     esac
   647 done
   648 for define in $opt_D; do
   649     name=`echo "$define" | sed -e 's;=.*$;;'`
   650     value=`echo "$define" | sed -e 's;^.*=;;'`
   651     eval "CF_$name='$value'"
   652 done
   653 CFG_FRAMEWORK=''
   654 for name in $params; do
   655     eval "value=\"\$CF_$name\""
   656     if [ ".$value" != . ]; then
   657         if [ ".$CFG_FRAMEWORK" = . ]; then
   658             CFG_FRAMEWORK="--$name=$value"
   659         else
   660             CFG_FRAMEWORK="$CFG_FRAMEWORK --$name=$value"
   661         fi
   662     fi
   663 done
   664 if [ ".$CF_musr" = . ]; then CF_musr="$CF_user";    fi
   665 if [ ".$CF_mgrp" = . ]; then CF_mgrp="$CF_group";   fi
   666 if [ ".$CF_rusr" = . ]; then CF_rusr="$CF_user-r";  fi
   667 if [ ".$CF_rgrp" = . ]; then CF_rgrp="$CF_group-r"; fi
   668 if [ ".$CF_nusr" = . ]; then CF_nusr="$CF_user-n";  fi
   669 if [ ".$CF_ngrp" = . ]; then CF_ngrp="$CF_group-n"; fi
   670 verbose 3 "name:     $CFG_NAME"
   671 verbose 3 "summary:  $CFG_SUMMARY"
   672 verbose 3 "packager: $CFG_PACKAGER"
   673 verbose 3 "version:  $CFG_VERSION"
   674 verbose 3 "release:  $CFG_RELEASE"
   676 #   determine target parameters
   677 if [ ".$CF_prefix" = . ]; then
   678     die "OpenPKG Framework parameter \"prefix\" required"
   679 fi
   680 prefix="$CF_prefix"
   681 if [ ".$CF_tag" = . ]; then
   682     die "OpenPKG Framework parameter \"tag\" required"
   683 fi
   684 tag="$CF_tag"
   685 shtool="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.shtool.sh"
   686 sed <$0 -e '1,/^## SHTOOL ##.*/d' >$shtool
   687 platform=`sh $shtool platform -n -L -S "" -C "+" -F '%<ap>-%<sp>'`
   688 verbose 3 "platform: $platform"
   689 verbose 3 "tag:      $tag"
   690 verbose 3 "prefix:   $prefix"
   692 #   determine operation directories
   693 srcdir="$opt_s"
   694 if [ ".$srcdir" = . ]; then
   695     srcdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.src.d"
   696 fi
   697 tmpdir="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.d"
   698 if [ ! -d "$tmpdir" ]; then
   699     (   umask 077
   700         rm -rf "$tmpdir" >/dev/null 2>&1 || true
   701         sh $shtool mkdir -p -m 700 "$tmpdir" >/dev/null 2>&1
   702         if [ $? -ne 0 ]; then
   703             die "failed to create temporary directory: \"$tmpdir\""
   704         fi
   705     ) || exit $?
   706 fi
   707 outdir="$opt_o"
   708 if [ ".$outdir" = . ]; then
   709     if [ ".$CFG_UNVERSIONED" = .yes ]; then
   710         outdir="$CFG_NAME.$platform-$tag.d"
   711     else
   712         outdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.$platform-$tag.d"
   713     fi
   714 fi
   715 if [ ! -d "$outdir" ]; then
   716     sh $shtool mkdir -p -m 755 "$outdir" >/dev/null 2>&1
   717     if [ $? -ne 0 ]; then
   718         die "failed to create output directory: \"$outdir\""
   719     fi
   720 fi
   721 verbose 3 "srcdir:   $srcdir"
   722 verbose 3 "outdir:   $outdir"
   723 verbose 3 "tmpdir:   $tmpdir"
   725 #   execute prolog script
   726 if [ ".@HAVE_PROLOG@" = .yes ]; then
   727     verbose 2 "execute prolog script"
   728     cat >$tmpdir/prolog.sh <<EOT
   729 #!/bin/sh
   730 #![OpenPKG]
   731 # %prolog
   732 EOT
   733     $opt_S sh $tmpdir/prolog.sh
   734     rm -f $tmpdir/prolog.sh
   735 fi
   737 if [ $opt_c -le 1 -a -x "$prefix/bin/openpkg" ]; then
   738     #   optionally fresh-up OpenPKG instance
   739     pkgs=`$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`
   740     if [ ".$pkgs" != . ]; then
   741         verbose 2 "uninstall already installed OpenPKG packages"
   742         for pkg in $pkgs; do
   743             verbose 3 "REMOVE: $pkg @ $prefix"
   744         done
   745         $opt_S $prefix/bin/openpkg rpm -e $pkgs || \
   746             die "failed to uninstall already installed OpenPKG packages"
   747     fi
   748 fi
   749 if [ $opt_c -le 0 -a -x "$prefix/bin/openpkg" ]; then
   750     #   optionally destroy OpenPKG instance
   751     verbose 2 "destroy existing OpenPKG framework"
   752     $opt_S $prefix/bin/openpkg rpm -e openpkg || \
   753         die "failed to destroy existing OpenPKG framework"
   754 fi
   756 #   check whether an already existing OpenPKG instance can be reused
   757 if [ -x "$prefix/bin/openpkg" ]; then
   758     verbose 2 "checking compatibility of existing OpenPKG framework"
   759     for name in $params; do
   760         case "$name" in
   761             user|group ) continue ;;
   762         esac
   763         eval "value_required=\"\$CF_$name\""
   764         if [ ".$value_required" != . ]; then
   765             value_existing=`$prefix/bin/openpkg rpm --eval "%{l_${name}}"`
   766             if [ ".$value_existing" != ".$value_required" ]; then
   767                 die "conflict on parameter \"$name\": value required: \"$value_required\", value existing: \"$value_existing\""
   768             fi
   769         fi
   770     done
   771 fi
   773 #   install or upgrade all packages
   774 verbose 2 "install or upgrade all OpenPKG packages"
   775 DIFS="$IFS"
   776 OIFS="$IFS"; IFS="
   777 "
   778 for spec in $CFG_PACKAGES; do
   779     #   determine information
   780     pkg=`echo "$spec"    | sed -e 's;^\([^ ]*\).*$;\1;'`
   781     opts=`echo "$spec"   | sed -e 's;^[^ ]*;;' -e 's;^ *;;'`
   782     name=`echo "$pkg"    | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'`
   783     version=`echo "$pkg" | sed -e 's;^.*-\([^-][^-]*\)-[^-][^-]*$;\1;'`
   784     release=`echo "$pkg" | sed -e 's;^.*-[^-][^-]*-\([^-][^-]*\)$;\1;'`
   786     if [ ".$name" = .openpkg ]; then
   787         #
   788         #   OpenPKG Framework
   789         #
   790         if [   ! -f "$outdir/$pkg.$platform-$tag.sh" \
   791             -o ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   792             #   build (bootstrap & regular)
   793             verbose 3 "BOOTSTRAP-BUILD: $srcdir/$pkg.src.sh"
   794             verbose 4 "options: $CFG_FRAMEWORK"
   795             if [ ! -f "$srcdir/$pkg.src.sh" ]; then
   796                 die "source shell package not existing: $srcdir/$pkg.src.sh"
   797             fi
   798             (   TMPDIR="$tmpdir"
   799                 srcdir="`cd $srcdir && pwd`"
   800                 cd "$outdir" || exit $?
   801                 cmd="sh \"$srcdir/$pkg.src.sh\" $CFG_FRAMEWORK"
   802                 if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
   803                 eval "$cmd" || \
   804                     die "failed to build package \"$srcdir/$pkg.src.sh\""
   805                 rm -f $pkg.src.rpm
   806             ) || exit $?
   807         fi
   808         if [ ! -x "$prefix/bin/openpkg" ]; then
   809             #   install (bootstrap)
   810             if [ ! -f "$outdir/$pkg.$platform-$tag.sh" ]; then
   811                 die "binary shell package not existing: $outdir/$pkg.$platform-$tag.sh"
   812             fi
   813             verbose 3 "BOOTSTRAP-INSTALL: $outdir/$pkg.$platform-$tag.sh"
   814             cmd="$opt_S sh \"$outdir/$pkg.$platform-$tag.sh\""
   815             if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
   816             eval "$cmd" || \
   817                 die "failed to install package \"$outdir/$pkg.$platform-$tag.sh\""
   818         else
   819             check=`$prefix/bin/openpkg rpm -q openpkg 2>/dev/null`
   820             if [ ".$check" != ".$pkg" ]; then
   821                 #   upgrade (regular)
   822                 if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   823                     die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
   824                 fi
   825                 verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm"
   826                 rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
   827                 $opt_S $prefix/bin/openpkg rpm $rpm_opt \
   828                     $outdir/$pkg.$platform-$tag.rpm || \
   829                     die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm"
   830             else
   831                 #   keep as-is
   832                 verbose 3 "KEEP AS-IS: $pkg @ $prefix"
   833             fi
   834         fi
   835     else
   836         #
   837         #   OpenPKG Packages
   838         #
   839         if [ ! -x "$prefix/bin/openpkg" ]; then
   840             #   usually will not happen because of correctly
   841             #   generated topologically correct package list
   842             die "command \"$prefix/bin/openpkg\" has to exit for building a regular OpenPKG package" 1>&2
   843         fi
   844         if [ ! -f $outdir/$pkg.$platform-$tag.rpm ]; then
   845             #    build (regular)
   846             if [ ! -f "$srcdir/$pkg.src.rpm" ]; then
   847                 die "source RPM package not existing: $srcdir/$pkg.src.rpm"
   848             fi
   849             verbose 3 "BUILD: $srcdir/$pkg.src.rpm"
   850             if [ ".$opts" != . ]; then
   851                 verbose 4 "options: $opts"
   852             fi
   853             rm -rf "$tmpdir/$pkg" >/dev/null 2>&1 || true
   854             sh $shtool mkdir -p -m 755 "$tmpdir/$pkg" >/dev/null 2>&1
   855             cmd="$prefix/bin/openpkg --keep-privileges"
   856             cmd="$cmd rpm --rebuild"
   857             cmd="$cmd --define \"_specdir   $tmpdir/$pkg\""
   858             cmd="$cmd --define \"_sourcedir $tmpdir/$pkg\""
   859             cmd="$cmd --define \"_builddir  $tmpdir/$pkg\""
   860             cmd="$cmd --define \"_tmppath   $tmpdir/$pkg\""
   861             cmd="$cmd --define \"_srcrpmdir $tmpdir/$pkg\""
   862             cmd="$cmd --define \"_rpmdir    $outdir\""
   863             OIFS2="$IFS"; IFS="$DIFS"
   864             for opt in $opts; do
   865                 opt_name=`echo "$opt" | sed -e 's;^\([^=]*\)=.*$;\1;'`
   866                 opt_value=`echo "$opt" | sed -e 's;^[^=]*=\(.*\)$;\1;'`
   867                 cmd="$cmd --define \"$opt_name $opt_value\""
   868             done
   869             IFS="$OIFS2"
   870             cmd="$cmd $srcdir/$pkg.src.rpm"
   871             if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
   872             eval "$cmd" || \
   873                 die "failed to build package \"$srcdir/$pkg.src.rpm\""
   874         fi
   875         check=`$prefix/bin/openpkg rpm -q "$name" 2>/dev/null`
   876         if [ ".$check" = ".package $name is not installed" ]; then
   877             #   install (regular)
   878             if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   879                 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
   880             fi
   881             verbose 3 "INSTALL: $outdir/$pkg.$platform-$tag.rpm"
   882             rpm_opt="-i"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
   883             $opt_S $prefix/bin/openpkg rpm $rpm_opt \
   884                 $outdir/$pkg.$platform-$tag.rpm || \
   885                 die "failed to install package: $outdir/$pkg.$platform-$tag.rpm"
   886         elif [ ".$check" != ".$pkg" ]; then
   887             #   upgrade (regular)
   888             if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   889                 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
   890             fi
   891             verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm"
   892             rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
   893             $opt_S $prefix/bin/openpkg rpm $rpm_opt \
   894                 $outdir/$pkg.$platform-$tag.rpm || \
   895                 die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm"
   896         else
   897             #   keep as-is
   898             verbose 3 "KEEP AS-IS: $pkg @ $prefix"
   899         fi
   900     fi
   901 done
   902 IFS="$OIFS"
   904 #   optionally remove residue packages from binary RPM package directory
   905 if [ $opt_c -lt 3 ]; then
   906     verbose 2 "cleanup target directory from residue packages"
   907     for pkg in $outdir/*.sh $outdir/*.rpm; do
   908         if [ ! -f "$pkg" ]; then
   909             continue
   910         fi
   911         pkg_base=`echo "$pkg" | sed -e 's;^.*/\([^/][^/]*-[0-9][^/-]*-[0-9][0-9.]*\)\.[^/][^/]*$;\1;'`
   912         erase=yes
   913         for spec in $CFG_PACKAGES; do
   914             spec_base=`echo "$spec" | sed -e 's;^\(.*-[^-][^-]*-[^-][^-]*\).*$;\1;'`
   915             if [ ".$pkg_base" = ".$spec_base" ]; then
   916                 erase=no
   917                 break
   918             fi
   919         done
   920         if [ ".$erase" = .yes ]; then
   921             verbose 3 "REMOVE: $pkg"
   922             rm -f "$pkg"
   923         fi
   924     done
   925 fi
   927 #   optionally remove residue packages from OpenPKG instance
   928 if [ $opt_c -lt 3 ]; then
   929     verbose 2 "cleanup OpenPKG instance from residue packages"
   930     for pkg1 in `$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`; do
   931         name1=`echo "$pkg1" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'`
   932         erase=yes
   933         for spec in $CFG_PACKAGES; do
   934             name2=`echo "$spec" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*.*$;\1;'`
   935             if [ ".$name1" = ".$name2" ]; then
   936                 erase=no
   937                 break
   938             fi
   939         done
   940         if [ ".$erase" = .yes ]; then
   941             verbose 3 "REMOVE: pkg1 @ $prefix"
   942             $opt_S $prefix/bin/openpkg rpm -e "$pkg1" || \
   943                 die "failed to erase residue package \"$pkg1\""
   944         fi
   945     done
   946 fi
   948 #   execute epilog script
   949 if [ ".@HAVE_EPILOG@" = .yes ]; then
   950     verbose 2 "execute epilog script"
   951     cat >$tmpdir/epilog.sh <<EOT
   952 #!/bin/sh
   953 #![OpenPKG]
   954 # %epilog
   955 EOT
   956     $opt_S sh $tmpdir/epilog.sh
   957     rm -f $tmpdir/epilog.sh
   958 fi
   960 #   cleanup
   961 rm -f  $shtool >/dev/null 3>&1 || true
   962 rm -rf $tmpdir >/dev/null 2>&1 || true
   964 exit 0
   966 ## SHTOOL ###################################################################

mercurial