openpkg/shtool

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 13
cb59d6afeb61
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 #!/bin/sh
     2 ##
     3 ##  GNU shtool -- The GNU Portable Shell Tool
     4 ##  Copyright (c) 1994-2008 Ralf S. Engelschall <rse@engelschall.com>
     5 ##
     6 ##  See http://www.gnu.org/software/shtool/ for more information.
     7 ##  See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
     8 ##
     9 ##  Version:  2.0.8 (18-Jul-2008)
    10 ##  Contents: all available modules
    11 ##
    13 ##
    14 ##  This program is free software; you can redistribute it and/or modify
    15 ##  it under the terms of the GNU General Public License as published by
    16 ##  the Free Software Foundation; either version 2 of the License, or
    17 ##  (at your option) any later version.
    18 ##
    19 ##  This program is distributed in the hope that it will be useful,
    20 ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
    21 ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    22 ##  General Public License for more details.
    23 ##
    24 ##  You should have received a copy of the GNU General Public License
    25 ##  along with this program; if not, write to the Free Software
    26 ##  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    27 ##  USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
    28 ##
    29 ##  NOTICE: Given that you include this file verbatim into your own
    30 ##  source tree, you are justified in saying that it remains separate
    31 ##  from your package, and that this way you are simply just using GNU
    32 ##  shtool. So, in this situation, there is no requirement that your
    33 ##  package itself is licensed under the GNU General Public License in
    34 ##  order to take advantage of GNU shtool.
    35 ##
    37 ##
    38 ##  Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
    39 ##
    40 ##  Available commands:
    41 ##    echo       Print string with optional construct expansion
    42 ##    mdate      Pretty-print modification time of a file or dir
    43 ##    table      Pretty-print a field-separated list as a table
    44 ##    prop       Display progress with a running propeller
    45 ##    move       Move files with simultaneous substitution
    46 ##    install    Install a program, script or datafile
    47 ##    mkdir      Make one or more directories
    48 ##    mkln       Make link with calculation of relative paths
    49 ##    mkshadow   Make a shadow tree through symbolic links
    50 ##    fixperm    Fix file permissions inside a source tree
    51 ##    rotate     Logfile rotation
    52 ##    tarball    Roll distribution tarballs
    53 ##    subst      Apply sed(1) substitution operations
    54 ##    platform   Platform Identification Utility
    55 ##    arx        Extended archive command
    56 ##    slo        Separate linker options by library class
    57 ##    scpp       Sharing C Pre-Processor
    58 ##    version    Maintain a version information file
    59 ##    path       Deal with program paths
    60 ##
    62 #   maximum Bourne-Shell compatibility
    63 if [ ".$ZSH_VERSION" != . ] && (emulate sh) >/dev/null 2>&1; then
    64     #   reconfigure zsh(1)
    65     emulate sh
    66     NULLCMD=:
    67     alias -g '${1+"$@"}'='"$@"'
    68 elif [ ".$BASH_VERSION" != . ] && (set -o posix) >/dev/null 2>&1; then
    69     #   reconfigure bash(1)
    70     set -o posix
    71 fi
    73 #   maximum independence of NLS nuisances
    74 for var in \
    75     LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
    76     LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
    77     LC_TELEPHONE LC_TIME
    78 do
    79     if (set +x; test -z "`(eval $var=C; export $var) 2>&1`"); then
    80         eval $var=C; export $var
    81     else
    82         unset $var
    83     fi
    84 done
    86 #   initial command line handling
    87 if [ $# -eq 0 ]; then
    88     echo "$0:Error: invalid command line" 1>&2
    89     echo "$0:Hint:  run \`$0 -h' for usage" 1>&2
    90     exit 1
    91 fi
    92 if [ ".$1" = ".-h" ] || [ ".$1" = ".--help" ]; then
    93     echo "This is GNU shtool, version 2.0.8 (18-Jul-2008)"
    94     echo 'Copyright (c) 1994-2008 Ralf S. Engelschall <rse@engelschall.com>'
    95     echo 'Report bugs to <bug-shtool@gnu.org>'
    96     echo ''
    97     echo 'Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]'
    98     echo ''
    99     echo 'Available global <options>:'
   100     echo '  -v, --version   display shtool version information'
   101     echo '  -h, --help      display shtool usage help page (this one)'
   102     echo '  -d, --debug     display shell trace information'
   103     echo '  -r, --recreate  recreate this shtool script via shtoolize'
   104     echo ''
   105     echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
   106     echo '  echo     [-n|--newline] [-e|--expand] [<string> ...]'
   107     echo '  mdate    [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]'
   108     echo '           [-f|--field-sep <str>] [-o|--order <spec>] <path>'
   109     echo '  table    [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns'
   110     echo '           <cols>] [-s|--strip <strip>] <str><sep><str>...'
   111     echo '  prop     [-p|--prefix <str>]'
   112     echo '  move     [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]'
   113     echo '           <src-file> <dst-file>'
   114     echo '  install  [-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy]'
   115     echo '           [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>]'
   116     echo '           [-o|--owner <owner>] [-g|--group <group>] [-e|--exec'
   117     echo '           <sed-cmd>] <file> [<file> ...] <path>'
   118     echo '  mkdir    [-t|--trace] [-f|--force] [-p|--parents] [-m|--mode'
   119     echo '           <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir>'
   120     echo '           [<dir> ...]'
   121     echo '  mkln     [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>'
   122     echo '           [<src-path> ...] <dst-path>'
   123     echo '  mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>'
   124     echo '  fixperm  [-v|--verbose] [-t|--trace] <path> [<path> ...]'
   125     echo '  rotate   [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files'
   126     echo '           <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]'
   127     echo '           [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]'
   128     echo '           [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode'
   129     echo '           <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate'
   130     echo '           <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]'
   131     echo '  tarball  [-t|--trace] [-v|--verbose] [-o|--output <tarball>]'
   132     echo '           [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user'
   133     echo '           <user>] [-g|--group <group>] [-e|--exclude <pattern>]'
   134     echo '           <path> [<path> ...]'
   135     echo '  subst    [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]'
   136     echo '           [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup'
   137     echo '           <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]'
   138     echo '           [...]'
   139     echo '  platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc'
   140     echo '           <string>] [-L|--lower] [-U|--upper] [-v|--verbose]'
   141     echo '           [-c|--concise] [-n|--no-newline] [-t|--type <type>]'
   142     echo '           [-V|--version] [-h|--help]'
   143     echo '  arx      [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>'
   144     echo '           ...]'
   145     echo '  slo      [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>'
   146     echo '           ...]'
   147     echo '  scpp     [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]'
   148     echo '           [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark'
   149     echo '           <mark>] [-D|--define <dname>] [-C|--class <cname>]'
   150     echo '           <file> [<file> ...]'
   151     echo '  version  [-l|--language <lang>] [-n|--name <name>] [-p|--prefix'
   152     echo '           <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase'
   153     echo '           <knob>] [-d|--display <type>] <file>'
   154     echo '  path     [-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename]'
   155     echo '           [-m|--magic] [-p|--path <path>] <str> [<str> ...]'
   156     echo ''
   157     exit 0
   158 fi
   159 if [ ".$1" = ".-v" ] || [ ".$1" = ".--version" ]; then
   160     echo "GNU shtool 2.0.8 (18-Jul-2008)"
   161     exit 0
   162 fi
   163 if [ ".$1" = ".-r" ] || [ ".$1" = ".--recreate" ]; then
   164     shtoolize -oshtool all
   165     exit 0
   166 fi
   167 if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
   168     shift
   169     set -x
   170 fi
   171 name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
   172 case "$name" in
   173     echo|mdate|table|prop|move|install|mkdir|mkln|mkshadow|fixperm|rotate|tarball|subst|platform|arx|slo|scpp|version|path )
   174         #   implicit tool command selection
   175         tool="$name"
   176         ;;
   177     * )
   178         #   explicit tool command selection
   179         tool="$1"
   180         shift
   181         ;;
   182 esac
   183 arg_spec=""
   184 opt_spec=""
   185 gen_tmpfile=no
   187 ##
   188 ##  DISPATCH INTO SCRIPT PROLOG
   189 ##
   191 case $tool in
   192     echo )
   193         str_tool="echo"
   194         str_usage="[-n|--newline] [-e|--expand] [<string> ...]"
   195         arg_spec="0+"
   196         opt_spec="n.e."
   197         opt_alias="n:newline,e:expand"
   198         opt_n=no
   199         opt_e=no
   200         ;;
   201     mdate )
   202         str_tool="mdate"
   203         str_usage="[-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits] [-f|--field-sep <str>] [-o|--order <spec>] <path>"
   204         arg_spec="1="
   205         opt_spec="n.z.s.d.f:o:"
   206         opt_alias="n:newline,z:zero,s:shorten,d:digits,f:field-sep,o:order"
   207         opt_n=no
   208         opt_z=no
   209         opt_s=no
   210         opt_d=no
   211         opt_f=" "
   212         opt_o="dmy"
   213         ;;
   214     table )
   215         str_tool="table"
   216         str_usage="[-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns <cols>] [-s|--strip <strip>] <str><sep><str>..."
   217         arg_spec="1+"
   218         opt_spec="F:w:c:s:"
   219         opt_alias="F:field-sep,w:width,c:columns,s:strip"
   220         opt_F=":"
   221         opt_w=15
   222         opt_c=3
   223         opt_s=79
   224         ;;
   225     prop )
   226         str_tool="prop"
   227         str_usage="[-p|--prefix <str>]"
   228         arg_spec="0="
   229         opt_spec="p:"
   230         opt_alias="p:prefix"
   231         opt_p=""
   232         ;;
   233     move )
   234         str_tool="move"
   235         str_usage="[-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve] <src-file> <dst-file>"
   236         arg_spec="2="
   237         opt_spec="v.t.e.p."
   238         opt_alias="v:verbose,t:trace,e:expand,p:preserve"
   239         opt_v=no
   240         opt_t=no
   241         opt_e=no
   242         opt_p=no
   243         ;;
   244     install )
   245         str_tool="install"
   246         str_usage="[-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy] [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-e|--exec <sed-cmd>] <file> [<file> ...] <path>"
   247         arg_spec="1+"
   248         opt_spec="v.t.d.c.C.s.m:o:g:e+"
   249         opt_alias="v:verbose,t:trace,d:mkdir,c:copy,C:compare-copy,s:strip,m:mode,o:owner,g:group,e:exec"
   250         opt_v=no
   251         opt_t=no
   252         opt_d=no
   253         opt_c=no
   254         opt_C=no
   255         opt_s=no
   256         opt_m="0755"
   257         opt_o=""
   258         opt_g=""
   259         opt_e=""
   260         ;;
   261     mkdir )
   262         str_tool="mkdir"
   263         str_usage="[-t|--trace] [-f|--force] [-p|--parents] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir> [<dir> ...]"
   264         arg_spec="1+"
   265         opt_spec="t.f.p.m:o:g:"
   266         opt_alias="t:trace,f:force,p:parents,m:mode,o:owner,g:group"
   267         opt_t=no
   268         opt_f=no
   269         opt_p=no
   270         opt_m=""
   271         opt_o=""
   272         opt_g=""
   273         ;;
   274     mkln )
   275         str_tool="mkln"
   276         str_usage="[-t|--trace] [-f|--force] [-s|--symbolic] <src-path> [<src-path> ...] <dst-path>"
   277         arg_spec="2+"
   278         opt_spec="t.f.s."
   279         opt_alias="t:trace,f:force,s:symbolic"
   280         opt_t=no
   281         opt_f=no
   282         opt_s=no
   283         ;;
   284     mkshadow )
   285         str_tool="mkshadow"
   286         str_usage="[-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>"
   287         arg_spec="2="
   288         opt_spec="v.t.a."
   289         opt_alias="v:verbose,t:trace,a:all"
   290         opt_v=no
   291         opt_t=no
   292         opt_a=no
   293         ;;
   294     fixperm )
   295         str_tool="fixperm"
   296         str_usage="[-v|--verbose] [-t|--trace] <path> [<path> ...]"
   297         arg_spec="1+"
   298         opt_spec="v.t."
   299         opt_alias="v:verbose,t:trace"
   300         opt_v=no
   301         opt_t=no
   302         ;;
   303     rotate )
   304         str_tool="rotate"
   305         str_usage="[-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files <count>] [-s|--size <size>] [-c|--copy] [-r|--remove] [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>] [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]"
   306         arg_spec="1+"
   307         opt_spec="v.t.f.n:s:c.r.a:z:b.d.p:o:g:m:M:P:E:"
   308         opt_alias="v:verbose,t:trace,f:force,n:num-files,s:size,c:copy,r:remove,a:archive-dir,z:compress,b:background,d:delay,p:pad,o:owner,g:group,m:mode,M:migrate,P:prolog,E:epilog"
   309         opt_v=no
   310         opt_t=no
   311         opt_f=no
   312         opt_n=10
   313         opt_s=""
   314         opt_c=no
   315         opt_r=no
   316         opt_a=""
   317         opt_z=""
   318         opt_b=no
   319         opt_d=no
   320         opt_p=1
   321         opt_o=""
   322         opt_g=""
   323         opt_m=""
   324         opt_M=""
   325         opt_P=""
   326         opt_E=""
   327         ;;
   328     tarball )
   329         str_tool="tarball"
   330         str_usage="[-t|--trace] [-v|--verbose] [-o|--output <tarball>] [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user <user>] [-g|--group <group>] [-e|--exclude <pattern>] <path> [<path> ...]"
   331         gen_tmpfile=yes
   332         arg_spec="1+"
   333         opt_spec="t.v.o:c:d:u:g:e:"
   334         opt_alias="t:trace,v:verbose,o:output,c:compress,d:directory,u:user,g:group,e:exclude"
   335         opt_t=no
   336         opt_v=no
   337         opt_o=""
   338         opt_c=""
   339         opt_d=""
   340         opt_u=""
   341         opt_g=""
   342         opt_e="CVS,\\.cvsignore,\\.svn,\\.[oa]\$"
   343         ;;
   344     subst )
   345         str_tool="subst"
   346         str_usage="[-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning] [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>] [...]"
   347         gen_tmpfile=yes
   348         arg_spec="0+"
   349         opt_spec="v.t.n.w.q.s.i.b:e+f:"
   350         opt_alias="v:verbose,t:trace,n:nop,w:warning,q:quiet,s:stealth,i:interactive,b:backup,e:exec,f:file"
   351         opt_v=no
   352         opt_t=no
   353         opt_n=no
   354         opt_w=no
   355         opt_q=no
   356         opt_s=no
   357         opt_i=no
   358         opt_b=""
   359         opt_e=""
   360         opt_f=""
   361         ;;
   362     platform )
   363         str_tool="platform"
   364         str_usage="[-F|--format <format>] [-S|--sep <string>] [-C|--conc <string>] [-L|--lower] [-U|--upper] [-v|--verbose] [-c|--concise] [-n|--no-newline] [-t|--type <type>] [-V|--version] [-h|--help]"
   365         arg_spec="0="
   366         opt_spec="F:S:C:L.U.v.c.n.t:d.V.h."
   367         opt_alias="F:format,S:sep,C:conc,L:lower,U:upper,v:verbose,c:consise,t:type,n:no-newline,V:version,h:help"
   368         opt_F="%{sp} (%{ap})"
   369         opt_S=" "
   370         opt_C="/"
   371         opt_L=no
   372         opt_U=no
   373         opt_t=""
   374         opt_v=no
   375         opt_c=no
   376         opt_n=no
   377         opt_V=no
   378         opt_h=no
   379         ;;
   380     arx )
   381         str_tool="arx"
   382         str_usage="[-t|--trace] [-C|--command <cmd>] <op> <archive> [<file> ...]"
   383         arg_spec="2+"
   384         opt_spec="t.C:"
   385         opt_alias="t:trace,C:command"
   386         opt_t=no
   387         opt_C="ar"
   388         ;;
   389     slo )
   390         str_tool="slo"
   391         str_usage="[-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib> ...]"
   392         arg_spec="1+"
   393         opt_spec="p:"
   394         opt_alias="p:prefix"
   395         opt_p="SLO_"
   396         ;;
   397     scpp )
   398         str_tool="scpp"
   399         str_usage="[-v|--verbose] [-p|--preserve] [-f|--filter <filter>] [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark <mark>] [-D|--define <dname>] [-C|--class <cname>] <file> [<file> ...]"
   400         gen_tmpfile=yes
   401         arg_spec="1+"
   402         opt_spec="v.p.f+o:t:M:D:C:"
   403         opt_alias="v:verbose,p:preserve,f:filter,o:output,t:template,M:mark,D:define,C:class"
   404         opt_v=no
   405         opt_p=no
   406         opt_f=""
   407         opt_o="lib.h"
   408         opt_t="lib.h.in"
   409         opt_M="%%MARK%%"
   410         opt_D="cpp"
   411         opt_C="intern"
   412         ;;
   413     version )
   414         str_tool="version"
   415         str_usage="[-l|--language <lang>] [-n|--name <name>] [-p|--prefix <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase <knob>] [-d|--display <type>] <file>"
   416         arg_spec="1="
   417         opt_spec="l:n:p:s:i:e.d:"
   418         opt_alias="l:language,n:name,p:prefix,s:set,e:edit,i:increase,d:display"
   419         opt_l="txt"
   420         opt_n="unknown"
   421         opt_p=""
   422         opt_s=""
   423         opt_e="no"
   424         opt_i=""
   425         opt_d="short"
   426         ;;
   427     path )
   428         str_tool="path"
   429         str_usage="[-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename] [-m|--magic] [-p|--path <path>] <str> [<str> ...]"
   430         gen_tmpfile=yes
   431         arg_spec="1+"
   432         opt_spec="s.r.d.b.m.p:"
   433         opt_alias="s:suppress,r:reverse,d:dirname,b:basename,m:magic,p:path"
   434         opt_s=no
   435         opt_r=no
   436         opt_d=no
   437         opt_b=no
   438         opt_m=no
   439         opt_p="$PATH"
   440         ;;
   441     -* )
   442         echo "$0:Error: unknown option \`$tool'" 2>&1
   443         echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
   444         exit 1
   445         ;;
   446     * )
   447         echo "$0:Error: unknown command \`$tool'" 2>&1
   448         echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
   449         exit 1
   450         ;;
   451 esac
   453 ##
   454 ##  COMMON UTILITY CODE
   455 ##
   457 #   commonly used ASCII values
   458 ASC_TAB="	"
   459 ASC_NL="
   460 "
   462 #   determine name of tool
   463 if [ ".$tool" != . ]; then
   464     #   used inside shtool script
   465     toolcmd="$0 $tool"
   466     toolcmdhelp="shtool $tool"
   467     msgprefix="shtool:$tool"
   468 else
   469     #   used as standalone script
   470     toolcmd="$0"
   471     toolcmdhelp="sh $0"
   472     msgprefix="$str_tool"
   473 fi
   475 #   parse argument specification string
   476 eval `echo $arg_spec |\
   477       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
   479 #   parse option specification string
   480 eval `echo h.$opt_spec |\
   481       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
   483 #   parse option alias string
   484 eval `echo h:help,$opt_alias |\
   485       sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
   487 #   interate over argument line
   488 opt_PREV=''
   489 while [ $# -gt 0 ]; do
   490     #   special option stops processing
   491     if [ ".$1" = ".--" ]; then
   492         shift
   493         break
   494     fi
   496     #   determine option and argument
   497     opt_ARG_OK=no
   498     if [ ".$opt_PREV" != . ]; then
   499         #   merge previous seen option with argument
   500         opt_OPT="$opt_PREV"
   501         opt_ARG="$1"
   502         opt_ARG_OK=yes
   503         opt_PREV=''
   504     else
   505         #   split argument into option and argument
   506         case "$1" in
   507             --[a-zA-Z0-9]*=*)
   508                 eval `echo "x$1" |\
   509                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
   510                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
   511                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
   512                 ;;
   513             --[a-zA-Z0-9]*)
   514                 opt_OPT=`echo "x$1" | cut -c4-`
   515                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
   516                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
   517                 opt_ARG=''
   518                 ;;
   519             -[a-zA-Z0-9]*)
   520                 eval `echo "x$1" |\
   521                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
   522                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
   523                 ;;
   524             -[a-zA-Z0-9])
   525                 opt_OPT=`echo "x$1" | cut -c3-`
   526                 opt_ARG=''
   527                 ;;
   528             *)
   529                 break
   530                 ;;
   531         esac
   532     fi
   534     #   eat up option
   535     shift
   537     #   determine whether option needs an argument
   538     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
   539     if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
   540         if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
   541             opt_PREV="$opt_OPT"
   542             continue
   543         fi
   544     fi
   546     #   process option
   547     case $opt_MODE in
   548         '.' )
   549             #   boolean option
   550             eval "opt_${opt_OPT}=yes"
   551             ;;
   552         ':' )
   553             #   option with argument (multiple occurances override)
   554             eval "opt_${opt_OPT}=\"\$opt_ARG\""
   555             ;;
   556         '+' )
   557             #   option with argument (multiple occurances append)
   558             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\""
   559             ;;
   560         * )
   561             echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2
   562             echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
   563             exit 1
   564             ;;
   565     esac
   566 done
   567 if [ ".$opt_PREV" != . ]; then
   568     echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2
   569     echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
   570     exit 1
   571 fi
   573 #   process help option
   574 if [ ".$opt_h" = .yes ]; then
   575     echo "Usage: $toolcmdhelp $str_usage"
   576     exit 0
   577 fi
   579 #   complain about incorrect number of arguments
   580 case $arg_MODE in
   581     '=' )
   582         if [ $# -ne $arg_NUMS ]; then
   583             echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
   584             echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
   585             exit 1
   586         fi
   587         ;;
   588     '+' )
   589         if [ $# -lt $arg_NUMS ]; then
   590             echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
   591             echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
   592             exit 1
   593         fi
   594         ;;
   595 esac
   597 #   establish a temporary file on request
   598 if [ ".$gen_tmpfile" = .yes ]; then
   599     #   create (explicitly) secure temporary directory
   600     if [ ".$TMPDIR" != . ]; then
   601         tmpdir="$TMPDIR"
   602     elif [ ".$TEMPDIR" != . ]; then
   603         tmpdir="$TEMPDIR"
   604     else
   605         tmpdir="/tmp"
   606     fi
   607     tmpdir="$tmpdir/.shtool.$$"
   608     ( umask 077
   609       rm -rf "$tmpdir" >/dev/null 2>&1 || true
   610       mkdir  "$tmpdir" >/dev/null 2>&1
   611       if [ $? -ne 0 ]; then
   612           echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2
   613           exit 1
   614       fi
   615     )
   617     #   create (implicitly) secure temporary file
   618     tmpfile="$tmpdir/shtool.tmp"
   619     touch "$tmpfile"
   620 fi
   622 #   utility function: map string to lower case
   623 util_lower () {
   624     echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
   625 }
   627 #   utility function: map string to upper case
   628 util_upper () {
   629     echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
   630 }
   632 #   cleanup procedure
   633 shtool_exit () {
   634     rc="$1"
   635     if [ ".$gen_tmpfile" = .yes ]; then
   636         rm -rf "$tmpdir" >/dev/null 2>&1 || true
   637     fi
   638     exit $rc
   639 }
   641 ##
   642 ##  DISPATCH INTO SCRIPT BODY
   643 ##
   645 case $tool in
   647 echo )
   648     ##
   649     ##  echo -- Print string with optional construct expansion
   650     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
   651     ##
   653     text="$*"
   655     #   check for broken escape sequence expansion
   656     seo=''
   657     bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
   658     if [ ".$bytes" != .3 ]; then
   659         bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
   660         if [ ".$bytes" = .3 ]; then
   661             seo='-E'
   662         fi
   663     fi
   665     #   check for existing -n option (to suppress newline)
   666     minusn=''
   667     bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
   668     if [ ".$bytes" = .3 ]; then
   669         minusn='-n'
   670     fi
   672     #   determine terminal bold sequence
   673     term_bold=''
   674     term_norm=''
   675     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then
   676         case $TERM in
   677             #   for the most important terminal types we directly know the sequences
   678             xterm|xterm*|vt220|vt220*)
   679                 term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
   680                 term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
   681                 ;;
   682             vt100|vt100*|cygwin)
   683                 term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
   684                 term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
   685                 ;;
   686             #   for all others, we try to use a possibly existing `tput' or `tcout' utility
   687             * )
   688                 paths=`echo $PATH | sed -e 's/:/ /g'`
   689                 for tool in tput tcout; do
   690                     for dir in $paths; do
   691                         if [ -r "$dir/$tool" ]; then
   692                             for seq in bold md smso; do # 'smso' is last
   693                                 bold="`$dir/$tool $seq 2>/dev/null`"
   694                                 if [ ".$bold" != . ]; then
   695                                     term_bold="$bold"
   696                                     break
   697                                 fi
   698                             done
   699                             if [ ".$term_bold" != . ]; then
   700                                 for seq in sgr0 me rmso init reset; do # 'reset' is last
   701                                     norm="`$dir/$tool $seq 2>/dev/null`"
   702                                     if [ ".$norm" != . ]; then
   703                                         term_norm="$norm"
   704                                         break
   705                                     fi
   706                                 done
   707                             fi
   708                             break
   709                         fi
   710                     done
   711                     if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then
   712                         break;
   713                     fi
   714                 done
   715                 ;;
   716         esac
   717         if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then
   718             echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
   719             term_bold=''
   720             term_norm=''
   721         fi
   722     fi
   724     #   determine user name
   725     username=''
   726     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then
   727         username="`(id -un) 2>/dev/null`"
   728         if [ ".$username" = . ]; then
   729             str="`(id) 2>/dev/null`"
   730             if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
   731                 username=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*[0-9]*(//' -e 's/).*$//'`
   732             fi
   733             if [ ".$username" = . ]; then
   734                 username="$LOGNAME"
   735                 if [ ".$username" = . ]; then
   736                     username="$USER"
   737                     if [ ".$username" = . ]; then
   738                         username="`(whoami) 2>/dev/null |\
   739                                    awk '{ printf("%s", $1); }'`"
   740                         if [ ".$username" = . ]; then
   741                             username="`(who am i) 2>/dev/null |\
   742                                        awk '{ printf("%s", $1); }'`"
   743                             if [ ".$username" = . ]; then
   744                                 username='unknown'
   745                             fi
   746                         fi
   747                     fi
   748                 fi
   749             fi
   750         fi
   751     fi
   753     #   determine user id
   754     userid=''
   755     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then
   756         userid="`(id -u) 2>/dev/null`"
   757         if [ ".$userid" = . ]; then
   758             userid="`(id -u ${username}) 2>/dev/null`"
   759             if [ ".$userid" = . ]; then
   760                 str="`(id) 2>/dev/null`"
   761                 if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
   762                     userid=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*//' -e 's/(.*$//'`
   763                 fi
   764                 if [ ".$userid" = . ]; then
   765                     userid=`(getent passwd ${username}) 2>/dev/null | \
   766                             sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
   767                     if [ ".$userid" = . ]; then
   768                         userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
   769                                 sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
   770                         if [ ".$userid" = . ]; then
   771                             userid=`(ypmatch "${username}" passwd; nismatch "${username}" passwd) 2>/dev/null | \
   772                                     sed -e 'q' | sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
   773                             if [ ".$userid" = . ]; then
   774                                 userid=`(nidump passwd . | grep "^${username}:") 2>/dev/null | \
   775                                         sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
   776                                 if [ ".$userid" = . ]; then
   777                                     userid='?'
   778                                 fi
   779                             fi
   780                         fi
   781                     fi
   782                 fi
   783             fi
   784         fi
   785     fi
   787     #   determine (primary) group id
   788     groupid=''
   789     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then
   790         groupid="`(id -g ${username}) 2>/dev/null`"
   791         if [ ".$groupid" = . ]; then
   792             str="`(id) 2>/dev/null`"
   793             if [ ".`echo $str | grep 'gid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
   794                 groupid=`echo $str | sed -e 's/^.*gid[ 	]*=[ 	]*//' -e 's/(.*$//'`
   795             fi
   796             if [ ".$groupid" = . ]; then
   797                 groupid=`(getent passwd ${username}) 2>/dev/null | \
   798                          sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
   799                 if [ ".$groupid" = . ]; then
   800                     groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
   801                              sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
   802                     if [ ".$groupid" = . ]; then
   803                         groupid=`(ypmatch "${username}" passwd; nismatch "${username}" passwd) 2>/dev/null | \
   804                                  sed -e 'q' | sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
   805                         if [ ".$groupid" = . ]; then
   806                             groupid=`(nidump passwd . | grep "^${username}:") 2>/dev/null | \
   807                                      sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
   808                             if [ ".$groupid" = . ]; then
   809                                 groupid='?'
   810                             fi
   811                         fi
   812                     fi
   813                 fi
   814             fi
   815         fi
   816     fi
   818     #   determine (primary) group name
   819     groupname=''
   820     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then
   821         groupname="`(id -gn ${username}) 2>/dev/null`"
   822         if [ ".$groupname" = . ]; then
   823             str="`(id) 2>/dev/null`"
   824             if [ ".`echo $str | grep 'gid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
   825                 groupname=`echo $str | sed -e 's/^.*gid[ 	]*=[ 	]*[0-9]*(//' -e 's/).*$//'`
   826             fi
   827             if [ ".$groupname" = . ]; then
   828                 groupname=`(getent group) 2>/dev/null | \
   829                            grep "^[^:]*:[^:]*:${groupid}:" | \
   830                            sed -e 's/:.*$//'`
   831                 if [ ".$groupname" = . ]; then
   832                     groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
   833                                sed -e 's/:.*$//'`
   834                     if [ ".$groupname" = . ]; then
   835                         groupname=`(ypcat group; niscat group) 2>/dev/null | \
   836                                    sed -e 'q' | grep "^[^:]*:[^:]*:${groupid}:" | \
   837                                    sed -e 's/:.*$//'`
   838                         if [ ".$groupname" = . ]; then
   839                             groupname=`(nidump group .) 2>/dev/null | \
   840                                        grep "^[^:]*:[^:]*:${groupid}:" | \
   841                                        sed -e 's/:.*$//'`
   842                             if [ ".$groupname" = . ]; then
   843                                 groupname='?'
   844                             fi
   845                         fi
   846                     fi
   847                 fi
   848             fi
   849         fi
   850     fi
   852     #   determine host and domain name
   853     hostname=''
   854     domainname=''
   855     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then
   856         hostname="`(uname -n) 2>/dev/null |\
   857                    awk '{ printf("%s", $1); }'`"
   858         if [ ".$hostname" = . ]; then
   859             hostname="`(hostname) 2>/dev/null |\
   860                        awk '{ printf("%s", $1); }'`"
   861             if [ ".$hostname" = . ]; then
   862                 hostname='unknown'
   863             fi
   864         fi
   865         case $hostname in
   866             *.* )
   867                 domainname=".`echo $hostname | cut -d. -f2-`"
   868                 hostname="`echo $hostname | cut -d. -f1`"
   869                 ;;
   870         esac
   871     fi
   872     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then
   873         if [ ".$domainname" = . ]; then
   874             if [ -f /etc/resolv.conf ]; then
   875                 domainname="`grep '^[ 	]*domain' /etc/resolv.conf | sed -e 'q' |\
   876                              sed -e 's/.*domain//' \
   877                                  -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
   878                                  -e 's/^\.//' -e 's/^/./' |\
   879                              awk '{ printf("%s", $1); }'`"
   880                 if [ ".$domainname" = . ]; then
   881                     domainname="`grep '^[ 	]*search' /etc/resolv.conf | sed -e 'q' |\
   882                                  sed -e 's/.*search//' \
   883                                      -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
   884                                      -e 's/ .*//' -e 's/	.*//' \
   885                                      -e 's/^\.//' -e 's/^/./' |\
   886                                  awk '{ printf("%s", $1); }'`"
   887                 fi
   888             fi
   889         fi
   890     fi
   892     #   determine current time
   893     time_day=''
   894     time_month=''
   895     time_year=''
   896     time_monthname=''
   897     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then
   898         time_day=`date '+%d'`
   899         time_month=`date '+%m'`
   900         time_year=`date '+%Y' 2>/dev/null`
   901         if [ ".$time_year" = . ]; then
   902             time_year=`date '+%y'`
   903             case $time_year in
   904                 [5-9][0-9]) time_year="19$time_year" ;;
   905                 [0-4][0-9]) time_year="20$time_year" ;;
   906             esac
   907         fi
   908         case $time_month in
   909             1|01) time_monthname='Jan' ;;
   910             2|02) time_monthname='Feb' ;;
   911             3|03) time_monthname='Mar' ;;
   912             4|04) time_monthname='Apr' ;;
   913             5|05) time_monthname='May' ;;
   914             6|06) time_monthname='Jun' ;;
   915             7|07) time_monthname='Jul' ;;
   916             8|08) time_monthname='Aug' ;;
   917             9|09) time_monthname='Sep' ;;
   918               10) time_monthname='Oct' ;;
   919               11) time_monthname='Nov' ;;
   920               12) time_monthname='Dec' ;;
   921         esac
   922     fi
   924     #   expand special ``%x'' constructs
   925     if [ ".$opt_e" = .yes ]; then
   926         text=`echo $seo "$text" |\
   927               sed -e "s/%B/${term_bold}/g" \
   928                   -e "s/%b/${term_norm}/g" \
   929                   -e "s/%u/${username}/g" \
   930                   -e "s/%U/${userid}/g" \
   931                   -e "s/%g/${groupname}/g" \
   932                   -e "s/%G/${groupid}/g" \
   933                   -e "s/%h/${hostname}/g" \
   934                   -e "s/%d/${domainname}/g" \
   935                   -e "s/%D/${time_day}/g" \
   936                   -e "s/%M/${time_month}/g" \
   937                   -e "s/%Y/${time_year}/g" \
   938                   -e "s/%m/${time_monthname}/g" 2>/dev/null`
   939     fi
   941     #   create output
   942     if [ .$opt_n = .no ]; then
   943         echo $seo "$text"
   944     else
   945         #   the harder part: echo -n is best, because
   946         #   awk may complain about some \xx sequences.
   947         if [ ".$minusn" != . ]; then
   948             echo $seo $minusn "$text"
   949         else
   950             echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
   951         fi
   952     fi
   954     shtool_exit 0
   955     ;;
   957 mdate )
   958     ##
   959     ##  mdate -- Pretty-print modification time of a file or dir
   960     ##  Copyright (c) 1995-1997 Free Software Foundation, Inc.
   961     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
   962     ##
   964     fod="$1"
   965     case "$opt_o" in
   966         [dmy][dmy][dmy] )
   967             ;;
   968         * ) echo "$msgprefix:Error: invalid argument to option \`-o': $opt_o" 1>&2
   969             shtool_exit 1
   970             ;;
   971     esac
   972     if [ ! -r "$fod" ]; then
   973         echo "$msgprefix:Error: file or directory not found: $fod" 1>&2
   974         shtool_exit 1
   975     fi
   977     #   GNU ls changes its time format in response to the TIME_STYLE
   978     #   variable. Since we cannot assume "unset" works, revert this
   979     #   variable to its documented default.
   980     if [ ".$TIME_STYLE" != . ]; then
   981         TIME_STYLE=posix-long-iso
   982         export TIME_STYLE
   983     fi
   985     #   get the extended ls output of the file or directory.
   986     if /bin/ls -L /dev/null >/dev/null 2>&1; then
   987         set - x`/bin/ls -L -l -d $fod`
   988     else
   989         set - x`/bin/ls -l -d $fod`
   990     fi
   992     #   The month is at least the fourth argument
   993     #   (3 shifts here, the next inside the loop).
   994     shift; shift; shift
   996     #   Find the month. Next argument is day, followed by the year or time.
   997     month=""
   998     while [ ".$month" = . ]; do
   999         shift
  1000         case $1 in
  1001             Jan) month=January;   nummonth=1  ;;
  1002             Feb) month=February;  nummonth=2  ;;
  1003             Mar) month=March;     nummonth=3  ;;
  1004             Apr) month=April;     nummonth=4  ;;
  1005             May) month=May;       nummonth=5  ;;
  1006             Jun) month=June;      nummonth=6  ;;
  1007             Jul) month=July;      nummonth=7  ;;
  1008             Aug) month=August;    nummonth=8  ;;
  1009             Sep) month=September; nummonth=9  ;;
  1010             Oct) month=October;   nummonth=10 ;;
  1011             Nov) month=November;  nummonth=11 ;;
  1012             Dec) month=December;  nummonth=12 ;;
  1013         esac
  1014     done
  1015     day="$2"
  1016     year="$3"
  1018     #   We finally have to deal with the problem that the "ls" output
  1019     #   gives either the time of the day or the year.
  1020     case $year in
  1021         *:*)
  1022             this_year=`date '+%Y' 2>/dev/null`
  1023             if [ ".$this_year" = . ]; then
  1024                 this_year=`date '+%y'`
  1025                 case $this_year in
  1026                     [5-9][0-9]) this_year="19$this_year" ;;
  1027                     [0-4][0-9]) this_year="20$this_year" ;;
  1028                 esac
  1029             fi
  1030             #   for the following months of the last year the time notation
  1031             #   is usually also used for files modified in the last year.
  1032             this_month=`date '+%m'`
  1033             if (expr $nummonth \> $this_month) >/dev/null; then
  1034                 this_year=`expr $this_year - 1`
  1035             fi
  1036             year="$this_year"
  1037             ;;
  1038     esac
  1040     #   Optionally fill day and month with leeding zeros
  1041     if [ ".$opt_z" = .yes ]; then
  1042         case $day in
  1043             [0-9][0-9] ) ;;
  1044                  [0-9] ) day="0$day" ;;
  1045         esac
  1046         case $nummonth in
  1047             [0-9][0-9] ) ;;
  1048                  [0-9] ) nummonth="0$nummonth" ;;
  1049         esac
  1050     fi
  1052     #   Optionally use digits for month
  1053     if [ ".$opt_d" = .yes ]; then
  1054         month="$nummonth"
  1055     fi
  1057     #   Optionally shorten the month name to three characters
  1058     if [ ".$opt_s" = .yes ]; then
  1059         month=`echo $month | cut -c1-3`
  1060     fi
  1062     #   Output the resulting date string
  1063     echo dummy | awk '{
  1064         for (i = 0; i < 3; i++) {
  1065             now = substr(order, 1, 1);
  1066             order = substr(order, 2);
  1067             if (now == "d")
  1068                 out = day;
  1069             else if (now == "m")
  1070                 out = month;
  1071             else if (now == "y")
  1072                 out = year;
  1073             if (i < 2)
  1074                 printf("%s%s", out, field);
  1075             else
  1076                 printf("%s", out);
  1078         if (newline != "yes")
  1079             printf("\n");
  1080     }' "day=$day" "month=$month" "year=$year" \
  1081        "field=$opt_f" "order=$opt_o" "newline=$opt_n"
  1083     shtool_exit 0
  1084     ;;
  1086 table )
  1087     ##
  1088     ##  table -- Pretty-print a field-separated list as a table
  1089     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
  1090     ##
  1092     if [ $opt_c -gt 4 ]; then
  1093         echo "$msgprefix:Error: Invalid number of colums (1..4 allowed only)" 1>&2
  1094         shtool_exit 1
  1095     fi
  1096     case "x$opt_F" in
  1097         x? ) ;;
  1098         *  ) echo "$msgprefix:Error: Invalid separator (one char allowed only)" 1>&2; shtool_exit 1 ;;
  1099     esac
  1101     #   split the list into a table
  1102     list=`
  1103         IFS="$opt_F"
  1104         for entry in $*; do
  1105             if [ ".$entry" != . ]; then
  1106                 echo "$entry"
  1107             fi
  1108         done |\
  1109         awk "
  1110             BEGIN { list = \"\"; n = 0; }
  1112                 list = list \\$1;
  1113                 n = n + 1;
  1114                 if (n < $opt_c) {
  1115                     list = list \":\";
  1117                 if (n == $opt_c) {
  1118                     list = list \"\\n\";
  1119                     n = 0;
  1122             END { print list; }
  1126     #   format table cells and make sure table
  1127     #   doesn't exceed maximum width
  1128     OIFS="$IFS"
  1129     IFS='
  1131     for entry in $list; do
  1132         case $opt_c in
  1133             1 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s\\n\", \$1); }'" ;;
  1134             2 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s\\n\", \$1, \$2); }'" ;;
  1135             3 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s %-${opt_w}s\\n\", \$1, \$2, \$3); }'" ;;
  1136             4 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s %-${opt_w}s %-${opt_w}s\\n\", \$1, \$2, \$3, \$4); }'" ;;
  1137         esac
  1138     done |\
  1139     awk "{
  1140         if (length(\$0) > $opt_s) {
  1141             printf(\"%s\\n\", substr(\$0, 0, $opt_s-1));
  1142         } else {
  1143             print \$0;
  1145     }"
  1146     IFS="$OIFS"
  1148     shtool_exit 0
  1149     ;;
  1151 prop )
  1152     ##
  1153     ##  prop -- Display progress with a running propeller
  1154     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
  1155     ##
  1157     perl=''
  1158     for dir in `echo $PATH | sed -e 's/:/ /g'` .; do
  1159         if [ -f "$dir/perl" ]; then
  1160             perl="$dir/perl"
  1161             break
  1162         fi
  1163     done
  1164     if [ ".$perl" != . ]; then
  1165         #   Perl is preferred because writing to STDERR in
  1166         #   Perl really writes immediately as one would expect
  1167         $perl -e '
  1168             @p = ("|","/","-","\\");
  1169             $i = 0;
  1170             while (<STDIN>) {
  1171                 printf(STDERR "\r%s...%s\b", $ARGV[0], $p[$i++]);
  1172                 $i = 0 if ($i > 3);
  1174             printf(STDERR "\r%s    \n", $ARGV[0]);
  1175         ' "$opt_p"
  1176     else
  1177         #   But if Perl doesn't exists we use Awk even
  1178         #   some Awk's buffer even the /dev/stderr writing :-(
  1179         awk '
  1180             BEGIN {
  1181                 split("|#/#-#\\", p, "#");
  1182                 i = 1;
  1185                 printf("\r%s%c\b", prefix, p[i++]) > "/dev/stderr";
  1186                 if (i > 4) { i = 1; }
  1188             END {
  1189                 printf("\r%s    \n", prefix) > "/dev/stderr";
  1191         ' "prefix=$opt_p"
  1192     fi
  1194     shtool_exit 0
  1195     ;;
  1197 move )
  1198     ##
  1199     ##  move -- Move files with simultaneous substitution
  1200     ##  Copyright (c) 1999-2008 Ralf S. Engelschall <rse@engelschall.com>
  1201     ##
  1203     src="$1"
  1204     dst="$2"
  1206     #   consistency checks
  1207     if [ ".$src" = . ] || [ ".$dst" = . ]; then
  1208         echo "$msgprefix:Error: Invalid arguments" 1>&2
  1209         shtool_exit 1
  1210     fi
  1211     if [ ".$src" = ".$dst" ]; then
  1212         echo "$msgprefix:Error: Source and destination files are the same" 1>&2
  1213         shtool_exit 1
  1214     fi
  1215     expsrc="$src"
  1216     if [ ".$opt_e" = .yes ]; then
  1217         expsrc="`echo $expsrc`"
  1218     fi
  1219     if [ ".$opt_e" = .yes ]; then
  1220         if [ ".`echo "$src" | sed -e 's;^.*\\*.*$;;'`" = ".$src" ]; then
  1221             echo "$msgprefix:Error: Source doesn't contain wildcard ('*'): $dst" 1>&2
  1222             shtool_exit 1
  1223         fi
  1224         if [ ".`echo "$dst" | sed -e 's;^.*%[1-9].*$;;'`" = ".$dst" ]; then
  1225             echo "$msgprefix:Error: Destination doesn't contain substitution ('%N'): $dst" 1>&2
  1226             shtool_exit 1
  1227         fi
  1228         if [ ".$expsrc" = ".$src" ]; then
  1229             echo "$msgprefix:Error: Sources not found or no asterisk : $src" 1>&2
  1230             shtool_exit 1
  1231         fi
  1232     else
  1233         if [ ! -r "$src" ]; then
  1234             echo "$msgprefix:Error: Source not found: $src" 1>&2
  1235             shtool_exit 1
  1236         fi
  1237     fi
  1239     #   determine substitution patterns
  1240     if [ ".$opt_e" = .yes ]; then
  1241         srcpat=`echo "$src" | sed -e 's/\\./\\\\./g' -e 's/;/\\;/g' -e 's;\\*;\\\\(.*\\\\);g'`
  1242         dstpat=`echo "$dst" | sed -e 's;%\([1-9]\);\\\\\1;g'`
  1243     fi
  1245     #   iterate over source(s)
  1246     for onesrc in $expsrc; do
  1247         if [ .$opt_e = .yes ]; then
  1248             onedst=`echo $onesrc | sed -e "s;$srcpat;$dstpat;"`
  1249         else
  1250             onedst="$dst"
  1251         fi
  1252         errorstatus=0
  1253         if [ ".$opt_v" = .yes ]; then
  1254             echo "$onesrc -> $onedst"
  1255         fi
  1256         if [ ".$opt_p" = .yes ]; then
  1257             if [ -r $onedst ]; then
  1258                 if cmp -s $onesrc $onedst; then
  1259                     if [ ".$opt_t" = .yes ]; then
  1260                         echo "rm -f $onesrc" 1>&2
  1261                     fi
  1262                     rm -f $onesrc || errorstatus=$?
  1263                 else
  1264                     if [ ".$opt_t" = .yes ]; then
  1265                         echo "mv -f $onesrc $onedst" 1>&2
  1266                     fi
  1267                     mv -f $onesrc $onedst || errorstatus=$?
  1268                 fi
  1269             else
  1270                 if [ ".$opt_t" = .yes ]; then
  1271                     echo "mv -f $onesrc $onedst" 1>&2
  1272                 fi
  1273                 mv -f $onesrc $onedst || errorstatus=$?
  1274             fi
  1275         else
  1276             if [ ".$opt_t" = .yes ]; then
  1277                 echo "mv -f $onesrc $onedst" 1>&2
  1278             fi
  1279             mv -f $onesrc $onedst || errorstatus=$?
  1280         fi
  1281         if [ $errorstatus -ne 0 ]; then
  1282             break;
  1283         fi
  1284     done
  1286     shtool_exit $errorstatus
  1287     ;;
  1289 install )
  1290     ##
  1291     ##  install -- Install a program, script or datafile
  1292     ##  Copyright (c) 1997-2008 Ralf S. Engelschall <rse@engelschall.com>
  1293     ##
  1295     #   special case: "shtool install -d <dir> [...]" internally
  1296     #   maps to "shtool mkdir -f -p -m 755 <dir> [...]"
  1297     if [ "$opt_d" = yes ]; then
  1298         cmd="$0 mkdir -f -p -m 755"
  1299         if [ ".$opt_o" != . ]; then
  1300             cmd="$cmd -o '$opt_o'"
  1301         fi
  1302         if [ ".$opt_g" != . ]; then
  1303             cmd="$cmd -g '$opt_g'"
  1304         fi
  1305         if [ ".$opt_v" = .yes ]; then
  1306             cmd="$cmd -v"
  1307         fi
  1308         if [ ".$opt_t" = .yes ]; then
  1309             cmd="$cmd -t"
  1310         fi
  1311         for dir in "$@"; do
  1312             eval "$cmd $dir" || shtool_exit $?
  1313         done
  1314         shtool_exit 0
  1315     fi
  1317     #   determine source(s) and destination
  1318     argc=$#
  1319     srcs=""
  1320     while [ $# -gt 1 ]; do
  1321         srcs="$srcs $1"
  1322         shift
  1323     done
  1324     dstpath="$1"
  1326     #   type check for destination
  1327     dstisdir=0
  1328     if [ -d $dstpath ]; then
  1329         dstpath=`echo "$dstpath" | sed -e 's:/$::'`
  1330         dstisdir=1
  1331     fi
  1333     #   consistency check for destination
  1334     if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then
  1335         echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
  1336         shtool_exit 1
  1337     fi
  1339     #   iterate over all source(s)
  1340     for src in $srcs; do
  1341         dst=$dstpath
  1343         #   if destination is a directory, append the input filename
  1344         if [ $dstisdir = 1 ]; then
  1345             dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
  1346             dst="$dst/$dstfile"
  1347         fi
  1349         #   check for correct arguments
  1350         if [ ".$src" = ".$dst" ]; then
  1351             echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
  1352             continue
  1353         fi
  1354         if [ -d "$src" ]; then
  1355             echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
  1356             continue
  1357         fi
  1359         #   make a temp file name in the destination directory
  1360         dsttmp=`echo $dst |\
  1361                 sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
  1362                     -e "s;\$;/#INST@$$#;"`
  1364         #   verbosity
  1365         if [ ".$opt_v" = .yes ]; then
  1366             echo "$src -> $dst" 1>&2
  1367         fi
  1369         #   copy or move the file name to the temp name
  1370         #   (because we might be not allowed to change the source)
  1371         if [ ".$opt_C" = .yes ]; then
  1372             opt_c=yes
  1373         fi
  1374         if [ ".$opt_c" = .yes ]; then
  1375             if [ ".$opt_t" = .yes ]; then
  1376                 echo "cp $src $dsttmp" 1>&2
  1377             fi
  1378             cp "$src" "$dsttmp" || shtool_exit $?
  1379         else
  1380             if [ ".$opt_t" = .yes ]; then
  1381                 echo "mv $src $dsttmp" 1>&2
  1382             fi
  1383             mv "$src" "$dsttmp" || shtool_exit $?
  1384         fi
  1386         #   adjust the target file
  1387         if [ ".$opt_e" != . ]; then
  1388             sed='sed'
  1389             OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
  1390             for e
  1391             do
  1392                 sed="$sed -e '$e'"
  1393             done
  1394             cp "$dsttmp" "$dsttmp.old"
  1395             chmod u+w $dsttmp
  1396             eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $?
  1397             rm -f $dsttmp.old
  1398         fi
  1399         if [ ".$opt_s" = .yes ]; then
  1400             if [ ".$opt_t" = .yes ]; then
  1401                 echo "strip $dsttmp" 1>&2
  1402             fi
  1403             strip $dsttmp || shtool_exit $?
  1404         fi
  1405         if [ ".$opt_o" != . ]; then
  1406             if [ ".$opt_t" = .yes ]; then
  1407                 echo "chown $opt_o $dsttmp" 1>&2
  1408             fi
  1409             chown $opt_o $dsttmp || shtool_exit $?
  1410         fi
  1411         if [ ".$opt_g" != . ]; then
  1412             if [ ".$opt_t" = .yes ]; then
  1413                 echo "chgrp $opt_g $dsttmp" 1>&2
  1414             fi
  1415             chgrp $opt_g $dsttmp || shtool_exit $?
  1416         fi
  1417         if [ ".$opt_m" != ".-" ]; then
  1418             if [ ".$opt_t" = .yes ]; then
  1419                 echo "chmod $opt_m $dsttmp" 1>&2
  1420             fi
  1421             chmod $opt_m $dsttmp || shtool_exit $?
  1422         fi
  1424         #   determine whether to do a quick install
  1425         #   (has to be done _after_ the strip was already done)
  1426         quick=no
  1427         if [ ".$opt_C" = .yes ]; then
  1428             if [ -r $dst ]; then
  1429                 if cmp -s "$src" "$dst"; then
  1430                     quick=yes
  1431                 fi
  1432             fi
  1433         fi
  1435         #   finally, install the file to the real destination
  1436         if [ $quick = yes ]; then
  1437             if [ ".$opt_t" = .yes ]; then
  1438                 echo "rm -f $dsttmp" 1>&2
  1439             fi
  1440             rm -f $dsttmp
  1441         else
  1442             if [ ".$opt_t" = .yes ]; then
  1443                 echo "rm -f $dst && mv $dsttmp $dst" 1>&2
  1444             fi
  1445             rm -f $dst && mv $dsttmp $dst
  1446         fi
  1447     done
  1449     shtool_exit 0
  1450     ;;
  1452 mkdir )
  1453     ##
  1454     ##  mkdir -- Make one or more directories
  1455     ##  Copyright (c) 1996-2008 Ralf S. Engelschall <rse@engelschall.com>
  1456     ##
  1458     errstatus=0
  1459     for p in ${1+"$@"}; do
  1460         #   if the directory already exists...
  1461         if [ -d "$p" ]; then
  1462             if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
  1463                 echo "$msgprefix:Error: directory already exists: $p" 1>&2
  1464                 errstatus=1
  1465                 break
  1466             else
  1467                 continue
  1468             fi
  1469         fi
  1470         #   if the directory has to be created...
  1471         if [ ".$opt_p" = .no ]; then
  1472             if [ ".$opt_t" = .yes ]; then
  1473                 echo "mkdir $p" 1>&2
  1474             fi
  1475             mkdir $p || errstatus=$?
  1476             if [ ".$opt_o" != . ]; then
  1477                 if [ ".$opt_t" = .yes ]; then
  1478                     echo "chown $opt_o $p" 1>&2
  1479                 fi
  1480                 chown $opt_o $p || errstatus=$?
  1481             fi
  1482             if [ ".$opt_g" != . ]; then
  1483                 if [ ".$opt_t" = .yes ]; then
  1484                     echo "chgrp $opt_g $p" 1>&2
  1485                 fi
  1486                 chgrp $opt_g $p || errstatus=$?
  1487             fi
  1488             if [ ".$opt_m" != . ]; then
  1489                 if [ ".$opt_t" = .yes ]; then
  1490                     echo "chmod $opt_m $p" 1>&2
  1491                 fi
  1492                 chmod $opt_m $p || errstatus=$?
  1493             fi
  1494         else
  1495             #   the smart situation
  1496             set fnord `echo ":$p" |\
  1497                        sed -e 's/^:\//%/' \
  1498                            -e 's/^://' \
  1499                            -e 's/\// /g' \
  1500                            -e 's/^%/\//'`
  1501             shift
  1502             pathcomp=''
  1503             for d in ${1+"$@"}; do
  1504                 pathcomp="$pathcomp$d"
  1505                 case "$pathcomp" in
  1506                     -* ) pathcomp="./$pathcomp" ;;
  1507                 esac
  1508                 if [ ! -d "$pathcomp" ]; then
  1509                     if [ ".$opt_t" = .yes ]; then
  1510                         echo "mkdir $pathcomp" 1>&2
  1511                     fi
  1512                     mkdir $pathcomp || errstatus=$?
  1513                     if [ ".$opt_o" != . ]; then
  1514                         if [ ".$opt_t" = .yes ]; then
  1515                             echo "chown $opt_o $pathcomp" 1>&2
  1516                         fi
  1517                         chown $opt_o $pathcomp || errstatus=$?
  1518                     fi
  1519                     if [ ".$opt_g" != . ]; then
  1520                         if [ ".$opt_t" = .yes ]; then
  1521                             echo "chgrp $opt_g $pathcomp" 1>&2
  1522                         fi
  1523                         chgrp $opt_g $pathcomp || errstatus=$?
  1524                     fi
  1525                     if [ ".$opt_m" != . ]; then
  1526                         if [ ".$opt_t" = .yes ]; then
  1527                             echo "chmod $opt_m $pathcomp" 1>&2
  1528                         fi
  1529                         chmod $opt_m $pathcomp || errstatus=$?
  1530                     fi
  1531                 fi
  1532                 pathcomp="$pathcomp/"
  1533             done
  1534         fi
  1535     done
  1537     shtool_exit $errstatus
  1538     ;;
  1540 mkln )
  1541     ##
  1542     ##  mkln -- Make link with calculation of relative paths
  1543     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
  1544     ##
  1546     #   determine source(s) and destination
  1547     args=$#
  1548     srcs=""
  1549     while [ $# -gt 1 ]; do
  1550         srcs="$srcs $1"
  1551         shift
  1552     done
  1553     dst="$1"
  1554     if [ ! -d $dst ]; then
  1555         if [ $args -gt 2 ]; then
  1556             echo "$msgprefix:Error: multiple sources not allowed when target isn't a directory" 1>&2
  1557             shtool_exit 1
  1558         fi
  1559     fi
  1561     #   determine link options
  1562     lnopt=""
  1563     if [ ".$opt_f" = .yes ]; then
  1564         lnopt="$lnopt -f"
  1565     fi
  1566     if [ ".$opt_s" = .yes ]; then
  1567         lnopt="$lnopt -s"
  1568     fi
  1570     #   iterate over sources
  1571     for src in $srcs; do
  1572         #   determine if one of the paths is an absolute path,
  1573         #   because then we _have_ to use an absolute symlink
  1574         oneisabs=0
  1575         srcisabs=0
  1576         dstisabs=0
  1577         case $src in
  1578             /* ) oneisabs=1; srcisabs=1 ;;
  1579         esac
  1580         case $dst in
  1581             /* ) oneisabs=1; dstisabs=1 ;;
  1582         esac
  1584         #   split source and destination into dir and base name
  1585         if [ -d $src ]; then
  1586             srcdir=`echo $src | sed -e 's;/*$;;'`
  1587             srcbase=""
  1588         else
  1589             srcdir=`echo  $src | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
  1590             srcbase=`echo $src | sed -e 's;.*/\([^/]*\)$;\1;'`
  1591         fi
  1592         if [ -d $dst ]; then
  1593             dstdir=`echo $dst | sed -e 's;/*$;;'`
  1594             dstbase=""
  1595         else
  1596             dstdir=`echo  $dst | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
  1597             dstbase=`echo $dst | sed -e 's;.*/\([^/]*\)$;\1;'`
  1598         fi
  1600         #   consistency check
  1601         if [ ".$dstdir" != . ]; then
  1602             if [ ! -d $dstdir ]; then
  1603                 echo "$msgprefix:Error: destination directory not found: $dstdir" 1>&2
  1604                 shtool_exit 1
  1605             fi
  1606         fi
  1608         #   make sure the source is reachable from the destination
  1609         if [ $dstisabs = 1 ]; then
  1610             if [ $srcisabs = 0 ]; then
  1611                 if [ ".$srcdir" = . ]; then
  1612                     srcdir="`pwd | sed -e 's;/*$;;'`"
  1613                     srcisabs=1
  1614                     oneisabs=1
  1615                 elif [ -d $srcdir ]; then
  1616                     srcdir="`cd $srcdir; pwd | sed -e 's;/*$;;'`"
  1617                     srcisabs=1
  1618                     oneisabs=1
  1619                 fi
  1620             fi
  1621         fi
  1623         #   split away a common prefix
  1624         prefix=""
  1625         if [ ".$srcdir" = ".$dstdir" ] && [ ".$srcdir" != . ]; then
  1626             prefix="$srcdir/"
  1627             srcdir=""
  1628             dstdir=""
  1629         else
  1630             while [ ".$srcdir" != . ] && [ ".$dstdir" != . ]; do
  1631                 presrc=`echo $srcdir | sed -e 's;^\([^/][^/]*\)/.*;\1;'`
  1632                 predst=`echo $dstdir | sed -e 's;^\([^/][^/]*\)/.*;\1;'`
  1633                 if [ ".$presrc" != ".$predst" ]; then
  1634                     break
  1635                 fi
  1636                 prefix="$prefix$presrc/"
  1637                 srcdir=`echo $srcdir | sed -e 's;^[^/][^/]*/*;;'`
  1638                 dstdir=`echo $dstdir | sed -e 's;^[^/][^/]*/*;;'`
  1639             done
  1640         fi
  1642         #   destination prefix is just the common prefix
  1643         dstpre="$prefix"
  1645         #   determine source prefix which is the reverse directory
  1646         #   step-up corresponding to the destination directory
  1647         srcpre=""
  1648         allow_relative_srcpre=no
  1649         if [ ".$prefix" != . ] && [ ".$prefix" != ./ ]; then
  1650             allow_relative_srcpre=yes
  1651         fi
  1652         if [ $oneisabs = 0 ]; then
  1653             allow_relative_srcpre=yes
  1654         fi
  1655         if [ ".$opt_s" != .yes ]; then
  1656             allow_relative_srcpre=no
  1657         fi
  1658         if [ ".$allow_relative_srcpre" = .yes ]; then
  1659             pl="$dstdir/"
  1660             OIFS="$IFS"; IFS='/'
  1661             for pe in $pl; do
  1662                 [ ".$pe" = .  ] && continue
  1663                 [ ".$pe" = .. ] && continue
  1664                 srcpre="../$srcpre"
  1665             done
  1666             IFS="$OIFS"
  1667         else
  1668             if [ $srcisabs = 1 ]; then
  1669                 srcpre="$prefix"
  1670             fi
  1671         fi
  1673         #   determine destination symlink name
  1674         if [ ".$dstbase" = . ]; then
  1675             if [ ".$srcbase" != . ]; then
  1676                 dstbase="$srcbase"
  1677             else
  1678                 dstbase=`echo "$prefix$srcdir" | sed -e 's;/*$;;' -e 's;.*/\([^/]*\)$;\1;'`
  1679             fi
  1680         fi
  1682         #   special case (usually on "mkln -s /foo /foo/bar", etc)
  1683         if [ ".$srcpre$srcdir$srcbase" = . ]; then
  1684             srcdir="."
  1685         fi
  1687         #   now finalize source and destination directory paths
  1688         srcdir=`echo $srcdir | sed -e 's;\([^/]\)$;\1/;'`
  1689         dstdir=`echo $dstdir | sed -e 's;\([^/]\)$;\1/;'`
  1691         #   run the final link command
  1692         if [ ".$opt_t" = .yes ]; then
  1693             echo "ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase"
  1694         fi
  1695         eval ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase
  1696     done
  1698     shtool_exit 0
  1699     ;;
  1701 mkshadow )
  1702     ##
  1703     ##  mkshadow -- Make a shadow tree through symbolic links
  1704     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
  1705     ##
  1707     #   source and destination directory
  1708     src=`echo "$1" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
  1709     dst=`echo "$2" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
  1711     #   check whether source exists
  1712     if [ ! -d $src ]; then
  1713         echo "$msgprefix:Error: source directory not found: \`$src'" 1>&2
  1714         shtool_exit 1
  1715     fi
  1717     #   determine if one of the paths is an absolute path,
  1718     #   because then we have to use an absolute symlink
  1719     oneisabs=0
  1720     case $src in
  1721         /* ) oneisabs=1 ;;
  1722     esac
  1723     case $dst in
  1724         /* ) oneisabs=1 ;;
  1725     esac
  1727     #   determine reverse directory for destination directory
  1728     dstrevdir=''
  1729     if [ $oneisabs = 0 ]; then
  1730         #   derive reverse path from forward path
  1731         pwd=`pwd`
  1732         OIFS="$IFS"; IFS='/'
  1733         for pe in $dst; do
  1734             if [ "x$pe" = "x.." ]; then
  1735                 OIFS2="$IFS"; IFS="$DIFS"
  1736                 eval `echo "$pwd" |\
  1737                       sed -e 's:\([^/]*\)$:; dir="\1":' \
  1738                           -e 's:^\(.*\)/[^/]*;:pwd="\1";:'\
  1739                           -e 's:^;:pwd="";:'`
  1740                 dstrevdir="$dir/$dstrevdir"
  1741                 IFS="$OIFS2"
  1742             else
  1743                 dstrevdir="../$dstrevdir"
  1744             fi
  1745         done
  1746         IFS="$OIFS"
  1747     else
  1748         src="`cd $src; pwd`";
  1749     fi
  1751     #   create directory tree at destination
  1752     if [ ! -d $dst ]; then
  1753         if [ ".$opt_t" = .yes ]; then
  1754             echo "mkdir $dst" 1>&2
  1755         fi
  1756         mkdir $dst
  1757     fi
  1758     if [ ".$opt_a" = .yes ]; then
  1759         DIRS=`cd $src; find . -type d -print |\
  1760               sed -e '/^\.$/d' -e 's:^\./::'`
  1761     else
  1762         DIRS=`cd $src; find . -type d -print |\
  1763               sed -e '/\/CVS/d' -e '/^\.$/d' -e 's:^\./::'`
  1764     fi
  1765     for dir in $DIRS; do
  1766         if [ ".$opt_t" = .yes ]; then
  1767             echo "mkdir $dst/$dir" 1>&2
  1768         fi
  1769         mkdir $dst/$dir
  1770     done
  1772     #   fill directory tree with symlinks to files
  1773     if [ ".$opt_a" = .yes ]; then
  1774         FILES="`cd $src; find . -depth -print |\
  1775                 sed -e 's/^\.\///'`"
  1776     else
  1777         FILES="`cd $src; find . -depth -print |\
  1778                 sed -e '/\.o$/d' -e '/\.a$/d' -e '/\.so$/d' \
  1779                     -e '/\.cvsignore$/d' -e '/\/CVS/d' \
  1780                     -e '/\/\.#/d' -e '/\.orig$/d' \
  1781                     -e 's/^\.\///'`"
  1782     fi
  1783     for file in $FILES; do
  1784          #  don't use `-type f' above for find because of symlinks
  1785          if [ -d "$src/$file" ]; then
  1786              continue
  1787          fi
  1788          basename=`echo $file | sed -e 's:^.*/::'`
  1789          dir=`echo $file | sed -e 's:[^/]*$::' -e 's:/$::' -e 's:$:/:' -e 's:^/$::'`
  1790          from=`echo "$src/$file" | sed -e 's/^\.\///'`
  1791          to="$dst/$dir$basename"
  1792          if [ $oneisabs = 0 ]; then
  1793              if [ ".$dir" != . ]; then
  1794                  subdir=`echo $dir | sed -e 's:/$::'`
  1795                  #   derive reverse path from forward path
  1796                  revdir=''
  1797                  OIFS="$IFS"; IFS='/'
  1798                  for pe in $subdir; do
  1799                      revdir="../$revdir"
  1800                  done
  1801                  IFS="$OIFS"
  1802                  #   finalize from
  1803                  from="$revdir$from"
  1804              fi
  1805              from="$dstrevdir$from"
  1806          fi
  1807          if [ ".$opt_v" = .yes ]; then
  1808              echo "    $to" 1>&2
  1809          fi
  1810          if [ ".$opt_t" = .yes ]; then
  1811              echo "ln -s $from $to" 1>&2
  1812          fi
  1813          ln -s $from $to
  1814     done
  1816     shtool_exit 0
  1817     ;;
  1819 fixperm )
  1820     ##
  1821     ##  fixperm -- Fix file permissions inside a source tree
  1822     ##  Copyright (c) 1996-2008 Ralf S. Engelschall <rse@engelschall.com>
  1823     ##
  1825     paths="$*"
  1827     #   check whether the test command supports the -x option
  1828     if [ -x /bin/sh ] 2>/dev/null; then
  1829         minusx="-x"
  1830     else
  1831         minusx="-r"
  1832     fi
  1834     #   iterate over paths
  1835     for p in $paths; do
  1836         for file in `find $p -depth -print`; do
  1837             if [ -f $file ]; then
  1838                 if [ $minusx $file ]; then
  1839                     if [ ".$opt_v" = .yes ]; then
  1840                         echo "-rwxr-xr-x $file" 2>&1
  1841                     fi
  1842                     if [ ".$opt_t" = .yes ]; then
  1843                         echo "chmod 755 $file" 2>&1
  1844                     fi
  1845                     chmod 755 $file
  1846                 else
  1847                     if [ ".$opt_v" = .yes ]; then
  1848                         echo "-rw-r--r-- $file" 2>&1
  1849                     fi
  1850                     if [ ".$opt_t" = .yes ]; then
  1851                         echo "chmod 644 $file" 2>&1
  1852                     fi
  1853                     chmod 644 $file
  1854                 fi
  1855                 continue
  1856             fi
  1857             if [ -d $file ]; then
  1858                 if [ ".$opt_v" = .yes ]; then
  1859                     echo "drwxr-xr-x $file" 2>&1
  1860                 fi
  1861                 if [ ".$opt_t" = .yes ]; then
  1862                     echo "chmod 755 $file" 2>&1
  1863                 fi
  1864                 chmod 755 $file
  1865                 continue
  1866             fi
  1867             if [ ".$opt_v" = .yes ]; then
  1868                 echo "?????????? $file" 2>&1
  1869             fi
  1870         done
  1871     done
  1873     shtool_exit 0
  1874     ;;
  1876 rotate )
  1877     ##
  1878     ##  rotate -- Logfile rotation
  1879     ##  Copyright (c) 2001-2008 Ralf S. Engelschall <rse@engelschall.com>
  1880     ##
  1882     #   make sure we have at least one file to rotate
  1883     if [ ".$opt_n" = .0 ]; then
  1884         echo "$msgprefix:Error: invalid argument \`$opt_n' to option -n." 1>&2
  1885         shtool_exit 1
  1886     fi
  1888     #   canonicalize -s option argument
  1889     if [ ".$opt_s" != . ]; then
  1890         if [ ".`expr $opt_s : '[0-9]*$'`" != .0 ]; then
  1892         elif [ ".`expr $opt_s : '[0-9]*[Kk]$'`" != .0 ]; then
  1893             opt_s=`expr $opt_s : '\([0-9]*\)[Kk]$'`
  1894             opt_s=`expr $opt_s \* 1024`
  1895         elif [ ".`expr $opt_s : '[0-9]*[Mm]$'`" != .0 ]; then
  1896             opt_s=`expr $opt_s : '\([0-9]*\)[Mm]$'`
  1897             opt_s=`expr $opt_s \* 1048576` # 1024*1024
  1898         elif [ ".`expr $opt_s : '[0-9]*[Gg]$'`" != .0 ]; then
  1899             opt_s=`expr $opt_s : '\([0-9]*\)[Gg]$'`
  1900             opt_s=`expr $opt_s \* 1073741824` # 1024*1024*1024
  1901         else
  1902             echo "$msgprefix:Error: invalid argument \`$opt_s' to option -s." 1>&2
  1903             shtool_exit 1
  1904         fi
  1905     fi
  1907     #   option -d/-z consistency
  1908     if [ ".$opt_d" = .yes ] && [ ".$opt_z" = . ]; then
  1909         echo "$msgprefix:Error: option -d requires option -z." 1>&2
  1910         shtool_exit 1
  1911     fi
  1913     #   make sure target directory exists
  1914     if [ ".$opt_a" != . ]; then
  1915         if [ ! -d $opt_a ]; then
  1916             if [ ".$opt_f" = .no ]; then
  1917                 echo "$msgprefix:Error: archive directory \`$opt_a' does not exist." 1>&2
  1918                 shtool_exit 1
  1919             fi
  1920             mkdir $opt_a || shtool_exit $?
  1921             chmod 755 $opt_a
  1922         fi
  1923         if [ ! -w $opt_a ]; then
  1924             echo "$msgprefix:Error: archive directory \`$opt_a' not writable." 1>&2
  1925             shtool_exit 1
  1926         fi
  1927     fi
  1929     #   determine compression approach
  1930     if [ ".$opt_z" != . ]; then
  1931         comp_lvl="$opt_z"
  1932         comp_prg=""
  1933         case $comp_lvl in
  1934             *:* ) eval `echo $comp_lvl |\
  1935                         sed -e 's%^\(.*\):\(.*\)$%comp_prg="\1"; comp_lvl="\2"%'` ;;
  1936         esac
  1938         #   compression level consistency
  1939         case $comp_lvl in
  1940             [0-9] )
  1941                 ;;
  1942             * ) echo "$msgprefix:Error: invalid compression level \`$comp_lvl'" 1>&2
  1943                 shtool_exit 1
  1944                 ;;
  1945         esac
  1947         #   determine a suitable compression tool
  1948         if [ ".$comp_prg" = . ]; then
  1949             #   check whether the test command supports the -x option
  1950             if [ -x /bin/sh ] 2>/dev/null; then
  1951                 minusx="-x"
  1952             else
  1953                 minusx="-r"
  1954             fi
  1955             #   search for tools in $PATH
  1956             paths="`echo $PATH |\
  1957                     sed -e 's%/*:%:%g' -e 's%/*$%%' \
  1958                         -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
  1959                         -e 's/:/ /g'`"
  1960             for prg in bzip2 gzip compress; do
  1961                 for path in $paths; do
  1962                     if [ $minusx "$path/$prg" ] && [ ! -d "$path/$prg" ]; then
  1963                         comp_prg="$prg"
  1964                         break
  1965                     fi
  1966                 done
  1967                 if [ ".$comp_prg" != . ]; then
  1968                     break
  1969                 fi
  1970             done
  1971             if [ ".$comp_prg" = . ]; then
  1972                 echo "$msgprefix:Error: no suitable compression tool found in \$PATH" 1>&2
  1973                 shtool_exit 1
  1974             fi
  1975         fi
  1977         #   determine standard compression extension
  1978         #   and make sure it is a known tool
  1979         case $comp_prg in
  1980             */bzip2    | bzip2    ) comp_ext="bz2" comp_lvl="-$comp_lvl" ;;
  1981             */gzip     | gzip     ) comp_ext="gz"  comp_lvl="-$comp_lvl" ;;
  1982             */compress | compress ) comp_ext="Z";  comp_lvl=""           ;;
  1983             * ) echo "$msgprefix:Error: tool \`$comp_prg' is not a known compression tool" 1>&2
  1984                 shtool_exit 1
  1985                 ;;
  1986         esac
  1987         comp_suf=".$comp_ext"
  1988     fi
  1990     #   iterate over all given logfile arguments
  1991     for file in $*; do
  1992         #   make sure the logfile exists
  1993         if [ ! -f $file ]; then
  1994             if [ ".$opt_f" = .yes ]; then
  1995                 continue
  1996             fi
  1997             echo "$msgprefix:Error: logfile \`$file' not found" 1>&2
  1998             shtool_exit 1
  1999         fi
  2001         #   determine log directory (where original logfile is placed)
  2002         ldir="."
  2003         case $file in
  2004             */* ) eval `echo $file | sed -e 's%^\(.*\)/\([^/]*\)$%ldir="\1"; file="\2";%'` ;;
  2005         esac
  2007         #   determine archive directory (where rotated logfiles are placed)
  2008         adir="$ldir"
  2009         if [ ".$opt_a" != . ]; then
  2010             case "$opt_a" in
  2011                 /* | ./* ) adir="$opt_a" ;;
  2012                 * ) adir="$ldir/$opt_a"  ;;
  2013             esac
  2014         fi
  2016         #   optionally take logfile size into account
  2017         if [ ".$opt_s" != . ]; then
  2018             #   determine size of logfile
  2019             set -- `env -i /bin/ls -l "$ldir/$file" | sed -e "s;$ldir/$file;;" |\
  2020                     sed -e 's; -> .*$;;' -e 's;[ 	][ 	]*; ;g'`
  2021             n=`expr $# - 3`
  2022             eval "size=\`echo \${$n}\`"
  2024             #   skip logfile if size is still too small
  2025             if [ $size -lt $opt_s ]; then
  2026                 if [ ".$opt_v" = .yes ]; then
  2027                     echo "$ldir/$file: still too small in size -- skipping"
  2028                 fi
  2029                 continue
  2030             fi
  2031         fi
  2033         #   verbosity
  2034         if [ ".$opt_v" = .yes ]; then
  2035             echo "rotating $ldir/$file"
  2036         fi
  2038         #   execute prolog
  2039         if [ ".$opt_P" != . ]; then
  2040             #   pass current log file name to prolog
  2041             #   prolog cannot be handed an argument as it may be
  2042             #   called as "prolog && something"  
  2043             SHTOOL_ROTATE_LOGFILE="$ldir/$file"
  2044             export SHTOOL_ROTATE_LOGFILE
  2045             if [ ".$opt_t" = .yes ]; then
  2046                 echo "$opt_P"
  2047             fi
  2048             eval $opt_P
  2049             [ $? -ne 0 ] && shtool_exit $?
  2050         fi
  2052         #   kick away out-rotated logfile
  2053         n=`expr $opt_n - 1`
  2054         n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
  2055         if [ -f "${adir}/${file}.${n}${comp_suf}" ]; then
  2056             #   optionally migrate away the out-rotated logfile
  2057             if [ ".$opt_M" != . ]; then
  2058                 if [ ".$opt_t" = .yes ]; then
  2059                     echo "$opt_M ${adir}/${file}.${n}${comp_suf}"
  2060                 fi
  2061                 eval "$opt_M ${adir}/${file}.${n}${comp_suf}"
  2062                 [ $? -ne 0 ] && shtool_exit $?
  2063             fi
  2064             #   finally get rid of the out-rotated logfile
  2065             if [ ".$opt_t" = .yes ]; then
  2066                 echo "rm -f ${adir}/${file}.${n}${comp_suf}"
  2067             fi
  2068             rm -f ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2069         fi
  2071         #   rotate already archived logfiles
  2072         while [ $n -gt 0 ]; do
  2073             m=$n
  2074             n=`expr $n - 1`
  2075             n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
  2076             if [ $n -eq 0 ] && [ ".$opt_d" = .yes ]; then
  2077                 #   special case: first rotation file under delayed compression situation
  2078                 if [ ! -f "${adir}/${file}.${n}" ]; then
  2079                     continue
  2080                 fi
  2082                 #   compress file (delayed)
  2083                 if [ ".$opt_b" = .yes ]; then
  2084                     if [ ".$opt_t" = .yes ]; then
  2085                         echo "mv ${adir}/${file}.${n} ${adir}/${file}.${m}"
  2086                     fi
  2087                     mv ${adir}/${file}.${n} ${adir}/${file}.${m} || shtool_exit $?
  2088                     if [ ".$opt_t" = .yes ]; then
  2089                         echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${m} >${adir}/${file}.${m}${comp_suf}; rm -f ${adir}/${file}.${m}) &"
  2090                     fi
  2091                     ( ${comp_prg} ${comp_lvl} \
  2092                           <${adir}/${file}.${m} \
  2093                           >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2094                       rm -f ${adir}/${file}.${m} || shtool_exit $?
  2095                     ) </dev/null >/dev/null 2>&1 &
  2096                 else
  2097                     if [ ".$opt_t" = .yes ]; then
  2098                         echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${m}${comp_suf}"
  2099                     fi
  2100                     ${comp_prg} ${comp_lvl} \
  2101                         <${adir}/${file}.${n} \
  2102                         >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2103                     if [ ".$opt_t" = .yes ]; then
  2104                         echo "rm -f ${adir}/${file}.${n}"
  2105                     fi
  2106                     rm -f ${adir}/${file}.${n} || shtool_exit $?
  2107                 fi
  2109                 #   fix file attributes
  2110                 if [ ".$opt_o" != . ]; then
  2111                     if [ ".$opt_t" = .yes ]; then
  2112                         echo "chown $opt_o ${adir}/${file}.${m}${comp_suf}"
  2113                     fi
  2114                     chown $opt_o ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2115                 fi
  2116                 if [ ".$opt_g" != . ]; then
  2117                     if [ ".$opt_t" = .yes ]; then
  2118                         echo "chgrp $opt_g ${adir}/${file}.${m}${comp_suf}"
  2119                     fi
  2120                     chgrp $opt_g ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2121                 fi
  2122                 if [ ".$opt_m" != . ]; then
  2123                     if [ ".$opt_t" = .yes ]; then
  2124                         echo "chmod $opt_m ${adir}/${file}.${m}${comp_suf}"
  2125                     fi
  2126                     chmod $opt_m ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2127                 fi
  2128             else
  2129                 #   standard case: second and following rotation file
  2130                 if [ ! -f "${adir}/${file}.${n}${comp_suf}" ]; then
  2131                     continue
  2132                 fi
  2133                 if [ ".$opt_t" = .yes ]; then
  2134                     echo "mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf}"
  2135                 fi
  2136                 mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2137             fi
  2138         done
  2140         #   move away current logfile
  2141         if [ ".$opt_c" = .yes ]; then
  2142             #   approach: copy[+truncate]
  2143             if [ ".$opt_t" = .yes ]; then
  2144                 echo "cp -p ${ldir}/${file} ${adir}/${file}.${n}"
  2145             fi
  2146             cp -p ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
  2147             if [ ".$opt_r" = .no ]; then
  2148                 if [ ".$opt_t" = .yes ]; then
  2149                     echo "cp /dev/null ${ldir}/${file}"
  2150                 fi
  2151                 cp /dev/null ${ldir}/${file} || shtool_exit $?
  2152             fi
  2153         else
  2154             #   approach: move[+touch]
  2155             if [ ".$opt_t" = .yes ]; then
  2156                 echo "mv ${ldir}/${file} ${adir}/${file}.${n}"
  2157             fi
  2158             mv ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
  2159             if [ ".$opt_r" = .no ]; then
  2160                 if [ ".$opt_t" = .yes ]; then
  2161                     echo "touch ${ldir}/${file}"
  2162                 fi
  2163                 touch ${ldir}/${file} || shtool_exit $?
  2164                 #   fix file attributes
  2165                 if [ ".$opt_o" != . ]; then
  2166                     if [ ".$opt_t" = .yes ]; then
  2167                         echo "chown $opt_o ${ldir}/${file}"
  2168                     fi
  2169                     chown $opt_o ${ldir}/${file} || shtool_exit $?
  2170                 fi
  2171                 if [ ".$opt_g" != . ]; then
  2172                     if [ ".$opt_t" = .yes ]; then
  2173                         echo "chgrp $opt_g ${ldir}/${file}"
  2174                     fi
  2175                     chgrp $opt_g ${ldir}/${file} || shtool_exit $?
  2176                 fi
  2177                 if [ ".$opt_m" != . ]; then
  2178                     if [ ".$opt_t" = .yes ]; then
  2179                         echo "chmod $opt_m ${ldir}/${file}"
  2180                     fi
  2181                     chmod $opt_m ${ldir}/${file} || shtool_exit $?
  2182                 fi
  2183             fi
  2184         fi
  2186         #   regular compression step
  2187         if [ ".$opt_z" != . ] && [ ".$opt_d" = .no ]; then
  2188             #   compress file
  2189             if [ ".$opt_b" = .yes ]; then
  2190                 if [ ".$opt_t" = .yes ]; then
  2191                     echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}; rm -f ${adir}/${file}.${n}) &"
  2192                 fi
  2193                 ( ${comp_prg} ${comp_lvl} \
  2194                       <${adir}/${file}.${n} \
  2195                       >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2196                   rm -f ${adir}/${file}.${n} || shtool_exit $?
  2197                 ) </dev/null >/dev/null 2>&1 &
  2198             else
  2199                 if [ ".$opt_t" = .yes ]; then
  2200                     echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}"
  2201                 fi
  2202                 ${comp_prg} ${comp_lvl} \
  2203                     <${adir}/${file}.${n} \
  2204                     >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2205                 if [ ".$opt_t" = .yes ]; then
  2206                     echo "rm -f ${opt_a}${file}.${n}"
  2207                 fi
  2208                 rm -f ${adir}/${file}.${n} || shtool_exit $?
  2209             fi
  2211             #   fix file attributes
  2212             if [ ".$opt_o" != . ]; then
  2213                 if [ ".$opt_t" = .yes ]; then
  2214                     echo "chown $opt_o ${adir}/${file}.${n}${comp_suf}"
  2215                 fi
  2216                 chown $opt_o ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2217             fi
  2218             if [ ".$opt_g" != . ]; then
  2219                 if [ ".$opt_t" = .yes ]; then
  2220                     echo "chgrp $opt_g ${adir}/${file}.${n}${comp_suf}"
  2221                 fi
  2222                 chgrp $opt_g ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2223             fi
  2224             if [ ".$opt_m" != . ]; then
  2225                 if [ ".$opt_t" = .yes ]; then
  2226                     echo "chmod $opt_m ${adir}/${file}.${n}${comp_suf}"
  2227                 fi
  2228                 chmod $opt_m ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2229             fi
  2230         fi
  2232         #   execute epilog
  2233         if [ ".$opt_E" != . ]; then
  2234             #   pass archive file name to epilog command
  2235             #   epilog cannot be handed an argument as it is often
  2236             #   called as "epilog && something"
  2237             SHTOOL_ROTATE_LOGFILE="${adir}/${file}"
  2238             export SHTOOL_ROTATE_LOGFILE
  2239             if [ ".$opt_t" = .yes ]; then
  2240                 echo "$opt_E"
  2241             fi
  2242             eval $opt_E
  2243             [ $? -ne 0 ] && shtool_exit $?
  2244         fi
  2245     done
  2247     shtool_exit 0
  2248     ;;
  2250 tarball )
  2251     ##
  2252     ##  tarball -- Roll distribution tarballs
  2253     ##  Copyright (c) 1999-2008 Ralf S. Engelschall <rse@engelschall.com>
  2254     ##
  2256     srcs="$*"
  2258     #   check whether the test command supports the -x option
  2259     if [ -x /bin/sh ] 2>/dev/null; then
  2260         minusx="-x"
  2261     else
  2262         minusx="-r"
  2263     fi
  2265     #   find the tools
  2266     paths="`echo $PATH |\
  2267             sed -e 's%/*:%:%g' -e 's%/*$%%' \
  2268                 -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
  2269                 -e 's/:/ /g'`"
  2270     for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do
  2271         prg=`echo $spec | sed -e 's/:.*$//'`
  2272         tools=`echo $spec | sed -e 's/^.*://'`
  2273         eval "prg_${prg}=''"
  2274         #   iterate over tools
  2275         for tool in `echo $tools | sed -e 's/,/ /g'`; do
  2276             #   iterate over paths
  2277             for path in $paths; do
  2278                 if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then
  2279                     eval "prg_${prg}=\"$path/$tool\""
  2280                     break
  2281                 fi
  2282             done
  2283             eval "val=\$prg_${prg}"
  2284             if [ ".$val" != . ]; then
  2285                 break
  2286             fi
  2287         done
  2288     done
  2290     #   expand source paths
  2291     exclude=''
  2292     for pat in `echo $opt_e | sed 's/,/ /g'`; do
  2293         exclude="$exclude | grep -v '$pat'"
  2294     done
  2295     if [ ".$opt_t" = .yes ]; then
  2296         echo "cp /dev/null $tmpfile.lst" 1>&2
  2297     fi
  2298     cp /dev/null $tmpfile.lst
  2299     for src in $srcs; do
  2300         if [ -d $src ]; then
  2301             if [ ".$opt_t" = .yes ]; then
  2302                 echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2
  2303             fi
  2304             (cd $src && $prg_find . -type f -depth -print) |\
  2305             sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst
  2306         else
  2307             if [ ".$opt_t" = .yes ]; then
  2308                 echo "echo $src >>$tmpfile.lst" 1>&2
  2309             fi
  2310             echo $src >>$tmpfile.lst
  2311         fi
  2312     done
  2313     sort <$tmpfile.lst >$tmpfile.lst.n
  2314     mv $tmpfile.lst.n $tmpfile.lst
  2315     if [ ".$opt_v" = .yes ]; then
  2316         cat $tmpfile.lst | sed -e 's/^/  /' 1>&2
  2317     fi
  2319     #   determine tarball file and directory name
  2320     if [ ".$opt_o" != . ]; then
  2321         tarfile="$opt_o"
  2322         if [ ".$opt_d" != . ]; then
  2323             tarname="$opt_d"
  2324         else
  2325             tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'`
  2326         fi
  2327     else
  2328         if [ ".$opt_d" != . ]; then
  2329             tarname="$opt_d"
  2330         elif [ -d "$from" ]; then
  2331             tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'`
  2332         else
  2333             tarname="out"
  2334         fi
  2335         tarfile="$tarname.tar"
  2336     fi
  2338     #   roll the tarball
  2339     compress=''
  2340     if [ ".$opt_c" != . ]; then
  2341         compress="| $opt_c"
  2342     fi
  2343     if [ ".$prg_tardy" != . ]; then
  2344         #   the elegant hackers way
  2345         tardy_opt="--prefix=$tarname"
  2346         tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security!
  2347         if [ ".$opt_u" != . ]; then
  2348             tardy_opt="$tardy_opt --user_name=$opt_u"
  2349         fi
  2350         if [ ".$opt_g" != . ]; then
  2351             tardy_opt="$tardy_opt --group_name=$opt_g"
  2352         fi
  2353         if [ ".$opt_t" = .yes ]; then
  2354             echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2
  2355         fi
  2356         cat $tmpfile.lst |\
  2357         xargs $prg_tar cf - |\
  2358         $prg_tardy $tardy_opt |\
  2359         eval cat $compress >$tmpfile.out
  2360         if [ ".$opt_t" = .yes ]; then
  2361             echo "cp $tmpfile.out $tarfile" 1>&2
  2362         fi
  2363         cp $tmpfile.out $tarfile
  2364     else
  2365         #  the portable standard way
  2366         if [ ".$opt_t" = .yes ]; then
  2367             echo "mkdir $tmpdir/$tarname" 1>&2
  2368         fi
  2369         mkdir $tmpdir/$tarname || shtool_exit 1
  2370         if [ ".$opt_t" = .yes ]; then
  2371             echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2
  2372         fi
  2373         cat $tmpfile.lst |\
  2374         xargs $prg_tar cf - |\
  2375         (cd $tmpdir/$tarname && $prg_tar xf -)
  2376         if [ ".$opt_u" != . ]; then
  2377             if [ ".$opt_t" = .yes ]; then
  2378                 echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1
  2379             fi
  2380             chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\
  2381             echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)"
  2382         fi
  2383         if [ ".$opt_g" != . ]; then
  2384             if [ ".$opt_t" = .yes ]; then
  2385                 echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1
  2386             fi
  2387             chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\
  2388             echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)"
  2389         fi
  2390         if [ ".$opt_t" = .yes ]; then
  2391             echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2
  2392         fi
  2393         (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\
  2394         eval cat $compress >$tmpfile.out
  2395         if [ ".$opt_t" = .yes ]; then
  2396             echo "cp $tmpfile.out $tarfile" 1>&2
  2397         fi
  2398         cp $tmpfile.out $tarfile
  2399         if [ ".$opt_t" = .yes ]; then
  2400             echo "rm -rf $tmpdir/$tarname" 1>&2
  2401         fi
  2402         rm -rf $tmpdir/$tarname
  2403     fi
  2405     #   cleanup
  2406     if [ ".$opt_t" = .yes ]; then
  2407         echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2
  2408     fi
  2409     rm -f $tmpfile.lst $tmpfile.out
  2411     shtool_exit 0
  2412     ;;
  2414 subst )
  2415     ##
  2416     ##  subst -- Apply sed(1) substitution operations
  2417     ##  Copyright (c) 2001-2008 Ralf S. Engelschall <rse@engelschall.com>
  2418     ##
  2420     #   remember optional list of file(s)
  2421     files="$*"
  2422     files_num="$#"
  2424     #   parameter consistency check
  2425     if [ $# -eq 0 ] && [ ".$opt_b" != . ]; then
  2426         echo "$msgprefix:Error: option -b cannot be applied to stdin" 1>&2
  2427         shtool_exit 1
  2428     fi
  2429     if [ $# -eq 0 ] && [ ".$opt_s" = .yes ]; then
  2430         echo "$msgprefix:Error: option -s cannot be applied to stdin" 1>&2
  2431         shtool_exit 1
  2432     fi
  2434     #   build underlying sed(1) command
  2435     sedcmd='sed'
  2436     if [ ".$opt_e" != . ]; then
  2437         OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
  2438         for e
  2439         do
  2440             sedcmd="$sedcmd -e '$e'"
  2441         done
  2442     elif [ ".$opt_f" != . ]; then
  2443         if [ ! -f $opt_f ]; then
  2444             echo "$msgprefix:Error: command file \`$opt_f' not found or not a regular file" 1>&2
  2445             shtool_exit 1
  2446         fi
  2447         sedcmd="$sedcmd -f '$opt_f'"
  2448     else
  2449         echo "$msgprefix:Error: either -e option(s) or -f option required" 1>&2
  2450         shtool_exit 1
  2451     fi
  2453     #   determine extension for original file
  2454     orig=".orig"
  2455     if [ ".$opt_b" != . ]; then
  2456         orig="$opt_b"
  2457     fi
  2459     #   apply sed(1) operation(s)
  2460     if [ ".$files" != . ]; then
  2461         #   apply operation(s) to files
  2462         substdone=no
  2463         for file in $files; do
  2464             test ".$file" = . && continue
  2465             if [ ! -f $file ]; then
  2466                 echo "$msgprefix:Warning: file \`$file' not found or not a regular file" 1>&2
  2467                 continue
  2468             fi
  2470             #   handle interactive mode
  2471             if [ ".$opt_i" = .yes ]; then
  2472                 eval "$sedcmd <$file >$file.new"
  2473                 skip=no
  2474                 if cmp $file $file.new >/dev/null 2>&1; then
  2475                     rm -f $file.new
  2476                     skip=yes
  2477                 else
  2478                     (diff -U1 $file $file.new >$tmpfile) 2>/dev/null
  2479                     if [ ".`cat $tmpfile`" = . ]; then
  2480                         (diff -C1 $file $file.new >$tmpfile) 2>/dev/null
  2481                         if [ ".`cat $tmpfile`" = . ]; then
  2482                             echo "$msgprefix:Warning: unable to show difference for file \`$file'" 1>&2
  2483                             cp /dev/null $tmpfile
  2484                         fi
  2485                     fi
  2486                     rm -f $file.new
  2487                     cat $tmpfile
  2488                     echo dummy | awk '{ printf("%s", TEXT); }' TEXT=">>> Apply [Y/n]: "
  2489                     read input
  2490                     if [ ".$input" != .Y ] &&\
  2491                        [ ".$input" != .y ] &&\
  2492                        [ ".$input" != . ]; then
  2493                        skip=yes
  2494                     fi
  2495                 fi
  2496                 if [ ".$skip" = .yes ]; then
  2497                     if [ ".$opt_v" = .yes ]; then
  2498                         echo "file \`$file' -- skipped" 1>&2
  2499                     fi
  2500                     continue
  2501                 fi
  2502             fi
  2504             #   apply sed(1) operation(s)
  2505             if [ ".$opt_v" = .yes ]; then
  2506                 echo "patching \`$file'" 1>&2
  2507             fi
  2508             if [ ".$opt_t" = .yes ]; then
  2509                 echo "\$ cp -p $file $file$orig"
  2510                 echo "\$ chmod u+w $file"
  2511                 echo "\$ $sedcmd <$file$orig >$file"
  2512             fi
  2513             if [ ".$opt_n" = .no ]; then
  2514                 cp -p $file $file$orig
  2515                 chmod u+w $file >/dev/null 2>&1 || true
  2516                 eval "$sedcmd <$file$orig >$file"
  2517             fi
  2519             #   optionally fix timestamp
  2520             if [ ".$opt_s" = .yes ]; then
  2521                 if [ ".$opt_t" = .yes ]; then
  2522                     echo "\$ touch -r $file$orig $file"
  2523                 fi
  2524                 if [ ".$opt_n" = .no ]; then
  2525                     touch -r $file$orig $file
  2526                 fi
  2527             fi
  2529             #   optionally check whether any content change actually occurred
  2530             if [ ".$opt_q" = .no ]; then
  2531                 if cmp $file$orig $file >/dev/null 2>&1; then
  2532                     if [ ".$opt_w" = .yes ]; then
  2533                         echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
  2534                     fi
  2535                 else
  2536                     substdone=yes
  2537                 fi
  2538             fi
  2540             #   optionally remove preserved original file
  2541             if [ ".$opt_b" = . ]; then
  2542                 if [ ".$opt_t" = .yes ]; then
  2543                     echo "\$ rm -f $file$orig"
  2544                 fi
  2545                 if [ ".$opt_n" = .no ]; then
  2546                     rm -f $file$orig
  2547                 fi
  2548             fi
  2549         done
  2550         if [ ".$opt_q" = .no ] && [ ".$opt_w" = .no ]; then
  2551             if [ ".$substdone" = .no ]; then
  2552                 if [ ".$files_num" = .1 ]; then
  2553                     echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
  2554                 else
  2555                     echo "$msgprefix:Warning: substitution resulted in no content change on any file" 1>&2
  2556                 fi
  2557             fi
  2558         fi
  2559     else
  2560         #   apply operation(s) to stdin/stdout
  2561         if [ ".$opt_v" = .yes ]; then
  2562             echo "patching <stdin>" 1>&2
  2563         fi
  2564         if [ ".$opt_t" = .yes ]; then
  2565             echo "\$ $sedcmd"
  2566         fi
  2567         if [ ".$opt_n" = .no ]; then
  2568             eval "$sedcmd"
  2569         fi
  2570     fi
  2572     shtool_exit 0
  2573     ;;
  2575 platform )
  2576     ##
  2577     ##  platform -- Platform Identification Utility
  2578     ##  Copyright (c) 2003-2008 Ralf S. Engelschall <rse@engelschall.com>
  2579     ##
  2581     #   option post-processing
  2582     if [ ".$opt_t" != . ]; then
  2583         case "$opt_t" in
  2584             binary )
  2585                 #   binary package id (OpenPKG RPM)
  2586                 opt_F="%<ap>-%<sp>"
  2587                 opt_L=yes
  2588                 opt_S=""
  2589                 opt_C="+"
  2590                 ;;
  2591             build )
  2592                 #   build time checking (OpenPKG RPM)
  2593                 opt_F="%<at>-%<st>"
  2594                 opt_L=yes
  2595                 opt_S=""
  2596                 opt_C="+"
  2597                 ;;
  2598             gnu )
  2599                 #   GNU config.guess style <arch>-<vendor>-<os><osversion>
  2600                 opt_F="%<at>-unknown-%<st>"
  2601                 opt_L=yes
  2602                 opt_S=""
  2603                 opt_C="+"
  2604                 ;;
  2605             web )
  2606                 #   non-whitespace HTTP Server-header id
  2607                 opt_F="%<sp>-%<ap>"
  2608                 opt_S="/"
  2609                 opt_C="+"
  2610                 ;;
  2611             summary)
  2612                 #   human readable verbose summary information
  2613                 opt_F="Class:      %[sc] (%[ac])\\nProduct:    %[sp] (%[ap])\\nTechnology: %[st] (%[at])"
  2614                 opt_S=" "
  2615                 opt_C="/"
  2616                 ;;
  2617             all-in-one )
  2618                 #   full-table all-in-one information
  2619                 opt_F=""
  2620                 opt_F="${opt_F}concise architecture class:      %<ac>\\n"
  2621                 opt_F="${opt_F}regular architecture class:      %{ac}\\n"
  2622                 opt_F="${opt_F}verbose architecture class:      %[ac]\\n"
  2623                 opt_F="${opt_F}concise architecture product:    %<ap>\\n"
  2624                 opt_F="${opt_F}regular architecture product:    %{ap}\\n"
  2625                 opt_F="${opt_F}verbose architecture product:    %[ap]\\n"
  2626                 opt_F="${opt_F}concise architecture technology: %<at>\\n"
  2627                 opt_F="${opt_F}regular architecture technology: %{at}\\n"
  2628                 opt_F="${opt_F}verbose architecture technology: %[at]\\n"
  2629                 opt_F="${opt_F}concise system class:            %<sc>\\n"
  2630                 opt_F="${opt_F}regular system class:            %{sc}\\n"
  2631                 opt_F="${opt_F}verbose system class:            %[sc]\\n"
  2632                 opt_F="${opt_F}concise system product:          %<sp>\\n"
  2633                 opt_F="${opt_F}regular system product:          %{sp}\\n"
  2634                 opt_F="${opt_F}verbose system product:          %[sp]\\n"
  2635                 opt_F="${opt_F}concise system technology:       %<st>\\n"
  2636                 opt_F="${opt_F}regular system technology:       %{st}\\n"
  2637                 opt_F="${opt_F}verbose system technology:       %[st]"
  2638                 ;;
  2639             * )
  2640                 echo "$msgprefix:Error: invalid type \`$opt_t'" 1>&2
  2641                 exit 1
  2642                 ;;
  2643         esac
  2644     fi
  2646     #   assemble initial platform information
  2647     UNAME_MACHINE=`(uname -m) 2>/dev/null` ||\
  2648     UNAME_MACHINE=`(uname -p) 2>/dev/null` ||\
  2649     UNAME_MACHINE='unknown'
  2650     UNAME_SYSTEM=`(uname -s) 2>/dev/null`  ||\
  2651     UNAME_SYSTEM='unknown'
  2652     UNAME_RELEASE=`(uname -r) 2>/dev/null` ||\
  2653     UNAME_RELEASE=`(uname -v) 2>/dev/null` ||\
  2654     UNAME_RELEASE='unknown'
  2656     UNAME="${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}"
  2658     AC=""; AP=""; AT=""
  2659     SC=""; SP=""; ST=""
  2661     #    dispatch into platform specific sections
  2662     case "${UNAME}" in
  2664         #   FreeBSD
  2665         *:FreeBSD:* )
  2666             #   determine architecture
  2667             AC="${UNAME_MACHINE}"
  2668             case "${AC}" in
  2669                 i386 ) AC="iX86" ;;
  2670             esac
  2671             AP="${AC}"
  2672             AT="${AP}"
  2673             if [ ".${AT}" = ".iX86" ]; then
  2674                 case "`(/sbin/sysctl -n hw.model) 2>&1`" in
  2675                     *"Xeon"* | *"Pentium Pro"* | *"Cyrix 6x86MX"* | *"Pentium II"* | *"Pentium III"* | *"Pentium 4"* | *"Celeron"* ) AT="i686" ;;
  2676                     *"Pentium"* ) AT="i586" ;; *"i486[SD]X"* | *"Cyrix 486"* | *"Cyrix [56]x86"* | *"Blue Lightning" | *"Cyrix 486S/DX" ) AT="i486" ;;
  2677                     *"i386[SD]X"* | *"NexGen 586"* ) AT="i386" ;;
  2678                 esac
  2679             fi
  2680             #   determine system
  2681             r=`echo "${UNAME_RELEASE}" |\
  2682                sed -e 's;[()];;' -e 's/\(-.*\)$/[\1]/'`
  2683             ST="FreeBSD ${r}"
  2684             SP="${ST}"
  2685             case "${r}" in
  2686                 1.* ) SC="4.3BSD" ;;
  2687                 *   ) SC="4.4BSD" ;;
  2688             esac
  2689             ;;
  2691         #   NetBSD
  2692         *:NetBSD:* )
  2693             #   determine architecture
  2694             AT="${UNAME_MACHINE}"
  2695             AP="${AT}"
  2696             case "${AP}" in
  2697                 i[3-6]86 ) AP="iX86" ;;
  2698             esac
  2699             AC="${AP}"
  2700             #   determine system
  2701             r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
  2702             ST="NetBSD ${r}"
  2703             SP="${ST}"
  2704             case "${r}" in
  2705                 0.* ) SC="4.3BSD" ;;
  2706                 *   ) SC="4.4BSD" ;;
  2707             esac
  2708             ;;
  2710         #   OpenBSD
  2711         *:OpenBSD:* )
  2712             #   determine architecture
  2713             AT="${UNAME_MACHINE}"
  2714             AP="${AT}"
  2715             case "${AP}" in
  2716                 i[3-6]86 ) AP="iX86" ;;
  2717             esac
  2718             AC="${AP}"
  2719             #   determine system
  2720             r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
  2721             ST="OpenBSD ${r}"
  2722             SP="${ST}"
  2723             SC="4.4BSD"
  2724             ;;
  2726         #   DragonFly BSD
  2727         *:DragonFly:* )
  2728             #   determine architecture
  2729             AT="${UNAME_MACHINE}"
  2730             AP="${AT}"
  2731             case "${AP}" in
  2732                 i[3-6]86 ) AP="iX86" ;;
  2733             esac
  2734             AC="${AP}"
  2735             #   determine system
  2736             r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
  2737             ST="DragonFly ${r}"
  2738             SP="${ST}"
  2739             SC="4.4BSD"
  2740             ;;
  2742         #   GNU/Linux
  2743         *:Linux:* )
  2744             #   determine architecture
  2745             AT="${UNAME_MACHINE}"
  2746             case "${AT}" in
  2747                ia64     ) AT="IA64"   ;;
  2748                x86_64   ) AT='AMD64'  ;;
  2749                parisc   ) AT="HPPA32" ;;
  2750                parisc64 ) AT="HPPA64" ;;
  2751             esac
  2752             AP="${AT}"
  2753             case "${AP}" in
  2754                i[3-6]86 ) AP='iX86' ;;
  2755             esac
  2756             AC="${AP}"
  2757             #   determine system
  2758             v_kern=`echo "${UNAME_RELEASE}" |\
  2759                 sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
  2760             v_libc=`(strings /lib/libc.so.* | grep '^GLIBC_' | sed -e 's/^GLIBC_//' |\
  2761                 env -i sort -n | sed -n -e '$p' | sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/') 2>/dev/null`
  2762             ST="GNU/<Linux >${v_libc}/<${v_kern}>"
  2763             if [ -f /etc/lsb-release ]; then
  2764                 eval `( . /etc/lsb-release
  2765                     echo "SC=\"LSB${LSB_VERSION}\""
  2766                     if [ ".${DISTRIB_ID}" != . -a ".${DISTRIB_RELEASE}" != . ]; then
  2767                         echo "SP=\"${DISTRIB_ID} ${DISTRIB_RELEASE}\""
  2768                     fi
  2769                 ) 2>/dev/null`
  2770             fi
  2771             if [ ".$SP" = . ]; then
  2772                 for tagfile in x \
  2773                     `cd /etc && \
  2774                     /bin/ls *[_-]release *[_-]version 2>/dev/null | env -i sort | \
  2775                     sed -e '/^redhat-release$/d' -e '/^lsb-release$/d'; \
  2776                     echo redhat-release lsb-release`
  2777                 do
  2778                     [ ".${tagfile}" = .x ] && continue
  2779                     [ ! -f "/etc/${tagfile}" ] && continue
  2780                     n=`echo ${tagfile} | sed -e 's/[_-]release$//' -e 's/[_-]version$//'`
  2781                     v=`(grep VERSION /etc/${tagfile}; cat /etc/${tagfile}) | grep '[0-9]' | sed -e 'q' |\
  2782                        sed -e 's/^/#/' \
  2783                            -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\).*$/\1[\2]/' \
  2784                            -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  2785                            -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
  2786                            -e 's/^#.*$//'`
  2787                     case "`util_lower ${n}`" in
  2788                         redhat )
  2789                             if [ ".`egrep '(Red Hat Enterprise Linux|CentOS)' /etc/${tagfile}`" != . ]; then
  2790                                 n="<R>ed <H>at <E>nterprise <L>inux"
  2791                             else
  2792                                 n="<R>ed <H>at <L>inux"
  2793                             fi
  2794                             ;;
  2795                         debian             ) n="Debian[ GNU/Linux]"        ;;
  2796                         ubuntu             ) n="Ubuntu[ GNU/Linux]"        ;;
  2797                         fedora             ) n="<Fedora> Core[ GNU/Linux]" ;;
  2798                         suse               ) n="[Novell ]SUSE[ Linux]"     ;;
  2799                         mandrake*|mandriva ) n="Mandriva[ Linux]"          ;;
  2800                         gentoo             ) n="Gentoo[ GNU/Linux]"        ;;
  2801                         slackware          ) n="Slackware[ Linux]"         ;;
  2802                         turbolinux         ) n="TurboLinux"                ;;
  2803                         unitedlinux        ) n="UnitedLinux"               ;;
  2804                         *                  ) n="${n}[ GNU/Linux]"          ;;
  2805                     esac
  2806                     case "$n" in
  2807                         *"<"*">"* ) SP="$n <$v>" ;;
  2808                         *         ) SP="$n $v"   ;;
  2809                     esac
  2810                     break
  2811                 done
  2812             fi
  2813             [ ".$SP" = . ] && SP="${ST}"
  2814             [ ".$SC" = . ] && SC="LSB"
  2815             ;;
  2817         #   Sun Solaris
  2818         *:SunOS:* )
  2819             #   determine architecture
  2820             AT="${UNAME_MACHINE}"
  2821             case "${AT}" in
  2822                 i86pc )
  2823                     AT="iX86"
  2824                     case "`(/bin/isainfo -k) 2>&1`" in
  2825                         amd64 ) AT="AMD64" ;;
  2826                     esac
  2827                     ;;
  2828             esac
  2829             AP="${AT}"
  2830             case "${AP}" in
  2831                 sun4[cdm] ) AP="SPARC32" ;;
  2832                 sun4[uv]  ) AP="SPARC64" ;;
  2833                 sun4*     ) AP="SPARC"   ;;
  2834             esac
  2835             AC="${AP}"
  2836             case "${AC}" in
  2837                 SPARC* ) AC="SPARC" ;;
  2838             esac
  2839             #   determine system
  2840             ST="[Sun ]SunOS ${UNAME_RELEASE}"
  2841             v=`echo "${UNAME_RELEASE}" |\
  2842                sed -e 's;^4\.;1.;' \
  2843                    -e 's;^5\.\([0-6]\)[^0-9]*$;2.\1;' \
  2844                    -e 's;^5\.\([0-9][0-9]*\).*;\1;'`
  2845             SP="[Sun ]Solaris $v"
  2846             case "${UNAME_RELEASE}" in
  2847                 4.* ) SC="4.3BSD" ;;
  2848                 5.* ) SC="SVR4"   ;;
  2849             esac
  2850             ;;
  2852         #   SCO UnixWare
  2853         *:UnixWare:* )
  2854             #   determine architecture
  2855             AT="${UNAME_MACHINE}"
  2856             case "${AT}" in
  2857                 i[3-6]86 | ix86at ) AT="iX86" ;;
  2858             esac
  2859             AP="${AT}"
  2860             #   determine system
  2861             v=`/sbin/uname -v`
  2862             ST="[SCO ]UnixWare ${v}"
  2863             SP="${ST}"
  2864             SC="SVR${UNAME_RELEASE}"
  2865             ;;
  2867         #   QNX
  2868         *:QNX:* )
  2869             #   determine architecture
  2870             AT="${UNAME_MACHINE}"
  2871             case "${AT}" in
  2872                 x86pc ) AT="iX86" ;;
  2873             esac
  2874             AP="${AT}"
  2875             #   determine system
  2876             v="${UNAME_RELEASE}"
  2877             ST="QNX[ Neutrino RTOS] ${v}"
  2878             v=`echo "${v}" | sed -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\).*$;\1;'`
  2879             SP="QNX[ Neutrino RTOS] ${v}"
  2880             SC="QNX"
  2881             ;;
  2883         #   SGI IRIX
  2884         *:IRIX*:* )
  2885             #   determine architecture
  2886             AT="${UNAME_MACHINE}"
  2887             AP="${AT}"
  2888             case "${AP}:${UNAME_SYSTEM}" in
  2889                 IP*:IRIX64 ) AP="MIPS64" ;;
  2890                 IP*:*      ) AP="MIPS"   ;;
  2891             esac
  2892             AC="${AP}"
  2893             #   determine system
  2894             v=`(/bin/uname -R || /bin/uname -r) 2>/dev/null | sed -e 's;[0-9.]* ;;'`
  2895             ST="[SGI ]IRIX ${v}"
  2896             v="${UNAME_RELEASE}"
  2897             SP="[SGI ]IRIX ${v}"
  2898             SC="4.2BSD/SVR3"
  2899             ;;
  2901         #   HP HP-UX
  2902         *:HP-UX:* )
  2903             #   determine architecture
  2904             AT="${UNAME_MACHINE}"
  2905             case "${AT}" in
  2906                 ia64 ) AT="IA64" ;;
  2907                 9000/[34]?? ) AT=M68K ;;
  2908                 9000/[678][0-9][0-9])
  2909                     sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
  2910                     sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
  2911                     case "${sc_cpu_version}" in
  2912                         523 ) AT="HPPA1.0" ;;
  2913                         528 ) AT="HPPA1.1" ;;
  2914                         532 ) AT="HPPA2.0"
  2915                             case "${sc_kernel_bits}" in
  2916                                 32 ) AT="${AT}n" ;;
  2917                                 64 ) AT="${AT}w" ;;
  2918                             esac
  2919                             ;;
  2920                     esac
  2921                     ;;
  2922             esac
  2923             AP="${AT}"
  2924             case "${AP}" in
  2925                 HPPA* ) AP="HPPA" ;;
  2926             esac
  2927             AC="${AP}"
  2928             #   determine system
  2929             v=`echo "${UNAME_RELEASE}" | sed -e 's;^[^0-9]*;;'`
  2930             ST="[HP ]<HP>-<UX ${v}>"
  2931             SP="${ST}"
  2932             case "${v}" in
  2933                 10.*   ) SC="SVR4.2" ;;
  2934                 [7-9]* ) SC="SVR4"   ;;
  2935             esac
  2936             ;;
  2938         #   HP Tru64 (OSF1)
  2939         *:OSF1:* )
  2940             #   determine architecture
  2941             AP="${UNAME_MACHINE}"
  2942             case "${AP}" in
  2943                 alpha ) AP="Alpha" ;;
  2944             esac
  2945             alpha_type=`(/usr/sbin/psrinfo -v) 2>/dev/null |\
  2946                 sed -n -e 's/^.*The alpha \([^ ][^ ]*\).*processor.*$/\1/p' | sed -e 'q'`
  2947             AT="${AP}${alpha_type}"
  2948             AC="${AP}"
  2949             #   determine system
  2950             v=`echo "${UNAME_RELEASE}" | sed -e 's;^[VTX];;'`
  2951             ST="[HP ]Tru64 ${v}"
  2952             SP="${ST}"
  2953             SC="OSF1"
  2954             ;;
  2956         #   IBM AIX
  2957         *:AIX:* )
  2958             #   determine architecture
  2959             cpu_arch=RS6000
  2960             if [ -x /usr/sbin/lsdev -a -x /usr/sbin/lsattr ]; then
  2961                 cpu_id=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
  2962                 if [ ".`/usr/sbin/lsattr -El ${cpu_id} | grep -i powerpc`" != . ]; then
  2963                     cpu_arch=PPC
  2964                 fi
  2965             elif [ -d /QOpenSys ]; then
  2966                 #   IBM i5/OS (aka OS/400) with PASE (Portable Application Solutions Environment)
  2967                 cpu_arch=PPC
  2968             fi
  2969             if [ -x /usr/bin/oslevel ]; then
  2970                 os_level=`/usr/bin/oslevel`
  2971             else
  2972                 os_level="`uname -v`.`uname -r`"
  2973             fi
  2974             os_level=`echo "${os_level}" |\
  2975                       sed -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\)\(.*\)$;<\1>\2[\3];' \
  2976                           -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\)\(.*\)$;<\1>\2;'`
  2977             AT="${cpu_arch}"
  2978             AP="${AT}"
  2979             AC="${AP}"
  2980             #   determine system
  2981             ST="[IBM ]<AIX >${os_level}"
  2982             SP="${ST}"
  2983             case "${os_level}" in
  2984                 [12]* ) SC="SVR2" ;;
  2985                 *     ) SC="SVR4" ;;
  2986             esac
  2987             ;;
  2989         #   Apple Mac OS X (Darwin)
  2990         *:Darwin:* )
  2991             #   determine architecture
  2992             AT="`uname -p`"
  2993             case "${AT}" in
  2994                 powerpc ) AT="PPC" ;;
  2995             esac
  2996             AP="${AT}"
  2997             case "${AP}" in
  2998                 i?86 ) AP="iX86" ;;
  2999             esac
  3000             AC="${AP}"
  3001             #   determine system
  3002             unset v1; unset v2; unset v3
  3003             eval `echo "${UNAME_RELEASE}" |\
  3004                   sed -e 's/^/#/' \
  3005                       -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"; v3="\3"/' \
  3006                       -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"/' \
  3007                       -e 's/^#\([0-9][0-9]*\).*$/v1="\1"/' \
  3008                       -e 's/^#.*$/v1="0"/'`
  3009             ST="[Apple ]<${UNAME_SYSTEM} ${v1}>${v2+.$v2}${v3+[.$v3]}"
  3010             SP="$ST"
  3011             v="`(sw_vers) 2>/dev/null | grep 'ProductVersion:' | sed -e 's/^ProductVersion:[^0-9]*\([0-9][0-9.]*\).*$/\1/'`"
  3012             if [ ".$v" = . ]; then
  3013                 for name in System Server; do
  3014                     if [ -f /System/Library/CoreServices/${name}Version.plist ]; then
  3015                         v=`(defaults read "/System/Library/CoreServices/${name}Version" "ProductVersion") 2>/dev/null`
  3016                         [ ".$v" != . ] && break
  3017                     fi
  3018                 done
  3019             fi
  3020             if [ ".$v" != . ]; then
  3021                 unset v1; unset v2; unset v3
  3022                 eval `echo "${v}" |\
  3023                       sed -e 's/^/#/' \
  3024                           -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"; v3="\3"/' \
  3025                           -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"/' \
  3026                           -e 's/^#\([0-9][0-9]*\).*$/v1="\1"/' \
  3027                           -e 's/^#.*$/v1="0"/'`
  3028                 SP="[Apple ]Mac OS X ${v1}${v2+.$v2}${v3+[.$v3]}"
  3029             fi
  3030             SC="4.4BSD/Mach3.0"
  3031             ;;
  3033         #   Windows/Cygwin
  3034         *:CYGWIN*:* )
  3035             #   determine architecture
  3036             AT="`uname -m`"
  3037             AP="${AT}"
  3038             case "${AP}" in
  3039                 i?86 ) AP="iX86" ;;
  3040             esac
  3041             AC="${AP}"
  3042             #   determine system
  3043             unset v1; unset v2; unset v3
  3044             eval `echo "${UNAME_RELEASE}" |\
  3045                   sed -e 's/^/#/' \
  3046                       -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"; v3="\3"/' \
  3047                       -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"/' \
  3048                       -e 's/^#\([0-9][0-9]*\).*$/v1="\1"/' \
  3049                       -e 's/^#.*$/v1="0"/'`
  3050             ST="Cygwin ${v1}${v2+.$v2}${v3+[.$v3]}"
  3051             SP="$ST"
  3052             SC="Windows"
  3053             v=`echo "${UNAME_SYSTEM}" | sed -e 's/^CYGWIN_NT-//' |\
  3054                sed -e 's/^/#/' -e 's/^#\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' -e 's/^#.*$//'`
  3055             case "$v" in
  3056                 4.0 ) SC="$SC[ NT]"    ;;
  3057                 5.0 ) SC="$SC[ 2000]"  ;;
  3058                 5.1 ) SC="$SC[ XP]"    ;;
  3059                 6.0 ) SC="$SC[ Vista]" ;;
  3060             esac
  3061             ;;
  3063         #   TODO ...ADD YOUR NEW PLATFORM CHECK HERE... TODO
  3064         # *:XXX:* )
  3065         #   ...
  3066         #   ;;
  3068         #   ...A STILL UNKNOWN PLATFORM...
  3069         * )
  3070             AT=`echo "${UNAME_MACHINE}" | sed -e "s; ;${opt_C};g"`
  3071             AP="${AT}"
  3072             AC="${AP}"
  3073             v=`echo "${UNAME_RELEASE}" |\
  3074                sed -e 's/^/#/' \
  3075                    -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  3076                    -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  3077                    -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
  3078                    -e 's/^#.*$/?/'`
  3079             ST="${UNAME_SYSTEM} ${v}"
  3080             SP="${ST}"
  3081             SC="${SP}"
  3082             ;;
  3084     esac
  3086     #   provide fallback values
  3087     [ ".$AT" = . ] && AT="${AP:-${AC}}"
  3088     [ ".$AP" = . ] && AP="${AT:-${AC}}"
  3089     [ ".$AC" = . ] && AC="${AP:-${AT}}"
  3090     [ ".$ST" = . ] && ST="${SP:-${SC}}"
  3091     [ ".$SP" = . ] && SP="${ST:-${SC}}"
  3092     [ ".$SC" = . ] && SC="${SP:-${ST}}"
  3094     #   support explicit enforced verbose/concise output
  3095     if [ ".$opt_v" = .yes ]; then
  3096         opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%[\1]/g'`
  3097     elif [ ".$opt_c" = .yes ]; then
  3098         opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%<\1>/g'`
  3099     fi
  3101     #   provide verbose and concise variants
  3102     AC_V=""; AC_N=""; AC_C=""
  3103     AP_V=""; AP_N=""; AP_C=""
  3104     AT_V=""; AT_N=""; AT_C=""
  3105     SC_V=""; SC_N=""; SC_C=""
  3106     SP_V=""; SP_N=""; SP_C=""
  3107     ST_V=""; ST_N=""; ST_C=""
  3108     for var_lc in at ap ac st sp sc; do
  3109         case "$opt_F" in
  3110             *"%[${val_lc}]"* | *"%{${val_lc}}"* | *"%${val_lc}"* | *"%<${val_lc}>"* )
  3111             var_uc=`util_upper "$var_lc"`
  3112             eval "val=\"\$${var_uc}\""
  3113             val_V=""; val_N=""; val_C=""
  3114             case "$opt_F" in
  3115                 *"%[${var_lc}]"* )
  3116                     val_V=`echo ":$val" | \
  3117                            sed -e 's/^://' \
  3118                                -e 's;\[\([^]]*\)\];\1;g' \
  3119                                -e 's;<\([^>]*\)>;\1;g' \
  3120                                -e "s; ;§§;g" \
  3121                                -e "s;/;%%;g" \
  3122                                -e "s;§§;${opt_S};g" \
  3123                                -e "s;%%;${opt_C};g"`
  3124                     eval "${var_uc}_V=\"\${val_V}\""
  3125                     ;;
  3126             esac
  3127             case "$opt_F" in
  3128                 *"%{${var_lc}}"* | *"%${var_lc}"* )
  3129                     val_N=`echo ":$val" | \
  3130                            sed -e 's/^://' \
  3131                                -e 's;\[\([^]]*\)\];;g' \
  3132                                -e 's;<\([^>]*\)>;\1;g' \
  3133                                -e "s; ;§§;g" \
  3134                                -e "s;/;%%;g" \
  3135                                -e "s;§§;${opt_S};g" \
  3136                                -e "s;%%;${opt_C};g"`
  3137                     eval "${var_uc}_N=\"\${val_N}\""
  3138                     ;;
  3139             esac
  3140             case "$opt_F" in
  3141                 *"%<${var_lc}>"* )
  3142                     val_C=`echo ":$val" | \
  3143                            sed -e 's/^://' \
  3144                                -e 's;\[\([^]]*\)\];;g' \
  3145                                -e 's;[^<]*<\([^>]*\)>[^<]*;\1;g' \
  3146                                -e "s; ;§§;g" \
  3147                                -e "s;/;%%;g" \
  3148                                -e "s;§§;${opt_S};g" \
  3149                                -e "s;%%;${opt_C};g"`
  3150                     eval "${var_uc}_C=\"\${val_C}\""
  3151                     ;;
  3152             esac
  3153             ;;
  3154         esac
  3155     done
  3157     #   create output string
  3158     output=`echo ":$opt_F" |\
  3159             sed -e "s/^://" \
  3160                 -e "s;%\\[ac\\];${AC_V};g" \
  3161                 -e "s;%{ac};${AC_N};g" \
  3162                 -e "s;%ac;${AC_N};g" \
  3163                 -e "s;%<ac>;${AC_C};g" \
  3164                 -e "s;%\\[ap\\];${AP_V};g" \
  3165                 -e "s;%{ap};${AP_N};g" \
  3166                 -e "s;%ap;${AP_N};g" \
  3167                 -e "s;%<ap>;${AP_C};g" \
  3168                 -e "s;%\\[at\\];${AT_V};g" \
  3169                 -e "s;%{at};${AT_N};g" \
  3170                 -e "s;%at;${AT_N};g" \
  3171                 -e "s;%<at>;${AT_C};g" \
  3172                 -e "s;%\\[sc\\];${SC_V};g" \
  3173                 -e "s;%{sc};${SC_N};g" \
  3174                 -e "s;%sc;${SC_N};g" \
  3175                 -e "s;%<sc>;${SC_C};g" \
  3176                 -e "s;%\\[sp\\];${SP_V};g" \
  3177                 -e "s;%{sp};${SP_N};g" \
  3178                 -e "s;%sp;${SP_N};g" \
  3179                 -e "s;%<sp>;${SP_C};g" \
  3180                 -e "s;%\\[st\\];${ST_V};g" \
  3181                 -e "s;%{st};${ST_N};g" \
  3182                 -e "s;%st;${ST_N};g" \
  3183                 -e "s;%<st>;${ST_C};g" \
  3184                 -e 's/\\\\n/^/g' |\
  3185              tr '^' '\012'`
  3187     #   support lower/upper-case mapping
  3188     if [ ".$opt_L" = .yes ]; then
  3189         output=`util_lower "$output"`
  3190     elif [ ".$opt_U" = .yes ]; then
  3191         output=`util_upper "$output"`
  3192     fi
  3194     #   display output string
  3195     if [ ".$opt_n" = .yes ]; then
  3196         echo . | awk '{ printf("%s", output); }' output="$output"
  3197     else
  3198         echo "$output"
  3199     fi
  3201     shtool_exit 0
  3202     ;;
  3204 arx )
  3205     ##
  3206     ##  arx -- Extended archive command
  3207     ##  Copyright (c) 1999-2008 Ralf S. Engelschall <rse@engelschall.com>
  3208     ##
  3210     ar_prg="$opt_C"
  3211     ar_cmd="$1"; shift
  3212     archive="$1"; shift
  3213     files="$*"
  3215     #   walk through the file list and expand archives members
  3216     ar_tmpdir=`echo $archive | sed -e 's;[^/]*$;.arx;'`
  3217     nfiles=''
  3218     if [ ".$files" != . ]; then
  3219         for file in $files; do
  3220             if [ ! -f $file ]; then
  3221                 echo "$msgprefix:Error: input file not found: $file" 1>&2
  3222                 shtool_exit 1
  3223             fi
  3224             case $file in
  3225                 *.a )
  3226                     if [ ! -d $ar_tmpdir ]; then
  3227                         if [ ".$opt_t" = .yes ]; then
  3228                             echo "mkdir $ar_tmpdir" 1>&2
  3229                         fi
  3230                         mkdir $ar_tmpdir
  3231                     fi
  3232                     case $ar_tmpdir in
  3233                          .arx )
  3234                              from="../$file"
  3235                              ;;
  3236                          * )
  3237                              dir=`echo $file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'`
  3238                              base=`echo $file | sed -e 's;.*/\([^/]*\)$;\1;'`
  3239                              from="`cd $dir; pwd`/$base"
  3240                              ;;
  3241                     esac
  3242                     if [ ".$opt_t" = .yes ]; then
  3243                         echo "(cd $ar_tmpdir && $ar_prg x $from)" 1>&2
  3244                     fi
  3245                     (cd $ar_tmpdir && eval $ar_prg x $from)
  3246                     if [ $? -ne 0 ]; then
  3247                         echo "$msgprefix:Error: member extraction failed for archive: $file" 1>&2
  3248                         shtool_exit 1
  3249                     fi
  3250                     for member in - `eval $ar_prg t $file | sed -e '/_\.SYMDEF/d'`; do
  3251                         [ ".$member" = .- ] && continue
  3252                         nfiles="$nfiles $ar_tmpdir/$member"
  3253                     done
  3254                     ;;
  3255                 * )
  3256                     nfiles="$nfiles $file"
  3257                     ;;
  3258             esac
  3259         done
  3260     fi
  3262     #   run the final archive command
  3263     if [ ".$opt_t" = .yes ]; then
  3264         echo "$ar_prg $ar_cmd $archive $nfiles" 1>&2
  3265     fi
  3266     eval $ar_prg $ar_cmd $archive $nfiles
  3267     if [ $? -ne 0 ]; then
  3268         echo "$msgprefix:Error: archive command failed" 1>&2
  3269         shtool_exit $?
  3270     fi
  3272     #   cleanup and die gracefully
  3273     if [ -d $ar_tmpdir ]; then
  3274         if [ ".$opt_t" = .yes ]; then
  3275             echo "rm -rf $ar_tmpdir" 1>&2
  3276         fi
  3277         rm -rf $ar_tmpdir
  3278     fi
  3280     shtool_exit 0
  3281     ;;
  3283 slo )
  3284     ##
  3285     ##  slo -- Separate linker options by library class
  3286     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
  3287     ##
  3289     DIFS="$IFS"
  3291     #   parse out -L and -l options from command line
  3292     DIRS=''
  3293     LIBS=''
  3294     ARGV=''
  3295     optprev=''
  3296     for opt
  3297     do
  3298         #   concatenate with previous option if exists
  3299         if [ ".$optprev" != . ]; then
  3300             opt="${optprev}${opt}";
  3301             optprev=''
  3302         fi
  3303         #   remember options for arg if used stand-alone
  3304         if [ ".$opt" = ".-L" ] || [ ".$opt" = ".-l" ]; then
  3305             optprev="$opt"
  3306             continue;
  3307         fi
  3308         #   split argument into option plus option argument
  3309         arg="`echo $opt | cut -c3-`"
  3310         opt="`echo $opt | cut -c1-2`"
  3311         #   store into containers
  3312         case $opt in
  3313             -L) DIRS="$DIRS:$arg" ;;
  3314             -l) LIBS="$LIBS:$arg" ;;
  3315              *) ARGV="$ARGV $opt" ;;
  3316         esac
  3317     done
  3319     #   set linker default directories
  3320     DIRS_DEFAULT='/lib:/usr/lib'
  3321     if [ ".$LD_LIBRARY_PATH" != . ]; then
  3322         DIRS_DEFAULT="$DIRS_DEFAULT:$LD_LIBRARY_PATH"
  3323     fi
  3325     #   sort options by class
  3326     DIRS_OBJ=''
  3327     LIBS_OBJ=''
  3328     DIRS_PIC=''
  3329     LIBS_PIC=''
  3330     DIRS_DSO=''
  3331     LIBS_DSO=''
  3333     #    for each library...
  3334     OIFS="$IFS"; IFS=':'
  3335     for lib in $LIBS; do
  3336         [ ".$lib" = . ] && continue
  3338         found='no'
  3339         found_indefdir='no'
  3340         found_type=''
  3341         found_dir=''
  3343         #    for each directory...
  3344         OIFS2="$IFS"; IFS=":$DIFS"
  3345         for dir in ${DIRS} switch-to-defdirs ${DIRS_DEFAULT}; do
  3346             [ ".$dir" = . ] && continue
  3347             [ ".$dir" = .switch-to-defdirs ] && found_indefdir=yes
  3348             [ ! -d $dir ] && continue
  3350             #    search the file
  3351             OIFS3="$IFS"; IFS="$DIFS"
  3352             for file in '' `cd $dir && env -i /bin/ls lib${lib}.* 2>/dev/null`; do
  3353                  [ ".$file" = . ] && continue
  3354                  case $file in
  3355                      *.so|*.so.[0-9]*|*.sl|*.sl.[0-9]* )
  3356                           found=yes;
  3357                           found_type=DSO;
  3358                           break
  3359                           ;;
  3360                      *.lo|*.la )
  3361                           found=yes;
  3362                           found_type=PIC
  3363                           ;;
  3364                      *.a )
  3365                           if [ ".$found_type" = . ]; then
  3366                               found=yes
  3367                               found_type=OBJ
  3368                           fi
  3369                           ;;
  3370                  esac
  3371             done
  3372             IFS="$OIFS3"
  3373             if [ ".$found" = .yes ]; then
  3374                 found_dir="$dir"
  3375                 break
  3376             fi
  3377         done
  3378         IFS="$OIFS2"
  3380         if [ ".$found" = .yes ]; then
  3381             if [ ".$found_indefdir" != .yes ]; then
  3382                 eval "dirlist=\"\${DIRS_${found_type}}:\""
  3383                 case "$dirlist" in
  3384                     *:$found_dir:* ) ;;
  3385                     * ) eval "DIRS_${found_type}=\"\$DIRS_${found_type}:${found_dir}\"" ;;
  3386                 esac
  3387                 eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
  3388             else
  3389                 eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
  3390             fi
  3391         else
  3392             LIBS_OBJ="$LIBS_OBJ:$lib"
  3393             #dirlist="`echo $DIRS $DIRS_DEFAULT | sed -e 's/:/ /g'`"
  3394             #echo "slo:Warning: library \"$lib\" not found in any of the following dirs:" 2>&1
  3395             #echo "slo:Warning: $dirlist" 1>&1
  3396         fi
  3397     done
  3398     IFS="$OIFS"
  3400     #   also pass-through unused dirs even if it's useless
  3401     OIFS="$IFS"; IFS=':'
  3402     for dir in $DIRS; do
  3403         dirlist="${DIRS_OBJ}:${DIRS_PIC}:${DIRS_DSO}:"
  3404         case "$dirlist" in
  3405             *:$dir:* ) ;;
  3406             * ) DIRS_OBJ="$DIRS_OBJ:$dir" ;;
  3407         esac
  3408     done
  3409     IFS="$OIFS"
  3411     #   reassemble the options but separated by type
  3412     for type in OBJ PIC DSO; do
  3413         OIFS="$IFS"; IFS=':'
  3414         eval "libs=\"\$LIBS_${type}\""
  3415         opts=''
  3416         for lib in $libs; do
  3417             [ ".$lib" = . ] && continue
  3418             opts="$opts -l$lib"
  3419         done
  3420         eval "LIBS_${type}=\"$opts\""
  3422         eval "dirs=\"\$DIRS_${type}\""
  3423         opts=''
  3424         for dir in $dirs; do
  3425             [ ".$dir" = . ] && continue
  3426             opts="$opts -L$dir"
  3427         done
  3428         eval "DIRS_${type}=\"$opts\""
  3429         IFS="$OIFS"
  3430     done
  3432     #   give back results
  3433     for var in ARGV DIRS_OBJ LIBS_OBJ DIRS_PIC LIBS_PIC DIRS_DSO LIBS_DSO; do
  3434         eval "val=\"\$${var}\""
  3435         val="`echo $val | sed -e 's/^ *//'`"
  3436         echo "${opt_p}${var}=\"${val}\""
  3437     done
  3439     shtool_exit 0
  3440     ;;
  3442 scpp )
  3443     ##
  3444     ##  scpp -- Sharing C Pre-Processor
  3445     ##  Copyright (c) 1999-2008 Ralf S. Engelschall <rse@engelschall.com>
  3446     ##
  3448     srcs="$*"
  3449     output="${opt_o}.n"
  3451     #   find a reasonable Awk
  3452     awk=''
  3453     paths=`echo $PATH |\
  3454            sed -e 's%/*:%:%g' -e 's%/$%%' \
  3455                -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
  3456                -e 's/:/ /g'`
  3457     for name in gawk nawk awk; do
  3458         for path in $paths; do
  3459             if [ -r "$path/$name" ]; then
  3460                 awk="$path/$name"
  3461                 break
  3462             fi
  3463         done
  3464         if [ ".$awk" != . ]; then
  3465             break
  3466         fi
  3467     done
  3468     if [ ".$awk" = . ]; then
  3469         echo "$msgprefix:Error: cannot find a reasonable Awk" 1>&2
  3470         shtool_exit 1
  3471     fi
  3473     #   parse source file(s)
  3474     if [ ".$opt_v" = .yes ]; then
  3475         echo "Parsing:" | $awk '{ printf("%s", $0); }' 1>&2
  3476     fi
  3477     for src in $srcs; do
  3478         if [ ".$opt_v" = .yes ]; then
  3479             echo $src | $awk '{ printf(" %s", $0); }' 1>&2
  3480         fi
  3481         if [ ".$opt_f" != . ]; then
  3482             inputcmd="sed"
  3483             OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_f; IFS="$OIFS"
  3484             for e
  3485             do
  3486                 inputcmd="$inputcmd -e '$e'"
  3487             done
  3488             inputcmd="$inputcmd '$src'"
  3489         else
  3490             inputcmd="cat '$src'"
  3491         fi
  3492         eval $inputcmd |\
  3493         $awk '
  3494            BEGIN {
  3495                ln    = 0;
  3496                fln   = 0;
  3497                level = 0;
  3498                mode  = "";
  3499                store = "";
  3502                ln++;
  3504            /^#if.*/ {
  3505                level++;
  3507            /^#if [a-zA-Z_][a-zA-Z0-9_]* *$/ {
  3508                if ($2 == define) {
  3509                    mode = "D";
  3510                    printf("D:#line %d \"%s\"\n", ln, src);
  3511                    next;
  3514            /^#endif.*/ {
  3515                level--;
  3516                if (mode == "D" && level == 0) {
  3517                    mode = "";
  3518                    next;
  3521            /^[a-zA-Z_][a-zA-Z0-9_].*;.*/ {
  3522                if ($1 == class) {
  3523                    printf("V:#line %d \"%s\"\n", ln, src);
  3524                    printf("V:%s\n", $0);
  3525                    printf("J:%s\n", $0);
  3526                    next;
  3529            /^[a-zA-Z_][a-zA-Z0-9_].*=.*/ {
  3530                if ($1 == class) {
  3531                    printf("V:#line %d \"%s\"\n", ln, src);
  3532                    printf("V:%s\n", $0);
  3533                    printf("J:%s\n", $0);
  3534                    next;
  3537            /^[a-zA-Z_][a-zA-Z0-9_]*/ {
  3538                if ($1 == class) {
  3539                    fln = ln;
  3540                    store = $0;
  3541                    mode = "F";
  3542                    next;
  3545            /^\{ *$/ {
  3546                if (mode == "F") {
  3547                    printf("F:#line %d \"%s\"\n", fln, src);
  3548                    printf("F:%s;\n", store);
  3549                    printf("I:%s;\n", store);
  3550                    store = "";
  3551                    mode = "";
  3552                    next;
  3556                if (mode == "D")
  3557                    printf("D:%s\n", $0);
  3558                else if (mode == "F")
  3559                    store = store " " $0;
  3561         ' "src=$src" "define=$opt_D" "class=$opt_C" >>$tmpfile
  3562     done
  3563     if [ ".$opt_v" = .yes ]; then
  3564         echo "" 1>&2
  3565     fi
  3567     #   start generating output header
  3568     echo "/* $opt_o -- autogenerated from $opt_t, DO NOT EDIT! */" >$output
  3569     echo "#line 1 \"$opt_t\"" >>$output
  3570     sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd' |\
  3571     sed -e "/^${opt_M} *\$/d" >>$output
  3573     #   merge in the define blocks
  3574     grep '^D:' $tmpfile | sed -e 's/^D://' >>$output
  3576     #   generate standard prolog
  3577     echo "#line 1 \"_ON_THE_FLY_\"" >>$output
  3578     echo "" >>$output
  3579     echo "/* make sure the scpp source extensions are skipped */" >>$output
  3580     echo "#define $opt_D 0" >>$output
  3581     echo "#define $opt_C /**/" >>$output
  3583     #   generate namespace hiding for variables
  3584     echo "" >>$output
  3585     echo "/* move intern variables to hidden namespace */" >>$output
  3586     grep '^J:' $tmpfile | sed >>$output \
  3587         -e 's/^J://' \
  3588         -e 's/  */ /g' \
  3589         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\];.*$/#define \1 __\1/' \
  3590         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\] =.*$/#define \1 __\1/' \
  3591         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\);.*$/#define \1 __\1/' \
  3592         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\) =.*$/#define \1 __\1/'
  3594     #   generate namespace hiding for functions
  3595     echo "" >>$output
  3596     echo "/* move intern functions to hidden namespace */" >>$output
  3597     grep '^I:' $tmpfile | sed >>$output \
  3598         -e 's/^I://' \
  3599         -e 's/\([ (]\) */\1/g' \
  3600         -e 's/ *\([),]\)/\1/g' \
  3601         -e 's/^[^(]*[ *]\([a-zA-Z0-9_]*\)(.*$/#define \1 __\1/'
  3603     #   generate prototypes for variables
  3604     echo "" >>$output
  3605     echo "/* prototypes for intern variables */" >>$output
  3606     grep '^V:' $tmpfile | sed >>$output \
  3607         -e 's/^V://' \
  3608         -e 's/  */ /g' \
  3609         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\);.*$/\1;/' \
  3610         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\) =.*$/\1;/' \
  3611         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\);.*$/\1;/' \
  3612         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\) =.*$/\1;/' \
  3613         -e 's/ ;/;/g' \
  3614         -e "s/^$opt_C /extern /"
  3616     #   generate prototypes for functions
  3617     echo "" >>$output
  3618     echo "/* prototypes for intern functions */" >>$output
  3619     grep '^F:' $tmpfile | sed >>$output \
  3620         -e 's/^F://' \
  3621         -e 's/\([ (]\) */\1/g' \
  3622         -e 's/ *\([),]\)/\1/g' \
  3623         -e 's/\([* ]\)[a-zA-Z0-9_]*,/\1,/g' \
  3624         -e 's/\([* ]\)[a-zA-Z0-9_]*);/\1);/g' \
  3625         -e 's/(\*[a-zA-Z0-9_]*)(/(*)(/g' \
  3626         -e 's/\([ (]\) */\1/g' \
  3627         -e 's/ *\([),]\)/\1/g' \
  3628         -e "s/^$opt_C /extern /"
  3630     #   finish generating output header
  3631     n=`(echo ''; sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd') |\
  3632        wc -l | sed -e 's;^ *\([0-9]*\) *$;\1;'`
  3633     echo "#line $n \"$opt_t\"" >>$output
  3634     sed <$opt_t -e "/^${opt_M} *\$/,\$p" -e 'd' |\
  3635     sed -e "/^${opt_M} *\$/d" >>$output
  3637     #   create final output file
  3638     if [ -f $opt_o ]; then
  3639         if [ ".$opt_p" = .yes ]; then
  3640             grep -v '^#line' $opt_o  >$tmpfile.o
  3641             grep -v '^#line' $output >$tmpfile.n
  3642             out_old="$tmpfile.o"
  3643             out_new="$tmpfile.n"
  3644         else
  3645             out_old="$opt_o"
  3646             out_new="$output"
  3647         fi
  3648         if cmp -s $out_old $out_new; then
  3650         else
  3651             cp $output $opt_o
  3652         fi
  3653     else
  3654         cp $output $opt_o
  3655     fi
  3656     rm -f $output
  3657     rm -f $tmpfile $tmpfile.* >/dev/null 2>&1
  3659     shtool_exit 0
  3660     ;;
  3662 version )
  3663     ##
  3664     ##  version -- Maintain a version information file
  3665     ##  Copyright (c) 1994-2008 Ralf S. Engelschall <rse@engelschall.com>
  3666     ##
  3668     file="$1"
  3670     #   determine prefix and name
  3671     name="$opt_n"
  3672     prefix="$opt_p"
  3674     #   determine current version
  3675     triple="$opt_s"
  3676     if [ ".$triple" != . ]; then
  3677         #   use given triple
  3678         if [ ".`echo $triple | grep '[0-9]*.[0-9]*[sabp.][0-9]*'`" = . ]; then
  3679             echo "$msgprefix:Error: invalid argument to option \`-s': \`$opt_s'" 1>&2
  3680             shtool_exit 1
  3681         fi
  3682         eval `echo $triple |\
  3683               sed -e 's%\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\).*%\
  3684               ver="\1";rev="\2";typ="\3";lev="\4"%'`
  3685         tim=calc
  3686     elif [ -r $file ]; then
  3687         #   determine triple from given file
  3688         eval `grep 'Version [0-9]*.[0-9]*[sabp.][0-9]* ([0-9]*-[a-zA-Z]*-[0-9]*)' $file |\
  3689               sed -e 's%.*Version \([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\) (\([0-9]*-[a-zA-Z]*-[0-9]*\)).*%\
  3690               ver="\1";rev="\2";typ="\3";lev="\4";tim="\5"%' -e 'q'`
  3691     else
  3692         #   intialise to first version
  3693         ver=0
  3694         rev=1
  3695         typ=.
  3696         lev=0
  3697         tim=calc
  3698     fi
  3700     #   determine new version in batch
  3701     if [ ".$opt_i" != . ]; then
  3702         case $opt_i in
  3703             v ) ver=`expr $ver + 1`
  3704                 rev=0
  3705                 lev=0
  3706                 ;;
  3707             r ) rev=`expr $rev + 1`
  3708                 lev=0
  3709                 ;;
  3710             l ) lev=`expr $lev + 1`
  3711                 ;;
  3712             * ) echo "$msgprefix:Error: invalid argument to option \`-i': \`$opt_i'" 1>&2
  3713                 shtool_exit 1
  3714                 ;;
  3715         esac
  3716         tim=calc
  3717     fi
  3719     #   determine new version interactively
  3720     if [ ".$opt_e" = .yes ]; then
  3721         echo "old version: ${ver}.${rev}${typ}${lev}"
  3722         while [ 1 ]; do
  3723             echo dummy | awk '{ printf("new version: "); }'
  3724             read triple
  3725             case $triple in
  3726                 [0-9]*.[0-9]*[sabp.][0-9]* )
  3727                     ;;
  3728                 * ) echo "$msgprefix:Error: invalid version string entered: \`$triple'" 1>&2
  3729                     continue
  3730                     ;;
  3731             esac
  3732             break
  3733         done
  3734         eval `echo $triple |\
  3735               sed -e 's%^\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\)$%\
  3736               ver="\1";rev="\2";typ="\3";lev="\4"%'`
  3737         tim=calc
  3738     fi
  3740     #   determine hexadecimal and libtool value of version
  3741     case $typ in
  3742         a     ) typnum=0;  levnum=$lev ;;
  3743         b     ) typnum=1;  levnum=$lev ;;
  3744         p | . ) typnum=2;  levnum=$lev ;;
  3745         s     ) typnum=15; levnum=255  ;; # snapshots are special
  3746     esac
  3747     hex=`echo "$ver:$rev:$typnum:$levnum" |\
  3748          awk -F: '{ printf("0x%x%02x%1x%02x", $1, $2, $3, $4); }' |\
  3749          tr 'abcdef' 'ABCDEF'`
  3750     ltv=`echo "$ver:$rev:$typnum:$levnum" |\
  3751          awk -F: '{ printf("%d:%d", $1*10 + $2, $3*10 + $4); }'`
  3753     #   determine date
  3754     if [ ".$tim" = .calc ]; then
  3755         day=`date '+%d'`
  3756         month=`date '+%m'`
  3757         year=`date '+%Y' 2>/dev/null`
  3758         if [ ".$time_year" = . ]; then
  3759             year=`date '+%y'`
  3760             case $year in
  3761                 [5-9][0-9]) year="19$year" ;;
  3762                 [0-4][0-9]) year="20$year" ;;
  3763             esac
  3764         fi
  3765         case $month in
  3766             1|01) month='Jan' ;;
  3767             2|02) month='Feb' ;;
  3768             3|03) month='Mar' ;;
  3769             4|04) month='Apr' ;;
  3770             5|05) month='May' ;;
  3771             6|06) month='Jun' ;;
  3772             7|07) month='Jul' ;;
  3773             8|08) month='Aug' ;;
  3774             9|09) month='Sep' ;;
  3775               10) month='Oct' ;;
  3776               11) month='Nov' ;;
  3777               12) month='Dec' ;;
  3778         esac
  3779         tim="${day}-${month}-${year}"
  3780     fi
  3782     #   perform result actions
  3783     mode=show
  3784     if [ ".$opt_i" != . ]; then
  3785         mode=edit
  3786     elif [ ".$opt_e" = .yes ]; then
  3787         mode=edit
  3788     elif [ ".$opt_s" != . ]; then
  3789         mode=edit
  3790     fi
  3791     if [ ".$mode" = .show ]; then
  3792         #   just display the current version
  3793         case $opt_d in
  3794             short )
  3795                 echo "${ver}.${rev}${typ}${lev}"
  3796                 ;;
  3797             long )
  3798                 echo "${ver}.${rev}${typ}${lev} ($tim)"
  3799                 ;;
  3800             libtool )
  3801                 echo "${ltv}"
  3802                 ;;
  3803             hex )
  3804                 echo "${hex}"
  3805                 ;;
  3806             * ) echo "$msgprefix:Error: invalid argument to option \`-d': \`$opt_d'" 1>&2
  3807                 shtool_exit 1
  3808                 ;;
  3809         esac
  3810     else
  3811         #   update the version file
  3813         #   pre-generate various strings
  3814         triple="${ver}.${rev}${typ}${lev}"
  3815         vHex="$hex"
  3816         vShort="${triple}"
  3817         vLong="${triple} (${tim})"
  3818         vTeX="This is ${name}, Version ${triple} (${tim})"
  3819         vGNU="${name} ${triple} (${tim})"
  3820         vWeb="${name}/${triple}"
  3821         vSCCS="@(#)${name} ${triple} (${tim})"
  3822         vRCS="\$Id: ${name} ${triple} (${tim}) \$"
  3824         #   determine string out of filename
  3825         #   (do NOT try to optimize this in any way because of portability)
  3826         filestr=`util_upper "$file" | tr './%+' '____' | sed -e 's/-/_/g'`
  3828         #   generate uppercase prefix
  3829         prefixupper=`util_upper "$prefix"`
  3831         #   create the version file according the the selected language
  3832         echo "new version: ${vLong}"
  3834         cp /dev/null $file
  3835         case $opt_l in
  3836             txt )
  3837                 echo >>$file ""
  3838                 echo >>$file "  ${file} -- Version Information for ${name} (syntax: Text)"
  3839                 echo >>$file "  [automatically generated and maintained by GNU shtool]"
  3840                 echo >>$file ""
  3841                 echo >>$file "  $vTeX"
  3842                 echo >>$file ""
  3843                 ;;
  3844             c )
  3845                 echo >>$file "/*"
  3846                 echo >>$file "**  ${file} -- Version Information for ${name} (syntax: C/C++)"
  3847                 echo >>$file "**  [automatically generated and maintained by GNU shtool]"
  3848                 echo >>$file "*/"
  3849                 echo >>$file ""
  3850                 echo >>$file "#ifdef _${filestr}_AS_HEADER_"
  3851                 echo >>$file ""
  3852                 echo >>$file "#ifndef _${filestr}_"
  3853                 echo >>$file "#define _${filestr}_"
  3854                 echo >>$file ""
  3855                 echo >>$file "#define ${prefixupper}VERSION ${vHex}"
  3856                 echo >>$file ""
  3857                 echo >>$file "typedef struct {"
  3858                 echo >>$file "    const int   v_hex;"
  3859                 echo >>$file "    const char *v_short;"
  3860                 echo >>$file "    const char *v_long;"
  3861                 echo >>$file "    const char *v_tex;"
  3862                 echo >>$file "    const char *v_gnu;"
  3863                 echo >>$file "    const char *v_web;"
  3864                 echo >>$file "    const char *v_sccs;"
  3865                 echo >>$file "    const char *v_rcs;"
  3866                 echo >>$file "} ${prefix}version_t;"
  3867                 echo >>$file ""
  3868                 echo >>$file "extern ${prefix}version_t ${prefix}version;"
  3869                 echo >>$file ""
  3870                 echo >>$file "#endif /* _${filestr}_ */"
  3871                 echo >>$file ""
  3872                 echo >>$file "#else /* _${filestr}_AS_HEADER_ */"
  3873                 echo >>$file ""
  3874                 echo >>$file "#define _${filestr}_AS_HEADER_"
  3875                 echo >>$file "#include \"${file}\""
  3876                 echo >>$file "#undef  _${filestr}_AS_HEADER_"
  3877                 echo >>$file ""
  3878                 echo >>$file "${prefix}version_t ${prefix}version = {"
  3879                 echo >>$file "    ${vHex},"
  3880                 echo >>$file "    \"${vShort}\","
  3881                 echo >>$file "    \"${vLong}\","
  3882                 echo >>$file "    \"${vTeX}\","
  3883                 echo >>$file "    \"${vGNU}\","
  3884                 echo >>$file "    \"${vWeb}\","
  3885                 echo >>$file "    \"${vSCCS}\","
  3886                 echo >>$file "    \"${vRCS}\""
  3887                 echo >>$file "};"
  3888                 echo >>$file ""
  3889                 echo >>$file "#endif /* _${filestr}_AS_HEADER_ */"
  3890                 echo >>$file ""
  3891                 ;;
  3892             m4 )
  3893                 echo >>$file "##"
  3894                 echo >>$file "##  ${file} -- Version Information for ${name} (syntax: M4)"
  3895                 echo >>$file "##  [automatically generated and maintained by GNU shtool]"
  3896                 echo >>$file "##"
  3897                 echo >>$file ""
  3898                 echo >>$file "m4_define([v_hex],   [${vHex}])"
  3899                 echo >>$file "m4_define([v_short], [${vShort}])"
  3900                 echo >>$file "m4_define([v_long],  [${vLong}])"
  3901                 echo >>$file "m4_define([v_tex],   [${vTeX}])"
  3902                 echo >>$file "m4_define([v_gnu],   [${vGNU}])"
  3903                 echo >>$file "m4_define([v_web],   [${vWeb}])"
  3904                 echo >>$file "m4_define([v_sccs],  [${vSCCS}])"
  3905                 echo >>$file "m4_define([v_rcs],   [${vRCS}])"
  3906                 echo >>$file ""
  3907                 ;;
  3908             perl )
  3909                 echo >>$file "##"
  3910                 echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Perl)"
  3911                 echo >>$file "##  [automatically generated and maintained by GNU shtool]"
  3912                 echo >>$file "##"
  3913                 echo >>$file ""
  3914                 echo >>$file "our \$${prefix}version = {"
  3915                 echo >>$file "    'v_hex'   => ${vHex},"
  3916                 echo >>$file "    'v_short' => \"${vShort}\","
  3917                 echo >>$file "    'v_long'  => \"${vLong}\","
  3918                 echo >>$file "    'v_tex'   => \"${vTeX}\","
  3919                 echo >>$file "    'v_gnu'   => \"${vGNU}\","
  3920                 echo >>$file "    'v_web'   => \"${vWeb}\","
  3921                 echo >>$file "    'v_sccs'  => \"${vSCCS}\","
  3922                 echo >>$file "    'v_rcs'   => \"\\${vRCS}/\""
  3923                 echo >>$file "};"
  3924                 echo >>$file ""
  3925                 echo >>$file "1;"
  3926                 echo >>$file ""
  3927                 ;;
  3928             python )
  3929                 echo >>$file "##"
  3930                 echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Python)"
  3931                 echo >>$file "##  [automatically generated and maintained by GNU shtool]"
  3932                 echo >>$file "##"
  3933                 echo >>$file ""
  3934                 echo >>$file "class ${prefix}version:"
  3935                 echo >>$file "    v_hex       = ${vHex}"
  3936                 echo >>$file "    v_short     = \"${vShort}\""
  3937                 echo >>$file "    v_long      = \"${vLong}\""
  3938                 echo >>$file "    v_tex       = \"${vTeX}\""
  3939                 echo >>$file "    v_gnu       = \"${vGNU}\""
  3940                 echo >>$file "    v_web       = \"${vWeb}\""
  3941                 echo >>$file "    v_sccs      = \"${vSCCS}\""
  3942                 echo >>$file "    v_rcs       = \"${vRCS}\""
  3943                 echo >>$file ""
  3944                 ;;
  3945             * ) echo "$msgprefix:Error: invalid argument to option \`-l': \`$opt_l'" 1>&2
  3946                 shtool_exit 1
  3947                 ;;
  3948         esac
  3949     fi
  3951     shtool_exit 0
  3952     ;;
  3954 path )
  3955     ##
  3956     ##  path -- Deal with program paths
  3957     ##  Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
  3958     ##
  3960     namelist="$*"
  3962     #   check whether the test command supports the -x option
  3963     if [ -x /bin/sh ] 2>/dev/null; then
  3964         minusx="-x"
  3965     else
  3966         minusx="-r"
  3967     fi
  3969     #   split path string
  3970     paths="`echo $opt_p |\
  3971             sed -e 's/^:/.:/' \
  3972                 -e 's/::/:.:/g' \
  3973                 -e 's/:$/:./' \
  3974                 -e 's/:/ /g'`"
  3976     #   SPECIAL REQUEST
  3977     #   translate forward to reverse path
  3978     if [ ".$opt_r" = .yes ]; then
  3979         if [ "x$namelist" = "x." ]; then
  3980             rp='.'
  3981         else
  3982             rp=''
  3983             for pe in `IFS="$IFS/"; echo $namelist`; do
  3984                 rp="../$rp"
  3985             done
  3986         fi
  3987         echo $rp | sed -e 's:/$::'
  3988         shtool_exit 0
  3989     fi
  3991     #   SPECIAL REQUEST
  3992     #   strip out directory or base name
  3993     if [ ".$opt_d" = .yes ]; then
  3994         echo "$namelist" |\
  3995         sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'
  3996         shtool_exit 0
  3997     fi
  3998     if [ ".$opt_b" = .yes ]; then
  3999         echo "$namelist" |\
  4000         sed -e 's;.*/\([^/]*\)$;\1;'
  4001         shtool_exit 0
  4002     fi
  4004     #   MAGIC SITUATION
  4005     #   Perl Interpreter (perl)
  4006     if [ ".$opt_m" = .yes ] && [ ".$namelist" = .perl ]; then
  4007         rm -f $tmpfile >/dev/null 2>&1
  4008         touch $tmpfile
  4009         found=0
  4010         pc=99
  4011         for dir in $paths; do
  4012             dir=`echo $dir | sed -e 's;/*$;;'`
  4013             nc=99
  4014             for name in perl perl5 miniperl; do
  4015                  if [ $minusx "$dir/$name" ] && [ ! -d "$dir/$name" ]; then
  4016                      perl="$dir/$name"
  4017                      pv=`$perl -e 'printf("%.3f", $]);'`
  4018                      echo "$pv:$pc:$nc:$perl" >>$tmpfile
  4019                      found=1
  4020                  fi
  4021                  nc=`expr $nc - 1`
  4022             done
  4023             pc=`expr $pc - 1`
  4024         done
  4025         if [ $found = 1 ]; then
  4026             perl="`cat $tmpfile | sort -r -u | sed -e 'q' | cut -d: -f4`"
  4027             rm -f $tmpfile >/dev/null 2>&1
  4028             echo "$perl"
  4029             shtool_exit 0
  4030         fi
  4031         rm -f $tmpfile >/dev/null 2>&1
  4032         shtool_exit 1
  4033     fi
  4035     #   MAGIC SITUATION
  4036     #   C pre-processor (cpp)
  4037     if [ ".$opt_m" = .yes ] && [ ".$namelist" = .cpp ]; then
  4038         echo >$tmpfile.c "#include <assert.h>"
  4039         echo >>$tmpfile.c "Syntax Error"
  4040         #   1. try the standard cc -E approach
  4041         cpp="${CC-cc} -E"
  4042         (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
  4043         my_error=`grep -v '^ *+' $tmpfile.out`
  4044         if [ ".$my_error" != . ]; then
  4045             #   2. try the cc -E approach and GCC's -traditional-ccp option
  4046             cpp="${CC-cc} -E -traditional-cpp"
  4047             (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
  4048             my_error=`grep -v '^ *+' $tmpfile.out`
  4049             if [ ".$my_error" != . ]; then
  4050                 #   3. try a standalone cpp command in path and lib dirs
  4051                 for path in $paths /lib /usr/lib /usr/local/lib; do
  4052                     path=`echo $path | sed -e 's;/*$;;'`
  4053                     if [ $minusx "$path/cpp" ] && [ ! -d "$path/cpp" ]; then
  4054                         cpp="$path/cpp"
  4055                         break
  4056                     fi
  4057                 done
  4058                 if [ ".$cpp" != . ]; then
  4059                     (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
  4060                     my_error=`grep -v '^ *+' $tmpfile.out`
  4061                     if [ ".$my_error" != . ]; then
  4062                         #   ok, we gave up...
  4063                         cpp=''
  4064                     fi
  4065                 fi
  4066             fi
  4067         fi
  4068         rm -f $tmpfile >/dev/null 2>&1
  4069         rm -f $tmpfile.c $tmpfile.out >/dev/null 2>&1
  4070         if [ ".$cpp" != . ]; then
  4071             echo "$cpp"
  4072             shtool_exit 0
  4073         fi
  4074         shtool_exit 1
  4075     fi
  4077     #   STANDARD SITUATION
  4078     #   iterate over names
  4079     for name in $namelist; do
  4080         #   iterate over paths
  4081         for path in $paths; do
  4082             path=`echo $path | sed -e 's;/*$;;'`
  4083             if [ $minusx "$path/$name" ] && [ ! -d "$path/$name" ]; then
  4084                 if [ ".$opt_s" != .yes ]; then
  4085                     echo "$path/$name"
  4086                 fi
  4087                 shtool_exit 0
  4088             fi
  4089         done
  4090     done
  4092     shtool_exit 1
  4093     ;;
  4095 esac
  4097 shtool_exit 0

mercurial