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