openpkg/shtool

Thu, 23 Apr 2009 15:20:21 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 23 Apr 2009 15:20:21 +0200
changeset 192
62106debeb75
child 428
f880f219c566
permissions
-rw-r--r--

Specify options in configuration and adapt package for virtual users.

     1 #!/bin/sh
     2 ##
     3 ##  GNU shtool -- The GNU Portable Shell Tool
     4 ##  Copyright (c) 1994-2007 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.7 (19-May-2007)
    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.7 (19-May-2007)"
    94     echo 'Copyright (c) 1994-2007 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.7 (19-May-2007)"
   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-2007 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-2007 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-2007 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-2007 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-2007 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-2007 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-2007 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-2007 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         #   now finalize source and destination directory paths
  1683         srcdir=`echo $srcdir | sed -e 's;\([^/]\)$;\1/;'`
  1684         dstdir=`echo $dstdir | sed -e 's;\([^/]\)$;\1/;'`
  1686         #   run the final link command
  1687         if [ ".$opt_t" = .yes ]; then
  1688             echo "ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase"
  1689         fi
  1690         eval ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase
  1691     done
  1693     shtool_exit 0
  1694     ;;
  1696 mkshadow )
  1697     ##
  1698     ##  mkshadow -- Make a shadow tree through symbolic links
  1699     ##  Copyright (c) 1998-2007 Ralf S. Engelschall <rse@engelschall.com>
  1700     ##
  1702     #   source and destination directory
  1703     src=`echo "$1" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
  1704     dst=`echo "$2" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
  1706     #   check whether source exists
  1707     if [ ! -d $src ]; then
  1708         echo "$msgprefix:Error: source directory not found: \`$src'" 1>&2
  1709         shtool_exit 1
  1710     fi
  1712     #   determine if one of the paths is an absolute path,
  1713     #   because then we have to use an absolute symlink
  1714     oneisabs=0
  1715     case $src in
  1716         /* ) oneisabs=1 ;;
  1717     esac
  1718     case $dst in
  1719         /* ) oneisabs=1 ;;
  1720     esac
  1722     #   determine reverse directory for destination directory
  1723     dstrevdir=''
  1724     if [ $oneisabs = 0 ]; then
  1725         #   derive reverse path from forward path
  1726         pwd=`pwd`
  1727         OIFS="$IFS"; IFS='/'
  1728         for pe in $dst; do
  1729             if [ "x$pe" = "x.." ]; then
  1730                 OIFS2="$IFS"; IFS="$DIFS"
  1731                 eval `echo "$pwd" |\
  1732                       sed -e 's:\([^/]*\)$:; dir="\1":' \
  1733                           -e 's:^\(.*\)/[^/]*;:pwd="\1";:'\
  1734                           -e 's:^;:pwd="";:'`
  1735                 dstrevdir="$dir/$dstrevdir"
  1736                 IFS="$OIFS2"
  1737             else
  1738                 dstrevdir="../$dstrevdir"
  1739             fi
  1740         done
  1741         IFS="$OIFS"
  1742     else
  1743         src="`cd $src; pwd`";
  1744     fi
  1746     #   create directory tree at destination
  1747     if [ ! -d $dst ]; then
  1748         if [ ".$opt_t" = .yes ]; then
  1749             echo "mkdir $dst" 1>&2
  1750         fi
  1751         mkdir $dst
  1752     fi
  1753     if [ ".$opt_a" = .yes ]; then
  1754         DIRS=`cd $src; find . -type d -print |\
  1755               sed -e '/^\.$/d' -e 's:^\./::'`
  1756     else
  1757         DIRS=`cd $src; find . -type d -print |\
  1758               sed -e '/\/CVS/d' -e '/^\.$/d' -e 's:^\./::'`
  1759     fi
  1760     for dir in $DIRS; do
  1761         if [ ".$opt_t" = .yes ]; then
  1762             echo "mkdir $dst/$dir" 1>&2
  1763         fi
  1764         mkdir $dst/$dir
  1765     done
  1767     #   fill directory tree with symlinks to files
  1768     if [ ".$opt_a" = .yes ]; then
  1769         FILES="`cd $src; find . -depth -print |\
  1770                 sed -e 's/^\.\///'`"
  1771     else
  1772         FILES="`cd $src; find . -depth -print |\
  1773                 sed -e '/\.o$/d' -e '/\.a$/d' -e '/\.so$/d' \
  1774                     -e '/\.cvsignore$/d' -e '/\/CVS/d' \
  1775                     -e '/\/\.#/d' -e '/\.orig$/d' \
  1776                     -e 's/^\.\///'`"
  1777     fi
  1778     for file in $FILES; do
  1779          #  don't use `-type f' above for find because of symlinks
  1780          if [ -d "$src/$file" ]; then
  1781              continue
  1782          fi
  1783          basename=`echo $file | sed -e 's:^.*/::'`
  1784          dir=`echo $file | sed -e 's:[^/]*$::' -e 's:/$::' -e 's:$:/:' -e 's:^/$::'`
  1785          from=`echo "$src/$file" | sed -e 's/^\.\///'`
  1786          to="$dst/$dir$basename"
  1787          if [ $oneisabs = 0 ]; then
  1788              if [ ".$dir" != . ]; then
  1789                  subdir=`echo $dir | sed -e 's:/$::'`
  1790                  #   derive reverse path from forward path
  1791                  revdir=''
  1792                  OIFS="$IFS"; IFS='/'
  1793                  for pe in $subdir; do
  1794                      revdir="../$revdir"
  1795                  done
  1796                  IFS="$OIFS"
  1797                  #   finalize from
  1798                  from="$revdir$from"
  1799              fi
  1800              from="$dstrevdir$from"
  1801          fi
  1802          if [ ".$opt_v" = .yes ]; then
  1803              echo "    $to" 1>&2
  1804          fi
  1805          if [ ".$opt_t" = .yes ]; then
  1806              echo "ln -s $from $to" 1>&2
  1807          fi
  1808          ln -s $from $to
  1809     done
  1811     shtool_exit 0
  1812     ;;
  1814 fixperm )
  1815     ##
  1816     ##  fixperm -- Fix file permissions inside a source tree
  1817     ##  Copyright (c) 1996-2007 Ralf S. Engelschall <rse@engelschall.com>
  1818     ##
  1820     paths="$*"
  1822     #   check whether the test command supports the -x option
  1823     if [ -x /bin/sh ] 2>/dev/null; then
  1824         minusx="-x"
  1825     else
  1826         minusx="-r"
  1827     fi
  1829     #   iterate over paths
  1830     for p in $paths; do
  1831         for file in `find $p -depth -print`; do
  1832             if [ -f $file ]; then
  1833                 if [ $minusx $file ]; then
  1834                     if [ ".$opt_v" = .yes ]; then
  1835                         echo "-rwxr-xr-x $file" 2>&1
  1836                     fi
  1837                     if [ ".$opt_t" = .yes ]; then
  1838                         echo "chmod 755 $file" 2>&1
  1839                     fi
  1840                     chmod 755 $file
  1841                 else
  1842                     if [ ".$opt_v" = .yes ]; then
  1843                         echo "-rw-r--r-- $file" 2>&1
  1844                     fi
  1845                     if [ ".$opt_t" = .yes ]; then
  1846                         echo "chmod 644 $file" 2>&1
  1847                     fi
  1848                     chmod 644 $file
  1849                 fi
  1850                 continue
  1851             fi
  1852             if [ -d $file ]; then
  1853                 if [ ".$opt_v" = .yes ]; then
  1854                     echo "drwxr-xr-x $file" 2>&1
  1855                 fi
  1856                 if [ ".$opt_t" = .yes ]; then
  1857                     echo "chmod 755 $file" 2>&1
  1858                 fi
  1859                 chmod 755 $file
  1860                 continue
  1861             fi
  1862             if [ ".$opt_v" = .yes ]; then
  1863                 echo "?????????? $file" 2>&1
  1864             fi
  1865         done
  1866     done
  1868     shtool_exit 0
  1869     ;;
  1871 rotate )
  1872     ##
  1873     ##  rotate -- Logfile rotation
  1874     ##  Copyright (c) 2001-2007 Ralf S. Engelschall <rse@engelschall.com>
  1875     ##
  1877     #   make sure we have at least one file to rotate
  1878     if [ ".$opt_n" = .0 ]; then
  1879         echo "$msgprefix:Error: invalid argument \`$opt_n' to option -n." 1>&2
  1880         shtool_exit 1
  1881     fi
  1883     #   canonicalize -s option argument
  1884     if [ ".$opt_s" != . ]; then
  1885         if [ ".`expr $opt_s : '[0-9]*$'`" != .0 ]; then
  1887         elif [ ".`expr $opt_s : '[0-9]*[Kk]$'`" != .0 ]; then
  1888             opt_s=`expr $opt_s : '\([0-9]*\)[Kk]$'`
  1889             opt_s=`expr $opt_s \* 1024`
  1890         elif [ ".`expr $opt_s : '[0-9]*[Mm]$'`" != .0 ]; then
  1891             opt_s=`expr $opt_s : '\([0-9]*\)[Mm]$'`
  1892             opt_s=`expr $opt_s \* 1048576` # 1024*1024
  1893         elif [ ".`expr $opt_s : '[0-9]*[Gg]$'`" != .0 ]; then
  1894             opt_s=`expr $opt_s : '\([0-9]*\)[Gg]$'`
  1895             opt_s=`expr $opt_s \* 1073741824` # 1024*1024*1024
  1896         else
  1897             echo "$msgprefix:Error: invalid argument \`$opt_s' to option -s." 1>&2
  1898             shtool_exit 1
  1899         fi
  1900     fi
  1902     #   option -d/-z consistency
  1903     if [ ".$opt_d" = .yes ] && [ ".$opt_z" = . ]; then
  1904         echo "$msgprefix:Error: option -d requires option -z." 1>&2
  1905         shtool_exit 1
  1906     fi
  1908     #   make sure target directory exists
  1909     if [ ".$opt_a" != . ]; then
  1910         if [ ! -d $opt_a ]; then
  1911             if [ ".$opt_f" = .no ]; then
  1912                 echo "$msgprefix:Error: archive directory \`$opt_a' does not exist." 1>&2
  1913                 shtool_exit 1
  1914             fi
  1915             mkdir $opt_a || shtool_exit $?
  1916             chmod 755 $opt_a
  1917         fi
  1918         if [ ! -w $opt_a ]; then
  1919             echo "$msgprefix:Error: archive directory \`$opt_a' not writable." 1>&2
  1920             shtool_exit 1
  1921         fi
  1922     fi
  1924     #   determine compression approach
  1925     if [ ".$opt_z" != . ]; then
  1926         comp_lvl="$opt_z"
  1927         comp_prg=""
  1928         case $comp_lvl in
  1929             *:* ) eval `echo $comp_lvl |\
  1930                         sed -e 's%^\(.*\):\(.*\)$%comp_prg="\1"; comp_lvl="\2"%'` ;;
  1931         esac
  1933         #   compression level consistency
  1934         case $comp_lvl in
  1935             [0-9] )
  1936                 ;;
  1937             * ) echo "$msgprefix:Error: invalid compression level \`$comp_lvl'" 1>&2
  1938                 shtool_exit 1
  1939                 ;;
  1940         esac
  1942         #   determine a suitable compression tool
  1943         if [ ".$comp_prg" = . ]; then
  1944             #   check whether the test command supports the -x option
  1945             if [ -x /bin/sh ] 2>/dev/null; then
  1946                 minusx="-x"
  1947             else
  1948                 minusx="-r"
  1949             fi
  1950             #   search for tools in $PATH
  1951             paths="`echo $PATH |\
  1952                     sed -e 's%/*:%:%g' -e 's%/*$%%' \
  1953                         -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
  1954                         -e 's/:/ /g'`"
  1955             for prg in bzip2 gzip compress; do
  1956                 for path in $paths; do
  1957                     if [ $minusx "$path/$prg" ] && [ ! -d "$path/$prg" ]; then
  1958                         comp_prg="$prg"
  1959                         break
  1960                     fi
  1961                 done
  1962                 if [ ".$comp_prg" != . ]; then
  1963                     break
  1964                 fi
  1965             done
  1966             if [ ".$comp_prg" = . ]; then
  1967                 echo "$msgprefix:Error: no suitable compression tool found in \$PATH" 1>&2
  1968                 shtool_exit 1
  1969             fi
  1970         fi
  1972         #   determine standard compression extension
  1973         #   and make sure it is a known tool
  1974         case $comp_prg in
  1975             */bzip2    | bzip2    ) comp_ext="bz2" comp_lvl="-$comp_lvl" ;;
  1976             */gzip     | gzip     ) comp_ext="gz"  comp_lvl="-$comp_lvl" ;;
  1977             */compress | compress ) comp_ext="Z";  comp_lvl=""           ;;
  1978             * ) echo "$msgprefix:Error: tool \`$comp_prg' is not a known compression tool" 1>&2
  1979                 shtool_exit 1
  1980                 ;;
  1981         esac
  1982         comp_suf=".$comp_ext"
  1983     fi
  1985     #   iterate over all given logfile arguments
  1986     for file in $*; do
  1987         #   make sure the logfile exists
  1988         if [ ! -f $file ]; then
  1989             if [ ".$opt_f" = .yes ]; then
  1990                 continue
  1991             fi
  1992             echo "$msgprefix:Error: logfile \`$file' not found" 1>&2
  1993             shtool_exit 1
  1994         fi
  1996         #   determine log directory (where original logfile is placed)
  1997         ldir="."
  1998         case $file in
  1999             */* ) eval `echo $file | sed -e 's%^\(.*\)/\([^/]*\)$%ldir="\1"; file="\2";%'` ;;
  2000         esac
  2002         #   determine archive directory (where rotated logfiles are placed)
  2003         adir="$ldir"
  2004         if [ ".$opt_a" != . ]; then
  2005             case "$opt_a" in
  2006                 /* | ./* ) adir="$opt_a" ;;
  2007                 * ) adir="$ldir/$opt_a"  ;;
  2008             esac
  2009         fi
  2011         #   optionally take logfile size into account
  2012         if [ ".$opt_s" != . ]; then
  2013             #   determine size of logfile
  2014             set -- `env -i /bin/ls -l "$ldir/$file" | sed -e "s;$ldir/$file;;" |\
  2015                     sed -e 's; -> .*$;;' -e 's;[ 	][ 	]*; ;g'`
  2016             n=`expr $# - 3`
  2017             eval "size=\`echo \${$n}\`"
  2019             #   skip logfile if size is still too small
  2020             if [ $size -lt $opt_s ]; then
  2021                 if [ ".$opt_v" = .yes ]; then
  2022                     echo "$ldir/$file: still too small in size -- skipping"
  2023                 fi
  2024                 continue
  2025             fi
  2026         fi
  2028         #   verbosity
  2029         if [ ".$opt_v" = .yes ]; then
  2030             echo "rotating $ldir/$file"
  2031         fi
  2033         #   execute prolog
  2034         if [ ".$opt_P" != . ]; then
  2035             if [ ".$opt_t" = .yes ]; then
  2036                 echo "$opt_P"
  2037             fi
  2038             eval $opt_P
  2039             [ $? -ne 0 ] && shtool_exit $?
  2040         fi
  2042         #   kick away out-rotated logfile
  2043         n=`expr $opt_n - 1`
  2044         n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
  2045         if [ -f "${adir}/${file}.${n}${comp_suf}" ]; then
  2046             #   optionally migrate away the out-rotated logfile
  2047             if [ ".$opt_M" != . ]; then
  2048                 if [ ".$opt_t" = .yes ]; then
  2049                     echo "$opt_M ${adir}/${file}.${n}${comp_suf}"
  2050                 fi
  2051                 eval "$opt_M ${adir}/${file}.${n}${comp_suf}"
  2052                 [ $? -ne 0 ] && shtool_exit $?
  2053             fi
  2054             #   finally get rid of the out-rotated logfile
  2055             if [ ".$opt_t" = .yes ]; then
  2056                 echo "rm -f ${adir}/${file}.${n}${comp_suf}"
  2057             fi
  2058             rm -f ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2059         fi
  2061         #   rotate already archived logfiles
  2062         while [ $n -gt 0 ]; do
  2063             m=$n
  2064             n=`expr $n - 1`
  2065             n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
  2066             if [ $n -eq 0 ] && [ ".$opt_d" = .yes ]; then
  2067                 #   special case: first rotation file under delayed compression situation
  2068                 if [ ! -f "${adir}/${file}.${n}" ]; then
  2069                     continue
  2070                 fi
  2072                 #   compress file (delayed)
  2073                 if [ ".$opt_b" = .yes ]; then
  2074                     if [ ".$opt_t" = .yes ]; then
  2075                         echo "mv ${adir}/${file}.${n} ${adir}/${file}.${m}"
  2076                     fi
  2077                     mv ${adir}/${file}.${n} ${adir}/${file}.${m} || shtool_exit $?
  2078                     if [ ".$opt_t" = .yes ]; then
  2079                         echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${m} >${adir}/${file}.${m}${comp_suf}; rm -f ${adir}/${file}.${m}) &"
  2080                     fi
  2081                     ( ${comp_prg} ${comp_lvl} \
  2082                           <${adir}/${file}.${m} \
  2083                           >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2084                       rm -f ${adir}/${file}.${m} || shtool_exit $?
  2085                     ) </dev/null >/dev/null 2>&1 &
  2086                 else
  2087                     if [ ".$opt_t" = .yes ]; then
  2088                         echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${m}${comp_suf}"
  2089                     fi
  2090                     ${comp_prg} ${comp_lvl} \
  2091                         <${adir}/${file}.${n} \
  2092                         >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2093                     if [ ".$opt_t" = .yes ]; then
  2094                         echo "rm -f ${adir}/${file}.${n}"
  2095                     fi
  2096                     rm -f ${adir}/${file}.${n} || shtool_exit $?
  2097                 fi
  2099                 #   fix file attributes
  2100                 if [ ".$opt_o" != . ]; then
  2101                     if [ ".$opt_t" = .yes ]; then
  2102                         echo "chown $opt_o ${adir}/${file}.${m}${comp_suf}"
  2103                     fi
  2104                     chown $opt_o ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2105                 fi
  2106                 if [ ".$opt_g" != . ]; then
  2107                     if [ ".$opt_t" = .yes ]; then
  2108                         echo "chgrp $opt_g ${adir}/${file}.${m}${comp_suf}"
  2109                     fi
  2110                     chgrp $opt_g ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2111                 fi
  2112                 if [ ".$opt_m" != . ]; then
  2113                     if [ ".$opt_t" = .yes ]; then
  2114                         echo "chmod $opt_m ${adir}/${file}.${m}${comp_suf}"
  2115                     fi
  2116                     chmod $opt_m ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2117                 fi
  2118             else
  2119                 #   standard case: second and following rotation file
  2120                 if [ ! -f "${adir}/${file}.${n}${comp_suf}" ]; then
  2121                     continue
  2122                 fi
  2123                 if [ ".$opt_t" = .yes ]; then
  2124                     echo "mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf}"
  2125                 fi
  2126                 mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
  2127             fi
  2128         done
  2130         #   move away current logfile
  2131         if [ ".$opt_c" = .yes ]; then
  2132             #   approach: copy[+truncate]
  2133             if [ ".$opt_t" = .yes ]; then
  2134                 echo "cp -p ${ldir}/${file} ${adir}/${file}.${n}"
  2135             fi
  2136             cp -p ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
  2137             if [ ".$opt_r" = .no ]; then
  2138                 if [ ".$opt_t" = .yes ]; then
  2139                     echo "cp /dev/null ${ldir}/${file}"
  2140                 fi
  2141                 cp /dev/null ${ldir}/${file} || shtool_exit $?
  2142             fi
  2143         else
  2144             #   approach: move[+touch]
  2145             if [ ".$opt_t" = .yes ]; then
  2146                 echo "mv ${ldir}/${file} ${adir}/${file}.${n}"
  2147             fi
  2148             mv ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
  2149             if [ ".$opt_r" = .no ]; then
  2150                 if [ ".$opt_t" = .yes ]; then
  2151                     echo "touch ${ldir}/${file}"
  2152                 fi
  2153                 touch ${ldir}/${file} || shtool_exit $?
  2154                 #   fix file attributes
  2155                 if [ ".$opt_o" != . ]; then
  2156                     if [ ".$opt_t" = .yes ]; then
  2157                         echo "chown $opt_o ${ldir}/${file}"
  2158                     fi
  2159                     chown $opt_o ${ldir}/${file} || shtool_exit $?
  2160                 fi
  2161                 if [ ".$opt_g" != . ]; then
  2162                     if [ ".$opt_t" = .yes ]; then
  2163                         echo "chgrp $opt_g ${ldir}/${file}"
  2164                     fi
  2165                     chgrp $opt_g ${ldir}/${file} || shtool_exit $?
  2166                 fi
  2167                 if [ ".$opt_m" != . ]; then
  2168                     if [ ".$opt_t" = .yes ]; then
  2169                         echo "chmod $opt_m ${ldir}/${file}"
  2170                     fi
  2171                     chmod $opt_m ${ldir}/${file} || shtool_exit $?
  2172                 fi
  2173             fi
  2174         fi
  2176         #   regular compression step
  2177         if [ ".$opt_z" != . ] && [ ".$opt_d" = .no ]; then
  2178             #   compress file
  2179             if [ ".$opt_b" = .yes ]; then
  2180                 if [ ".$opt_t" = .yes ]; then
  2181                     echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}; rm -f ${adir}/${file}.${n}) &"
  2182                 fi
  2183                 ( ${comp_prg} ${comp_lvl} \
  2184                       <${adir}/${file}.${n} \
  2185                       >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2186                   rm -f ${adir}/${file}.${n} || shtool_exit $?
  2187                 ) </dev/null >/dev/null 2>&1 &
  2188             else
  2189                 if [ ".$opt_t" = .yes ]; then
  2190                     echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}"
  2191                 fi
  2192                 ${comp_prg} ${comp_lvl} \
  2193                     <${adir}/${file}.${n} \
  2194                     >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2195                 if [ ".$opt_t" = .yes ]; then
  2196                     echo "rm -f ${opt_a}${file}.${n}"
  2197                 fi
  2198                 rm -f ${adir}/${file}.${n} || shtool_exit $?
  2199             fi
  2201             #   fix file attributes
  2202             if [ ".$opt_o" != . ]; then
  2203                 if [ ".$opt_t" = .yes ]; then
  2204                     echo "chown $opt_o ${adir}/${file}.${n}${comp_suf}"
  2205                 fi
  2206                 chown $opt_o ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2207             fi
  2208             if [ ".$opt_g" != . ]; then
  2209                 if [ ".$opt_t" = .yes ]; then
  2210                     echo "chgrp $opt_g ${adir}/${file}.${n}${comp_suf}"
  2211                 fi
  2212                 chgrp $opt_g ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2213             fi
  2214             if [ ".$opt_m" != . ]; then
  2215                 if [ ".$opt_t" = .yes ]; then
  2216                     echo "chmod $opt_m ${adir}/${file}.${n}${comp_suf}"
  2217                 fi
  2218                 chmod $opt_m ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
  2219             fi
  2220         fi
  2222         #   execute epilog
  2223         if [ ".$opt_E" != . ]; then
  2224             if [ ".$opt_t" = .yes ]; then
  2225                 echo "$opt_E"
  2226             fi
  2227             eval $opt_E
  2228             [ $? -ne 0 ] && shtool_exit $?
  2229         fi
  2230     done
  2232     shtool_exit 0
  2233     ;;
  2235 tarball )
  2236     ##
  2237     ##  tarball -- Roll distribution tarballs
  2238     ##  Copyright (c) 1999-2007 Ralf S. Engelschall <rse@engelschall.com>
  2239     ##
  2241     srcs="$*"
  2243     #   check whether the test command supports the -x option
  2244     if [ -x /bin/sh ] 2>/dev/null; then
  2245         minusx="-x"
  2246     else
  2247         minusx="-r"
  2248     fi
  2250     #   find the tools
  2251     paths="`echo $PATH |\
  2252             sed -e 's%/*:%:%g' -e 's%/*$%%' \
  2253                 -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
  2254                 -e 's/:/ /g'`"
  2255     for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do
  2256         prg=`echo $spec | sed -e 's/:.*$//'`
  2257         tools=`echo $spec | sed -e 's/^.*://'`
  2258         eval "prg_${prg}=''"
  2259         #   iterate over tools
  2260         for tool in `echo $tools | sed -e 's/,/ /g'`; do
  2261             #   iterate over paths
  2262             for path in $paths; do
  2263                 if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then
  2264                     eval "prg_${prg}=\"$path/$tool\""
  2265                     break
  2266                 fi
  2267             done
  2268             eval "val=\$prg_${prg}"
  2269             if [ ".$val" != . ]; then
  2270                 break
  2271             fi
  2272         done
  2273     done
  2275     #   expand source paths
  2276     exclude=''
  2277     for pat in `echo $opt_e | sed 's/,/ /g'`; do
  2278         exclude="$exclude | grep -v '$pat'"
  2279     done
  2280     if [ ".$opt_t" = .yes ]; then
  2281         echo "cp /dev/null $tmpfile.lst" 1>&2
  2282     fi
  2283     cp /dev/null $tmpfile.lst
  2284     for src in $srcs; do
  2285         if [ -d $src ]; then
  2286             if [ ".$opt_t" = .yes ]; then
  2287                 echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2
  2288             fi
  2289             (cd $src && $prg_find . -type f -depth -print) |\
  2290             sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst
  2291         else
  2292             if [ ".$opt_t" = .yes ]; then
  2293                 echo "echo $src >>$tmpfile.lst" 1>&2
  2294             fi
  2295             echo $src >>$tmpfile.lst
  2296         fi
  2297     done
  2298     sort <$tmpfile.lst >$tmpfile.lst.n
  2299     mv $tmpfile.lst.n $tmpfile.lst
  2300     if [ ".$opt_v" = .yes ]; then
  2301         cat $tmpfile.lst | sed -e 's/^/  /' 1>&2
  2302     fi
  2304     #   determine tarball file and directory name
  2305     if [ ".$opt_o" != . ]; then
  2306         tarfile="$opt_o"
  2307         if [ ".$opt_d" != . ]; then
  2308             tarname="$opt_d"
  2309         else
  2310             tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'`
  2311         fi
  2312     else
  2313         if [ ".$opt_d" != . ]; then
  2314             tarname="$opt_d"
  2315         elif [ -d "$from" ]; then
  2316             tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'`
  2317         else
  2318             tarname="out"
  2319         fi
  2320         tarfile="$tarname.tar"
  2321     fi
  2323     #   roll the tarball
  2324     compress=''
  2325     if [ ".$opt_c" != . ]; then
  2326         compress="| $opt_c"
  2327     fi
  2328     if [ ".$prg_tardy" != . ]; then
  2329         #   the elegant hackers way
  2330         tardy_opt="--prefix=$tarname"
  2331         tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security!
  2332         if [ ".$opt_u" != . ]; then
  2333             tardy_opt="$tardy_opt --user_name=$opt_u"
  2334         fi
  2335         if [ ".$opt_g" != . ]; then
  2336             tardy_opt="$tardy_opt --group_name=$opt_g"
  2337         fi
  2338         if [ ".$opt_t" = .yes ]; then
  2339             echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2
  2340         fi
  2341         cat $tmpfile.lst |\
  2342         xargs $prg_tar cf - |\
  2343         $prg_tardy $tardy_opt |\
  2344         eval cat $compress >$tmpfile.out
  2345         if [ ".$opt_t" = .yes ]; then
  2346             echo "cp $tmpfile.out $tarfile" 1>&2
  2347         fi
  2348         cp $tmpfile.out $tarfile
  2349     else
  2350         #  the portable standard way
  2351         if [ ".$opt_t" = .yes ]; then
  2352             echo "mkdir $tmpdir/$tarname" 1>&2
  2353         fi
  2354         mkdir $tmpdir/$tarname || shtool_exit 1
  2355         if [ ".$opt_t" = .yes ]; then
  2356             echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2
  2357         fi
  2358         cat $tmpfile.lst |\
  2359         xargs $prg_tar cf - |\
  2360         (cd $tmpdir/$tarname && $prg_tar xf -)
  2361         if [ ".$opt_u" != . ]; then
  2362             if [ ".$opt_t" = .yes ]; then
  2363                 echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1
  2364             fi
  2365             chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\
  2366             echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)"
  2367         fi
  2368         if [ ".$opt_g" != . ]; then
  2369             if [ ".$opt_t" = .yes ]; then
  2370                 echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1
  2371             fi
  2372             chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\
  2373             echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)"
  2374         fi
  2375         if [ ".$opt_t" = .yes ]; then
  2376             echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2
  2377         fi
  2378         (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\
  2379         eval cat $compress >$tmpfile.out
  2380         if [ ".$opt_t" = .yes ]; then
  2381             echo "cp $tmpfile.out $tarfile" 1>&2
  2382         fi
  2383         cp $tmpfile.out $tarfile
  2384         if [ ".$opt_t" = .yes ]; then
  2385             echo "rm -rf $tmpdir/$tarname" 1>&2
  2386         fi
  2387         rm -rf $tmpdir/$tarname
  2388     fi
  2390     #   cleanup
  2391     if [ ".$opt_t" = .yes ]; then
  2392         echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2
  2393     fi
  2394     rm -f $tmpfile.lst $tmpfile.out
  2396     shtool_exit 0
  2397     ;;
  2399 subst )
  2400     ##
  2401     ##  subst -- Apply sed(1) substitution operations
  2402     ##  Copyright (c) 2001-2007 Ralf S. Engelschall <rse@engelschall.com>
  2403     ##
  2405     #   remember optional list of file(s)
  2406     files="$*"
  2407     files_num="$#"
  2409     #   parameter consistency check
  2410     if [ $# -eq 0 ] && [ ".$opt_b" != . ]; then
  2411         echo "$msgprefix:Error: option -b cannot be applied to stdin" 1>&2
  2412         shtool_exit 1
  2413     fi
  2414     if [ $# -eq 0 ] && [ ".$opt_s" = .yes ]; then
  2415         echo "$msgprefix:Error: option -s cannot be applied to stdin" 1>&2
  2416         shtool_exit 1
  2417     fi
  2419     #   build underlying sed(1) command
  2420     sedcmd='sed'
  2421     if [ ".$opt_e" != . ]; then
  2422         OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
  2423         for e
  2424         do
  2425             sedcmd="$sedcmd -e '$e'"
  2426         done
  2427     elif [ ".$opt_f" != . ]; then
  2428         if [ ! -f $opt_f ]; then
  2429             echo "$msgprefix:Error: command file \`$opt_f' not found or not a regular file" 1>&2
  2430             shtool_exit 1
  2431         fi
  2432         sedcmd="$sedcmd -f '$opt_f'"
  2433     else
  2434         echo "$msgprefix:Error: either -e option(s) or -f option required" 1>&2
  2435         shtool_exit 1
  2436     fi
  2438     #   determine extension for original file
  2439     orig=".orig"
  2440     if [ ".$opt_b" != . ]; then
  2441         orig="$opt_b"
  2442     fi
  2444     #   apply sed(1) operation(s)
  2445     if [ ".$files" != . ]; then
  2446         #   apply operation(s) to files
  2447         substdone=no
  2448         for file in $files; do
  2449             test ".$file" = . && continue
  2450             if [ ! -f $file ]; then
  2451                 echo "$msgprefix:Warning: file \`$file' not found or not a regular file" 1>&2
  2452                 continue
  2453             fi
  2455             #   handle interactive mode
  2456             if [ ".$opt_i" = .yes ]; then
  2457                 eval "$sedcmd <$file >$file.new"
  2458                 skip=no
  2459                 if cmp $file $file.new >/dev/null 2>&1; then
  2460                     rm -f $file.new
  2461                     skip=yes
  2462                 else
  2463                     (diff -U1 $file $file.new >$tmpfile) 2>/dev/null
  2464                     if [ ".`cat $tmpfile`" = . ]; then
  2465                         (diff -C1 $file $file.new >$tmpfile) 2>/dev/null
  2466                         if [ ".`cat $tmpfile`" = . ]; then
  2467                             echo "$msgprefix:Warning: unable to show difference for file \`$file'" 1>&2
  2468                             cp /dev/null $tmpfile
  2469                         fi
  2470                     fi
  2471                     rm -f $file.new
  2472                     cat $tmpfile
  2473                     echo dummy | awk '{ printf("%s", TEXT); }' TEXT=">>> Apply [Y/n]: "
  2474                     read input
  2475                     if [ ".$input" != .Y ] &&\
  2476                        [ ".$input" != .y ] &&\
  2477                        [ ".$input" != . ]; then
  2478                        skip=yes
  2479                     fi
  2480                 fi
  2481                 if [ ".$skip" = .yes ]; then
  2482                     if [ ".$opt_v" = .yes ]; then
  2483                         echo "file \`$file' -- skipped" 1>&2
  2484                     fi
  2485                     continue
  2486                 fi
  2487             fi
  2489             #   apply sed(1) operation(s)
  2490             if [ ".$opt_v" = .yes ]; then
  2491                 echo "patching \`$file'" 1>&2
  2492             fi
  2493             if [ ".$opt_t" = .yes ]; then
  2494                 echo "\$ cp -p $file $file$orig"
  2495                 echo "\$ chmod u+w $file"
  2496                 echo "\$ $sedcmd <$file$orig >$file"
  2497             fi
  2498             if [ ".$opt_n" = .no ]; then
  2499                 cp -p $file $file$orig
  2500                 chmod u+w $file >/dev/null 2>&1 || true
  2501                 eval "$sedcmd <$file$orig >$file"
  2502             fi
  2504             #   optionally fix timestamp
  2505             if [ ".$opt_s" = .yes ]; then
  2506                 if [ ".$opt_t" = .yes ]; then
  2507                     echo "\$ touch -r $file$orig $file"
  2508                 fi
  2509                 if [ ".$opt_n" = .no ]; then
  2510                     touch -r $file$orig $file
  2511                 fi
  2512             fi
  2514             #   optionally check whether any content change actually occurred 
  2515             if [ ".$opt_q" = .no ]; then
  2516                 if cmp $file$orig $file >/dev/null 2>&1; then
  2517                     if [ ".$opt_w" = .yes ]; then
  2518                         echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
  2519                     fi
  2520                 else
  2521                     substdone=yes
  2522                 fi
  2523             fi
  2525             #   optionally remove preserved original file
  2526             if [ ".$opt_b" = . ]; then
  2527                 if [ ".$opt_t" = .yes ]; then
  2528                     echo "\$ rm -f $file$orig"
  2529                 fi
  2530                 if [ ".$opt_n" = .no ]; then
  2531                     rm -f $file$orig
  2532                 fi
  2533             fi
  2534         done
  2535         if [ ".$opt_q" = .no ] && [ ".$opt_w" = .no ]; then
  2536             if [ ".$substdone" = .no ]; then
  2537                 if [ ".$files_num" = .1 ]; then
  2538                     echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
  2539                 else
  2540                     echo "$msgprefix:Warning: substitution resulted in no content change on any file" 1>&2
  2541                 fi
  2542             fi
  2543         fi
  2544     else
  2545         #   apply operation(s) to stdin/stdout
  2546         if [ ".$opt_v" = .yes ]; then
  2547             echo "patching <stdin>" 1>&2
  2548         fi
  2549         if [ ".$opt_t" = .yes ]; then
  2550             echo "\$ $sedcmd"
  2551         fi
  2552         if [ ".$opt_n" = .no ]; then
  2553             eval "$sedcmd"
  2554         fi
  2555     fi
  2557     shtool_exit 0
  2558     ;;
  2560 platform )
  2561     ##
  2562     ##  platform -- Platform Identification Utility
  2563     ##  Copyright (c) 2003-2007 Ralf S. Engelschall <rse@engelschall.com>
  2564     ##
  2566     #   option post-processing
  2567     if [ ".$opt_t" != . ]; then
  2568         case "$opt_t" in
  2569             binary )
  2570                 #   binary package id (OpenPKG RPM)
  2571                 opt_F="%<ap>-%<sp>"
  2572                 opt_L=yes
  2573                 opt_S=""
  2574                 opt_C="+"
  2575                 ;;
  2576             build )
  2577                 #   build time checking (OpenPKG RPM)
  2578                 opt_F="%<at>-%<st>"
  2579                 opt_L=yes
  2580                 opt_S=""
  2581                 opt_C="+"
  2582                 ;;
  2583             gnu )
  2584                 #   GNU config.guess style <arch>-<vendor>-<os><osversion>
  2585                 opt_F="%<at>-unknown-%<st>"
  2586                 opt_L=yes
  2587                 opt_S=""
  2588                 opt_C="+"
  2589                 ;;
  2590             web )
  2591                 #   non-whitespace HTTP Server-header id
  2592                 opt_F="%<sp>-%<ap>"
  2593                 opt_S="/"
  2594                 opt_C="+"
  2595                 ;;
  2596             summary)
  2597                 #   human readable verbose summary information
  2598                 opt_F="Class:      %[sc] (%[ac])\\nProduct:    %[sp] (%[ap])\\nTechnology: %[st] (%[at])"
  2599                 opt_S=" "
  2600                 opt_C="/"
  2601                 ;;
  2602             all-in-one )
  2603                 #   full-table all-in-one information
  2604                 opt_F=""
  2605                 opt_F="${opt_F}concise architecture class:      %<ac>\\n"
  2606                 opt_F="${opt_F}regular architecture class:      %{ac}\\n"
  2607                 opt_F="${opt_F}verbose architecture class:      %[ac]\\n"
  2608                 opt_F="${opt_F}concise architecture product:    %<ap>\\n"
  2609                 opt_F="${opt_F}regular architecture product:    %{ap}\\n"
  2610                 opt_F="${opt_F}verbose architecture product:    %[ap]\\n"
  2611                 opt_F="${opt_F}concise architecture technology: %<at>\\n"
  2612                 opt_F="${opt_F}regular architecture technology: %{at}\\n"
  2613                 opt_F="${opt_F}verbose architecture technology: %[at]\\n"
  2614                 opt_F="${opt_F}concise system class:            %<sc>\\n"
  2615                 opt_F="${opt_F}regular system class:            %{sc}\\n"
  2616                 opt_F="${opt_F}verbose system class:            %[sc]\\n"
  2617                 opt_F="${opt_F}concise system product:          %<sp>\\n"
  2618                 opt_F="${opt_F}regular system product:          %{sp}\\n"
  2619                 opt_F="${opt_F}verbose system product:          %[sp]\\n"
  2620                 opt_F="${opt_F}concise system technology:       %<st>\\n"
  2621                 opt_F="${opt_F}regular system technology:       %{st}\\n"
  2622                 opt_F="${opt_F}verbose system technology:       %[st]"
  2623                 ;;
  2624             * )
  2625                 echo "$msgprefix:Error: invalid type \`$opt_t'" 1>&2
  2626                 exit 1
  2627                 ;;
  2628         esac
  2629     fi
  2631     #   assemble initial platform information
  2632     UNAME_MACHINE=`(uname -m) 2>/dev/null` ||\
  2633     UNAME_MACHINE=`(uname -p) 2>/dev/null` ||\
  2634     UNAME_MACHINE='unknown'
  2635     UNAME_SYSTEM=`(uname -s) 2>/dev/null`  ||\
  2636     UNAME_SYSTEM='unknown'
  2637     UNAME_RELEASE=`(uname -r) 2>/dev/null` ||\
  2638     UNAME_RELEASE=`(uname -v) 2>/dev/null` ||\
  2639     UNAME_RELEASE='unknown'
  2641     UNAME="${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}"
  2643     AC=""; AP=""; AT=""
  2644     SC=""; SP=""; ST=""
  2646     #    dispatch into platform specific sections
  2647     case "${UNAME}" in
  2649         #   FreeBSD
  2650         *:FreeBSD:* )
  2651             #   determine architecture
  2652             AC="${UNAME_MACHINE}"
  2653             case "${AC}" in
  2654                 i386 ) AC="iX86" ;;
  2655             esac
  2656             AP="${AC}"
  2657             AT="${AP}"
  2658             if [ ".${AT}" = ".iX86" ]; then
  2659                 case "`(/sbin/sysctl -n hw.model) 2>&1`" in
  2660                     *"Xeon"* | *"Pentium Pro"* | *"Cyrix 6x86MX"* | *"Pentium II"* | *"Pentium III"* | *"Pentium 4"* | *"Celeron"* ) AT="i686" ;;
  2661                     *"Pentium"* ) AT="i586" ;; *"i486[SD]X"* | *"Cyrix 486"* | *"Cyrix [56]x86"* | *"Blue Lightning" | *"Cyrix 486S/DX" ) AT="i486" ;;
  2662                     *"i386[SD]X"* | *"NexGen 586"* ) AT="i386" ;;
  2663                 esac
  2664             fi
  2665             #   determine system
  2666             r=`echo "${UNAME_RELEASE}" |\
  2667                sed -e 's;[()];;' -e 's/\(-.*\)$/[\1]/'`
  2668             ST="FreeBSD ${r}"
  2669             SP="${ST}"
  2670             case "${r}" in
  2671                 1.* ) SC="4.3BSD" ;;
  2672                 *   ) SC="4.4BSD" ;;
  2673             esac
  2674             ;;
  2676         #   NetBSD
  2677         *:NetBSD:* )
  2678             #   determine architecture
  2679             AT="${UNAME_MACHINE}"
  2680             AP="${AT}"
  2681             case "${AP}" in
  2682                 i[3-6]86 ) AP="iX86" ;;
  2683             esac
  2684             AC="${AP}"
  2685             #   determine system
  2686             r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
  2687             ST="NetBSD ${r}"
  2688             SP="${ST}"
  2689             case "${r}" in
  2690                 0.* ) SC="4.3BSD" ;;
  2691                 *   ) SC="4.4BSD" ;;
  2692             esac
  2693             ;;
  2695         #   OpenBSD
  2696         *:OpenBSD:* )
  2697             #   determine architecture
  2698             AT="${UNAME_MACHINE}"
  2699             AP="${AT}"
  2700             case "${AP}" in
  2701                 i[3-6]86 ) AP="iX86" ;;
  2702             esac
  2703             AC="${AP}"
  2704             #   determine system
  2705             r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
  2706             ST="OpenBSD ${r}"
  2707             SP="${ST}"
  2708             SC="4.4BSD"
  2709             ;;
  2711         #   GNU/Linux
  2712         *:Linux:* )
  2713             #   determine architecture
  2714             AT="${UNAME_MACHINE}"
  2715             case "${AT}" in
  2716                ia64     ) AT="IA64"   ;;
  2717                x86_64   ) AT='AMD64'  ;;
  2718                parisc   ) AT="HPPA32" ;;
  2719                parisc64 ) AT="HPPA64" ;;
  2720             esac
  2721             AP="${AT}"
  2722             case "${AP}" in
  2723                i[3-6]86 ) AP='iX86' ;;
  2724             esac
  2725             AC="${AP}"
  2726             #   determine system
  2727             v_kern=`echo "${UNAME_RELEASE}" |\
  2728                 sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
  2729             v_libc=`(strings /lib/libc.so.* | grep '^GLIBC_' | sed -e 's/^GLIBC_//' |\
  2730                 env -i sort -n | sed -n -e '$p' | sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/') 2>/dev/null`
  2731             ST="GNU/<Linux >${v_libc}/<${v_kern}>"
  2732             if [ -f /etc/lsb-release ]; then
  2733                 eval `( . /etc/lsb-release
  2734                     echo "SC=\"LSB${LSB_VERSION}\""
  2735                     if [ ".${DISTRIB_ID}" != . -a ".${DISTRIB_RELEASE}" != . ]; then
  2736                         echo "SP=\"${DISTRIB_ID} ${DISTRIB_RELEASE}\""
  2737                     fi
  2738                 ) 2>/dev/null`
  2739             fi
  2740             if [ ".$SP" = . ]; then
  2741                 for tagfile in x \
  2742                     `cd /etc && \
  2743                     /bin/ls *[_-]release *[_-]version 2>/dev/null | env -i sort | \
  2744                     sed -e '/^redhat-release$/d' -e '/^lsb-release$/d'; \
  2745                     echo redhat-release lsb-release`
  2746                 do
  2747                     [ ".${tagfile}" = .x ] && continue
  2748                     [ ! -f "/etc/${tagfile}" ] && continue
  2749                     n=`echo ${tagfile} | sed -e 's/[_-]release$//' -e 's/[_-]version$//'`
  2750                     v=`(grep VERSION /etc/${tagfile}; cat /etc/${tagfile}) | grep '[0-9]' | sed -e 'q' |\
  2751                        sed -e 's/^/#/' \
  2752                            -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  2753                            -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  2754                            -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
  2755                            -e 's/^#.*$//'`
  2756                     case "`util_lower ${n}`" in
  2757                         redhat )
  2758                             if [ ".`egrep '(Red Hat Enterprise Linux|CentOS)' /etc/${tagfile}`" != . ]; then
  2759                                 n="<R>ed <H>at <E>nterprise <L>inux"
  2760                             else
  2761                                 n="<R>ed <H>at <L>inux"
  2762                             fi
  2763                             ;;
  2764                         debian             ) n="Debian[ GNU/Linux]"        ;;
  2765                         ubuntu             ) n="Ubuntu[ GNU/Linux]"        ;;
  2766                         fedora             ) n="<Fedora> Core[ GNU/Linux]" ;;
  2767                         suse               ) n="[Novell ]SUSE[ Linux]"     ;;
  2768                         mandrake*|mandriva ) n="Mandriva[ Linux]"          ;;
  2769                         gentoo             ) n="Gentoo[ GNU/Linux]"        ;;
  2770                         slackware          ) n="Slackware[ Linux]"         ;;
  2771                         turbolinux         ) n="TurboLinux"                ;;
  2772                         unitedlinux        ) n="UnitedLinux"               ;;
  2773                         *                  ) n="${n}[ GNU/Linux]"          ;;
  2774                     esac
  2775                     case "$n" in
  2776                         *"<"*">"* ) SP="$n <$v>" ;;
  2777                         *         ) SP="$n $v"   ;;
  2778                     esac
  2779                     break
  2780                 done
  2781             fi
  2782             [ ".$SP" = . ] && SP="${ST}"
  2783             [ ".$SC" = . ] && SC="LSB"
  2784             ;;
  2786         #   Sun Solaris
  2787         *:SunOS:* )
  2788             #   determine architecture
  2789             AT="${UNAME_MACHINE}"
  2790             case "${AT}" in
  2791                 i86pc )
  2792                     AT="iX86"
  2793                     case "`(/bin/isainfo -k) 2>&1`" in
  2794                         amd64 ) AT="AMD64" ;;
  2795                     esac
  2796                     ;;
  2797             esac
  2798             AP="${AT}"
  2799             case "${AP}" in
  2800                 sun4[cdm] ) AP="SPARC32" ;;
  2801                 sun4[uv]  ) AP="SPARC64" ;;
  2802                 sun4*     ) AP="SPARC"   ;;
  2803             esac
  2804             AC="${AP}"
  2805             case "${AC}" in
  2806                 SPARC* ) AC="SPARC" ;;
  2807             esac
  2808             #   determine system
  2809             ST="[Sun ]SunOS ${UNAME_RELEASE}"
  2810             v=`echo "${UNAME_RELEASE}" |\
  2811                sed -e 's;^4\.;1.;' \
  2812                    -e 's;^5\.\([0-6]\)[^0-9]*$;2.\1;' \
  2813                    -e 's;^5\.\([0-9][0-9]*\).*;\1;'`
  2814             SP="[Sun ]Solaris $v"
  2815             case "${UNAME_RELEASE}" in
  2816                 4.* ) SC="4.3BSD" ;;
  2817                 5.* ) SC="SVR4"   ;;
  2818             esac
  2819             ;;
  2821         #   SCO UnixWare
  2822         *:UnixWare:* )
  2823             #   determine architecture
  2824             AT="${UNAME_MACHINE}"
  2825             case "${AT}" in
  2826                 i[3-6]86 | ix86at ) AT="iX86" ;;
  2827             esac
  2828             AP="${AT}"
  2829             #   determine system
  2830             v=`/sbin/uname -v`
  2831             ST="[SCO ]UnixWare ${v}"
  2832             SP="${ST}"
  2833             SC="SVR${UNAME_RELEASE}"
  2834             ;;
  2836         #   QNX
  2837         *:QNX:* )
  2838             #   determine architecture
  2839             AT="${UNAME_MACHINE}"
  2840             case "${AT}" in
  2841                 x86pc ) AT="iX86" ;;
  2842             esac
  2843             AP="${AT}"
  2844             #   determine system
  2845             v="${UNAME_RELEASE}"
  2846             ST="QNX[ Neutrino RTOS] ${v}"
  2847             v=`echo "${v}" | sed -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\).*$;\1;'`
  2848             SP="QNX[ Neutrino RTOS] ${v}"
  2849             SC="QNX"
  2850             ;;
  2852         #   SGI IRIX
  2853         *:IRIX*:* )
  2854             #   determine architecture
  2855             AT="${UNAME_MACHINE}"
  2856             AP="${AT}"
  2857             case "${AP}:${UNAME_SYSTEM}" in
  2858                 IP*:IRIX64 ) AP="MIPS64" ;;
  2859                 IP*:*      ) AP="MIPS"   ;;
  2860             esac
  2861             AC="${AP}"
  2862             #   determine system
  2863             v=`(/bin/uname -R || /bin/uname -r) 2>/dev/null | sed -e 's;[0-9.]* ;;'`
  2864             ST="[SGI ]IRIX ${v}"
  2865             v="${UNAME_RELEASE}"
  2866             SP="[SGI ]IRIX ${v}"
  2867             SC="4.2BSD/SVR3"
  2868             ;;
  2870         #   HP HP-UX
  2871         *:HP-UX:* )
  2872             #   determine architecture
  2873             AT="${UNAME_MACHINE}"
  2874             case "${AT}" in
  2875                 ia64 ) AT="IA64" ;;
  2876                 9000/[34]?? ) AT=M68K ;;
  2877                 9000/[678][0-9][0-9])
  2878                     sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
  2879                     sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
  2880                     case "${sc_cpu_version}" in
  2881                         523 ) AT="HPPA1.0" ;;
  2882                         528 ) AT="HPPA1.1" ;;
  2883                         532 ) AT="HPPA2.0"
  2884                             case "${sc_kernel_bits}" in
  2885                                 32 ) AT="${AT}n" ;;
  2886                                 64 ) AT="${AT}w" ;;
  2887                             esac
  2888                             ;;
  2889                     esac
  2890                     ;;
  2891             esac
  2892             AP="${AT}"
  2893             case "${AP}" in
  2894                 HPPA* ) AP="HPPA" ;;
  2895             esac
  2896             AC="${AP}"
  2897             #   determine system
  2898             v=`echo "${UNAME_RELEASE}" | sed -e 's;^[^0-9]*;;'`
  2899             ST="[HP ]<HP>-<UX ${v}>"
  2900             SP="${ST}"
  2901             case "${v}" in
  2902                 10.*   ) SC="SVR4.2" ;;
  2903                 [7-9]* ) SC="SVR4"   ;;
  2904             esac
  2905             ;;
  2907         #   HP Tru64 (OSF1)
  2908         *:OSF1:* )
  2909             #   determine architecture
  2910             AP="${UNAME_MACHINE}"
  2911             case "${AP}" in
  2912                 alpha ) AP="Alpha" ;;
  2913             esac
  2914             alpha_type=`(/usr/sbin/psrinfo -v) 2>/dev/null |\
  2915                 sed -n -e 's/^.*The alpha \([^ ][^ ]*\).*processor.*$/\1/p' | sed -e 'q'`
  2916             AT="${AP}${alpha_type}"
  2917             AC="${AP}"
  2918             #   determine system
  2919             v=`echo "${UNAME_RELEASE}" | sed -e 's;^[VTX];;'`
  2920             ST="[HP ]Tru64 ${v}"
  2921             SP="${ST}"
  2922             SC="OSF1"
  2923             ;;
  2925         #   IBM AIX
  2926         *:AIX:* )
  2927             #   determine architecture
  2928             cpu_arch=rs6000
  2929             if [ -x /usr/sbin/lsdev -a -x /usr/sbin/lsattr ]; then
  2930                 cpu_id=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
  2931                 if [ ".`/usr/sbin/lsattr -El ${cpu_id} | grep -i powerpc`" != . ]; then
  2932                     cpu_arch=powerpc
  2933                 fi
  2934             elif [ -d /QOpenSys ]; then
  2935                 #   IBM i5/OS (aka OS/400) with PASE (Portable Application Solutions Environment)
  2936                 cpu_arch=powerpc
  2937             fi
  2938             if [ -x /usr/bin/oslevel ]; then
  2939                 os_level=`/usr/bin/oslevel`
  2940             else
  2941                 os_level="`uname -v`.`uname -r`"
  2942             fi
  2943             os_level=`echo "${os_level}" |\
  2944                       sed -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\)\(.*\)$;<\1>\2[\3];' \
  2945                           -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\)\(.*\)$;<\1>\2;'`
  2946             AT="${cpu_arch}"
  2947             AP="${AT}"
  2948             AC="${AP}"
  2949             #   determine system
  2950             ST="[IBM ]<AIX >${os_level}"
  2951             SP="${ST}"
  2952             case "${os_level}" in
  2953                 [12]* ) SC="SVR2" ;;
  2954                 *     ) SC="SVR4" ;;
  2955             esac
  2956             ;;
  2958         #   Apple Mac OS X (Darwin)
  2959         *:Darwin:* )
  2960             #   determine architecture
  2961             AT="`uname -p`"
  2962             case "${AT}" in
  2963                 powerpc ) AT="PPC" ;;
  2964             esac
  2965             AP="${AT}"
  2966             case "${AP}" in
  2967                 i?86 ) AP="iX86" ;;
  2968             esac
  2969             AC="${AP}"
  2970             #   determine system
  2971             unset v1; unset v2; unset v3
  2972             eval `echo "${UNAME_RELEASE}" |\
  2973                   sed -e 's/^/#/' \
  2974                       -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"; v3="\3"/' \
  2975                       -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"/' \
  2976                       -e 's/^#\([0-9][0-9]*\).*$/v1="\1"/' \
  2977                       -e 's/^#.*$/v1="0"/'`
  2978             ST="[Apple ]<${UNAME_SYSTEM} ${v1}>${v2+.$v2}${v3+[.$v3]}"
  2979             SP="$ST"
  2980             v="`(sw_vers) 2>/dev/null | grep 'ProductVersion:' | sed -e 's/^ProductVersion:[^0-9]*\([0-9][0-9.]*\).*$/\1/'`"
  2981             if [ ".$v" = . ]; then
  2982                 for name in System Server; do
  2983                     if [ -f /System/Library/CoreServices/${name}Version.plist ]; then
  2984                         v=`(defaults read "/System/Library/CoreServices/${name}Version" "ProductVersion") 2>/dev/null`
  2985                         [ ".$v" != . ] && break
  2986                     fi
  2987                 done
  2988             fi
  2989             if [ ".$v" != . ]; then
  2990                 unset v1; unset v2; unset v3
  2991                 eval `echo "${v}" |\
  2992                       sed -e 's/^/#/' \
  2993                           -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"; v3="\3"/' \
  2994                           -e 's/^#\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/v1="\1"; v2="\2"/' \
  2995                           -e 's/^#\([0-9][0-9]*\).*$/v1="\1"/' \
  2996                           -e 's/^#.*$/v1="0"/'`
  2997                 SP="[Apple ]Mac OS X ${v1}${v2+.$v2}${v3+[.$v3]}"
  2998             fi
  2999             SC="4.4BSD/Mach3.0"
  3000             ;;
  3002         #   TODO ...ADD YOUR NEW PLATFORM CHECK HERE... TODO
  3003         # *:XXX:* )
  3004         #   ...
  3005         #   ;;
  3007         #   ...A STILL UNKNOWN PLATFORM...
  3008         * )
  3009             AT=`echo "${UNAME_MACHINE}" | sed -e "s; ;${opt_C};g"`
  3010             AP="${AT}"
  3011             AC="${AP}"
  3012             v=`echo "${UNAME_RELEASE}" |\
  3013                sed -e 's/^/#/' \
  3014                    -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  3015                    -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
  3016                    -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
  3017                    -e 's/^#.*$/?/'`
  3018             ST="${UNAME_SYSTEM} ${v}"
  3019             SP="${ST}"
  3020             SC="${SP}"
  3021             ;;
  3023     esac
  3025     #   provide fallback values
  3026     [ ".$AT" = . ] && AT="${AP:-${AC}}"
  3027     [ ".$AP" = . ] && AP="${AT:-${AC}}"
  3028     [ ".$AC" = . ] && AC="${AP:-${AT}}"
  3029     [ ".$ST" = . ] && ST="${SP:-${SC}}"
  3030     [ ".$SP" = . ] && SP="${ST:-${SC}}"
  3031     [ ".$SC" = . ] && SC="${SP:-${ST}}"
  3033     #   support explicit enforced verbose/concise output
  3034     if [ ".$opt_v" = .yes ]; then
  3035         opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%[\1]/g'`
  3036     elif [ ".$opt_c" = .yes ]; then
  3037         opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%<\1>/g'`
  3038     fi
  3040     #   provide verbose and concise variants
  3041     AC_V=""; AC_N=""; AC_C=""
  3042     AP_V=""; AP_N=""; AP_C=""
  3043     AT_V=""; AT_N=""; AT_C=""
  3044     SC_V=""; SC_N=""; SC_C=""
  3045     SP_V=""; SP_N=""; SP_C=""
  3046     ST_V=""; ST_N=""; ST_C=""
  3047     for var_lc in at ap ac st sp sc; do
  3048         case "$opt_F" in
  3049             *"%[${val_lc}]"* | *"%{${val_lc}}"* | *"%${val_lc}"* | *"%<${val_lc}>"* )
  3050             var_uc=`util_upper "$var_lc"`
  3051             eval "val=\"\$${var_uc}\""
  3052             val_V=""; val_N=""; val_C=""
  3053             case "$opt_F" in
  3054                 *"%[${var_lc}]"* )
  3055                     val_V=`echo ":$val" | \
  3056                            sed -e 's/^://' \
  3057                                -e 's;\[\([^]]*\)\];\1;g' \
  3058                                -e 's;<\([^>]*\)>;\1;g' \
  3059                                -e "s; ;§§;g" \
  3060                                -e "s;/;%%;g" \
  3061                                -e "s;§§;${opt_S};g" \
  3062                                -e "s;%%;${opt_C};g"`
  3063                     eval "${var_uc}_V=\"\${val_V}\""
  3064                     ;;
  3065             esac
  3066             case "$opt_F" in
  3067                 *"%{${var_lc}}"* | *"%${var_lc}"* )
  3068                     val_N=`echo ":$val" | \
  3069                            sed -e 's/^://' \
  3070                                -e 's;\[\([^]]*\)\];;g' \
  3071                                -e 's;<\([^>]*\)>;\1;g' \
  3072                                -e "s; ;§§;g" \
  3073                                -e "s;/;%%;g" \
  3074                                -e "s;§§;${opt_S};g" \
  3075                                -e "s;%%;${opt_C};g"`
  3076                     eval "${var_uc}_N=\"\${val_N}\""
  3077                     ;;
  3078             esac
  3079             case "$opt_F" in
  3080                 *"%<${var_lc}>"* )
  3081                     val_C=`echo ":$val" | \
  3082                            sed -e 's/^://' \
  3083                                -e 's;\[\([^]]*\)\];;g' \
  3084                                -e 's;[^<]*<\([^>]*\)>[^<]*;\1;g' \
  3085                                -e "s; ;§§;g" \
  3086                                -e "s;/;%%;g" \
  3087                                -e "s;§§;${opt_S};g" \
  3088                                -e "s;%%;${opt_C};g"`
  3089                     eval "${var_uc}_C=\"\${val_C}\""
  3090                     ;;
  3091             esac
  3092             ;;
  3093         esac
  3094     done
  3096     #   create output string
  3097     output=`echo ":$opt_F" |\
  3098             sed -e "s/^://" \
  3099                 -e "s;%\\[ac\\];${AC_V};g" \
  3100                 -e "s;%{ac};${AC_N};g" \
  3101                 -e "s;%ac;${AC_N};g" \
  3102                 -e "s;%<ac>;${AC_C};g" \
  3103                 -e "s;%\\[ap\\];${AP_V};g" \
  3104                 -e "s;%{ap};${AP_N};g" \
  3105                 -e "s;%ap;${AP_N};g" \
  3106                 -e "s;%<ap>;${AP_C};g" \
  3107                 -e "s;%\\[at\\];${AT_V};g" \
  3108                 -e "s;%{at};${AT_N};g" \
  3109                 -e "s;%at;${AT_N};g" \
  3110                 -e "s;%<at>;${AT_C};g" \
  3111                 -e "s;%\\[sc\\];${SC_V};g" \
  3112                 -e "s;%{sc};${SC_N};g" \
  3113                 -e "s;%sc;${SC_N};g" \
  3114                 -e "s;%<sc>;${SC_C};g" \
  3115                 -e "s;%\\[sp\\];${SP_V};g" \
  3116                 -e "s;%{sp};${SP_N};g" \
  3117                 -e "s;%sp;${SP_N};g" \
  3118                 -e "s;%<sp>;${SP_C};g" \
  3119                 -e "s;%\\[st\\];${ST_V};g" \
  3120                 -e "s;%{st};${ST_N};g" \
  3121                 -e "s;%st;${ST_N};g" \
  3122                 -e "s;%<st>;${ST_C};g" \
  3123                 -e 's/\\\\n/^/g' |\
  3124              tr '^' '\012'`
  3126     #   support lower/upper-case mapping
  3127     if [ ".$opt_L" = .yes ]; then
  3128         output=`util_lower "$output"`
  3129     elif [ ".$opt_U" = .yes ]; then
  3130         output=`util_upper "$output"`
  3131     fi
  3133     #   display output string
  3134     if [ ".$opt_n" = .yes ]; then
  3135         echo . | awk '{ printf("%s", output); }' output="$output"
  3136     else
  3137         echo "$output"
  3138     fi
  3140     shtool_exit 0
  3141     ;;
  3143 arx )
  3144     ##
  3145     ##  arx -- Extended archive command
  3146     ##  Copyright (c) 1999-2007 Ralf S. Engelschall <rse@engelschall.com>
  3147     ##
  3149     ar_prg="$opt_C"
  3150     ar_cmd="$1"; shift
  3151     archive="$1"; shift
  3152     files="$*"
  3154     #   walk through the file list and expand archives members
  3155     ar_tmpdir=`echo $archive | sed -e 's;[^/]*$;.arx;'`
  3156     nfiles=''
  3157     if [ ".$files" != . ]; then
  3158         for file in $files; do
  3159             if [ ! -f $file ]; then
  3160                 echo "$msgprefix:Error: input file not found: $file" 1>&2
  3161                 shtool_exit 1
  3162             fi
  3163             case $file in
  3164                 *.a )
  3165                     if [ ! -d $ar_tmpdir ]; then
  3166                         if [ ".$opt_t" = .yes ]; then
  3167                             echo "mkdir $ar_tmpdir" 1>&2
  3168                         fi
  3169                         mkdir $ar_tmpdir
  3170                     fi
  3171                     case $ar_tmpdir in
  3172                          .arx )
  3173                              from="../$file"
  3174                              ;;
  3175                          * )
  3176                              dir=`echo $file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'`
  3177                              base=`echo $file | sed -e 's;.*/\([^/]*\)$;\1;'`
  3178                              from="`cd $dir; pwd`/$base"
  3179                              ;;
  3180                     esac
  3181                     if [ ".$opt_t" = .yes ]; then
  3182                         echo "(cd $ar_tmpdir && $ar_prg x $from)" 1>&2
  3183                     fi
  3184                     (cd $ar_tmpdir && eval $ar_prg x $from)
  3185                     if [ $? -ne 0 ]; then
  3186                         echo "$msgprefix:Error: member extraction failed for archive: $file" 1>&2
  3187                         shtool_exit 1
  3188                     fi
  3189                     for member in - `eval $ar_prg t $file | sed -e '/_\.SYMDEF/d'`; do
  3190                         [ ".$member" = .- ] && continue
  3191                         nfiles="$nfiles $ar_tmpdir/$member"
  3192                     done
  3193                     ;;
  3194                 * )
  3195                     nfiles="$nfiles $file"
  3196                     ;;
  3197             esac
  3198         done
  3199     fi
  3201     #   run the final archive command
  3202     if [ ".$opt_t" = .yes ]; then
  3203         echo "$ar_prg $ar_cmd $archive $nfiles" 1>&2
  3204     fi
  3205     eval $ar_prg $ar_cmd $archive $nfiles
  3206     if [ $? -ne 0 ]; then
  3207         echo "$msgprefix:Error: archive command failed" 1>&2
  3208         shtool_exit $?
  3209     fi
  3211     #   cleanup and die gracefully
  3212     if [ -d $ar_tmpdir ]; then
  3213         if [ ".$opt_t" = .yes ]; then
  3214             echo "rm -rf $ar_tmpdir" 1>&2
  3215         fi
  3216         rm -rf $ar_tmpdir
  3217     fi
  3219     shtool_exit 0
  3220     ;;
  3222 slo )
  3223     ##
  3224     ##  slo -- Separate linker options by library class
  3225     ##  Copyright (c) 1998-2007 Ralf S. Engelschall <rse@engelschall.com>
  3226     ##
  3228     DIFS="$IFS"
  3230     #   parse out -L and -l options from command line
  3231     DIRS=''
  3232     LIBS=''
  3233     ARGV=''
  3234     optprev=''
  3235     for opt
  3236     do
  3237         #   concatenate with previous option if exists
  3238         if [ ".$optprev" != . ]; then
  3239             opt="${optprev}${opt}";
  3240             optprev=''
  3241         fi
  3242         #   remember options for arg if used stand-alone
  3243         if [ ".$opt" = ".-L" ] || [ ".$opt" = ".-l" ]; then
  3244             optprev="$opt"
  3245             continue;
  3246         fi
  3247         #   split argument into option plus option argument
  3248         arg="`echo $opt | cut -c3-`"
  3249         opt="`echo $opt | cut -c1-2`"
  3250         #   store into containers
  3251         case $opt in
  3252             -L) DIRS="$DIRS:$arg" ;;
  3253             -l) LIBS="$LIBS:$arg" ;;
  3254              *) ARGV="$ARGV $opt" ;;
  3255         esac
  3256     done
  3258     #   set linker default directories
  3259     DIRS_DEFAULT='/lib:/usr/lib'
  3260     if [ ".$LD_LIBRARY_PATH" != . ]; then
  3261         DIRS_DEFAULT="$DIRS_DEFAULT:$LD_LIBRARY_PATH"
  3262     fi
  3264     #   sort options by class
  3265     DIRS_OBJ=''
  3266     LIBS_OBJ=''
  3267     DIRS_PIC=''
  3268     LIBS_PIC=''
  3269     DIRS_DSO=''
  3270     LIBS_DSO=''
  3272     #    for each library...
  3273     OIFS="$IFS"; IFS=':'
  3274     for lib in $LIBS; do
  3275         [ ".$lib" = . ] && continue
  3277         found='no'
  3278         found_indefdir='no'
  3279         found_type=''
  3280         found_dir=''
  3282         #    for each directory...
  3283         OIFS2="$IFS"; IFS=":$DIFS"
  3284         for dir in ${DIRS} switch-to-defdirs ${DIRS_DEFAULT}; do
  3285             [ ".$dir" = . ] && continue
  3286             [ ".$dir" = .switch-to-defdirs ] && found_indefdir=yes
  3287             [ ! -d $dir ] && continue
  3289             #    search the file
  3290             OIFS3="$IFS"; IFS="$DIFS"
  3291             for file in '' `cd $dir && env -i /bin/ls lib${lib}.* 2>/dev/null`; do
  3292                  [ ".$file" = . ] && continue
  3293                  case $file in
  3294                      *.so|*.so.[0-9]*|*.sl|*.sl.[0-9]* )
  3295                           found=yes;
  3296                           found_type=DSO;
  3297                           break
  3298                           ;;
  3299                      *.lo|*.la )
  3300                           found=yes;
  3301                           found_type=PIC
  3302                           ;;
  3303                      *.a )
  3304                           if [ ".$found_type" = . ]; then
  3305                               found=yes
  3306                               found_type=OBJ
  3307                           fi
  3308                           ;;
  3309                  esac
  3310             done
  3311             IFS="$OIFS3"
  3312             if [ ".$found" = .yes ]; then
  3313                 found_dir="$dir"
  3314                 break
  3315             fi
  3316         done
  3317         IFS="$OIFS2"
  3319         if [ ".$found" = .yes ]; then
  3320             if [ ".$found_indefdir" != .yes ]; then
  3321                 eval "dirlist=\"\${DIRS_${found_type}}:\""
  3322                 case "$dirlist" in
  3323                     *:$found_dir:* ) ;;
  3324                     * ) eval "DIRS_${found_type}=\"\$DIRS_${found_type}:${found_dir}\"" ;;
  3325                 esac
  3326                 eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
  3327             else
  3328                 eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
  3329             fi
  3330         else
  3331             LIBS_OBJ="$LIBS_OBJ:$lib"
  3332             #dirlist="`echo $DIRS $DIRS_DEFAULT | sed -e 's/:/ /g'`"
  3333             #echo "slo:Warning: library \"$lib\" not found in any of the following dirs:" 2>&1
  3334             #echo "slo:Warning: $dirlist" 1>&1
  3335         fi
  3336     done
  3337     IFS="$OIFS"
  3339     #   also pass-through unused dirs even if it's useless
  3340     OIFS="$IFS"; IFS=':'
  3341     for dir in $DIRS; do
  3342         dirlist="${DIRS_OBJ}:${DIRS_PIC}:${DIRS_DSO}:"
  3343         case "$dirlist" in
  3344             *:$dir:* ) ;;
  3345             * ) DIRS_OBJ="$DIRS_OBJ:$dir" ;;
  3346         esac
  3347     done
  3348     IFS="$OIFS"
  3350     #   reassemble the options but separated by type
  3351     for type in OBJ PIC DSO; do
  3352         OIFS="$IFS"; IFS=':'
  3353         eval "libs=\"\$LIBS_${type}\""
  3354         opts=''
  3355         for lib in $libs; do
  3356             [ ".$lib" = . ] && continue
  3357             opts="$opts -l$lib"
  3358         done
  3359         eval "LIBS_${type}=\"$opts\""
  3361         eval "dirs=\"\$DIRS_${type}\""
  3362         opts=''
  3363         for dir in $dirs; do
  3364             [ ".$dir" = . ] && continue
  3365             opts="$opts -L$dir"
  3366         done
  3367         eval "DIRS_${type}=\"$opts\""
  3368         IFS="$OIFS"
  3369     done
  3371     #   give back results
  3372     for var in ARGV DIRS_OBJ LIBS_OBJ DIRS_PIC LIBS_PIC DIRS_DSO LIBS_DSO; do
  3373         eval "val=\"\$${var}\""
  3374         val="`echo $val | sed -e 's/^ *//'`"
  3375         echo "${opt_p}${var}=\"${val}\""
  3376     done
  3378     shtool_exit 0
  3379     ;;
  3381 scpp )
  3382     ##
  3383     ##  scpp -- Sharing C Pre-Processor
  3384     ##  Copyright (c) 1999-2007 Ralf S. Engelschall <rse@engelschall.com>
  3385     ##
  3387     srcs="$*"
  3388     output="${opt_o}.n"
  3390     #   find a reasonable Awk
  3391     awk=''
  3392     paths=`echo $PATH |\
  3393            sed -e 's%/*:%:%g' -e 's%/$%%' \
  3394                -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
  3395                -e 's/:/ /g'`
  3396     for name in gawk nawk awk; do
  3397         for path in $paths; do
  3398             if [ -r "$path/$name" ]; then
  3399                 awk="$path/$name"
  3400                 break
  3401             fi
  3402         done
  3403         if [ ".$awk" != . ]; then
  3404             break
  3405         fi
  3406     done
  3407     if [ ".$awk" = . ]; then
  3408         echo "$msgprefix:Error: cannot find a reasonable Awk" 1>&2
  3409         shtool_exit 1
  3410     fi
  3412     #   parse source file(s)
  3413     if [ ".$opt_v" = .yes ]; then
  3414         echo "Parsing:" | $awk '{ printf("%s", $0); }' 1>&2
  3415     fi
  3416     for src in $srcs; do
  3417         if [ ".$opt_v" = .yes ]; then
  3418             echo $src | $awk '{ printf(" %s", $0); }' 1>&2
  3419         fi
  3420         if [ ".$opt_f" != . ]; then
  3421             inputcmd="sed"
  3422             OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_f; IFS="$OIFS"
  3423             for e
  3424             do
  3425                 inputcmd="$inputcmd -e '$e'"
  3426             done
  3427             inputcmd="$inputcmd '$src'"
  3428         else
  3429             inputcmd="cat '$src'"
  3430         fi
  3431         eval $inputcmd |\
  3432         $awk '
  3433            BEGIN {
  3434                ln    = 0;
  3435                fln   = 0;
  3436                level = 0;
  3437                mode  = "";
  3438                store = "";
  3441                ln++;
  3443            /^#if.*/ {
  3444                level++;
  3446            /^#if [a-zA-Z_][a-zA-Z0-9_]* *$/ {
  3447                if ($2 == define) {
  3448                    mode = "D";
  3449                    printf("D:#line %d \"%s\"\n", ln, src);
  3450                    next;
  3453            /^#endif.*/ {
  3454                level--;
  3455                if (mode == "D" && level == 0) {
  3456                    mode = "";
  3457                    next;
  3460            /^[a-zA-Z_][a-zA-Z0-9_].*;.*/ {
  3461                if ($1 == class) {
  3462                    printf("V:#line %d \"%s\"\n", ln, src);
  3463                    printf("V:%s\n", $0);
  3464                    printf("J:%s\n", $0);
  3465                    next;
  3468            /^[a-zA-Z_][a-zA-Z0-9_].*=.*/ {
  3469                if ($1 == class) {
  3470                    printf("V:#line %d \"%s\"\n", ln, src);
  3471                    printf("V:%s\n", $0);
  3472                    printf("J:%s\n", $0);
  3473                    next;
  3476            /^[a-zA-Z_][a-zA-Z0-9_]*/ {
  3477                if ($1 == class) {
  3478                    fln = ln;
  3479                    store = $0;
  3480                    mode = "F";
  3481                    next;
  3484            /^\{ *$/ {
  3485                if (mode == "F") {
  3486                    printf("F:#line %d \"%s\"\n", fln, src);
  3487                    printf("F:%s;\n", store);
  3488                    printf("I:%s;\n", store);
  3489                    store = "";
  3490                    mode = "";
  3491                    next;
  3495                if (mode == "D")
  3496                    printf("D:%s\n", $0);
  3497                else if (mode == "F")
  3498                    store = store " " $0;
  3500         ' "src=$src" "define=$opt_D" "class=$opt_C" >>$tmpfile
  3501     done
  3502     if [ ".$opt_v" = .yes ]; then
  3503         echo "" 1>&2
  3504     fi
  3506     #   start generating output header
  3507     echo "/* $opt_o -- autogenerated from $opt_t, DO NOT EDIT! */" >$output
  3508     echo "#line 1 \"$opt_t\"" >>$output
  3509     sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd' |\
  3510     sed -e "/^${opt_M} *\$/d" >>$output
  3512     #   merge in the define blocks
  3513     grep '^D:' $tmpfile | sed -e 's/^D://' >>$output
  3515     #   generate standard prolog
  3516     echo "#line 1 \"_ON_THE_FLY_\"" >>$output
  3517     echo "" >>$output
  3518     echo "/* make sure the scpp source extensions are skipped */" >>$output
  3519     echo "#define $opt_D 0" >>$output
  3520     echo "#define $opt_C /**/" >>$output
  3522     #   generate namespace hiding for variables
  3523     echo "" >>$output
  3524     echo "/* move intern variables to hidden namespace */" >>$output
  3525     grep '^J:' $tmpfile | sed >>$output \
  3526         -e 's/^J://' \
  3527         -e 's/  */ /g' \
  3528         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\];.*$/#define \1 __\1/' \
  3529         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\] =.*$/#define \1 __\1/' \
  3530         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\);.*$/#define \1 __\1/' \
  3531         -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\) =.*$/#define \1 __\1/'
  3533     #   generate namespace hiding for functions
  3534     echo "" >>$output
  3535     echo "/* move intern functions to hidden namespace */" >>$output
  3536     grep '^I:' $tmpfile | sed >>$output \
  3537         -e 's/^I://' \
  3538         -e 's/\([ (]\) */\1/g' \
  3539         -e 's/ *\([),]\)/\1/g' \
  3540         -e 's/^[^(]*[ *]\([a-zA-Z0-9_]*\)(.*$/#define \1 __\1/'
  3542     #   generate prototypes for variables
  3543     echo "" >>$output
  3544     echo "/* prototypes for intern variables */" >>$output
  3545     grep '^V:' $tmpfile | sed >>$output \
  3546         -e 's/^V://' \
  3547         -e 's/  */ /g' \
  3548         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\);.*$/\1;/' \
  3549         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\) =.*$/\1;/' \
  3550         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\);.*$/\1;/' \
  3551         -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\) =.*$/\1;/' \
  3552         -e 's/ ;/;/g' \
  3553         -e "s/^$opt_C /extern /"
  3555     #   generate prototypes for functions
  3556     echo "" >>$output
  3557     echo "/* prototypes for intern functions */" >>$output
  3558     grep '^F:' $tmpfile | sed >>$output \
  3559         -e 's/^F://' \
  3560         -e 's/\([ (]\) */\1/g' \
  3561         -e 's/ *\([),]\)/\1/g' \
  3562         -e 's/\([* ]\)[a-zA-Z0-9_]*,/\1,/g' \
  3563         -e 's/\([* ]\)[a-zA-Z0-9_]*);/\1);/g' \
  3564         -e 's/(\*[a-zA-Z0-9_]*)(/(*)(/g' \
  3565         -e 's/\([ (]\) */\1/g' \
  3566         -e 's/ *\([),]\)/\1/g' \
  3567         -e "s/^$opt_C /extern /"
  3569     #   finish generating output header
  3570     n=`(echo ''; sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd') |\
  3571        wc -l | sed -e 's;^ *\([0-9]*\) *$;\1;'`
  3572     echo "#line $n \"$opt_t\"" >>$output
  3573     sed <$opt_t -e "/^${opt_M} *\$/,\$p" -e 'd' |\
  3574     sed -e "/^${opt_M} *\$/d" >>$output
  3576     #   create final output file
  3577     if [ -f $opt_o ]; then
  3578         if [ ".$opt_p" = .yes ]; then
  3579             grep -v '^#line' $opt_o  >$tmpfile.o
  3580             grep -v '^#line' $output >$tmpfile.n
  3581             out_old="$tmpfile.o"
  3582             out_new="$tmpfile.n"
  3583         else
  3584             out_old="$opt_o"
  3585             out_new="$output"
  3586         fi
  3587         if cmp -s $out_old $out_new; then
  3589         else
  3590             cp $output $opt_o
  3591         fi
  3592     else
  3593         cp $output $opt_o
  3594     fi
  3595     rm -f $output
  3596     rm -f $tmpfile $tmpfile.* >/dev/null 2>&1
  3598     shtool_exit 0
  3599     ;;
  3601 version )
  3602     ##
  3603     ##  version -- Maintain a version information file
  3604     ##  Copyright (c) 1994-2007 Ralf S. Engelschall <rse@engelschall.com>
  3605     ##
  3607     file="$1"
  3609     #   determine prefix and name
  3610     name="$opt_n"
  3611     prefix="$opt_p"
  3613     #   determine current version
  3614     triple="$opt_s"
  3615     if [ ".$triple" != . ]; then
  3616         #   use given triple
  3617         if [ ".`echo $triple | grep '[0-9]*.[0-9]*[sabp.][0-9]*'`" = . ]; then
  3618             echo "$msgprefix:Error: invalid argument to option \`-s': \`$opt_s'" 1>&2
  3619             shtool_exit 1
  3620         fi
  3621         eval `echo $triple |\
  3622               sed -e 's%\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\).*%\
  3623               ver="\1";rev="\2";typ="\3";lev="\4"%'`
  3624         tim=calc
  3625     elif [ -r $file ]; then
  3626         #   determine triple from given file
  3627         eval `grep 'Version [0-9]*.[0-9]*[sabp.][0-9]* ([0-9]*-[a-zA-Z]*-[0-9]*)' $file |\
  3628               sed -e 's%.*Version \([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\) (\([0-9]*-[a-zA-Z]*-[0-9]*\)).*%\
  3629               ver="\1";rev="\2";typ="\3";lev="\4";tim="\5"%' -e 'q'`
  3630     else
  3631         #   intialise to first version
  3632         ver=0
  3633         rev=1
  3634         typ=.
  3635         lev=0
  3636         tim=calc
  3637     fi
  3639     #   determine new version in batch
  3640     if [ ".$opt_i" != . ]; then
  3641         case $opt_i in
  3642             v ) ver=`expr $ver + 1`
  3643                 rev=0
  3644                 lev=0
  3645                 ;;
  3646             r ) rev=`expr $rev + 1`
  3647                 lev=0
  3648                 ;;
  3649             l ) lev=`expr $lev + 1`
  3650                 ;;
  3651             * ) echo "$msgprefix:Error: invalid argument to option \`-i': \`$opt_i'" 1>&2
  3652                 shtool_exit 1
  3653                 ;;
  3654         esac
  3655         tim=calc
  3656     fi
  3658     #   determine new version interactively
  3659     if [ ".$opt_e" = .yes ]; then
  3660         echo "old version: ${ver}.${rev}${typ}${lev}"
  3661         while [ 1 ]; do
  3662             echo dummy | awk '{ printf("new version: "); }'
  3663             read triple
  3664             case $triple in
  3665                 [0-9]*.[0-9]*[sabp.][0-9]* )
  3666                     ;;
  3667                 * ) echo "$msgprefix:Error: invalid version string entered: \`$triple'" 1>&2
  3668                     continue
  3669                     ;;
  3670             esac
  3671             break
  3672         done
  3673         eval `echo $triple |\
  3674               sed -e 's%^\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\)$%\
  3675               ver="\1";rev="\2";typ="\3";lev="\4"%'`
  3676         tim=calc
  3677     fi
  3679     #   determine hexadecimal and libtool value of version
  3680     case $typ in
  3681         a     ) typnum=0;  levnum=$lev ;;
  3682         b     ) typnum=1;  levnum=$lev ;;
  3683         p | . ) typnum=2;  levnum=$lev ;;
  3684         s     ) typnum=15; levnum=255  ;; # snapshots are special
  3685     esac
  3686     hex=`echo "$ver:$rev:$typnum:$levnum" |\
  3687          awk -F: '{ printf("0x%x%02x%1x%02x", $1, $2, $3, $4); }' |\
  3688          tr 'abcdef' 'ABCDEF'`
  3689     ltv=`echo "$ver:$rev:$typnum:$levnum" |\
  3690          awk -F: '{ printf("%d:%d", $1*10 + $2, $3*10 + $4); }'`
  3692     #   determine date
  3693     if [ ".$tim" = .calc ]; then
  3694         day=`date '+%d'`
  3695         month=`date '+%m'`
  3696         year=`date '+%Y' 2>/dev/null`
  3697         if [ ".$time_year" = . ]; then
  3698             year=`date '+%y'`
  3699             case $year in
  3700                 [5-9][0-9]) year="19$year" ;;
  3701                 [0-4][0-9]) year="20$year" ;;
  3702             esac
  3703         fi
  3704         case $month in
  3705             1|01) month='Jan' ;;
  3706             2|02) month='Feb' ;;
  3707             3|03) month='Mar' ;;
  3708             4|04) month='Apr' ;;
  3709             5|05) month='May' ;;
  3710             6|06) month='Jun' ;;
  3711             7|07) month='Jul' ;;
  3712             8|08) month='Aug' ;;
  3713             9|09) month='Sep' ;;
  3714               10) month='Oct' ;;
  3715               11) month='Nov' ;;
  3716               12) month='Dec' ;;
  3717         esac
  3718         tim="${day}-${month}-${year}"
  3719     fi
  3721     #   perform result actions
  3722     mode=show
  3723     if [ ".$opt_i" != . ]; then
  3724         mode=edit
  3725     elif [ ".$opt_e" = .yes ]; then
  3726         mode=edit
  3727     elif [ ".$opt_s" != . ]; then
  3728         mode=edit
  3729     fi
  3730     if [ ".$mode" = .show ]; then
  3731         #   just display the current version
  3732         case $opt_d in
  3733             short )
  3734                 echo "${ver}.${rev}${typ}${lev}"
  3735                 ;;
  3736             long )
  3737                 echo "${ver}.${rev}${typ}${lev} ($tim)"
  3738                 ;;
  3739             libtool )
  3740                 echo "${ltv}"
  3741                 ;;
  3742             hex )
  3743                 echo "${hex}"
  3744                 ;;
  3745             * ) echo "$msgprefix:Error: invalid argument to option \`-d': \`$opt_d'" 1>&2
  3746                 shtool_exit 1
  3747                 ;;
  3748         esac
  3749     else
  3750         #   update the version file
  3752         #   pre-generate various strings
  3753         triple="${ver}.${rev}${typ}${lev}"
  3754         vHex="$hex"
  3755         vShort="${triple}"
  3756         vLong="${triple} (${tim})"
  3757         vTeX="This is ${name}, Version ${triple} (${tim})"
  3758         vGNU="${name} ${triple} (${tim})"
  3759         vWeb="${name}/${triple}"
  3760         vSCCS="@(#)${name} ${triple} (${tim})"
  3761         vRCS="\$Id: ${name} ${triple} (${tim}) \$"
  3763         #   determine string out of filename
  3764         #   (do NOT try to optimize this in any way because of portability)
  3765         filestr=`util_upper "$file" | tr './%+' '____' | sed -e 's/-/_/g'`
  3767         #   generate uppercase prefix
  3768         prefixupper=`util_upper "$prefix"`
  3770         #   create the version file according the the selected language
  3771         echo "new version: ${vLong}"
  3773         cp /dev/null $file
  3774         case $opt_l in
  3775             txt )
  3776                 echo >>$file ""
  3777                 echo >>$file "  ${file} -- Version Information for ${name} (syntax: Text)"
  3778                 echo >>$file "  [automatically generated and maintained by GNU shtool]"
  3779                 echo >>$file ""
  3780                 echo >>$file "  $vTeX"
  3781                 echo >>$file ""
  3782                 ;;
  3783             c )
  3784                 echo >>$file "/*"
  3785                 echo >>$file "**  ${file} -- Version Information for ${name} (syntax: C/C++)"
  3786                 echo >>$file "**  [automatically generated and maintained by GNU shtool]"
  3787                 echo >>$file "*/"
  3788                 echo >>$file ""
  3789                 echo >>$file "#ifdef _${filestr}_AS_HEADER_"
  3790                 echo >>$file ""
  3791                 echo >>$file "#ifndef _${filestr}_"
  3792                 echo >>$file "#define _${filestr}_"
  3793                 echo >>$file ""
  3794                 echo >>$file "#define ${prefixupper}VERSION ${vHex}"
  3795                 echo >>$file ""
  3796                 echo >>$file "typedef struct {"
  3797                 echo >>$file "    const int   v_hex;"
  3798                 echo >>$file "    const char *v_short;"
  3799                 echo >>$file "    const char *v_long;"
  3800                 echo >>$file "    const char *v_tex;"
  3801                 echo >>$file "    const char *v_gnu;"
  3802                 echo >>$file "    const char *v_web;"
  3803                 echo >>$file "    const char *v_sccs;"
  3804                 echo >>$file "    const char *v_rcs;"
  3805                 echo >>$file "} ${prefix}version_t;"
  3806                 echo >>$file ""
  3807                 echo >>$file "extern ${prefix}version_t ${prefix}version;"
  3808                 echo >>$file ""
  3809                 echo >>$file "#endif /* _${filestr}_ */"
  3810                 echo >>$file ""
  3811                 echo >>$file "#else /* _${filestr}_AS_HEADER_ */"
  3812                 echo >>$file ""
  3813                 echo >>$file "#define _${filestr}_AS_HEADER_"
  3814                 echo >>$file "#include \"${file}\""
  3815                 echo >>$file "#undef  _${filestr}_AS_HEADER_"
  3816                 echo >>$file ""
  3817                 echo >>$file "${prefix}version_t ${prefix}version = {"
  3818                 echo >>$file "    ${vHex},"
  3819                 echo >>$file "    \"${vShort}\","
  3820                 echo >>$file "    \"${vLong}\","
  3821                 echo >>$file "    \"${vTeX}\","
  3822                 echo >>$file "    \"${vGNU}\","
  3823                 echo >>$file "    \"${vWeb}\","
  3824                 echo >>$file "    \"${vSCCS}\","
  3825                 echo >>$file "    \"${vRCS}\""
  3826                 echo >>$file "};"
  3827                 echo >>$file ""
  3828                 echo >>$file "#endif /* _${filestr}_AS_HEADER_ */"
  3829                 echo >>$file ""
  3830                 ;;
  3831             m4 )
  3832                 echo >>$file "##"
  3833                 echo >>$file "##  ${file} -- Version Information for ${name} (syntax: M4)"
  3834                 echo >>$file "##  [automatically generated and maintained by GNU shtool]"
  3835                 echo >>$file "##"
  3836                 echo >>$file ""
  3837                 echo >>$file "m4_define([v_hex],   [${vHex}])"
  3838                 echo >>$file "m4_define([v_short], [${vShort}])"
  3839                 echo >>$file "m4_define([v_long],  [${vLong}])"
  3840                 echo >>$file "m4_define([v_tex],   [${vTeX}])"
  3841                 echo >>$file "m4_define([v_gnu],   [${vGNU}])"
  3842                 echo >>$file "m4_define([v_web],   [${vWeb}])"
  3843                 echo >>$file "m4_define([v_sccs],  [${vSCCS}])"
  3844                 echo >>$file "m4_define([v_rcs],   [${vRCS}])"
  3845                 echo >>$file ""
  3846                 ;;
  3847             perl )
  3848                 echo >>$file "##"
  3849                 echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Perl)"
  3850                 echo >>$file "##  [automatically generated and maintained by GNU shtool]"
  3851                 echo >>$file "##"
  3852                 echo >>$file ""
  3853                 echo >>$file "our \$${prefix}version = {"
  3854                 echo >>$file "    'v_hex'   => ${vHex},"
  3855                 echo >>$file "    'v_short' => \"${vShort}\","
  3856                 echo >>$file "    'v_long'  => \"${vLong}\","
  3857                 echo >>$file "    'v_tex'   => \"${vTeX}\","
  3858                 echo >>$file "    'v_gnu'   => \"${vGNU}\","
  3859                 echo >>$file "    'v_web'   => \"${vWeb}\","
  3860                 echo >>$file "    'v_sccs'  => \"${vSCCS}\","
  3861                 echo >>$file "    'v_rcs'   => \"\\${vRCS}/\""
  3862                 echo >>$file "};"
  3863                 echo >>$file ""
  3864                 echo >>$file "1;"
  3865                 echo >>$file ""
  3866                 ;;
  3867             python )
  3868                 echo >>$file "##"
  3869                 echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Python)"
  3870                 echo >>$file "##  [automatically generated and maintained by GNU shtool]"
  3871                 echo >>$file "##"
  3872                 echo >>$file ""
  3873                 echo >>$file "class ${prefix}version:"
  3874                 echo >>$file "    v_hex       = ${vHex}"
  3875                 echo >>$file "    v_short     = \"${vShort}\""
  3876                 echo >>$file "    v_long      = \"${vLong}\""
  3877                 echo >>$file "    v_tex       = \"${vTeX}\""
  3878                 echo >>$file "    v_gnu       = \"${vGNU}\""
  3879                 echo >>$file "    v_web       = \"${vWeb}\""
  3880                 echo >>$file "    v_sccs      = \"${vSCCS}\""
  3881                 echo >>$file "    v_rcs       = \"${vRCS}\""
  3882                 echo >>$file ""
  3883                 ;;
  3884             * ) echo "$msgprefix:Error: invalid argument to option \`-l': \`$opt_l'" 1>&2
  3885                 shtool_exit 1
  3886                 ;;
  3887         esac
  3888     fi
  3890     shtool_exit 0
  3891     ;;
  3893 path )
  3894     ##
  3895     ##  path -- Deal with program paths
  3896     ##  Copyright (c) 1998-2007 Ralf S. Engelschall <rse@engelschall.com>
  3897     ##
  3899     namelist="$*"
  3901     #   check whether the test command supports the -x option
  3902     if [ -x /bin/sh ] 2>/dev/null; then
  3903         minusx="-x"
  3904     else
  3905         minusx="-r"
  3906     fi
  3908     #   split path string
  3909     paths="`echo $opt_p |\
  3910             sed -e 's/^:/.:/' \
  3911                 -e 's/::/:.:/g' \
  3912                 -e 's/:$/:./' \
  3913                 -e 's/:/ /g'`"
  3915     #   SPECIAL REQUEST
  3916     #   translate forward to reverse path
  3917     if [ ".$opt_r" = .yes ]; then
  3918         if [ "x$namelist" = "x." ]; then
  3919             rp='.'
  3920         else
  3921             rp=''
  3922             for pe in `IFS="$IFS/"; echo $namelist`; do
  3923                 rp="../$rp"
  3924             done
  3925         fi
  3926         echo $rp | sed -e 's:/$::'
  3927         shtool_exit 0
  3928     fi
  3930     #   SPECIAL REQUEST
  3931     #   strip out directory or base name
  3932     if [ ".$opt_d" = .yes ]; then
  3933         echo "$namelist" |\
  3934         sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'
  3935         shtool_exit 0
  3936     fi
  3937     if [ ".$opt_b" = .yes ]; then
  3938         echo "$namelist" |\
  3939         sed -e 's;.*/\([^/]*\)$;\1;'
  3940         shtool_exit 0
  3941     fi
  3943     #   MAGIC SITUATION
  3944     #   Perl Interpreter (perl)
  3945     if [ ".$opt_m" = .yes ] && [ ".$namelist" = .perl ]; then
  3946         rm -f $tmpfile >/dev/null 2>&1
  3947         touch $tmpfile
  3948         found=0
  3949         pc=99
  3950         for dir in $paths; do
  3951             dir=`echo $dir | sed -e 's;/*$;;'`
  3952             nc=99
  3953             for name in perl perl5 miniperl; do
  3954                  if [ $minusx "$dir/$name" ] && [ ! -d "$dir/$name" ]; then
  3955                      perl="$dir/$name"
  3956                      pv=`$perl -e 'printf("%.3f", $]);'`
  3957                      echo "$pv:$pc:$nc:$perl" >>$tmpfile
  3958                      found=1
  3959                  fi
  3960                  nc=`expr $nc - 1`
  3961             done
  3962             pc=`expr $pc - 1`
  3963         done
  3964         if [ $found = 1 ]; then
  3965             perl="`cat $tmpfile | sort -r -u | sed -e 'q' | cut -d: -f4`"
  3966             rm -f $tmpfile >/dev/null 2>&1
  3967             echo "$perl"
  3968             shtool_exit 0
  3969         fi
  3970         rm -f $tmpfile >/dev/null 2>&1
  3971         shtool_exit 1
  3972     fi
  3974     #   MAGIC SITUATION
  3975     #   C pre-processor (cpp)
  3976     if [ ".$opt_m" = .yes ] && [ ".$namelist" = .cpp ]; then
  3977         echo >$tmpfile.c "#include <assert.h>"
  3978         echo >>$tmpfile.c "Syntax Error"
  3979         #   1. try the standard cc -E approach
  3980         cpp="${CC-cc} -E"
  3981         (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
  3982         my_error=`grep -v '^ *+' $tmpfile.out`
  3983         if [ ".$my_error" != . ]; then
  3984             #   2. try the cc -E approach and GCC's -traditional-ccp option
  3985             cpp="${CC-cc} -E -traditional-cpp"
  3986             (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
  3987             my_error=`grep -v '^ *+' $tmpfile.out`
  3988             if [ ".$my_error" != . ]; then
  3989                 #   3. try a standalone cpp command in path and lib dirs
  3990                 for path in $paths /lib /usr/lib /usr/local/lib; do
  3991                     path=`echo $path | sed -e 's;/*$;;'`
  3992                     if [ $minusx "$path/cpp" ] && [ ! -d "$path/cpp" ]; then
  3993                         cpp="$path/cpp"
  3994                         break
  3995                     fi
  3996                 done
  3997                 if [ ".$cpp" != . ]; then
  3998                     (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
  3999                     my_error=`grep -v '^ *+' $tmpfile.out`
  4000                     if [ ".$my_error" != . ]; then
  4001                         #   ok, we gave up...
  4002                         cpp=''
  4003                     fi
  4004                 fi
  4005             fi
  4006         fi
  4007         rm -f $tmpfile >/dev/null 2>&1
  4008         rm -f $tmpfile.c $tmpfile.out >/dev/null 2>&1
  4009         if [ ".$cpp" != . ]; then
  4010             echo "$cpp"
  4011             shtool_exit 0
  4012         fi
  4013         shtool_exit 1
  4014     fi
  4016     #   STANDARD SITUATION
  4017     #   iterate over names
  4018     for name in $namelist; do
  4019         #   iterate over paths
  4020         for path in $paths; do
  4021             path=`echo $path | sed -e 's;/*$;;'`
  4022             if [ $minusx "$path/$name" ] && [ ! -d "$path/$name" ]; then
  4023                 if [ ".$opt_s" != .yes ]; then
  4024                     echo "$path/$name"
  4025                 fi
  4026                 shtool_exit 0
  4027             fi
  4028         done
  4029     done
  4031     shtool_exit 1
  4032     ;;
  4034 esac
  4036 shtool_exit 0

mercurial