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