openpkg/shtool

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

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

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

     1 #!/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