/[jscoverage]/trunk/js/shtool
ViewVC logotype

Annotation of /trunk/js/shtool

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Wed Aug 1 13:51:53 2007 UTC (13 years ago) by siliconforks
File size: 137486 byte(s)
Initial import.

1 siliconforks 2 #!/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: all 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     ## 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     ##
61    
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
72    
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
85    
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.6 (19-Apr-2006)"
94     echo 'Copyright (c) 1994-2006 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.6 (19-Apr-2006)"
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
186    
187     ##
188     ## DISPATCH INTO SCRIPT PROLOG
189     ##
190    
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
452    
453     ##
454     ## COMMON UTILITY CODE
455     ##
456    
457     # commonly used ASCII values
458     ASC_TAB=" "
459     ASC_NL="
460     "
461    
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
474    
475     # parse argument specification string
476     eval `echo $arg_spec |\
477     sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
478    
479     # parse option specification string
480     eval `echo h.$opt_spec |\
481     sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
482    
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'`
486    
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
495    
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
533    
534     # eat up option
535     shift
536    
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
545    
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
572    
573     # process help option
574     if [ ".$opt_h" = .yes ]; then
575     echo "Usage: $toolcmdhelp $str_usage"
576     exit 0
577     fi
578    
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
596    
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     )
616    
617     # create (implicitly) secure temporary file
618     tmpfile="$tmpdir/shtool.tmp"
619     touch "$tmpfile"
620     fi
621    
622     # utility function: map string to lower case
623     util_lower () {
624     echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
625     }
626    
627     # utility function: map string to upper case
628     util_upper () {
629     echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
630     }
631    
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     }
640    
641     ##
642     ## DISPATCH INTO SCRIPT BODY
643     ##
644    
645     case $tool in
646    
647     echo )
648     ##
649     ## echo -- Print string with optional construct expansion
650     ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
651     ##
652    
653     text="$*"
654    
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
664    
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
671    
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
723    
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
752    
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=`(ypcat passwd) 2>/dev/null |
772     grep "^${username}:" | \
773     sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
774     if [ ".$userid" = . ]; then
775     userid='?'
776     fi
777     fi
778     fi
779     fi
780     fi
781     fi
782     fi
783    
784     # determine (primary) group id
785     groupid=''
786     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then
787     groupid="`(id -g ${username}) 2>/dev/null`"
788     if [ ".$groupid" = . ]; then
789     str="`(id) 2>/dev/null`"
790     if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then
791     groupid=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*//' -e 's/(.*$//'`
792     fi
793     if [ ".$groupid" = . ]; then
794     groupid=`(getent passwd ${username}) 2>/dev/null | \
795     sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
796     if [ ".$groupid" = . ]; then
797     groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
798     sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
799     if [ ".$groupid" = . ]; then
800     groupid=`(ypcat passwd) 2>/dev/null | grep "^${username}:" | \
801     sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
802     if [ ".$groupid" = . ]; then
803     groupid='?'
804     fi
805     fi
806     fi
807     fi
808     fi
809     fi
810    
811     # determine (primary) group name
812     groupname=''
813     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then
814     groupname="`(id -gn ${username}) 2>/dev/null`"
815     if [ ".$groupname" = . ]; then
816     str="`(id) 2>/dev/null`"
817     if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then
818     groupname=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'`
819     fi
820     if [ ".$groupname" = . ]; then
821     groupname=`(getent group) 2>/dev/null | \
822     grep "^[^:]*:[^:]*:${groupid}:" | \
823     sed -e 's/:.*$//'`
824     if [ ".$groupname" = . ]; then
825     groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
826     sed -e 's/:.*$//'`
827     if [ ".$groupname" = . ]; then
828     groupname=`(ypcat group) 2>/dev/null | \
829     grep "^[^:]*:[^:]*:${groupid}:" | \
830     sed -e 's/:.*$//'`
831     if [ ".$groupname" = . ]; then
832     groupname='?'
833     fi
834     fi
835     fi
836     fi
837     fi
838     fi
839    
840     # determine host and domain name
841     hostname=''
842     domainname=''
843     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then
844     hostname="`(uname -n) 2>/dev/null |\
845     awk '{ printf("%s", $1); }'`"
846     if [ ".$hostname" = . ]; then
847     hostname="`(hostname) 2>/dev/null |\
848     awk '{ printf("%s", $1); }'`"
849     if [ ".$hostname" = . ]; then
850     hostname='unknown'
851     fi
852     fi
853     case $hostname in
854     *.* )
855     domainname=".`echo $hostname | cut -d. -f2-`"
856     hostname="`echo $hostname | cut -d. -f1`"
857     ;;
858     esac
859     fi
860     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then
861     if [ ".$domainname" = . ]; then
862     if [ -f /etc/resolv.conf ]; then
863     domainname="`grep '^[ ]*domain' /etc/resolv.conf | sed -e 'q' |\
864     sed -e 's/.*domain//' \
865     -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
866     -e 's/^\.//' -e 's/^/./' |\
867     awk '{ printf("%s", $1); }'`"
868     if [ ".$domainname" = . ]; then
869     domainname="`grep '^[ ]*search' /etc/resolv.conf | sed -e 'q' |\
870     sed -e 's/.*search//' \
871     -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
872     -e 's/ .*//' -e 's/ .*//' \
873     -e 's/^\.//' -e 's/^/./' |\
874     awk '{ printf("%s", $1); }'`"
875     fi
876     fi
877     fi
878     fi
879    
880     # determine current time
881     time_day=''
882     time_month=''
883     time_year=''
884     time_monthname=''
885     if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then
886     time_day=`date '+%d'`
887     time_month=`date '+%m'`
888     time_year=`date '+%Y' 2>/dev/null`
889     if [ ".$time_year" = . ]; then
890     time_year=`date '+%y'`
891     case $time_year in
892     [5-9][0-9]) time_year="19$time_year" ;;
893     [0-4][0-9]) time_year="20$time_year" ;;
894     esac
895     fi
896     case $time_month in
897     1|01) time_monthname='Jan' ;;
898     2|02) time_monthname='Feb' ;;
899     3|03) time_monthname='Mar' ;;
900     4|04) time_monthname='Apr' ;;
901     5|05) time_monthname='May' ;;
902     6|06) time_monthname='Jun' ;;
903     7|07) time_monthname='Jul' ;;
904     8|08) time_monthname='Aug' ;;
905     9|09) time_monthname='Sep' ;;
906     10) time_monthname='Oct' ;;
907     11) time_monthname='Nov' ;;
908     12) time_monthname='Dec' ;;
909     esac
910     fi
911    
912     # expand special ``%x'' constructs
913     if [ ".$opt_e" = .yes ]; then
914     text=`echo $seo "$text" |\
915     sed -e "s/%B/${term_bold}/g" \
916     -e "s/%b/${term_norm}/g" \
917     -e "s/%u/${username}/g" \
918     -e "s/%U/${userid}/g" \
919     -e "s/%g/${groupname}/g" \
920     -e "s/%G/${groupid}/g" \
921     -e "s/%h/${hostname}/g" \
922     -e "s/%d/${domainname}/g" \
923     -e "s/%D/${time_day}/g" \
924     -e "s/%M/${time_month}/g" \
925     -e "s/%Y/${time_year}/g" \
926     -e "s/%m/${time_monthname}/g" 2>/dev/null`
927     fi
928    
929     # create output
930     if [ .$opt_n = .no ]; then
931     echo $seo "$text"
932     else
933     # the harder part: echo -n is best, because
934     # awk may complain about some \xx sequences.
935     if [ ".$minusn" != . ]; then
936     echo $seo $minusn "$text"
937     else
938     echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
939     fi
940     fi
941    
942     shtool_exit 0
943     ;;
944    
945     mdate )
946     ##
947     ## mdate -- Pretty-print modification time of a file or dir
948     ## Copyright (c) 1995-1997 Free Software Foundation, Inc.
949     ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
950     ##
951    
952     fod="$1"
953     case "$opt_o" in
954     [dmy][dmy][dmy] )
955     ;;
956     * ) echo "$msgprefix:Error: invalid argument to option \`-o': $opt_o" 1>&2
957     shtool_exit 1
958     ;;
959     esac
960     if [ ! -r "$fod" ]; then
961     echo "$msgprefix:Error: file or directory not found: $fod" 1>&2
962     shtool_exit 1
963     fi
964    
965     # GNU ls changes its time format in response to the TIME_STYLE
966     # variable. Since we cannot assume "unset" works, revert this
967     # variable to its documented default.
968     if [ ".$TIME_STYLE" != . ]; then
969     TIME_STYLE=posix-long-iso
970     export TIME_STYLE
971     fi
972    
973     # get the extended ls output of the file or directory.
974     if /bin/ls -L /dev/null >/dev/null 2>&1; then
975     set - x`/bin/ls -L -l -d $fod`
976     else
977     set - x`/bin/ls -l -d $fod`
978     fi
979    
980     # The month is at least the fourth argument
981     # (3 shifts here, the next inside the loop).
982     shift; shift; shift
983    
984     # Find the month. Next argument is day, followed by the year or time.
985     month=""
986     while [ ".$month" = . ]; do
987     shift
988     case $1 in
989     Jan) month=January; nummonth=1 ;;
990     Feb) month=February; nummonth=2 ;;
991     Mar) month=March; nummonth=3 ;;
992     Apr) month=April; nummonth=4 ;;
993     May) month=May; nummonth=5 ;;
994     Jun) month=June; nummonth=6 ;;
995     Jul) month=July; nummonth=7 ;;
996     Aug) month=August; nummonth=8 ;;
997     Sep) month=September; nummonth=9 ;;
998     Oct) month=October; nummonth=10 ;;
999     Nov) month=November; nummonth=11 ;;
1000     Dec) month=December; nummonth=12 ;;
1001     esac
1002     done
1003     day="$2"
1004     year="$3"
1005    
1006     # We finally have to deal with the problem that the "ls" output
1007     # gives either the time of the day or the year.
1008     case $year in
1009     *:*)
1010     this_year=`date '+%Y' 2>/dev/null`
1011     if [ ".$this_year" = . ]; then
1012     this_year=`date '+%y'`
1013     case $this_year in
1014     [5-9][0-9]) this_year="19$this_year" ;;
1015     [0-4][0-9]) this_year="20$this_year" ;;
1016     esac
1017     fi
1018     # for the following months of the last year the time notation
1019     # is usually also used for files modified in the last year.
1020     this_month=`date '+%m'`
1021     if (expr $nummonth \> $this_month) >/dev/null; then
1022     this_year=`expr $this_year - 1`
1023     fi
1024     year="$this_year"
1025     ;;
1026     esac
1027    
1028     # Optionally fill day and month with leeding zeros
1029     if [ ".$opt_z" = .yes ]; then
1030     case $day in
1031     [0-9][0-9] ) ;;
1032     [0-9] ) day="0$day" ;;
1033     esac
1034     case $nummonth in
1035     [0-9][0-9] ) ;;
1036     [0-9] ) nummonth="0$nummonth" ;;
1037     esac
1038     fi
1039    
1040     # Optionally use digits for month
1041     if [ ".$opt_d" = .yes ]; then
1042     month="$nummonth"
1043     fi
1044    
1045     # Optionally shorten the month name to three characters
1046     if [ ".$opt_s" = .yes ]; then
1047     month=`echo $month | cut -c1-3`
1048     fi
1049    
1050     # Output the resulting date string
1051     echo dummy | awk '{
1052     for (i = 0; i < 3; i++) {
1053     now = substr(order, 1, 1);
1054     order = substr(order, 2);
1055     if (now == "d")
1056     out = day;
1057     else if (now == "m")
1058     out = month;
1059     else if (now == "y")
1060     out = year;
1061     if (i < 2)
1062     printf("%s%s", out, field);
1063     else
1064     printf("%s", out);
1065     }
1066     if (newline != "yes")
1067     printf("\n");
1068     }' "day=$day" "month=$month" "year=$year" \
1069     "field=$opt_f" "order=$opt_o" "newline=$opt_n"
1070    
1071     shtool_exit 0
1072     ;;
1073    
1074     table )
1075     ##
1076     ## table -- Pretty-print a field-separated list as a table
1077     ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
1078     ##
1079    
1080     if [ $opt_c -gt 4 ]; then
1081     echo "$msgprefix:Error: Invalid number of colums (1..4 allowed only)" 1>&2
1082     shtool_exit 1
1083     fi
1084     case "x$opt_F" in
1085     x? ) ;;
1086     * ) echo "$msgprefix:Error: Invalid separator (one char allowed only)" 1>&2; shtool_exit 1 ;;
1087     esac
1088    
1089     # split the list into a table
1090     list=`
1091     IFS="$opt_F"
1092     for entry in $*; do
1093     if [ ".$entry" != . ]; then
1094     echo "$entry"
1095     fi
1096     done |\
1097     awk "
1098     BEGIN { list = \"\"; n = 0; }
1099     {
1100     list = list \\$1;
1101     n = n + 1;
1102     if (n < $opt_c) {
1103     list = list \":\";
1104     }
1105     if (n == $opt_c) {
1106     list = list \"\\n\";
1107     n = 0;
1108     }
1109     }
1110     END { print list; }
1111     "
1112     `
1113    
1114     # format table cells and make sure table
1115     # doesn't exceed maximum width
1116     OIFS="$IFS"
1117     IFS='
1118     '
1119     for entry in $list; do
1120     case $opt_c in
1121     1 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s\\n\", \$1); }'" ;;
1122     2 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s\\n\", \$1, \$2); }'" ;;
1123     3 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s %-${opt_w}s\\n\", \$1, \$2, \$3); }'" ;;
1124     4 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s %-${opt_w}s %-${opt_w}s\\n\", \$1, \$2, \$3, \$4); }'" ;;
1125     esac
1126     done |\
1127     awk "{
1128     if (length(\$0) > $opt_s) {
1129     printf(\"%s\\n\", substr(\$0, 0, $opt_s-1));
1130     } else {
1131     print \$0;
1132     }
1133     }"
1134     IFS="$OIFS"
1135    
1136     shtool_exit 0
1137     ;;
1138    
1139     prop )
1140     ##
1141     ## prop -- Display progress with a running propeller
1142     ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
1143     ##
1144    
1145     perl=''
1146     for dir in `echo $PATH | sed -e 's/:/ /g'` .; do
1147     if [ -f "$dir/perl" ]; then
1148     perl="$dir/perl"
1149     break
1150     fi
1151     done
1152     if [ ".$perl" != . ]; then
1153     # Perl is preferred because writing to STDERR in
1154     # Perl really writes immediately as one would expect
1155     $perl -e '
1156     @p = ("|","/","-","\\");
1157     $i = 0;
1158     while (<STDIN>) {
1159     printf(STDERR "\r%s...%s\b", $ARGV[0], $p[$i++]);
1160     $i = 0 if ($i > 3);
1161     }
1162     printf(STDERR "\r%s \n", $ARGV[0]);
1163     ' "$opt_p"
1164     else
1165     # But if Perl doesn't exists we use Awk even
1166     # some Awk's buffer even the /dev/stderr writing :-(
1167     awk '
1168     BEGIN {
1169     split("|#/#-#\\", p, "#");
1170     i = 1;
1171     }
1172     {
1173     printf("\r%s%c\b", prefix, p[i++]) > "/dev/stderr";
1174     if (i > 4) { i = 1; }
1175     }
1176     END {
1177     printf("\r%s \n", prefix) > "/dev/stderr";
1178     }
1179     ' "prefix=$opt_p"
1180     fi
1181    
1182     shtool_exit 0
1183     ;;
1184    
1185     move )
1186     ##
1187     ## move -- Move files with simultaneous substitution
1188     ## Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
1189     ##
1190    
1191     src="$1"
1192     dst="$2"
1193    
1194     # consistency checks
1195     if [ ".$src" = . ] || [ ".$dst" = . ]; then
1196     echo "$msgprefix:Error: Invalid arguments" 1>&2
1197     shtool_exit 1
1198     fi
1199     if [ ".$src" = ".$dst" ]; then
1200     echo "$msgprefix:Error: Source and destination files are the same" 1>&2
1201     shtool_exit 1
1202     fi
1203     expsrc="$src"
1204     if [ ".$opt_e" = .yes ]; then
1205     expsrc="`echo $expsrc`"
1206     fi
1207     if [ ".$opt_e" = .yes ]; then
1208     if [ ".`echo "$src" | sed -e 's;^.*\\*.*$;;'`" = ".$src" ]; then
1209     echo "$msgprefix:Error: Source doesn't contain wildcard ('*'): $dst" 1>&2
1210     shtool_exit 1
1211     fi
1212     if [ ".`echo "$dst" | sed -e 's;^.*%[1-9].*$;;'`" = ".$dst" ]; then
1213     echo "$msgprefix:Error: Destination doesn't contain substitution ('%N'): $dst" 1>&2
1214     shtool_exit 1
1215     fi
1216     if [ ".$expsrc" = ".$src" ]; then
1217     echo "$msgprefix:Error: Sources not found or no asterisk : $src" 1>&2
1218     shtool_exit 1
1219     fi
1220     else
1221     if [ ! -r "$src" ]; then
1222     echo "$msgprefix:Error: Source not found: $src" 1>&2
1223     shtool_exit 1
1224     fi
1225     fi
1226    
1227     # determine substitution patterns
1228     if [ ".$opt_e" = .yes ]; then
1229     srcpat=`echo "$src" | sed -e 's/\\./\\\\./g' -e 's/;/\\;/g' -e 's;\\*;\\\\(.*\\\\);g'`
1230     dstpat=`echo "$dst" | sed -e 's;%\([1-9]\);\\\\\1;g'`
1231     fi
1232    
1233     # iterate over source(s)
1234     for onesrc in $expsrc; do
1235     if [ .$opt_e = .yes ]; then
1236     onedst=`echo $onesrc | sed -e "s;$srcpat;$dstpat;"`
1237     else
1238     onedst="$dst"
1239     fi
1240     errorstatus=0
1241     if [ ".$opt_v" = .yes ]; then
1242     echo "$onesrc -> $onedst"
1243     fi
1244     if [ ".$opt_p" = .yes ]; then
1245     if [ -r $onedst ]; then
1246     if cmp -s $onesrc $onedst; then
1247     if [ ".$opt_t" = .yes ]; then
1248     echo "rm -f $onesrc" 1>&2
1249     fi
1250     rm -f $onesrc || errorstatus=$?
1251     else
1252     if [ ".$opt_t" = .yes ]; then
1253     echo "mv -f $onesrc $onedst" 1>&2
1254     fi
1255     mv -f $onesrc $onedst || errorstatus=$?
1256     fi
1257     else
1258     if [ ".$opt_t" = .yes ]; then
1259     echo "mv -f $onesrc $onedst" 1>&2
1260     fi
1261     mv -f $onesrc $onedst || errorstatus=$?
1262     fi
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     if [ $errorstatus -ne 0 ]; then
1270     break;
1271     fi
1272     done
1273    
1274     shtool_exit $errorstatus
1275     ;;
1276    
1277     install )
1278     ##
1279     ## install -- Install a program, script or datafile
1280     ## Copyright (c) 1997-2006 Ralf S. Engelschall <rse@engelschall.com>
1281     ##
1282    
1283     # special case: "shtool install -d <dir> [...]" internally
1284     # maps to "shtool mkdir -f -p -m 755 <dir> [...]"
1285     if [ "$opt_d" = yes ]; then
1286     cmd="$0 mkdir -f -p -m 755"
1287     if [ ".$opt_o" != . ]; then
1288     cmd="$cmd -o '$opt_o'"
1289     fi
1290     if [ ".$opt_g" != . ]; then
1291     cmd="$cmd -g '$opt_g'"
1292     fi
1293     if [ ".$opt_v" = .yes ]; then
1294     cmd="$cmd -v"
1295     fi
1296     if [ ".$opt_t" = .yes ]; then
1297     cmd="$cmd -t"
1298     fi
1299     for dir in "$@"; do
1300     eval "$cmd $dir" || shtool_exit $?
1301     done
1302     shtool_exit 0
1303     fi
1304    
1305     # determine source(s) and destination
1306     argc=$#
1307     srcs=""
1308     while [ $# -gt 1 ]; do
1309     srcs="$srcs $1"
1310     shift
1311     done
1312     dstpath="$1"
1313    
1314     # type check for destination
1315     dstisdir=0
1316     if [ -d $dstpath ]; then
1317     dstpath=`echo "$dstpath" | sed -e 's:/$::'`
1318     dstisdir=1
1319     fi
1320    
1321     # consistency check for destination
1322     if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then
1323     echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
1324     shtool_exit 1
1325     fi
1326    
1327     # iterate over all source(s)
1328     for src in $srcs; do
1329     dst=$dstpath
1330    
1331     # if destination is a directory, append the input filename
1332     if [ $dstisdir = 1 ]; then
1333     dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
1334     dst="$dst/$dstfile"
1335     fi
1336    
1337     # check for correct arguments
1338     if [ ".$src" = ".$dst" ]; then
1339     echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
1340     continue
1341     fi
1342     if [ -d "$src" ]; then
1343     echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
1344     continue
1345     fi
1346    
1347     # make a temp file name in the destination directory
1348     dsttmp=`echo $dst |\
1349     sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
1350     -e "s;\$;/#INST@$$#;"`
1351    
1352     # verbosity
1353     if [ ".$opt_v" = .yes ]; then
1354     echo "$src -> $dst" 1>&2
1355     fi
1356    
1357     # copy or move the file name to the temp name
1358     # (because we might be not allowed to change the source)
1359     if [ ".$opt_C" = .yes ]; then
1360     opt_c=yes
1361     fi
1362     if [ ".$opt_c" = .yes ]; then
1363     if [ ".$opt_t" = .yes ]; then
1364     echo "cp $src $dsttmp" 1>&2
1365     fi
1366     cp $src $dsttmp || shtool_exit $?
1367     else
1368     if [ ".$opt_t" = .yes ]; then
1369     echo "mv $src $dsttmp" 1>&2
1370     fi
1371     mv $src $dsttmp || shtool_exit $?
1372     fi
1373    
1374     # adjust the target file
1375     if [ ".$opt_e" != . ]; then
1376     sed='sed'
1377     OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
1378     for e
1379     do
1380     sed="$sed -e '$e'"
1381     done
1382     cp $dsttmp $dsttmp.old
1383     chmod u+w $dsttmp
1384     eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $?
1385     rm -f $dsttmp.old
1386     fi
1387     if [ ".$opt_s" = .yes ]; then
1388     if [ ".$opt_t" = .yes ]; then
1389     echo "strip $dsttmp" 1>&2
1390     fi
1391     strip $dsttmp || shtool_exit $?
1392     fi
1393     if [ ".$opt_o" != . ]; then
1394     if [ ".$opt_t" = .yes ]; then
1395     echo "chown $opt_o $dsttmp" 1>&2
1396     fi
1397     chown $opt_o $dsttmp || shtool_exit $?
1398     fi
1399     if [ ".$opt_g" != . ]; then
1400     if [ ".$opt_t" = .yes ]; then
1401     echo "chgrp $opt_g $dsttmp" 1>&2
1402     fi
1403     chgrp $opt_g $dsttmp || shtool_exit $?
1404     fi
1405     if [ ".$opt_m" != ".-" ]; then
1406     if [ ".$opt_t" = .yes ]; then
1407     echo "chmod $opt_m $dsttmp" 1>&2
1408     fi
1409     chmod $opt_m $dsttmp || shtool_exit $?
1410     fi
1411    
1412     # determine whether to do a quick install
1413     # (has to be done _after_ the strip was already done)
1414     quick=no
1415     if [ ".$opt_C" = .yes ]; then
1416     if [ -r $dst ]; then
1417     if cmp -s $src $dst; then
1418     quick=yes
1419     fi
1420     fi
1421     fi
1422    
1423     # finally, install the file to the real destination
1424     if [ $quick = yes ]; then
1425     if [ ".$opt_t" = .yes ]; then
1426     echo "rm -f $dsttmp" 1>&2
1427     fi
1428     rm -f $dsttmp
1429     else
1430     if [ ".$opt_t" = .yes ]; then
1431     echo "rm -f $dst && mv $dsttmp $dst" 1>&2
1432     fi
1433     rm -f $dst && mv $dsttmp $dst
1434     fi
1435     done
1436    
1437     shtool_exit 0
1438     ;;
1439    
1440     mkdir )
1441     ##
1442     ## mkdir -- Make one or more directories
1443     ## Copyright (c) 1996-2006 Ralf S. Engelschall <rse@engelschall.com>
1444     ##
1445    
1446     errstatus=0
1447     for p in ${1+"$@"}; do
1448     # if the directory already exists...
1449     if [ -d "$p" ]; then
1450     if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
1451     echo "$msgprefix:Error: directory already exists: $p" 1>&2
1452     errstatus=1
1453     break
1454     else
1455     continue
1456     fi
1457     fi
1458     # if the directory has to be created...
1459     if [ ".$opt_p" = .no ]; then
1460     if [ ".$opt_t" = .yes ]; then
1461     echo "mkdir $p" 1>&2
1462     fi
1463     mkdir $p || errstatus=$?
1464     if [ ".$opt_o" != . ]; then
1465     if [ ".$opt_t" = .yes ]; then
1466     echo "chown $opt_o $p" 1>&2
1467     fi
1468     chown $opt_o $p || errstatus=$?
1469     fi
1470     if [ ".$opt_g" != . ]; then
1471     if [ ".$opt_t" = .yes ]; then
1472     echo "chgrp $opt_g $p" 1>&2
1473     fi
1474     chgrp $opt_g $p || errstatus=$?
1475     fi
1476     if [ ".$opt_m" != . ]; then
1477     if [ ".$opt_t" = .yes ]; then
1478     echo "chmod $opt_m $p" 1>&2
1479     fi
1480     chmod $opt_m $p || errstatus=$?
1481     fi
1482     else
1483     # the smart situation
1484     set fnord `echo ":$p" |\
1485     sed -e 's/^:\//%/' \
1486     -e 's/^://' \
1487     -e 's/\// /g' \
1488     -e 's/^%/\//'`
1489     shift
1490     pathcomp=''
1491     for d in ${1+"$@"}; do
1492     pathcomp="$pathcomp$d"
1493     case "$pathcomp" in
1494     -* ) pathcomp="./$pathcomp" ;;
1495     esac
1496     if [ ! -d "$pathcomp" ]; then
1497     if [ ".$opt_t" = .yes ]; then
1498     echo "mkdir $pathcomp" 1>&2
1499     fi
1500     mkdir $pathcomp || errstatus=$?
1501     if [ ".$opt_o" != . ]; then
1502     if [ ".$opt_t" = .yes ]; then
1503     echo "chown $opt_o $pathcomp" 1>&2
1504     fi
1505     chown $opt_o $pathcomp || errstatus=$?
1506     fi
1507     if [ ".$opt_g" != . ]; then
1508     if [ ".$opt_t" = .yes ]; then
1509     echo "chgrp $opt_g $pathcomp" 1>&2
1510     fi
1511     chgrp $opt_g $pathcomp || errstatus=$?
1512     fi
1513     if [ ".$opt_m" != . ]; then
1514     if [ ".$opt_t" = .yes ]; then
1515     echo "chmod $opt_m $pathcomp" 1>&2
1516     fi
1517     chmod $opt_m $pathcomp || errstatus=$?
1518     fi
1519     fi
1520     pathcomp="$pathcomp/"
1521     done
1522     fi
1523     done
1524    
1525     shtool_exit $errstatus
1526     ;;
1527    
1528     mkln )
1529     ##
1530     ## mkln -- Make link with calculation of relative paths
1531     ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
1532     ##
1533    
1534     # determine source(s) and destination
1535     args=$?
1536     srcs=""
1537     while [ $# -gt 1 ]; do
1538     srcs="$srcs $1"
1539     shift
1540     done
1541     dst="$1"
1542     if [ ! -d $dst ]; then
1543     if [ $args -gt 2 ]; then
1544     echo "$msgprefix:Error: multiple sources not allowed when target isn't a directory" 1>&2
1545     shtool_exit 1
1546     fi
1547     fi
1548    
1549     # determine link options
1550     lnopt=""
1551     if [ ".$opt_f" = .yes ]; then
1552     lnopt="$lnopt -f"
1553     fi
1554     if [ ".$opt_s" = .yes ]; then
1555     lnopt="$lnopt -s"
1556     fi
1557    
1558     # iterate over sources
1559     for src in $srcs; do
1560     # determine if one of the paths is an absolute path,
1561     # because then we _have_ to use an absolute symlink
1562     oneisabs=0
1563     srcisabs=0
1564     dstisabs=0
1565     case $src in
1566     /* ) oneisabs=1; srcisabs=1 ;;
1567     esac
1568     case $dst in
1569     /* ) oneisabs=1; dstisabs=1 ;;
1570     esac
1571    
1572     # split source and destination into dir and base name
1573     if [ -d $src ]; then
1574     srcdir=`echo $src | sed -e 's;/*$;;'`
1575     srcbase=""
1576     else
1577     srcdir=`echo $src | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
1578     srcbase=`echo $src | sed -e 's;.*/\([^/]*\)$;\1;'`
1579     fi
1580     if [ -d $dst ]; then
1581     dstdir=`echo $dst | sed -e 's;/*$;;'`
1582     dstbase=""
1583     else
1584     dstdir=`echo $dst | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
1585     dstbase=`echo $dst | sed -e 's;.*/\([^/]*\)$;\1;'`
1586     fi
1587    
1588     # consistency check
1589     if [ ".$dstdir" != . ]; then
1590     if [ ! -d $dstdir ]; then
1591     echo "$msgprefix:Error: destination directory not found: $dstdir" 1>&2
1592     shtool_exit 1
1593     fi
1594     fi
1595    
1596     # make sure the source is reachable from the destination
1597     if [ $dstisabs = 1 ]; then
1598     if [ $srcisabs = 0 ]; then
1599     if [ ".$srcdir" = . ]; then
1600     srcdir="`pwd | sed -e 's;/*$;;'`"
1601     srcisabs=1
1602     oneisabs=1
1603     elif [ -d $srcdir ]; then
1604     srcdir="`cd $srcdir; pwd | sed -e 's;/*$;;'`"
1605     srcisabs=1
1606     oneisabs=1
1607     fi
1608     fi
1609     fi
1610    
1611     # split away a common prefix
1612     prefix=""
1613     if [ ".$srcdir" = ".$dstdir" ] && [ ".$srcdir" != . ]; then
1614     prefix="$srcdir/"
1615     srcdir=""
1616     dstdir=""
1617     else
1618     while [ ".$srcdir" != . ] && [ ".$dstdir" != . ]; do
1619     presrc=`echo $srcdir | sed -e 's;^\([^/]*\)/.*;\1;'`
1620     predst=`echo $dstdir | sed -e 's;^\([^/]*\)/.*;\1;'`
1621     if [ ".$presrc" != ".$predst" ]; then
1622     break
1623     fi
1624     prefix="$prefix$presrc/"
1625     srcdir=`echo $srcdir | sed -e 's;^[^/]*/*;;'`
1626     dstdir=`echo $dstdir | sed -e 's;^[^/]*/*;;'`
1627     done
1628     fi
1629    
1630     # destination prefix is just the common prefix
1631     dstpre="$prefix"
1632    
1633     # determine source prefix which is the reverse directory
1634     # step-up corresponding to the destination directory
1635     srcpre=""
1636    
1637     isroot=0
1638     if [ ".$prefix" = . ] || [ ".$prefix" = ./ ]; then
1639     isroot=1
1640     fi
1641     if [ $oneisabs = 0 ] || [ $isroot = 0 ]; then
1642     pl="$dstdir/"
1643     OIFS="$IFS"; IFS='/'
1644     for pe in $pl; do
1645     [ ".$pe" = . ] && continue
1646     [ ".$pe" = .. ] && continue
1647     srcpre="../$srcpre"
1648     done
1649     IFS="$OIFS"
1650     else
1651     if [ $srcisabs = 1 ]; then
1652     srcpre="$prefix"
1653     fi
1654     fi
1655    
1656     # determine destination symlink name
1657     if [ ".$dstbase" = . ]; then
1658     if [ ".$srcbase" != . ]; then
1659     dstbase="$srcbase"
1660     else
1661     dstbase=`echo "$prefix$srcdir" | sed -e 's;/*$;;' -e 's;.*/\([^/]*\)$;\1;'`
1662     fi
1663     fi
1664    
1665     # now finalize source and destination directory paths
1666     srcdir=`echo $srcdir | sed -e 's;\([^/]\)$;\1/;'`
1667     dstdir=`echo $dstdir | sed -e 's;\([^/]\)$;\1/;'`
1668    
1669     # run the final link command
1670     if [ ".$opt_t" = .yes ]; then
1671     echo "ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase"
1672     fi
1673     eval ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase
1674     done
1675    
1676     shtool_exit 0
1677     ;;
1678    
1679     mkshadow )
1680     ##
1681     ## mkshadow -- Make a shadow tree through symbolic links
1682     ## Copyright (c) 1998-2006 Ralf S. Engelschall <rse@engelschall.com>
1683     ##
1684    
1685     # source and destination directory
1686     src=`echo "$1" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
1687     dst=`echo "$2" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
1688    
1689     # check whether source exists
1690     if [ ! -d $src ]; then
1691     echo "$msgprefix:Error: source directory not found: \`$src'" 1>&2
1692     shtool_exit 1
1693     fi
1694    
1695     # determine if one of the paths is an absolute path,
1696     # because then we have to use an absolute symlink
1697     oneisabs=0
1698     case $src in
1699     /* ) oneisabs=1 ;;
1700     esac
1701     case $dst in
1702     /* ) oneisabs=1 ;;
1703     esac
1704    
1705     # determine reverse directory for destination directory
1706     dstrevdir=''
1707     if [ $oneisabs = 0 ]; then
1708     # derive reverse path from forward path
1709     pwd=`pwd`
1710     OIFS="$IFS"; IFS='/'
1711     for pe in $dst; do
1712     if [ "x$pe" = "x.." ]; then
1713     OIFS2="$IFS"; IFS="$DIFS"
1714     eval `echo "$pwd" |\
1715     sed -e 's:\([^/]*\)$:; dir="\1":' \
1716     -e 's:^\(.*\)/[^/]*;:pwd="\1";:'\
1717     -e 's:^;:pwd="";:'`
1718     dstrevdir="$dir/$dstrevdir"
1719     IFS="$OIFS2"
1720     else
1721     dstrevdir="../$dstrevdir"
1722     fi
1723     done
1724     IFS="$OIFS"
1725     else
1726     src="`cd $src; pwd`";
1727     fi
1728    
1729     # create directory tree at destination
1730     if [ ! -d $dst ]; then
1731     if [ ".$opt_t" = .yes ]; then
1732     echo "mkdir $dst" 1>&2
1733     fi
1734     mkdir $dst
1735     fi
1736     if [ ".$opt_a" = .yes ]; then
1737     DIRS=`cd $src; find . -type d -print |\
1738     sed -e '/^\.$/d' -e 's:^\./::'`
1739     else
1740     DIRS=`cd $src; find . -type d -print |\
1741     sed -e '/\/CVS/d' -e '/^\.$/d' -e 's:^\./::'`
1742     fi
1743     for dir in $DIRS; do
1744     if [ ".$opt_t" = .yes ]; then
1745     echo "mkdir $dst/$dir" 1>&2
1746     fi
1747     mkdir $dst/$dir
1748     done
1749    
1750     # fill directory tree with symlinks to files
1751     if [ ".$opt_a" = .yes ]; then
1752     FILES="`cd $src; find . -depth -print |\
1753     sed -e 's/^\.\///'`"
1754     else
1755     FILES="`cd $src; find . -depth -print |\
1756     sed -e '/\.o$/d' -e '/\.a$/d' -e '/\.so$/d' \
1757     -e '/\.cvsignore$/d' -e '/\/CVS/d' \
1758     -e '/\/\.#/d' -e '/\.orig$/d' \
1759     -e 's/^\.\///'`"
1760     fi
1761     for file in $FILES; do
1762     # don't use `-type f' above for find because of symlinks
1763     if [ -d "$src/$file" ]; then
1764     continue
1765     fi
1766     basename=`echo $file | sed -e 's:^.*/::'`
1767     dir=`echo $file | sed -e 's:[^/]*$::' -e 's:/$::' -e 's:$:/:' -e 's:^/$::'`
1768     from=`echo "$src/$file" | sed -e 's/^\.\///'`
1769     to="$dst/$dir$basename"
1770     if [ $oneisabs = 0 ]; then
1771     if [ ".$dir" != . ]; then
1772     subdir=`echo $dir | sed -e 's:/$::'`
1773     # derive reverse path from forward path
1774     revdir=''
1775     OIFS="$IFS"; IFS='/'
1776     for pe in $subdir; do
1777     revdir="../$revdir"
1778     done
1779     IFS="$OIFS"
1780     # finalize from
1781     from="$revdir$from"
1782     fi
1783     from="$dstrevdir$from"
1784     fi
1785     if [ ".$opt_v" = .yes ]; then
1786     echo " $to" 1>&2
1787     fi
1788     if [ ".$opt_t" = .yes ]; then
1789     echo "ln -s $from $to" 1>&2
1790     fi
1791     ln -s $from $to
1792     done
1793    
1794     shtool_exit 0
1795     ;;
1796    
1797     fixperm )
1798     ##
1799     ## fixperm -- Fix file permissions inside a source tree
1800     ## Copyright (c) 1996-2006 Ralf S. Engelschall <rse@engelschall.com>
1801     ##
1802    
1803     paths="$*"
1804    
1805     # check whether the test command supports the -x option
1806     if [ -x /bin/sh ] 2>/dev/null; then
1807     minusx="-x"
1808     else
1809     minusx="-r"
1810     fi
1811    
1812     # iterate over paths
1813     for p in $paths; do
1814     for file in `find $p -depth -print`; do
1815     if [ -f $file ]; then
1816     if [ $minusx $file ]; then
1817     if [ ".$opt_v" = .yes ]; then
1818     echo "-rwxr-xr-x $file" 2>&1
1819     fi
1820     if [ ".$opt_t" = .yes ]; then
1821     echo "chmod 755 $file" 2>&1
1822     fi
1823     chmod 755 $file
1824     else
1825     if [ ".$opt_v" = .yes ]; then
1826     echo "-rw-r--r-- $file" 2>&1
1827     fi
1828     if [ ".$opt_t" = .yes ]; then
1829     echo "chmod 644 $file" 2>&1
1830     fi
1831     chmod 644 $file
1832     fi
1833     continue
1834     fi
1835     if [ -d $file ]; then
1836     if [ ".$opt_v" = .yes ]; then
1837     echo "drwxr-xr-x $file" 2>&1
1838     fi
1839     if [ ".$opt_t" = .yes ]; then
1840     echo "chmod 755 $file" 2>&1
1841     fi
1842     chmod 755 $file
1843     continue
1844     fi
1845     if [ ".$opt_v" = .yes ]; then
1846     echo "?????????? $file" 2>&1
1847     fi
1848     done
1849     done
1850    
1851     shtool_exit 0
1852     ;;
1853    
1854     rotate )
1855     ##
1856     ## rotate -- Logfile rotation
1857     ## Copyright (c) 2001-2006 Ralf S. Engelschall <rse@engelschall.com>
1858     ##
1859    
1860     # make sure we have at least one file to rotate
1861     if [ ".$opt_n" = .0 ]; then
1862     echo "$msgprefix:Error: invalid argument \`$opt_n' to option -n." 1>&2
1863     shtool_exit 1
1864     fi
1865    
1866     # canonicalize -s option argument
1867     if [ ".$opt_s" != . ]; then
1868     if [ ".`expr $opt_s : '[0-9]*$'`" != .0 ]; then
1869     :
1870     elif [ ".`expr $opt_s : '[0-9]*[Kk]$'`" != .0 ]; then
1871     opt_s=`expr $opt_s : '\([0-9]*\)[Kk]$'`
1872     opt_s=`expr $opt_s \* 1024`
1873     elif [ ".`expr $opt_s : '[0-9]*[Mm]$'`" != .0 ]; then
1874     opt_s=`expr $opt_s : '\([0-9]*\)[Mm]$'`
1875     opt_s=`expr $opt_s \* 1048576` # 1024*1024
1876     elif [ ".`expr $opt_s : '[0-9]*[Gg]$'`" != .0 ]; then
1877     opt_s=`expr $opt_s : '\([0-9]*\)[Gg]$'`
1878     opt_s=`expr $opt_s \* 1073741824` # 1024*1024*1024
1879     else
1880     echo "$msgprefix:Error: invalid argument \`$opt_s' to option -s." 1>&2
1881     shtool_exit 1
1882     fi
1883     fi
1884    
1885     # option -d/-z consistency
1886     if [ ".$opt_d" = .yes ] && [ ".$opt_z" = . ]; then
1887     echo "$msgprefix:Error: option -d requires option -z." 1>&2
1888     shtool_exit 1
1889     fi
1890    
1891     # make sure target directory exists
1892     if [ ".$opt_a" != . ]; then
1893     if [ ! -d $opt_a ]; then
1894     if [ ".$opt_f" = .no ]; then
1895     echo "$msgprefix:Error: archive directory \`$opt_a' does not exist." 1>&2
1896     shtool_exit 1
1897     fi
1898     mkdir $opt_a || shtool_exit $?
1899     chmod 755 $opt_a
1900     fi
1901     if [ ! -w $opt_a ]; then
1902     echo "$msgprefix:Error: archive directory \`$opt_a' not writable." 1>&2
1903     shtool_exit 1
1904     fi
1905     fi
1906    
1907     # determine compression approach
1908     if [ ".$opt_z" != . ]; then
1909     comp_lvl="$opt_z"
1910     comp_prg=""
1911     case $comp_lvl in
1912     *:* ) eval `echo $comp_lvl |\
1913     sed -e 's%^\(.*\):\(.*\)$%comp_prg="\1"; comp_lvl="\2"%'` ;;
1914     esac
1915    
1916     # compression level consistency
1917     case $comp_lvl in
1918     [0-9] )
1919     ;;
1920     * ) echo "$msgprefix:Error: invalid compression level \`$comp_lvl'" 1>&2
1921     shtool_exit 1
1922     ;;
1923     esac
1924    
1925     # determine a suitable compression tool
1926     if [ ".$comp_prg" = . ]; then
1927     # check whether the test command supports the -x option
1928     if [ -x /bin/sh ] 2>/dev/null; then
1929     minusx="-x"
1930     else
1931     minusx="-r"
1932     fi
1933     # search for tools in $PATH
1934     paths="`echo $PATH |\
1935     sed -e 's%/*:%:%g' -e 's%/*$%%' \
1936     -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
1937     -e 's/:/ /g'`"
1938     for prg in bzip2 gzip compress; do
1939     for path in $paths; do
1940     if [ $minusx "$path/$prg" ] && [ ! -d "$path/$prg" ]; then
1941     comp_prg="$prg"
1942     break
1943     fi
1944     done
1945     if [ ".$comp_prg" != . ]; then
1946     break
1947     fi
1948     done
1949     if [ ".$comp_prg" = . ]; then
1950     echo "$msgprefix:Error: no suitable compression tool found in \$PATH" 1>&2
1951     shtool_exit 1
1952     fi
1953     fi
1954    
1955     # determine standard compression extension
1956     # and make sure it is a known tool
1957     case $comp_prg in
1958     */bzip2 | bzip2 ) comp_ext="bz2" comp_lvl="-$comp_lvl" ;;
1959     */gzip | gzip ) comp_ext="gz" comp_lvl="-$comp_lvl" ;;
1960     */compress | compress ) comp_ext="Z"; comp_lvl="" ;;
1961     * ) echo "$msgprefix:Error: tool \`$comp_prg' is not a known compression tool" 1>&2
1962     shtool_exit 1
1963     ;;
1964     esac
1965     comp_suf=".$comp_ext"
1966     fi
1967    
1968     # iterate over all given logfile arguments
1969     for file in $*; do
1970     # make sure the logfile exists
1971     if [ ! -f $file ]; then
1972     if [ ".$opt_f" = .yes ]; then
1973     continue
1974     fi
1975     echo "$msgprefix:Error: logfile \`$file' not found" 1>&2
1976     shtool_exit 1
1977     fi
1978    
1979     # determine log directory (where original logfile is placed)
1980     ldir="."
1981     case $file in
1982     */* ) eval `echo $file | sed -e 's%^\(.*\)/\([^/]*\)$%ldir="\1"; file="\2";%'` ;;
1983     esac
1984    
1985     # determine archive directory (where rotated logfiles are placed)
1986     adir="$ldir"
1987     if [ ".$opt_a" != . ]; then
1988     case "$opt_a" in
1989     /* | ./* ) adir="$opt_a" ;;
1990     * ) adir="$ldir/$opt_a" ;;
1991     esac
1992     fi
1993    
1994     # optionally take logfile size into account
1995     if [ ".$opt_s" != . ]; then
1996     # determine size of logfile
1997     set -- `env -i /bin/ls -l "$ldir/$file" | sed -e "s;$ldir/$file;;" |\
1998     sed -e 's; -> .*$;;' -e 's;[ ][ ]*; ;g'`
1999     n=`expr $# - 3`
2000     eval "size=\`echo \${$n}\`"
2001    
2002     # skip logfile if size is still too small
2003     if [ $size -lt $opt_s ]; then
2004     if [ ".$opt_v" = .yes ]; then
2005     echo "$ldir/$file: still too small in size -- skipping"
2006     fi
2007     continue
2008     fi
2009     fi
2010    
2011     # verbosity
2012     if [ ".$opt_v" = .yes ]; then
2013     echo "rotating $ldir/$file"
2014     fi
2015    
2016     # execute prolog
2017     if [ ".$opt_P" != . ]; then
2018     if [ ".$opt_t" = .yes ]; then
2019     echo "$opt_P"
2020     fi
2021     eval $opt_P
2022     [ $? -ne 0 ] && shtool_exit $?
2023     fi
2024    
2025     # kick away out-rotated logfile
2026     n=`expr $opt_n - 1`
2027     n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
2028     if [ -f "${adir}/${file}.${n}${comp_suf}" ]; then
2029     # optionally migrate away the out-rotated logfile
2030     if [ ".$opt_M" != . ]; then
2031     if [ ".$opt_t" = .yes ]; then
2032     echo "$opt_M ${adir}/${file}.${n}${comp_suf}"
2033     fi
2034     eval "$opt_M ${adir}/${file}.${n}${comp_suf}"
2035     [ $? -ne 0 ] && shtool_exit $?
2036     fi
2037     # finally get rid of the out-rotated logfile
2038     if [ ".$opt_t" = .yes ]; then
2039     echo "rm -f ${adir}/${file}.${n}${comp_suf}"
2040     fi
2041     rm -f ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
2042     fi
2043    
2044     # rotate already archived logfiles
2045     while [ $n -gt 0 ]; do
2046     m=$n
2047     n=`expr $n - 1`
2048     n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
2049     if [ $n -eq 0 ] && [ ".$opt_d" = .yes ]; then
2050     # special case: first rotation file under delayed compression situation
2051     if [ ! -f "${adir}/${file}.${n}" ]; then
2052     continue
2053     fi
2054    
2055     # compress file (delayed)
2056     if [ ".$opt_b" = .yes ]; then
2057     if [ ".$opt_t" = .yes ]; then
2058     echo "mv ${adir}/${file}.${n} ${adir}/${file}.${m}"
2059     fi
2060     mv ${adir}/${file}.${n} ${adir}/${file}.${m} || shtool_exit $?
2061     if [ ".$opt_t" = .yes ]; then
2062     echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${m} >${adir}/${file}.${m}${comp_suf}; rm -f ${adir}/${file}.${m}) &"
2063     fi
2064     ( ${comp_prg} ${comp_lvl} \
2065     <${adir}/${file}.${m} \
2066     >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
2067     rm -f ${adir}/${file}.${m} || shtool_exit $?
2068     ) </dev/null >/dev/null 2>&1 &
2069     else
2070     if [ ".$opt_t" = .yes ]; then
2071     echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${m}${comp_suf}"
2072     fi
2073     ${comp_prg} ${comp_lvl} \
2074     <${adir}/${file}.${n} \
2075     >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
2076     if [ ".$opt_t" = .yes ]; then
2077     echo "rm -f ${adir}/${file}.${n}"
2078     fi
2079     rm -f ${adir}/${file}.${n} || shtool_exit $?
2080     fi
2081    
2082     # fix file attributes
2083     if [ ".$opt_o" != . ]; then
2084     if [ ".$opt_t" = .yes ]; then
2085     echo "chown $opt_o ${adir}/${file}.${m}${comp_suf}"
2086     fi
2087     chown $opt_o ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
2088     fi
2089     if [ ".$opt_g" != . ]; then
2090     if [ ".$opt_t" = .yes ]; then
2091     echo "chgrp $opt_g ${adir}/${file}.${m}${comp_suf}"
2092     fi
2093     chgrp $opt_g ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
2094     fi
2095     if [ ".$opt_m" != . ]; then
2096     if [ ".$opt_t" = .yes ]; then
2097     echo "chmod $opt_m ${adir}/${file}.${m}${comp_suf}"
2098     fi
2099     chmod $opt_m ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
2100     fi
2101     else
2102     # standard case: second and following rotation file
2103     if [ ! -f "${adir}/${file}.${n}${comp_suf}" ]; then
2104     continue
2105     fi
2106     if [ ".$opt_t" = .yes ]; then
2107     echo "mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf}"
2108     fi
2109     mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
2110     fi
2111     done
2112    
2113     # move away current logfile
2114     if [ ".$opt_c" = .yes ]; then
2115     # approach: copy[+truncate]
2116     if [ ".$opt_t" = .yes ]; then
2117     echo "cp -p ${ldir}/${file} ${adir}/${file}.${n}"
2118     fi
2119     cp -p ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
2120     if [ ".$opt_r" = .no ]; then
2121     if [ ".$opt_t" = .yes ]; then
2122     echo "cp /dev/null ${ldir}/${file}"
2123     fi
2124     cp /dev/null ${ldir}/${file} || shtool_exit $?
2125     fi
2126     else
2127     # approach: move[+touch]
2128     if [ ".$opt_t" = .yes ]; then
2129     echo "mv ${ldir}/${file} ${adir}/${file}.${n}"
2130     fi
2131     mv ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
2132     if [ ".$opt_r" = .no ]; then
2133     if [ ".$opt_t" = .yes ]; then
2134     echo "touch ${ldir}/${file}"
2135     fi
2136     touch ${ldir}/${file} || shtool_exit $?
2137     # fix file attributes
2138     if [ ".$opt_o" != . ]; then
2139     if [ ".$opt_t" = .yes ]; then
2140     echo "chown $opt_o ${ldir}/${file}"
2141     fi
2142     chown $opt_o ${ldir}/${file} || shtool_exit $?
2143     fi
2144     if [ ".$opt_g" != . ]; then
2145     if [ ".$opt_t" = .yes ]; then
2146     echo "chgrp $opt_g ${ldir}/${file}"
2147     fi
2148     chgrp $opt_g ${ldir}/${file} || shtool_exit $?
2149     fi
2150     if [ ".$opt_m" != . ]; then
2151     if [ ".$opt_t" = .yes ]; then
2152     echo "chmod $opt_m ${ldir}/${file}"
2153     fi
2154     chmod $opt_m ${ldir}/${file} || shtool_exit $?
2155     fi
2156     fi
2157     fi
2158    
2159     # regular compression step
2160     if [ ".$opt_z" != . ] && [ ".$opt_d" = .no ]; then
2161     # compress file
2162     if [ ".$opt_b" = .yes ]; then
2163     if [ ".$opt_t" = .yes ]; then
2164     echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}; rm -f ${adir}/${file}.${n}) &"
2165     fi
2166     ( ${comp_prg} ${comp_lvl} \
2167     <${adir}/${file}.${n} \
2168     >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
2169     rm -f ${adir}/${file}.${n} || shtool_exit $?
2170     ) </dev/null >/dev/null 2>&1 &
2171     else
2172     if [ ".$opt_t" = .yes ]; then
2173     echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}"
2174     fi
2175     ${comp_prg} ${comp_lvl} \
2176     <${adir}/${file}.${n} \
2177     >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
2178     if [ ".$opt_t" = .yes ]; then
2179     echo "rm -f ${opt_a}${file}.${n}"
2180     fi
2181     rm -f ${adir}/${file}.${n} || shtool_exit $?
2182     fi
2183    
2184     # fix file attributes
2185     if [ ".$opt_o" != . ]; then
2186     if [ ".$opt_t" = .yes ]; then
2187     echo "chown $opt_o ${adir}/${file}.${n}${comp_suf}"
2188     fi
2189     chown $opt_o ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
2190     fi
2191     if [ ".$opt_g" != . ]; then
2192     if [ ".$opt_t" = .yes ]; then
2193     echo "chgrp $opt_g ${adir}/${file}.${n}${comp_suf}"
2194     fi
2195     chgrp $opt_g ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
2196     fi
2197     if [ ".$opt_m" != . ]; then
2198     if [ ".$opt_t" = .yes ]; then
2199     echo "chmod $opt_m ${adir}/${file}.${n}${comp_suf}"
2200     fi
2201     chmod $opt_m ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
2202     fi
2203     fi
2204    
2205     # execute epilog
2206     if [ ".$opt_E" != . ]; then
2207     if [ ".$opt_t" = .yes ]; then
2208     echo "$opt_E"
2209     fi
2210     eval $opt_E
2211     [ $? -ne 0 ] && shtool_exit $?
2212     fi
2213     done
2214    
2215     shtool_exit 0
2216     ;;
2217    
2218     tarball )
2219     ##
2220     ## tarball -- Roll distribution tarballs
2221     ## Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
2222     ##
2223    
2224     srcs="$*"
2225    
2226     # check whether the test command supports the -x option
2227     if [ -x /bin/sh ] 2>/dev/null; then
2228     minusx="-x"
2229     else
2230     minusx="-r"
2231     fi
2232    
2233     # find the tools
2234     paths="`echo $PATH |\
2235     sed -e 's%/*:%:%g' -e 's%/*$%%' \
2236     -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
2237     -e 's/:/ /g'`"
2238     for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do
2239     prg=`echo $spec | sed -e 's/:.*$//'`
2240     tools=`echo $spec | sed -e 's/^.*://'`
2241     eval "prg_${prg}=''"
2242     # iterate over tools
2243     for tool in `echo $tools | sed -e 's/,/ /g'`; do
2244     # iterate over paths
2245     for path in $paths; do
2246     if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then
2247     eval "prg_${prg}=\"$path/$tool\""
2248     break
2249     fi
2250     done
2251     eval "val=\$prg_${prg}"
2252     if [ ".$val" != . ]; then
2253     break
2254     fi
2255     done
2256     done
2257    
2258     # expand source paths
2259     exclude=''
2260     for pat in `echo $opt_e | sed 's/,/ /g'`; do
2261     exclude="$exclude | grep -v '$pat'"
2262     done
2263     if [ ".$opt_t" = .yes ]; then
2264     echo "cp /dev/null $tmpfile.lst" 1>&2
2265     fi
2266     cp /dev/null $tmpfile.lst
2267     for src in $srcs; do
2268     if [ -d $src ]; then
2269     if [ ".$opt_t" = .yes ]; then
2270     echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2
2271     fi
2272     (cd $src && $prg_find . -type f -depth -print) |\
2273     sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst
2274     else
2275     if [ ".$opt_t" = .yes ]; then
2276     echo "echo $src >>$tmpfile.lst" 1>&2
2277     fi
2278     echo $src >>$tmpfile.lst
2279     fi
2280     done
2281     sort <$tmpfile.lst >$tmpfile.lst.n
2282     mv $tmpfile.lst.n $tmpfile.lst
2283     if [ ".$opt_v" = .yes ]; then
2284     cat $tmpfile.lst | sed -e 's/^/ /' 1>&2
2285     fi
2286    
2287     # determine tarball file and directory name
2288     if [ ".$opt_o" != . ]; then
2289     tarfile="$opt_o"
2290     if [ ".$opt_d" != . ]; then
2291     tarname="$opt_d"
2292     else
2293     tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'`
2294     fi
2295     else
2296     if [ ".$opt_d" != . ]; then
2297     tarname="$opt_d"
2298     elif [ -d "$from" ]; then
2299     tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'`
2300     else
2301     tarname="out"
2302     fi
2303     tarfile="$tarname.tar"
2304     fi
2305    
2306     # roll the tarball
2307     compress=''
2308     if [ ".$opt_c" != . ]; then
2309     compress="| $opt_c"
2310     fi
2311     if [ ".$prg_tardy" != . ]; then
2312     # the elegant hackers way
2313     tardy_opt="--prefix=$tarname"
2314     tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security!
2315     if [ ".$opt_u" != . ]; then
2316     tardy_opt="$tardy_opt --user_name=$opt_u"
2317     fi
2318     if [ ".$opt_g" != . ]; then
2319     tardy_opt="$tardy_opt --group_name=$opt_g"
2320     fi
2321     if [ ".$opt_t" = .yes ]; then
2322     echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2
2323     fi
2324     cat $tmpfile.lst |\
2325     xargs $prg_tar cf - |\
2326     $prg_tardy $tardy_opt |\
2327     eval cat $compress >$tmpfile.out
2328     if [ ".$opt_t" = .yes ]; then
2329     echo "cp $tmpfile.out $tarfile" 1>&2
2330     fi
2331     cp $tmpfile.out $tarfile
2332     else
2333     # the portable standard way
2334     if [ ".$opt_t" = .yes ]; then
2335     echo "mkdir $tmpdir/$tarname" 1>&2
2336     fi
2337     mkdir $tmpdir/$tarname || shtool_exit 1
2338     if [ ".$opt_t" = .yes ]; then
2339     echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2
2340     fi
2341     cat $tmpfile.lst |\
2342     xargs $prg_tar cf - |\
2343     (cd $tmpdir/$tarname && $prg_tar xf -)
2344     if [ ".$opt_u" != . ]; then
2345     if [ ".$opt_t" = .yes ]; then
2346     echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1
2347     fi
2348     chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\
2349     echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)"
2350     fi
2351     if [ ".$opt_g" != . ]; then
2352     if [ ".$opt_t" = .yes ]; then
2353     echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1
2354     fi
2355     chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\
2356     echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)"
2357     fi
2358     if [ ".$opt_t" = .yes ]; then
2359     echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2
2360     fi
2361     (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\
2362     eval cat $compress >$tmpfile.out
2363     if [ ".$opt_t" = .yes ]; then
2364     echo "cp $tmpfile.out $tarfile" 1>&2
2365     fi
2366     cp $tmpfile.out $tarfile
2367     if [ ".$opt_t" = .yes ]; then
2368     echo "rm -rf $tmpdir/$tarname" 1>&2
2369     fi
2370     rm -rf $tmpdir/$tarname
2371     fi
2372    
2373     # cleanup
2374     if [ ".$opt_t" = .yes ]; then
2375     echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2
2376     fi
2377     rm -f $tmpfile.lst $tmpfile.out
2378    
2379     shtool_exit 0
2380     ;;
2381    
2382     subst )
2383     ##
2384     ## subst -- Apply sed(1) substitution operations
2385     ## Copyright (c) 2001-2006 Ralf S. Engelschall <rse@engelschall.com>
2386     ##
2387    
2388     # remember optional list of file(s)
2389     files="$*"
2390     files_num="$#"
2391    
2392     # parameter consistency check
2393     if [ $# -eq 0 ] && [ ".$opt_b" != . ]; then
2394     echo "$msgprefix:Error: option -b cannot be applied to stdin" 1>&2
2395     shtool_exit 1
2396     fi
2397     if [ $# -eq 0 ] && [ ".$opt_s" = .yes ]; then
2398     echo "$msgprefix:Error: option -s cannot be applied to stdin" 1>&2
2399     shtool_exit 1
2400     fi
2401    
2402     # build underlying sed(1) command
2403     sedcmd='sed'
2404     if [ ".$opt_e" != . ]; then
2405     OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
2406     for e
2407     do
2408     sedcmd="$sedcmd -e '$e'"
2409     done
2410     elif [ ".$opt_f" != . ]; then
2411     if [ ! -f $opt_f ]; then
2412     echo "$msgprefix:Error: command file \`$opt_f' not found or not a regular file" 1>&2
2413     shtool_exit 1
2414     fi
2415     sedcmd="$sedcmd -f '$opt_f'"
2416     else
2417     echo "$msgprefix:Error: either -e option(s) or -f option required" 1>&2
2418     shtool_exit 1
2419     fi
2420    
2421     # determine extension for original file
2422     orig=".orig"
2423     if [ ".$opt_b" != . ]; then
2424     orig="$opt_b"
2425     fi
2426    
2427     # apply sed(1) operation(s)
2428     if [ ".$files" != . ]; then
2429     # apply operation(s) to files
2430     substdone=no
2431     for file in $files; do
2432     test ".$file" = . && continue
2433     if [ ! -f $file ]; then
2434     echo "$msgprefix:Warning: file \`$file' not found or not a regular file" 1>&2
2435     continue
2436     fi
2437    
2438     # handle interactive mode
2439     if [ ".$opt_i" = .yes ]; then
2440     eval "$sedcmd <$file >$file.new"
2441     skip=no
2442     if cmp $file $file.new >/dev/null 2>&1; then
2443     rm -f $file.new
2444     skip=yes
2445     else
2446     (diff -U1 $file $file.new >$tmpfile) 2>/dev/null
2447     if [ ".`cat $tmpfile`" = . ]; then
2448     (diff -C1 $file $file.new >$tmpfile) 2>/dev/null
2449     if [ ".`cat $tmpfile`" = . ]; then
2450     echo "$msgprefix:Warning: unable to show difference for file \`$file'" 1>&2
2451     cp /dev/null $tmpfile
2452     fi
2453     fi
2454     rm -f $file.new
2455     cat $tmpfile
2456     echo dummy | awk '{ printf("%s", TEXT); }' TEXT=">>> Apply [Y/n]: "
2457     read input
2458     if [ ".$input" != .Y ] &&\
2459     [ ".$input" != .y ] &&\
2460     [ ".$input" != . ]; then
2461     skip=yes
2462     fi
2463     fi
2464     if [ ".$skip" = .yes ]; then
2465     if [ ".$opt_v" = .yes ]; then
2466     echo "file \`$file' -- skipped" 1>&2
2467     fi
2468     continue
2469     fi
2470     fi
2471    
2472     # apply sed(1) operation(s)
2473     if [ ".$opt_v" = .yes ]; then
2474     echo "patching \`$file'" 1>&2
2475     fi
2476     if [ ".$opt_t" = .yes ]; then
2477     echo "\$ cp -p $file $file$orig"
2478     echo "\$ chmod u+w $file"
2479     echo "\$ $sedcmd <$file$orig >$file"
2480     fi
2481     if [ ".$opt_n" = .no ]; then
2482     cp -p $file $file$orig
2483     chmod u+w $file >/dev/null 2>&1 || true
2484     eval "$sedcmd <$file$orig >$file"
2485     fi
2486    
2487     # optionally fix timestamp
2488     if [ ".$opt_s" = .yes ]; then
2489     if [ ".$opt_t" = .yes ]; then
2490     echo "\$ touch -r $file$orig $file"
2491     fi
2492     if [ ".$opt_n" = .no ]; then
2493     touch -r $file$orig $file
2494     fi
2495     fi
2496    
2497     # optionally check whether any content change actually occurred
2498     if [ ".$opt_q" = .no ]; then
2499     if cmp $file$orig $file >/dev/null 2>&1; then
2500     if [ ".$opt_w" = .yes ]; then
2501     echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
2502     fi
2503     else
2504     substdone=yes
2505     fi
2506     fi
2507    
2508     # optionally remove preserved original file
2509     if [ ".$opt_b" = . ]; then
2510     if [ ".$opt_t" = .yes ]; then
2511     echo "\$ rm -f $file$orig"
2512     fi
2513     if [ ".$opt_n" = .no ]; then
2514     rm -f $file$orig
2515     fi
2516     fi
2517     done
2518     if [ ".$opt_q" = .no ] && [ ".$opt_w" = .no ]; then
2519     if [ ".$substdone" = .no ]; then
2520     if [ ".$files_num" = .1 ]; then
2521     echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
2522     else
2523     echo "$msgprefix:Warning: substitution resulted in no content change on any file" 1>&2
2524     fi
2525     fi
2526     fi
2527     else
2528     # apply operation(s) to stdin/stdout
2529     if [ ".$opt_v" = .yes ]; then
2530     echo "patching <stdin>" 1>&2
2531     fi
2532     if [ ".$opt_t" = .yes ]; then
2533     echo "\$ $sedcmd"
2534     fi
2535     if [ ".$opt_n" = .no ]; then
2536     eval "$sedcmd"
2537     fi
2538     fi
2539    
2540     shtool_exit 0
2541     ;;
2542    
2543     platform )
2544     ##
2545     ## platform -- Platform Identification Utility
2546     ## Copyright (c) 2003-2006 Ralf S. Engelschall <rse@engelschall.com>
2547     ##
2548    
2549     # option post-processing
2550     if [ ".$opt_t" != . ]; then
2551     case "$opt_t" in
2552     binary )
2553     # binary package id (OpenPKG RPM)
2554     opt_F="%<ap>-%<sp>"
2555     opt_L=yes
2556     opt_S=""
2557     opt_C="+"
2558     ;;
2559     build )
2560     # build time checking (OpenPKG RPM)
2561     opt_F="%<at>-%<st>"
2562     opt_L=yes
2563     opt_S=""
2564     opt_C="+"
2565     ;;
2566     gnu )
2567     # GNU config.guess style <arch>-<vendor>-<os><osversion>
2568     opt_F="%<at>-unknown-%<st>"
2569     opt_L=yes
2570     opt_S=""
2571     opt_C="+"
2572     ;;
2573     web )
2574     # non-whitespace HTTP Server-header id
2575     opt_F="%<sp>-%<ap>"
2576     opt_S="/"
2577     opt_C="+"
2578     ;;
2579     summary)
2580     # human readable verbose summary information
2581     opt_F="Class: %[sc] (%[ac])\\nProduct: %[sp] (%[ap])\\nTechnology: %[st] (%[at])"
2582     opt_S=" "
2583     opt_C="/"
2584     ;;
2585     all-in-one )
2586     # full-table all-in-one information
2587     opt_F=""
2588     opt_F="${opt_F}concise architecture class: %<ac>\\n"
2589     opt_F="${opt_F}regular architecture class: %{ac}\\n"
2590     opt_F="${opt_F}verbose architecture class: %[ac]\\n"
2591     opt_F="${opt_F}concise architecture product: %<ap>\\n"
2592     opt_F="${opt_F}regular architecture product: %{ap}\\n"
2593     opt_F="${opt_F}verbose architecture product: %[ap]\\n"
2594     opt_F="${opt_F}concise architecture technology: %<at>\\n"
2595     opt_F="${opt_F}regular architecture technology: %{at}\\n"
2596     opt_F="${opt_F}verbose architecture technology: %[at]\\n"
2597     opt_F="${opt_F}concise system class: %<sc>\\n"
2598     opt_F="${opt_F}regular system class: %{sc}\\n"
2599     opt_F="${opt_F}verbose system class: %[sc]\\n"
2600     opt_F="${opt_F}concise system product: %<sp>\\n"
2601     opt_F="${opt_F}regular system product: %{sp}\\n"
2602     opt_F="${opt_F}verbose system product: %[sp]\\n"
2603     opt_F="${opt_F}concise system technology: %<st>\\n"
2604     opt_F="${opt_F}regular system technology: %{st}\\n"
2605     opt_F="${opt_F}verbose system technology: %[st]"
2606     ;;
2607     * )
2608     echo "$msgprefix:Error: invalid type \`$opt_t'" 1>&2
2609     exit 1
2610     ;;
2611     esac
2612     fi
2613    
2614     # assemble initial platform information
2615     UNAME_MACHINE=`(uname -m) 2>/dev/null` ||\
2616     UNAME_MACHINE=`(uname -p) 2>/dev/null` ||\
2617     UNAME_MACHINE='unknown'
2618