1#!/bin/sh
2##
3##  GNU shtool -- The GNU Portable Shell Tool
4##  Copyright (c) 1994-2006 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.6 (19-Apr-2006)
10##  Contents: 7/19 available modules
11##
12
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##
36
37##
38##  Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
39##
40##  Available commands:
41##    echo       Print string with optional construct expansion
42##    install    Install a program, script or datafile
43##    mkdir      Make one or more directories
44##    fixperm    Fix file permissions inside a source tree
45##    tarball    Roll distribution tarballs
46##    scpp       Sharing C Pre-Processor
47##    version    Maintain a version information file
48##
49##  Not available commands (because module was not built-in):
50##    mdate      Pretty-print modification time of a file or dir
51##    table      Pretty-print a field-separated list as a table
52##    prop       Display progress with a running propeller
53##    move       Move files with simultaneous substitution
54##    mkln       Make link with calculation of relative paths
55##    mkshadow   Make a shadow tree through symbolic links
56##    rotate     Logfile rotation
57##    subst      Apply sed(1) substitution operations
58##    platform   Platform Identification Utility
59##    arx        Extended archive command
60##    slo        Separate linker options by library class
61##    path       Deal with program paths
62##
63
64#   maximum Bourne-Shell compatibility
65if [ ".$ZSH_VERSION" != . ] && (emulate sh) >/dev/null 2>&1; then
66    #   reconfigure zsh(1)
67    emulate sh
68    NULLCMD=:
69    alias -g '${1+"$@"}'='"$@"'
70elif [ ".$BASH_VERSION" != . ] && (set -o posix) >/dev/null 2>&1; then
71    #   reconfigure bash(1)
72    set -o posix
73fi
74
75#   maximum independence of NLS nuisances
76for var in \
77    LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
78    LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
79    LC_TELEPHONE LC_TIME
80do
81    if (set +x; test -z "`(eval $var=C; export $var) 2>&1`"); then
82        eval $var=C; export $var
83    else
84        unset $var
85    fi
86done
87
88#   initial command line handling
89if [ $# -eq 0 ]; then
90    echo "$0:Error: invalid command line" 1>&2
91    echo "$0:Hint:  run \`$0 -h' for usage" 1>&2
92    exit 1
93fi
94if [ ".$1" = ".-h" ] || [ ".$1" = ".--help" ]; then
95    echo "This is GNU shtool, version 2.0.6 (19-Apr-2006)"
96    echo 'Copyright (c) 1994-2006 Ralf S. Engelschall <rse@engelschall.com>'
97    echo 'Report bugs to <bug-shtool@gnu.org>'
98    echo ''
99    echo 'Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]'
100    echo ''
101    echo 'Available global <options>:'
102    echo '  -v, --version   display shtool version information'
103    echo '  -h, --help      display shtool usage help page (this one)'
104    echo '  -d, --debug     display shell trace information'
105    echo '  -r, --recreate  recreate this shtool script via shtoolize'
106    echo ''
107    echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
108    echo '  echo     [-n|--newline] [-e|--expand] [<string> ...]'
109    echo '  install  [-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy]'
110    echo '           [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>]'
111    echo '           [-o|--owner <owner>] [-g|--group <group>] [-e|--exec'
112    echo '           <sed-cmd>] <file> [<file> ...] <path>'
113    echo '  mkdir    [-t|--trace] [-f|--force] [-p|--parents] [-m|--mode'
114    echo '           <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir>'
115    echo '           [<dir> ...]'
116    echo '  fixperm  [-v|--verbose] [-t|--trace] <path> [<path> ...]'
117    echo '  tarball  [-t|--trace] [-v|--verbose] [-o|--output <tarball>]'
118    echo '           [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user'
119    echo '           <user>] [-g|--group <group>] [-e|--exclude <pattern>]'
120    echo '           <path> [<path> ...]'
121    echo '  scpp     [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]'
122    echo '           [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark'
123    echo '           <mark>] [-D|--define <dname>] [-C|--class <cname>]'
124    echo '           <file> [<file> ...]'
125    echo '  version  [-l|--language <lang>] [-n|--name <name>] [-p|--prefix'
126    echo '           <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase'
127    echo '           <knob>] [-d|--display <type>] <file>'
128    echo ''
129    echo 'Not available <cmd-name> (because module was not built-in):'
130    echo '  mdate    [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]'
131    echo '           [-f|--field-sep <str>] [-o|--order <spec>] <path>'
132    echo '  table    [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns'
133    echo '           <cols>] [-s|--strip <strip>] <str><sep><str>...'
134    echo '  prop     [-p|--prefix <str>]'
135    echo '  move     [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]'
136    echo '           <src-file> <dst-file>'
137    echo '  mkln     [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>'
138    echo '           [<src-path> ...] <dst-path>'
139    echo '  mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>'
140    echo '  rotate   [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files'
141    echo '           <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]'
142    echo '           [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]'
143    echo '           [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode'
144    echo '           <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate'
145    echo '           <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]'
146    echo '  subst    [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]'
147    echo '           [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup'
148    echo '           <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]'
149    echo '           [...]'
150    echo '  platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc'
151    echo '           <string>] [-L|--lower] [-U|--upper] [-v|--verbose]'
152    echo '           [-c|--concise] [-n|--no-newline] [-t|--type <type>]'
153    echo '           [-V|--version] [-h|--help]'
154    echo '  arx      [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>'
155    echo '           ...]'
156    echo '  slo      [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>'
157    echo '           ...]'
158    echo '  path     [-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename]'
159    echo '           [-m|--magic] [-p|--path <path>] <str> [<str> ...]'
160    echo ''
161    exit 0
162fi
163if [ ".$1" = ".-v" ] || [ ".$1" = ".--version" ]; then
164    echo "GNU shtool 2.0.6 (19-Apr-2006)"
165    exit 0
166fi
167if [ ".$1" = ".-r" ] || [ ".$1" = ".--recreate" ]; then
168    shtoolize -oshtool echo install mkdir fixperm tarball scpp version
169    exit 0
170fi
171if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
172    shift
173    set -x
174fi
175name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
176case "$name" in
177    echo|install|mkdir|fixperm|tarball|scpp|version )
178        #   implicit tool command selection
179        tool="$name"
180        ;;
181    * )
182        #   explicit tool command selection
183        tool="$1"
184        shift
185        ;;
186esac
187arg_spec=""
188opt_spec=""
189gen_tmpfile=no
190
191##
192##  DISPATCH INTO SCRIPT PROLOG
193##
194
195case $tool in
196    echo )
197        str_tool="echo"
198        str_usage="[-n|--newline] [-e|--expand] [<string> ...]"
199        arg_spec="0+"
200        opt_spec="n.e."
201        opt_alias="n:newline,e:expand"
202        opt_n=no
203        opt_e=no
204        ;;
205    install )
206        str_tool="install"
207        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>"
208        arg_spec="1+"
209        opt_spec="v.t.d.c.C.s.m:o:g:e+"
210        opt_alias="v:verbose,t:trace,d:mkdir,c:copy,C:compare-copy,s:strip,m:mode,o:owner,g:group,e:exec"
211        opt_v=no
212        opt_t=no
213        opt_d=no
214        opt_c=no
215        opt_C=no
216        opt_s=no
217        opt_m="0755"
218        opt_o=""
219        opt_g=""
220        opt_e=""
221        ;;
222    mkdir )
223        str_tool="mkdir"
224        str_usage="[-t|--trace] [-f|--force] [-p|--parents] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir> [<dir> ...]"
225        arg_spec="1+"
226        opt_spec="t.f.p.m:o:g:"
227        opt_alias="t:trace,f:force,p:parents,m:mode,o:owner,g:group"
228        opt_t=no
229        opt_f=no
230        opt_p=no
231        opt_m=""
232        opt_o=""
233        opt_g=""
234        ;;
235    fixperm )
236        str_tool="fixperm"
237        str_usage="[-v|--verbose] [-t|--trace] <path> [<path> ...]"
238        arg_spec="1+"
239        opt_spec="v.t."
240        opt_alias="v:verbose,t:trace"
241        opt_v=no
242        opt_t=no
243        ;;
244    tarball )
245        str_tool="tarball"
246        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> ...]"
247        gen_tmpfile=yes
248        arg_spec="1+"
249        opt_spec="t.v.o:c:d:u:g:e:"
250        opt_alias="t:trace,v:verbose,o:output,c:compress,d:directory,u:user,g:group,e:exclude"
251        opt_t=no
252        opt_v=no
253        opt_o=""
254        opt_c=""
255        opt_d=""
256        opt_u=""
257        opt_g=""
258        opt_e="CVS,\\.cvsignore,\\.svn,\\.[oa]\$"
259        ;;
260    scpp )
261        str_tool="scpp"
262        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> ...]"
263        gen_tmpfile=yes
264        arg_spec="1+"
265        opt_spec="v.p.f+o:t:M:D:C:"
266        opt_alias="v:verbose,p:preserve,f:filter,o:output,t:template,M:mark,D:define,C:class"
267        opt_v=no
268        opt_p=no
269        opt_f=""
270        opt_o="lib.h"
271        opt_t="lib.h.in"
272        opt_M="%%MARK%%"
273        opt_D="cpp"
274        opt_C="intern"
275        ;;
276    version )
277        str_tool="version"
278        str_usage="[-l|--language <lang>] [-n|--name <name>] [-p|--prefix <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase <knob>] [-d|--display <type>] <file>"
279        arg_spec="1="
280        opt_spec="l:n:p:s:i:e.d:"
281        opt_alias="l:language,n:name,p:prefix,s:set,e:edit,i:increase,d:display"
282        opt_l="txt"
283        opt_n="unknown"
284        opt_p=""
285        opt_s=""
286        opt_e="no"
287        opt_i=""
288        opt_d="short"
289        ;;
290    -* )
291        echo "$0:Error: unknown option \`$tool'" 2>&1
292        echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
293        exit 1
294        ;;
295    * )
296        echo "$0:Error: unknown command \`$tool'" 2>&1
297        echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
298        exit 1
299        ;;
300esac
301
302##
303##  COMMON UTILITY CODE
304##
305
306#   commonly used ASCII values
307ASC_TAB="	"
308ASC_NL="
309"
310
311#   determine name of tool
312if [ ".$tool" != . ]; then
313    #   used inside shtool script
314    toolcmd="$0 $tool"
315    toolcmdhelp="shtool $tool"
316    msgprefix="shtool:$tool"
317else
318    #   used as standalone script
319    toolcmd="$0"
320    toolcmdhelp="sh $0"
321    msgprefix="$str_tool"
322fi
323
324#   parse argument specification string
325eval `echo $arg_spec |\
326      sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
327
328#   parse option specification string
329eval `echo h.$opt_spec |\
330      sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
331
332#   parse option alias string
333eval `echo h:help,$opt_alias |\
334      sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
335
336#   interate over argument line
337opt_PREV=''
338while [ $# -gt 0 ]; do
339    #   special option stops processing
340    if [ ".$1" = ".--" ]; then
341        shift
342        break
343    fi
344
345    #   determine option and argument
346    opt_ARG_OK=no
347    if [ ".$opt_PREV" != . ]; then
348        #   merge previous seen option with argument
349        opt_OPT="$opt_PREV"
350        opt_ARG="$1"
351        opt_ARG_OK=yes
352        opt_PREV=''
353    else
354        #   split argument into option and argument
355        case "$1" in
356            --[a-zA-Z0-9]*=*)
357                eval `echo "x$1" |\
358                      sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
359                opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
360                eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
361                ;;
362            --[a-zA-Z0-9]*)
363                opt_OPT=`echo "x$1" | cut -c4-`
364                opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
365                eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
366                opt_ARG=''
367                ;;
368            -[a-zA-Z0-9]*)
369                eval `echo "x$1" |\
370                      sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
371                          -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
372                ;;
373            -[a-zA-Z0-9])
374                opt_OPT=`echo "x$1" | cut -c3-`
375                opt_ARG=''
376                ;;
377            *)
378                break
379                ;;
380        esac
381    fi
382
383    #   eat up option
384    shift
385
386    #   determine whether option needs an argument
387    eval "opt_MODE=\$opt_MODE_${opt_OPT}"
388    if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
389        if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
390            opt_PREV="$opt_OPT"
391            continue
392        fi
393    fi
394
395    #   process option
396    case $opt_MODE in
397        '.' )
398            #   boolean option
399            eval "opt_${opt_OPT}=yes"
400            ;;
401        ':' )
402            #   option with argument (multiple occurances override)
403            eval "opt_${opt_OPT}=\"\$opt_ARG\""
404            ;;
405        '+' )
406            #   option with argument (multiple occurances append)
407            eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\""
408            ;;
409        * )
410            echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2
411            echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
412            exit 1
413            ;;
414    esac
415done
416if [ ".$opt_PREV" != . ]; then
417    echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2
418    echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
419    exit 1
420fi
421
422#   process help option
423if [ ".$opt_h" = .yes ]; then
424    echo "Usage: $toolcmdhelp $str_usage"
425    exit 0
426fi
427
428#   complain about incorrect number of arguments
429case $arg_MODE in
430    '=' )
431        if [ $# -ne $arg_NUMS ]; then
432            echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
433            echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
434            exit 1
435        fi
436        ;;
437    '+' )
438        if [ $# -lt $arg_NUMS ]; then
439            echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
440            echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
441            exit 1
442        fi
443        ;;
444esac
445
446#   establish a temporary file on request
447if [ ".$gen_tmpfile" = .yes ]; then
448    #   create (explicitly) secure temporary directory
449    if [ ".$TMPDIR" != . ]; then
450        tmpdir="$TMPDIR"
451    elif [ ".$TEMPDIR" != . ]; then
452        tmpdir="$TEMPDIR"
453    else
454        tmpdir="/tmp"
455    fi
456    tmpdir="$tmpdir/.shtool.$$"
457    ( umask 077
458      rm -rf "$tmpdir" >/dev/null 2>&1 || true
459      mkdir  "$tmpdir" >/dev/null 2>&1
460      if [ $? -ne 0 ]; then
461          echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2
462          exit 1
463      fi
464    )
465
466    #   create (implicitly) secure temporary file
467    tmpfile="$tmpdir/shtool.tmp"
468    touch "$tmpfile"
469fi
470
471#   utility function: map string to lower case
472util_lower () {
473    echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
474}
475
476#   utility function: map string to upper case
477util_upper () {
478    echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
479}
480
481#   cleanup procedure
482shtool_exit () {
483    rc="$1"
484    if [ ".$gen_tmpfile" = .yes ]; then
485        rm -rf "$tmpdir" >/dev/null 2>&1 || true
486    fi
487    exit $rc
488}
489
490##
491##  DISPATCH INTO SCRIPT BODY
492##
493
494case $tool in
495
496echo )
497    ##
498    ##  echo -- Print string with optional construct expansion
499    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
500    ##
501
502    text="$*"
503
504    #   check for broken escape sequence expansion
505    seo=''
506    bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
507    if [ ".$bytes" != .3 ]; then
508        bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
509        if [ ".$bytes" = .3 ]; then
510            seo='-E'
511        fi
512    fi
513
514    #   check for existing -n option (to suppress newline)
515    minusn=''
516    bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
517    if [ ".$bytes" = .3 ]; then
518        minusn='-n'
519    fi
520
521    #   determine terminal bold sequence
522    term_bold=''
523    term_norm=''
524    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then
525        case $TERM in
526            #   for the most important terminal types we directly know the sequences
527            xterm|xterm*|vt220|vt220*)
528                term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
529                term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
530                ;;
531            vt100|vt100*|cygwin)
532                term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
533                term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
534                ;;
535            #   for all others, we try to use a possibly existing `tput' or `tcout' utility
536            * )
537                paths=`echo $PATH | sed -e 's/:/ /g'`
538                for tool in tput tcout; do
539                    for dir in $paths; do
540                        if [ -r "$dir/$tool" ]; then
541                            for seq in bold md smso; do # 'smso' is last
542                                bold="`$dir/$tool $seq 2>/dev/null`"
543                                if [ ".$bold" != . ]; then
544                                    term_bold="$bold"
545                                    break
546                                fi
547                            done
548                            if [ ".$term_bold" != . ]; then
549                                for seq in sgr0 me rmso init reset; do # 'reset' is last
550                                    norm="`$dir/$tool $seq 2>/dev/null`"
551                                    if [ ".$norm" != . ]; then
552                                        term_norm="$norm"
553                                        break
554                                    fi
555                                done
556                            fi
557                            break
558                        fi
559                    done
560                    if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then
561                        break;
562                    fi
563                done
564                ;;
565        esac
566        if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then
567            echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
568            term_bold=''
569            term_norm=''
570        fi
571    fi
572
573    #   determine user name
574    username=''
575    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then
576        username="`(id -un) 2>/dev/null`"
577        if [ ".$username" = . ]; then
578            str="`(id) 2>/dev/null`"
579            if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
580                username=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*[0-9]*(//' -e 's/).*$//'`
581            fi
582            if [ ".$username" = . ]; then
583                username="$LOGNAME"
584                if [ ".$username" = . ]; then
585                    username="$USER"
586                    if [ ".$username" = . ]; then
587                        username="`(whoami) 2>/dev/null |\
588                                   awk '{ printf("%s", $1); }'`"
589                        if [ ".$username" = . ]; then
590                            username="`(who am i) 2>/dev/null |\
591                                       awk '{ printf("%s", $1); }'`"
592                            if [ ".$username" = . ]; then
593                                username='unknown'
594                            fi
595                        fi
596                    fi
597                fi
598            fi
599        fi
600    fi
601
602    #   determine user id
603    userid=''
604    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then
605        userid="`(id -u) 2>/dev/null`"
606        if [ ".$userid" = . ]; then
607            userid="`(id -u ${username}) 2>/dev/null`"
608            if [ ".$userid" = . ]; then
609                str="`(id) 2>/dev/null`"
610                if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
611                    userid=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*//' -e 's/(.*$//'`
612                fi
613                if [ ".$userid" = . ]; then
614                    userid=`(getent passwd ${username}) 2>/dev/null | \
615                            sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
616                    if [ ".$userid" = . ]; then
617                        userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
618                                sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
619                        if [ ".$userid" = . ]; then
620                            userid=`(ypcat passwd) 2>/dev/null |
621                                    grep "^${username}:" | \
622                                    sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
623                            if [ ".$userid" = . ]; then
624                                userid='?'
625                            fi
626                        fi
627                    fi
628                fi
629            fi
630        fi
631    fi
632
633    #   determine (primary) group id
634    groupid=''
635    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then
636        groupid="`(id -g ${username}) 2>/dev/null`"
637        if [ ".$groupid" = . ]; then
638            str="`(id) 2>/dev/null`"
639            if [ ".`echo $str | grep 'gid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
640                groupid=`echo $str | sed -e 's/^.*gid[ 	]*=[ 	]*//' -e 's/(.*$//'`
641            fi
642            if [ ".$groupid" = . ]; then
643                groupid=`(getent passwd ${username}) 2>/dev/null | \
644                         sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
645                if [ ".$groupid" = . ]; then
646                    groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
647                             sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
648                    if [ ".$groupid" = . ]; then
649                        groupid=`(ypcat passwd) 2>/dev/null | grep "^${username}:" | \
650                                 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
651                        if [ ".$groupid" = . ]; then
652                            groupid='?'
653                        fi
654                    fi
655                fi
656            fi
657        fi
658    fi
659
660    #   determine (primary) group name
661    groupname=''
662    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then
663        groupname="`(id -gn ${username}) 2>/dev/null`"
664        if [ ".$groupname" = . ]; then
665            str="`(id) 2>/dev/null`"
666            if [ ".`echo $str | grep 'gid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
667                groupname=`echo $str | sed -e 's/^.*gid[ 	]*=[ 	]*[0-9]*(//' -e 's/).*$//'`
668            fi
669            if [ ".$groupname" = . ]; then
670                groupname=`(getent group) 2>/dev/null | \
671                           grep "^[^:]*:[^:]*:${groupid}:" | \
672                           sed -e 's/:.*$//'`
673                if [ ".$groupname" = . ]; then
674                    groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
675                               sed -e 's/:.*$//'`
676                    if [ ".$groupname" = . ]; then
677                        groupname=`(ypcat group) 2>/dev/null | \
678                                   grep "^[^:]*:[^:]*:${groupid}:" | \
679                                   sed -e 's/:.*$//'`
680                        if [ ".$groupname" = . ]; then
681                            groupname='?'
682                        fi
683                    fi
684                fi
685            fi
686        fi
687    fi
688
689    #   determine host and domain name
690    hostname=''
691    domainname=''
692    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then
693        hostname="`(uname -n) 2>/dev/null |\
694                   awk '{ printf("%s", $1); }'`"
695        if [ ".$hostname" = . ]; then
696            hostname="`(hostname) 2>/dev/null |\
697                       awk '{ printf("%s", $1); }'`"
698            if [ ".$hostname" = . ]; then
699                hostname='unknown'
700            fi
701        fi
702        case $hostname in
703            *.* )
704                domainname=".`echo $hostname | cut -d. -f2-`"
705                hostname="`echo $hostname | cut -d. -f1`"
706                ;;
707        esac
708    fi
709    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then
710        if [ ".$domainname" = . ]; then
711            if [ -f /etc/resolv.conf ]; then
712                domainname="`grep '^[ 	]*domain' /etc/resolv.conf | sed -e 'q' |\
713                             sed -e 's/.*domain//' \
714                                 -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
715                                 -e 's/^\.//' -e 's/^/./' |\
716                             awk '{ printf("%s", $1); }'`"
717                if [ ".$domainname" = . ]; then
718                    domainname="`grep '^[ 	]*search' /etc/resolv.conf | sed -e 'q' |\
719                                 sed -e 's/.*search//' \
720                                     -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
721                                     -e 's/ .*//' -e 's/	.*//' \
722                                     -e 's/^\.//' -e 's/^/./' |\
723                                 awk '{ printf("%s", $1); }'`"
724                fi
725            fi
726        fi
727    fi
728
729    #   determine current time
730    time_day=''
731    time_month=''
732    time_year=''
733    time_monthname=''
734    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then
735        time_day=`date '+%d'`
736        time_month=`date '+%m'`
737        time_year=`date '+%Y' 2>/dev/null`
738        if [ ".$time_year" = . ]; then
739            time_year=`date '+%y'`
740            case $time_year in
741                [5-9][0-9]) time_year="19$time_year" ;;
742                [0-4][0-9]) time_year="20$time_year" ;;
743            esac
744        fi
745        case $time_month in
746            1|01) time_monthname='Jan' ;;
747            2|02) time_monthname='Feb' ;;
748            3|03) time_monthname='Mar' ;;
749            4|04) time_monthname='Apr' ;;
750            5|05) time_monthname='May' ;;
751            6|06) time_monthname='Jun' ;;
752            7|07) time_monthname='Jul' ;;
753            8|08) time_monthname='Aug' ;;
754            9|09) time_monthname='Sep' ;;
755              10) time_monthname='Oct' ;;
756              11) time_monthname='Nov' ;;
757              12) time_monthname='Dec' ;;
758        esac
759    fi
760
761    #   expand special ``%x'' constructs
762    if [ ".$opt_e" = .yes ]; then
763        text=`echo $seo "$text" |\
764              sed -e "s/%B/${term_bold}/g" \
765                  -e "s/%b/${term_norm}/g" \
766                  -e "s/%u/${username}/g" \
767                  -e "s/%U/${userid}/g" \
768                  -e "s/%g/${groupname}/g" \
769                  -e "s/%G/${groupid}/g" \
770                  -e "s/%h/${hostname}/g" \
771                  -e "s/%d/${domainname}/g" \
772                  -e "s/%D/${time_day}/g" \
773                  -e "s/%M/${time_month}/g" \
774                  -e "s/%Y/${time_year}/g" \
775                  -e "s/%m/${time_monthname}/g" 2>/dev/null`
776    fi
777
778    #   create output
779    if [ .$opt_n = .no ]; then
780        echo $seo "$text"
781    else
782        #   the harder part: echo -n is best, because
783        #   awk may complain about some \xx sequences.
784        if [ ".$minusn" != . ]; then
785            echo $seo $minusn "$text"
786        else
787            echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
788        fi
789    fi
790
791    shtool_exit 0
792    ;;
793
794install )
795    ##
796    ##  install -- Install a program, script or datafile
797    ##  Copyright (c) 1997-2006 Ralf S. Engelschall <rse@engelschall.com>
798    ##
799
800    #   special case: "shtool install -d <dir> [...]" internally
801    #   maps to "shtool mkdir -f -p -m 755 <dir> [...]"
802    if [ "$opt_d" = yes ]; then
803        cmd="$0 mkdir -f -p -m 755"
804        if [ ".$opt_o" != . ]; then
805            cmd="$cmd -o '$opt_o'"
806        fi
807        if [ ".$opt_g" != . ]; then
808            cmd="$cmd -g '$opt_g'"
809        fi
810        if [ ".$opt_v" = .yes ]; then
811            cmd="$cmd -v"
812        fi
813        if [ ".$opt_t" = .yes ]; then
814            cmd="$cmd -t"
815        fi
816        for dir in "$@"; do
817            eval "$cmd $dir" || shtool_exit $?
818        done
819        shtool_exit 0
820    fi
821
822    #   determine source(s) and destination
823    argc=$#
824    srcs=""
825    while [ $# -gt 1 ]; do
826        srcs="$srcs $1"
827        shift
828    done
829    dstpath="$1"
830
831    #   type check for destination
832    dstisdir=0
833    if [ -d $dstpath ]; then
834        dstpath=`echo "$dstpath" | sed -e 's:/$::'`
835        dstisdir=1
836    fi
837
838    #   consistency check for destination
839    if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then
840        echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
841        shtool_exit 1
842    fi
843
844    #   iterate over all source(s)
845    for src in $srcs; do
846        dst=$dstpath
847
848        #   if destination is a directory, append the input filename
849        if [ $dstisdir = 1 ]; then
850            dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
851            dst="$dst/$dstfile"
852        fi
853
854        #   check for correct arguments
855        if [ ".$src" = ".$dst" ]; then
856            echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
857            continue
858        fi
859        if [ -d "$src" ]; then
860            echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
861            continue
862        fi
863
864        #   make a temp file name in the destination directory
865        dsttmp=`echo $dst |\
866                sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
867                    -e "s;\$;/#INST@$$#;"`
868
869        #   verbosity
870        if [ ".$opt_v" = .yes ]; then
871            echo "$src -> $dst" 1>&2
872        fi
873
874        #   copy or move the file name to the temp name
875        #   (because we might be not allowed to change the source)
876        if [ ".$opt_C" = .yes ]; then
877            opt_c=yes
878        fi
879        if [ ".$opt_c" = .yes ]; then
880            if [ ".$opt_t" = .yes ]; then
881                echo "cp $src $dsttmp" 1>&2
882            fi
883            cp $src $dsttmp || shtool_exit $?
884        else
885            if [ ".$opt_t" = .yes ]; then
886                echo "mv $src $dsttmp" 1>&2
887            fi
888            mv $src $dsttmp || shtool_exit $?
889        fi
890
891        #   adjust the target file
892        if [ ".$opt_e" != . ]; then
893            sed='sed'
894            OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
895            for e
896            do
897                sed="$sed -e '$e'"
898            done
899            cp $dsttmp $dsttmp.old
900            chmod u+w $dsttmp
901            eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $?
902            rm -f $dsttmp.old
903        fi
904        if [ ".$opt_s" = .yes ]; then
905            if [ ".$opt_t" = .yes ]; then
906                echo "strip $dsttmp" 1>&2
907            fi
908            strip $dsttmp || shtool_exit $?
909        fi
910        if [ ".$opt_o" != . ]; then
911            if [ ".$opt_t" = .yes ]; then
912                echo "chown $opt_o $dsttmp" 1>&2
913            fi
914            chown $opt_o $dsttmp || shtool_exit $?
915        fi
916        if [ ".$opt_g" != . ]; then
917            if [ ".$opt_t" = .yes ]; then
918                echo "chgrp $opt_g $dsttmp" 1>&2
919            fi
920            chgrp $opt_g $dsttmp || shtool_exit $?
921        fi
922        if [ ".$opt_m" != ".-" ]; then
923            if [ ".$opt_t" = .yes ]; then
924                echo "chmod $opt_m $dsttmp" 1>&2
925            fi
926            chmod $opt_m $dsttmp || shtool_exit $?
927        fi
928
929        #   determine whether to do a quick install
930        #   (has to be done _after_ the strip was already done)
931        quick=no
932        if [ ".$opt_C" = .yes ]; then
933            if [ -r $dst ]; then
934                if cmp -s $src $dst; then
935                    quick=yes
936                fi
937            fi
938        fi
939
940        #   finally, install the file to the real destination
941        if [ $quick = yes ]; then
942            if [ ".$opt_t" = .yes ]; then
943                echo "rm -f $dsttmp" 1>&2
944            fi
945            rm -f $dsttmp
946        else
947            if [ ".$opt_t" = .yes ]; then
948                echo "rm -f $dst && mv $dsttmp $dst" 1>&2
949            fi
950            rm -f $dst && mv $dsttmp $dst
951        fi
952    done
953
954    shtool_exit 0
955    ;;
956
957mkdir )
958    ##
959    ##  mkdir -- Make one or more directories
960    ##  Copyright (c) 1996-2006 Ralf S. Engelschall <rse@engelschall.com>
961    ##
962
963    errstatus=0
964    for p in ${1+"$@"}; do
965        #   if the directory already exists...
966        if [ -d "$p" ]; then
967            if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
968                echo "$msgprefix:Error: directory already exists: $p" 1>&2
969                errstatus=1
970                break
971            else
972                continue
973            fi
974        fi
975        #   if the directory has to be created...
976        if [ ".$opt_p" = .no ]; then
977            if [ ".$opt_t" = .yes ]; then
978                echo "mkdir $p" 1>&2
979            fi
980            mkdir $p || errstatus=$?
981            if [ ".$opt_o" != . ]; then
982                if [ ".$opt_t" = .yes ]; then
983                    echo "chown $opt_o $p" 1>&2
984                fi
985                chown $opt_o $p || errstatus=$?
986            fi
987            if [ ".$opt_g" != . ]; then
988                if [ ".$opt_t" = .yes ]; then
989                    echo "chgrp $opt_g $p" 1>&2
990                fi
991                chgrp $opt_g $p || errstatus=$?
992            fi
993            if [ ".$opt_m" != . ]; then
994                if [ ".$opt_t" = .yes ]; then
995                    echo "chmod $opt_m $p" 1>&2
996                fi
997                chmod $opt_m $p || errstatus=$?
998            fi
999        else
1000            #   the smart situation
1001            set fnord `echo ":$p" |\
1002                       sed -e 's/^:\//%/' \
1003                           -e 's/^://' \
1004                           -e 's/\// /g' \
1005                           -e 's/^%/\//'`
1006            shift
1007            pathcomp=''
1008            for d in ${1+"$@"}; do
1009                pathcomp="$pathcomp$d"
1010                case "$pathcomp" in
1011                    -* ) pathcomp="./$pathcomp" ;;
1012                esac
1013                if [ ! -d "$pathcomp" ]; then
1014                    if [ ".$opt_t" = .yes ]; then
1015                        echo "mkdir $pathcomp" 1>&2
1016                    fi
1017                    mkdir $pathcomp || errstatus=$?
1018                    if [ ".$opt_o" != . ]; then
1019                        if [ ".$opt_t" = .yes ]; then
1020                            echo "chown $opt_o $pathcomp" 1>&2
1021                        fi
1022                        chown $opt_o $pathcomp || errstatus=$?
1023                    fi
1024                    if [ ".$opt_g" != . ]; then
1025                        if [ ".$opt_t" = .yes ]; then
1026                            echo "chgrp $opt_g $pathcomp" 1>&2
1027                        fi
1028                        chgrp $opt_g $pathcomp || errstatus=$?
1029                    fi
1030                    if [ ".$opt_m" != . ]; then
1031                        if [ ".$opt_t" = .yes ]; then
1032                            echo "chmod $opt_m $pathcomp" 1>&2
1033                        fi
1034                        chmod $opt_m $pathcomp || errstatus=$?
1035                    fi
1036                fi
1037                pathcomp="$pathcomp/"
1038            done
1039        fi
1040    done
1041
1042    shtool_exit $errstatus
1043    ;;
1044
1045fixperm )
1046    ##
1047    ##  fixperm -- Fix file permissions inside a source tree
1048    ##  Copyright (c) 1996-2006 Ralf S. Engelschall <rse@engelschall.com>
1049    ##
1050
1051    paths="$*"
1052
1053    #   check whether the test command supports the -x option
1054    if [ -x /bin/sh ] 2>/dev/null; then
1055        minusx="-x"
1056    else
1057        minusx="-r"
1058    fi
1059
1060    #   iterate over paths
1061    for p in $paths; do
1062        for file in `find $p -depth -print`; do
1063            if [ -f $file ]; then
1064                if [ $minusx $file ]; then
1065                    if [ ".$opt_v" = .yes ]; then
1066                        echo "-rwxr-xr-x $file" 2>&1
1067                    fi
1068                    if [ ".$opt_t" = .yes ]; then
1069                        echo "chmod 755 $file" 2>&1
1070                    fi
1071                    chmod 755 $file
1072                else
1073                    if [ ".$opt_v" = .yes ]; then
1074                        echo "-rw-r--r-- $file" 2>&1
1075                    fi
1076                    if [ ".$opt_t" = .yes ]; then
1077                        echo "chmod 644 $file" 2>&1
1078                    fi
1079                    chmod 644 $file
1080                fi
1081                continue
1082            fi
1083            if [ -d $file ]; then
1084                if [ ".$opt_v" = .yes ]; then
1085                    echo "drwxr-xr-x $file" 2>&1
1086                fi
1087                if [ ".$opt_t" = .yes ]; then
1088                    echo "chmod 755 $file" 2>&1
1089                fi
1090                chmod 755 $file
1091                continue
1092            fi
1093            if [ ".$opt_v" = .yes ]; then
1094                echo "?????????? $file" 2>&1
1095            fi
1096        done
1097    done
1098
1099    shtool_exit 0
1100    ;;
1101
1102tarball )
1103    ##
1104    ##  tarball -- Roll distribution tarballs
1105    ##  Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
1106    ##
1107
1108    srcs="$*"
1109
1110    #   check whether the test command supports the -x option
1111    if [ -x /bin/sh ] 2>/dev/null; then
1112        minusx="-x"
1113    else
1114        minusx="-r"
1115    fi
1116
1117    #   find the tools
1118    paths="`echo $PATH |\
1119            sed -e 's%/*:%:%g' -e 's%/*$%%' \
1120                -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
1121                -e 's/:/ /g'`"
1122    for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do
1123        prg=`echo $spec | sed -e 's/:.*$//'`
1124        tools=`echo $spec | sed -e 's/^.*://'`
1125        eval "prg_${prg}=''"
1126        #   iterate over tools
1127        for tool in `echo $tools | sed -e 's/,/ /g'`; do
1128            #   iterate over paths
1129            for path in $paths; do
1130                if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then
1131                    eval "prg_${prg}=\"$path/$tool\""
1132                    break
1133                fi
1134            done
1135            eval "val=\$prg_${prg}"
1136            if [ ".$val" != . ]; then
1137                break
1138            fi
1139        done
1140    done
1141
1142    #   expand source paths
1143    exclude=''
1144    for pat in `echo $opt_e | sed 's/,/ /g'`; do
1145        exclude="$exclude | grep -v '$pat'"
1146    done
1147    if [ ".$opt_t" = .yes ]; then
1148        echo "cp /dev/null $tmpfile.lst" 1>&2
1149    fi
1150    cp /dev/null $tmpfile.lst
1151    for src in $srcs; do
1152        if [ -d $src ]; then
1153            if [ ".$opt_t" = .yes ]; then
1154                echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2
1155            fi
1156            (cd $src && $prg_find . -type f -depth -print) |\
1157            sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst
1158        else
1159            if [ ".$opt_t" = .yes ]; then
1160                echo "echo $src >>$tmpfile.lst" 1>&2
1161            fi
1162            echo $src >>$tmpfile.lst
1163        fi
1164    done
1165    sort <$tmpfile.lst >$tmpfile.lst.n
1166    mv $tmpfile.lst.n $tmpfile.lst
1167    if [ ".$opt_v" = .yes ]; then
1168        cat $tmpfile.lst | sed -e 's/^/  /' 1>&2
1169    fi
1170
1171    #   determine tarball file and directory name
1172    if [ ".$opt_o" != . ]; then
1173        tarfile="$opt_o"
1174        if [ ".$opt_d" != . ]; then
1175            tarname="$opt_d"
1176        else
1177            tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'`
1178        fi
1179    else
1180        if [ ".$opt_d" != . ]; then
1181            tarname="$opt_d"
1182        elif [ -d "$from" ]; then
1183            tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'`
1184        else
1185            tarname="out"
1186        fi
1187        tarfile="$tarname.tar"
1188    fi
1189
1190    #   roll the tarball
1191    compress=''
1192    if [ ".$opt_c" != . ]; then
1193        compress="| $opt_c"
1194    fi
1195    if [ ".$prg_tardy" != . ]; then
1196        #   the elegant hackers way
1197        tardy_opt="--prefix=$tarname"
1198        tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security!
1199        if [ ".$opt_u" != . ]; then
1200            tardy_opt="$tardy_opt --user_name=$opt_u"
1201        fi
1202        if [ ".$opt_g" != . ]; then
1203            tardy_opt="$tardy_opt --group_name=$opt_g"
1204        fi
1205        if [ ".$opt_t" = .yes ]; then
1206            echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2
1207        fi
1208        cat $tmpfile.lst |\
1209        xargs $prg_tar cf - |\
1210        $prg_tardy $tardy_opt |\
1211        eval cat $compress >$tmpfile.out
1212        if [ ".$opt_t" = .yes ]; then
1213            echo "cp $tmpfile.out $tarfile" 1>&2
1214        fi
1215        cp $tmpfile.out $tarfile
1216    else
1217        #  the portable standard way
1218        if [ ".$opt_t" = .yes ]; then
1219            echo "mkdir $tmpdir/$tarname" 1>&2
1220        fi
1221        mkdir $tmpdir/$tarname || shtool_exit 1
1222        if [ ".$opt_t" = .yes ]; then
1223            echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2
1224        fi
1225        cat $tmpfile.lst |\
1226        xargs $prg_tar cf - |\
1227        (cd $tmpdir/$tarname && $prg_tar xf -)
1228        if [ ".$opt_u" != . ]; then
1229            if [ ".$opt_t" = .yes ]; then
1230                echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1
1231            fi
1232            chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\
1233            echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)"
1234        fi
1235        if [ ".$opt_g" != . ]; then
1236            if [ ".$opt_t" = .yes ]; then
1237                echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1
1238            fi
1239            chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\
1240            echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)"
1241        fi
1242        if [ ".$opt_t" = .yes ]; then
1243            echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2
1244        fi
1245        (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\
1246        eval cat $compress >$tmpfile.out
1247        if [ ".$opt_t" = .yes ]; then
1248            echo "cp $tmpfile.out $tarfile" 1>&2
1249        fi
1250        cp $tmpfile.out $tarfile
1251        if [ ".$opt_t" = .yes ]; then
1252            echo "rm -rf $tmpdir/$tarname" 1>&2
1253        fi
1254        rm -rf $tmpdir/$tarname
1255    fi
1256
1257    #   cleanup
1258    if [ ".$opt_t" = .yes ]; then
1259        echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2
1260    fi
1261    rm -f $tmpfile.lst $tmpfile.out
1262
1263    shtool_exit 0
1264    ;;
1265
1266scpp )
1267    ##
1268    ##  scpp -- Sharing C Pre-Processor
1269    ##  Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
1270    ##
1271
1272    srcs="$*"
1273    output="${opt_o}.n"
1274
1275    #   find a reasonable Awk
1276    awk=''
1277    paths=`echo $PATH |\
1278           sed -e 's%/*:%:%g' -e 's%/$%%' \
1279               -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
1280               -e 's/:/ /g'`
1281    for name in gawk nawk awk; do
1282        for path in $paths; do
1283            if [ -r "$path/$name" ]; then
1284                awk="$path/$name"
1285                break
1286            fi
1287        done
1288        if [ ".$awk" != . ]; then
1289            break
1290        fi
1291    done
1292    if [ ".$awk" = . ]; then
1293        echo "$msgprefix:Error: cannot find a reasonable Awk" 1>&2
1294        shtool_exit 1
1295    fi
1296
1297    #   parse source file(s)
1298    if [ ".$opt_v" = .yes ]; then
1299        echo "Parsing:" | $awk '{ printf("%s", $0); }' 1>&2
1300    fi
1301    for src in $srcs; do
1302        if [ ".$opt_v" = .yes ]; then
1303            echo $src | $awk '{ printf(" %s", $0); }' 1>&2
1304        fi
1305        if [ ".$opt_f" != . ]; then
1306            inputcmd="sed"
1307            OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_f; IFS="$OIFS"
1308            for e
1309            do
1310                inputcmd="$inputcmd -e '$e'"
1311            done
1312            inputcmd="$inputcmd '$src'"
1313        else
1314            inputcmd="cat '$src'"
1315        fi
1316        eval $inputcmd |\
1317        $awk '
1318           BEGIN {
1319               ln    = 0;
1320               fln   = 0;
1321               level = 0;
1322               mode  = "";
1323               store = "";
1324           }
1325           {
1326               ln++;
1327           }
1328           /^#if.*/ {
1329               level++;
1330           }
1331           /^#if [a-zA-Z_][a-zA-Z0-9_]* *$/ {
1332               if ($2 == define) {
1333                   mode = "D";
1334                   printf("D:#line %d \"%s\"\n", ln, src);
1335                   next;
1336               }
1337           }
1338           /^#endif.*/ {
1339               level--;
1340               if (mode == "D" && level == 0) {
1341                   mode = "";
1342                   next;
1343               }
1344           }
1345           /^[a-zA-Z_][a-zA-Z0-9_].*;.*/ {
1346               if ($1 == class) {
1347                   printf("V:#line %d \"%s\"\n", ln, src);
1348                   printf("V:%s\n", $0);
1349                   printf("J:%s\n", $0);
1350                   next;
1351               }
1352           }
1353           /^[a-zA-Z_][a-zA-Z0-9_].*=.*/ {
1354               if ($1 == class) {
1355                   printf("V:#line %d \"%s\"\n", ln, src);
1356                   printf("V:%s\n", $0);
1357                   printf("J:%s\n", $0);
1358                   next;
1359               }
1360           }
1361           /^[a-zA-Z_][a-zA-Z0-9_]*/ {
1362               if ($1 == class) {
1363                   fln = ln;
1364                   store = $0;
1365                   mode = "F";
1366                   next;
1367               }
1368           }
1369           /^\{ *$/ {
1370               if (mode == "F") {
1371                   printf("F:#line %d \"%s\"\n", fln, src);
1372                   printf("F:%s;\n", store);
1373                   printf("I:%s;\n", store);
1374                   store = "";
1375                   mode = "";
1376                   next;
1377               }
1378           }
1379           {
1380               if (mode == "D")
1381                   printf("D:%s\n", $0);
1382               else if (mode == "F")
1383                   store = store " " $0;
1384           }
1385        ' "src=$src" "define=$opt_D" "class=$opt_C" >>$tmpfile
1386    done
1387    if [ ".$opt_v" = .yes ]; then
1388        echo "" 1>&2
1389    fi
1390
1391    #   start generating output header
1392    echo "/* $opt_o -- autogenerated from $opt_t, DO NOT EDIT! */" >$output
1393    echo "#line 1 \"$opt_t\"" >>$output
1394    sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd' |\
1395    sed -e "/^${opt_M} *\$/d" >>$output
1396
1397    #   merge in the define blocks
1398    grep '^D:' $tmpfile | sed -e 's/^D://' >>$output
1399
1400    #   generate standard prolog
1401    echo "#line 1 \"_ON_THE_FLY_\"" >>$output
1402    echo "" >>$output
1403    echo "/* make sure the scpp source extensions are skipped */" >>$output
1404    echo "#define $opt_D 0" >>$output
1405    echo "#define $opt_C /**/" >>$output
1406
1407    #   generate namespace hiding for variables
1408    echo "" >>$output
1409    echo "/* move intern variables to hidden namespace */" >>$output
1410    grep '^J:' $tmpfile | sed >>$output \
1411        -e 's/^J://' \
1412        -e 's/  */ /g' \
1413        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\];.*$/#define \1 __\1/' \
1414        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\] =.*$/#define \1 __\1/' \
1415        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\);.*$/#define \1 __\1/' \
1416        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\) =.*$/#define \1 __\1/'
1417
1418    #   generate namespace hiding for functions
1419    echo "" >>$output
1420    echo "/* move intern functions to hidden namespace */" >>$output
1421    grep '^I:' $tmpfile | sed >>$output \
1422        -e 's/^I://' \
1423        -e 's/\([ (]\) */\1/g' \
1424        -e 's/ *\([),]\)/\1/g' \
1425        -e 's/^[^(]*[ *]\([a-zA-Z0-9_]*\)(.*$/#define \1 __\1/'
1426
1427    #   generate prototypes for variables
1428    echo "" >>$output
1429    echo "/* prototypes for intern variables */" >>$output
1430    grep '^V:' $tmpfile | sed >>$output \
1431        -e 's/^V://' \
1432        -e 's/  */ /g' \
1433        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\);.*$/\1;/' \
1434        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\) =.*$/\1;/' \
1435        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\);.*$/\1;/' \
1436        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\) =.*$/\1;/' \
1437        -e 's/ ;/;/g' \
1438        -e "s/^$opt_C /extern /"
1439
1440    #   generate prototypes for functions
1441    echo "" >>$output
1442    echo "/* prototypes for intern functions */" >>$output
1443    grep '^F:' $tmpfile | sed >>$output \
1444        -e 's/^F://' \
1445        -e 's/\([ (]\) */\1/g' \
1446        -e 's/ *\([),]\)/\1/g' \
1447        -e 's/\([* ]\)[a-zA-Z0-9_]*,/\1,/g' \
1448        -e 's/\([* ]\)[a-zA-Z0-9_]*);/\1);/g' \
1449        -e 's/(\*[a-zA-Z0-9_]*)(/(*)(/g' \
1450        -e 's/\([ (]\) */\1/g' \
1451        -e 's/ *\([),]\)/\1/g' \
1452        -e "s/^$opt_C /extern /"
1453
1454    #   finish generating output header
1455    n=`(echo ''; sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd') |\
1456       wc -l | sed -e 's;^ *\([0-9]*\) *$;\1;'`
1457    echo "#line $n \"$opt_t\"" >>$output
1458    sed <$opt_t -e "/^${opt_M} *\$/,\$p" -e 'd' |\
1459    sed -e "/^${opt_M} *\$/d" >>$output
1460
1461    #   create final output file
1462    if [ -f $opt_o ]; then
1463        if [ ".$opt_p" = .yes ]; then
1464            grep -v '^#line' $opt_o  >$tmpfile.o
1465            grep -v '^#line' $output >$tmpfile.n
1466            out_old="$tmpfile.o"
1467            out_new="$tmpfile.n"
1468        else
1469            out_old="$opt_o"
1470            out_new="$output"
1471        fi
1472        if cmp -s $out_old $out_new; then
1473            :
1474        else
1475            cp $output $opt_o
1476        fi
1477    else
1478        cp $output $opt_o
1479    fi
1480    rm -f $output
1481    rm -f $tmpfile $tmpfile.* >/dev/null 2>&1
1482
1483    shtool_exit 0
1484    ;;
1485
1486version )
1487    ##
1488    ##  version -- Maintain a version information file
1489    ##  Copyright (c) 1994-2006 Ralf S. Engelschall <rse@engelschall.com>
1490    ##
1491
1492    file="$1"
1493
1494    #   determine prefix and name
1495    name="$opt_n"
1496    prefix="$opt_p"
1497
1498    #   determine current version
1499    triple="$opt_s"
1500    if [ ".$triple" != . ]; then
1501        #   use given triple
1502        if [ ".`echo $triple | grep '[0-9]*.[0-9]*[sabp.][0-9]*'`" = . ]; then
1503            echo "$msgprefix:Error: invalid argument to option \`-s': \`$opt_s'" 1>&2
1504            shtool_exit 1
1505        fi
1506        eval `echo $triple |\
1507              sed -e 's%\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\).*%\
1508              ver="\1";rev="\2";typ="\3";lev="\4"%'`
1509        tim=calc
1510    elif [ -r $file ]; then
1511        #   determine triple from given file
1512        eval `grep 'Version [0-9]*.[0-9]*[sabp.][0-9]* ([0-9]*-[a-zA-Z]*-[0-9]*)' $file |\
1513              sed -e 's%.*Version \([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\) (\([0-9]*-[a-zA-Z]*-[0-9]*\)).*%\
1514              ver="\1";rev="\2";typ="\3";lev="\4";tim="\5"%' -e 'q'`
1515    else
1516        #   intialise to first version
1517        ver=0
1518        rev=1
1519        typ=.
1520        lev=0
1521        tim=calc
1522    fi
1523
1524    #   determine new version in batch
1525    if [ ".$opt_i" != . ]; then
1526        case $opt_i in
1527            v ) ver=`expr $ver + 1`
1528                rev=0
1529                lev=0
1530                ;;
1531            r ) rev=`expr $rev + 1`
1532                lev=0
1533                ;;
1534            l ) lev=`expr $lev + 1`
1535                ;;
1536            * ) echo "$msgprefix:Error: invalid argument to option \`-i': \`$opt_i'" 1>&2
1537                shtool_exit 1
1538                ;;
1539        esac
1540        tim=calc
1541    fi
1542
1543    #   determine new version interactively
1544    if [ ".$opt_e" = .yes ]; then
1545        echo "old version: ${ver}.${rev}${typ}${lev}"
1546        while [ 1 ]; do
1547            echo dummy | awk '{ printf("new version: "); }'
1548            read triple
1549            case $triple in
1550                [0-9]*.[0-9]*[sabp.][0-9]* )
1551                    ;;
1552                * ) echo "$msgprefix:Error: invalid version string entered: \`$triple'" 1>&2
1553                    continue
1554                    ;;
1555            esac
1556            break
1557        done
1558        eval `echo $triple |\
1559              sed -e 's%^\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\)$%\
1560              ver="\1";rev="\2";typ="\3";lev="\4"%'`
1561        tim=calc
1562    fi
1563
1564    #   determine hexadecimal and libtool value of version
1565    case $typ in
1566        a     ) typnum=0;  levnum=$lev ;;
1567        b     ) typnum=1;  levnum=$lev ;;
1568        p | . ) typnum=2;  levnum=$lev ;;
1569        s     ) typnum=15; levnum=255  ;; # snapshots are special
1570    esac
1571    hex=`echo "$ver:$rev:$typnum:$levnum" |\
1572         awk -F: '{ printf("0x%x%02x%1x%02x", $1, $2, $3, $4); }' |\
1573         tr 'abcdef' 'ABCDEF'`
1574    ltv=`echo "$ver:$rev:$typnum:$levnum" |\
1575         awk -F: '{ printf("%d:%d", $1*10 + $2, $3*10 + $4); }'`
1576
1577    #   determine date
1578    if [ ".$tim" = .calc ]; then
1579        day=`date '+%d'`
1580        month=`date '+%m'`
1581        year=`date '+%Y' 2>/dev/null`
1582        if [ ".$time_year" = . ]; then
1583            year=`date '+%y'`
1584            case $year in
1585                [5-9][0-9]) year="19$year" ;;
1586                [0-4][0-9]) year="20$year" ;;
1587            esac
1588        fi
1589        case $month in
1590            1|01) month='Jan' ;;
1591            2|02) month='Feb' ;;
1592            3|03) month='Mar' ;;
1593            4|04) month='Apr' ;;
1594            5|05) month='May' ;;
1595            6|06) month='Jun' ;;
1596            7|07) month='Jul' ;;
1597            8|08) month='Aug' ;;
1598            9|09) month='Sep' ;;
1599              10) month='Oct' ;;
1600              11) month='Nov' ;;
1601              12) month='Dec' ;;
1602        esac
1603        tim="${day}-${month}-${year}"
1604    fi
1605
1606    #   perform result actions
1607    mode=show
1608    if [ ".$opt_i" != . ]; then
1609        mode=edit
1610    elif [ ".$opt_e" = .yes ]; then
1611        mode=edit
1612    elif [ ".$opt_s" != . ]; then
1613        mode=edit
1614    fi
1615    if [ ".$mode" = .show ]; then
1616        #   just display the current version
1617        case $opt_d in
1618            short )
1619                echo "${ver}.${rev}${typ}${lev}"
1620                ;;
1621            long )
1622                echo "${ver}.${rev}${typ}${lev} ($tim)"
1623                ;;
1624            libtool )
1625                echo "${ltv}"
1626                ;;
1627            hex )
1628                echo "${hex}"
1629                ;;
1630            * ) echo "$msgprefix:Error: invalid argument to option \`-d': \`$opt_d'" 1>&2
1631                shtool_exit 1
1632                ;;
1633        esac
1634    else
1635        #   update the version file
1636
1637        #   pre-generate various strings
1638        triple="${ver}.${rev}${typ}${lev}"
1639        vHex="$hex"
1640        vShort="${triple}"
1641        vLong="${triple} (${tim})"
1642        vTeX="This is ${name}, Version ${triple} (${tim})"
1643        vGNU="${name} ${triple} (${tim})"
1644        vWeb="${name}/${triple}"
1645        vSCCS="@(#)${name} ${triple} (${tim})"
1646        vRCS="\$Id: ${name} ${triple} (${tim}) \$"
1647
1648        #   determine string out of filename
1649        #   (do NOT try to optimize this in any way because of portability)
1650        filestr=`util_upper "$file" | tr './%+' '____' | sed -e 's/-/_/g'`
1651
1652        #   generate uppercase prefix
1653        prefixupper=`util_upper "$prefix"`
1654
1655        #   create the version file according the the selected language
1656        echo "new version: ${vLong}"
1657
1658        cp /dev/null $file
1659        case $opt_l in
1660            txt )
1661                echo >>$file ""
1662                echo >>$file "  ${file} -- Version Information for ${name} (syntax: Text)"
1663                echo >>$file "  [automatically generated and maintained by GNU shtool]"
1664                echo >>$file ""
1665                echo >>$file "  $vTeX"
1666                echo >>$file ""
1667                ;;
1668            c )
1669                echo >>$file "/*"
1670                echo >>$file "**  ${file} -- Version Information for ${name} (syntax: C/C++)"
1671                echo >>$file "**  [automatically generated and maintained by GNU shtool]"
1672                echo >>$file "*/"
1673                echo >>$file ""
1674                echo >>$file "#ifdef _${filestr}_AS_HEADER_"
1675                echo >>$file ""
1676                echo >>$file "#ifndef _${filestr}_"
1677                echo >>$file "#define _${filestr}_"
1678                echo >>$file ""
1679                echo >>$file "#define ${prefixupper}VERSION ${vHex}"
1680                echo >>$file ""
1681                echo >>$file "typedef struct {"
1682                echo >>$file "    const int   v_hex;"
1683                echo >>$file "    const char *v_short;"
1684                echo >>$file "    const char *v_long;"
1685                echo >>$file "    const char *v_tex;"
1686                echo >>$file "    const char *v_gnu;"
1687                echo >>$file "    const char *v_web;"
1688                echo >>$file "    const char *v_sccs;"
1689                echo >>$file "    const char *v_rcs;"
1690                echo >>$file "} ${prefix}version_t;"
1691                echo >>$file ""
1692                echo >>$file "extern ${prefix}version_t ${prefix}version;"
1693                echo >>$file ""
1694                echo >>$file "#endif /* _${filestr}_ */"
1695                echo >>$file ""
1696                echo >>$file "#else /* _${filestr}_AS_HEADER_ */"
1697                echo >>$file ""
1698                echo >>$file "#define _${filestr}_AS_HEADER_"
1699                echo >>$file "#include \"${file}\""
1700                echo >>$file "#undef  _${filestr}_AS_HEADER_"
1701                echo >>$file ""
1702                echo >>$file "${prefix}version_t ${prefix}version = {"
1703                echo >>$file "    ${vHex},"
1704                echo >>$file "    \"${vShort}\","
1705                echo >>$file "    \"${vLong}\","
1706                echo >>$file "    \"${vTeX}\","
1707                echo >>$file "    \"${vGNU}\","
1708                echo >>$file "    \"${vWeb}\","
1709                echo >>$file "    \"${vSCCS}\","
1710                echo >>$file "    \"${vRCS}\""
1711                echo >>$file "};"
1712                echo >>$file ""
1713                echo >>$file "#endif /* _${filestr}_AS_HEADER_ */"
1714                echo >>$file ""
1715                ;;
1716            m4 )
1717                echo >>$file "##"
1718                echo >>$file "##  ${file} -- Version Information for ${name} (syntax: M4)"
1719                echo >>$file "##  [automatically generated and maintained by GNU shtool]"
1720                echo >>$file "##"
1721                echo >>$file ""
1722                echo >>$file "m4_define([v_hex],   [${vHex}])"
1723                echo >>$file "m4_define([v_short], [${vShort}])"
1724                echo >>$file "m4_define([v_long],  [${vLong}])"
1725                echo >>$file "m4_define([v_tex],   [${vTeX}])"
1726                echo >>$file "m4_define([v_gnu],   [${vGNU}])"
1727                echo >>$file "m4_define([v_web],   [${vWeb}])"
1728                echo >>$file "m4_define([v_sccs],  [${vSCCS}])"
1729                echo >>$file "m4_define([v_rcs],   [${vRCS}])"
1730                echo >>$file ""
1731                ;;
1732            perl )
1733                echo >>$file "##"
1734                echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Perl)"
1735                echo >>$file "##  [automatically generated and maintained by GNU shtool]"
1736                echo >>$file "##"
1737                echo >>$file ""
1738                echo >>$file "our \$${prefix}version = {"
1739                echo >>$file "    'v_hex'   => ${vHex},"
1740                echo >>$file "    'v_short' => \"${vShort}\","
1741                echo >>$file "    'v_long'  => \"${vLong}\","
1742                echo >>$file "    'v_tex'   => \"${vTeX}\","
1743                echo >>$file "    'v_gnu'   => \"${vGNU}\","
1744                echo >>$file "    'v_web'   => \"${vWeb}\","
1745                echo >>$file "    'v_sccs'  => \"${vSCCS}\","
1746                echo >>$file "    'v_rcs'   => \"\\${vRCS}/\""
1747                echo >>$file "};"
1748                echo >>$file ""
1749                echo >>$file "1;"
1750                echo >>$file ""
1751                ;;
1752            python )
1753                echo >>$file "##"
1754                echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Python)"
1755                echo >>$file "##  [automatically generated and maintained by GNU shtool]"
1756                echo >>$file "##"
1757                echo >>$file ""
1758                echo >>$file "class ${prefix}version:"
1759                echo >>$file "    v_hex       = ${vHex}"
1760                echo >>$file "    v_short     = \"${vShort}\""
1761                echo >>$file "    v_long      = \"${vLong}\""
1762                echo >>$file "    v_tex       = \"${vTeX}\""
1763                echo >>$file "    v_gnu       = \"${vGNU}\""
1764                echo >>$file "    v_web       = \"${vWeb}\""
1765                echo >>$file "    v_sccs      = \"${vSCCS}\""
1766                echo >>$file "    v_rcs       = \"${vRCS}\""
1767                echo >>$file ""
1768                ;;
1769            * ) echo "$msgprefix:Error: invalid argument to option \`-l': \`$opt_l'" 1>&2
1770                shtool_exit 1
1771                ;;
1772        esac
1773    fi
1774
1775    shtool_exit 0
1776    ;;
1777
1778esac
1779
1780shtool_exit 0
1781
1782