openpkg/sea.sh

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
parent 428
f880f219c566
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

     1 ##
     2 ##  sea -- Shell Execution Archive
     3 ##  Copyright (c) 2012 Ralf S. Engelschall <rse@engelschall.com>
     4 ##
     5 ##  This program is free software; you can redistribute it and/or modify
     6 ##  it under the terms of the GNU General Public License as published by
     7 ##  the Free Software Foundation; either version 2 of the License, or
     8 ##  (at your option) any later version.
     9 ##
    10 ##  This program is distributed in the hope that it will be useful,
    11 ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    13 ##  General Public License for more details.
    14 ##
    15 ##  You should have received a copy of the GNU General Public License
    16 ##  along with this program; if not, write to the Free Software
    17 ##  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    18 ##  USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
    19 ##
    20 ##  NOTICE: Given that you include this file verbatim into your own
    21 ##  source tree, you are justified in saying that it remains separate
    22 ##  from your package, and that this way you are simply just using GNU
    23 ##  shtool. So, in this situation, there is no requirement that your
    24 ##  package itself is licensed under the GNU General Public License in
    25 ##  order to take advantage of GNU shtool.
    26 ##
    28 ##
    29 ##  COMMAND LINE PARSING
    30 ##
    32 str_usage="[-h|--help] [-o|--output <file>] <script> [<file-or-dir> ...]"
    33 arg_spec="1+"
    34 opt_spec="h.o:"
    35 opt_alias="h:help,o:output"
    36 opt_h=no
    37 opt_o=""
    39 #   parse argument specification string
    40 eval `echo $arg_spec |\
    41       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
    43 #   parse option specification string
    44 eval `echo $opt_spec |\
    45       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
    47 #   parse option alias string
    48 eval `echo $opt_alias |\
    49       sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
    51 #   interate over argument line
    52 opt_PREV=''
    53 while [ $# -gt 0 ]; do
    54     #   special option stops processing
    55     if [ ".$1" = ".--" ]; then
    56         shift
    57         break
    58     fi
    60     #   determine option and argument
    61     opt_ARG_OK=no
    62     if [ ".$opt_PREV" != . ]; then
    63         #   merge previous seen option with argument
    64         opt_OPT="$opt_PREV"
    65         opt_ARG="$1"
    66         opt_ARG_OK=yes
    67         opt_PREV=''
    68     else
    69         #   split argument into option and argument
    70         case "$1" in
    71             --[a-zA-Z0-9]*=*)
    72                 eval `echo "x$1" |\
    73                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
    74                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
    75                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
    76                 ;;
    77             --[a-zA-Z0-9]*)
    78                 opt_OPT=`echo "x$1" | cut -c4-`
    79                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
    80                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
    81                 opt_ARG=''
    82                 ;;
    83             -[a-zA-Z0-9]*)
    84                 eval `echo "x$1" |\
    85                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
    86                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
    87                 ;;
    88             -[a-zA-Z0-9])
    89                 opt_OPT=`echo "x$1" | cut -c3-`
    90                 opt_ARG=''
    91                 ;;
    92             *)
    93                 break
    94                 ;;
    95         esac
    96     fi
    98     #   eat up option
    99     shift
   101     #   determine whether option needs an argument
   102     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
   103     if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
   104         if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
   105             opt_PREV="$opt_OPT"
   106             continue
   107         fi
   108     fi
   110     #   process option
   111     case $opt_MODE in
   112         '.' )
   113             #   boolean option
   114             eval "opt_${opt_OPT}=yes"
   115             ;;
   116         ':' )
   117             #   option with argument (multiple occurances override)
   118             eval "opt_${opt_OPT}=\"\$opt_ARG\""
   119             ;;
   120         '+' )
   121             #   option with argument (multiple occurances append)
   122             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
   123             ;;
   124         * )
   125             echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
   126             exit 1
   127             ;;
   128     esac
   129 done
   130 if [ ".$opt_PREV" != . ]; then
   131     echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
   132     exit 1
   133 fi
   135 #   process help option
   136 if [ ".$opt_h" = .yes ]; then
   137     echo "Usage: $0 $str_usage"
   138     exit 0
   139 fi
   141 #   complain about incorrect number of arguments
   142 case $arg_MODE in
   143     '=' )
   144         if [ $# -ne $arg_NUMS ]; then
   145             echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
   146             exit 1
   147         fi
   148         ;;
   149     '+' )
   150         if [ $# -lt $arg_NUMS ]; then
   151             echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
   152             exit 1
   153         fi
   154         ;;
   155 esac
   157 ##
   158 ##  MAIN
   159 ##
   161 #   we required at least the control script
   162 script="$1"
   163 shift
   165 #   determine output file
   166 sea="$opt_o"
   167 if [ ".$sea" = . ]; then
   168     sea=`echo "$script" | sed -e 's;\.[^.][^.]*$;;' -e 's;$;.sea;'`
   169 fi
   171 #   wrap into a self-extracting distribution file
   172 tmpdir="${TMPDIR-/tmp}"
   173 tmpfile="$tmpdir/sea.tmp.$$"
   174 rm -f $tmpfile
   175 set -o noclobber
   176 (   sed <$0 \
   177         -e '1,/^____/d' \
   178         -e "s;@script@;$script;g"
   179     echo . | awk '{
   180         for (i = 0; i < 2048/8; i++) {
   181             printf("        ");
   182         }
   183     }'
   184 ) >$tmpfile
   185 dd bs=2048 count=1 if=$tmpfile of=$sea 2>/dev/null
   186 rm -f $tmpfile
   187 tar cf - "$script" "$@" 2>/dev/null >>$sea
   189 #   graceful termination
   190 #   (before the shell discovers that we carry the wrapper with us below)
   191 exit 0
   193 ##
   194 ##  WRAPPER SCRIPT
   195 ##
   197 ______________________________________________________________________________
   198 #!/bin/sh
   199 #![OpenPKG]
   200 ##
   201 ##  THIS IS AN AUTOGENERATED SHELL WRAPPER ARCHIVE
   202 ##
   204 #   establish sane environment
   205 PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin"
   206 LC_CTYPE=C
   207 export LC_CTYPE
   208 umask 022
   210 #   passthrough
   211 if [ $# -eq 1 -a ".$1" = ".--tar" ]; then
   212     #   passthrough attached payload on stdout
   213     dd if="$0" bs=2048 skip=1 2>/dev/null
   214     rc=$?
   215 else
   216     #   extract attached payload
   217     rm -rf "$0.d" >/dev/null 2>&1
   218     mkdir "$0.d" || exit $?
   219     dd if="$0" bs=2048 skip=1 2>/dev/null | \
   220     (cd "$0.d" && tar xf - 2>/dev/null)
   221     if [ ! -f "$0.d/@script@" ]; then
   222         echo "$0: ERROR: failed to unpack attached payload into directory \"$0.d\"" 1>&2
   223         rm -rf "$0.d" >/dev/null 2>&1 || true
   224         exit 1
   225     fi
   227     #   passthrough execution to control script
   228     (cd "$0.d" && exec sh "./@script@" ${1+"$@"})
   229     rc=$?
   231     #   cleanup
   232     rm -rf "$0.d" >/dev/null 2>&1 || true
   233 fi
   235 #   terminate gracefully
   236 #   (before the shell discovers that we carry MBs of raw data with us below)
   237 exit $rc
   239 #   the payload tarball is appended in raw format directly to the end
   240 #   of this script, just leaded by padding whitespaces which make sure
   241 #   that the tarball data starts at the predefined offset of 2KB. This
   242 #   allows us to unpack the tarball by just skipping the leading 2KB.

mercurial