Mon, 28 Jan 2013 17:37:18 +0100
Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.
1 #!@l_prefix@/lib/openpkg/bash
2 ##
3 ## rpmtool -- OpenPKG RPM Auxiliary Tool
4 ## Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>
5 ##
6 ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
7 ## All rights reserved. Licenses which grant limited permission to use,
8 ## copy, modify and distribute this software are available from the
9 ## OpenPKG GmbH.
10 ##
11 ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
12 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
15 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
16 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
17 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
21 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22 ## SUCH DAMAGE.
23 ##
25 prog_path="$0"
26 prog_name="rpmtool"
27 prog_vers="1.1.0"
28 prog_date="05-Mar-2007"
30 if [ $# -eq 0 ]; then
31 echo "$0:Error: invalid command line" 1>&2
32 echo "$0:Hint: run \`$0 -h' for usage" 1>&2
33 exit 1
34 fi
35 if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
36 echo "This is $prog_name, version $prog_vers ($prog_date)"
37 echo "Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>"
38 echo ''
39 echo "Usage: $prog_name [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]"
40 echo ''
41 echo 'Available global <options>:'
42 echo ' -d, --debug enable internal debugging'
43 echo ' -v, --version display version information'
44 echo ' -h, --help display usage help page (this one)'
45 echo ''
46 echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
47 echo ' platform'
48 echo ' mflags [-O] <tool>'
49 echo ' cflags [-O] <tool>'
50 echo ' cppflags [-p <prefix>] [<subdir> ...]'
51 echo ' ldflags [-p <prefix>] [<subdir> ...]'
52 echo ' files [-v] [-o <outfile>] [-r <buildroot>] [<filelist>]'
53 echo ' signal [-v] [-t] [-n] [-c] [-d <delay>] [-p <pid>] [-m <pattern>] <sig> [<sig> ...]'
54 echo ' config [-v] [-s] [-a] [-r] [-b <ext>] [-p <tagprefix>] [-t <tagname>] [-i <tagid>] <file>'
55 echo ' msg [-b] [-r] [-t <type>]'
56 echo ''
57 exit 0
58 fi
59 if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then
60 echo "$prog_name $prog_vers ($prog_date)"
61 exit 0
62 fi
63 if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then
64 shift
65 set -x
66 fi
68 tool="$1"
69 shift
70 arg_spec=""
71 opt_spec=""
72 gen_tmpfile=no
74 # configure tool specific option parsing
75 case $tool in
76 platform )
77 str_usage=""
78 arg_spec="0="
79 opt_spec=""
80 ;;
81 mflags )
82 str_usage="[-O] <tool>"
83 arg_spec="1="
84 opt_spec="O."
85 opt_O=no
86 ;;
87 cflags )
88 str_usage="[-O] <tool>"
89 arg_spec="1="
90 opt_spec="O."
91 opt_O=no
92 ;;
93 cppflags )
94 str_usage="[-p <prefix>] [-i] [<subdir> ...]"
95 arg_spec="0+"
96 opt_spec="p:i."
97 opt_p="/"
98 ;;
99 ldflags )
100 str_usage="[-p <prefix>] [<subdir> ...]"
101 arg_spec="0+"
102 opt_spec="p:"
103 opt_p="/"
104 ;;
105 files )
106 gen_tmpfile=yes
107 str_usage="[-v] [-o <outfile>] [-r <buildroot>] [<filelist>]"
108 arg_spec="0+"
109 opt_spec="v.o:r:"
110 opt_v=no
111 opt_o=''
112 opt_r=''
113 ;;
114 signal )
115 str_usage="[-v] [-t] [-n] [-c] [-d <delay>] [-p <pid>] [-m <pattern>] <sig> [<sig> ...]"
116 arg_spec="1+"
117 opt_spec="v.t.n.c.d:p:m:"
118 opt_v=no
119 opt_t=no
120 opt_n=no
121 opt_c=no
122 opt_d=1
123 opt_p=""
124 opt_m=""
125 ;;
126 config )
127 str_usage="[-v] [-s] [-a] [-r] [-b <ext>] [-p <tagprefix>] [-t <tagname>] [-i <tagid>] <file>"
128 arg_spec="1="
129 opt_spec="v.s.a.r.b:p:t:i:c:"
130 opt_v=no
131 opt_s=no
132 opt_a=no
133 opt_r=no
134 opt_b=""
135 opt_p="#"
136 opt_t="OpenPKG"
137 opt_i=""
138 gen_tmpfile=yes
139 ;;
140 msg )
141 str_usage="[-b] [-r] [-t <type>]"
142 arg_spec="0="
143 opt_spec="b.r.t:"
144 opt_b=no
145 opt_r=no
146 opt_t=info
147 ;;
148 check-class )
149 str_usage=""
150 arg_spec="1="
151 opt_spec=""
152 ;;
153 -* )
154 echo "$prog_name:Error: unknown option \`$tool'" 2>&1
155 echo "$prog_name:Hint: run \`$0 -h' for usage" 2>&1
156 exit 1
157 ;;
158 * )
159 echo "$prog_name:Error: unknown command \`$tool'" 2>&1
160 echo "$prog_name:Hint: run \`$0 -h' for usage" 2>&1
161 exit 1
162 ;;
163 esac
165 # tool information
166 toolcmd="$0 $tool"
167 toolcmdhelp="$prog_name $tool"
168 msgprefix="$prog_name:$tool"
170 # parse argument specification string
171 eval `echo $arg_spec |\
172 sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
174 # parse option specification string
175 eval `echo h.$opt_spec |\
176 sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
178 # iterate over argument line
179 opt_PREV=''
180 while [ $# -gt 0 ]; do
181 # special option stops processing
182 if [ ".$1" = ".--" ]; then
183 shift
184 break
185 fi
187 # determine option and argument
188 opt_ARG_OK=no
189 if [ ".$opt_PREV" != . ]; then
190 # merge previous seen option with argument
191 opt_OPT="$opt_PREV"
192 opt_ARG="$1"
193 opt_ARG_OK=yes
194 opt_PREV=''
195 else
196 # split argument into option and argument
197 case "$1" in
198 -[a-zA-Z0-9]*)
199 eval `echo "x$1" |\
200 sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
201 -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
202 ;;
203 -[a-zA-Z0-9])
204 opt_OPT=`echo "x$1" | cut -c3-`
205 opt_ARG=''
206 ;;
207 *)
208 break
209 ;;
210 esac
211 fi
213 # eat up option
214 shift
216 # determine whether option needs an argument
217 eval "opt_MODE=\$opt_MODE_${opt_OPT}"
218 if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then
219 if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then
220 opt_PREV="$opt_OPT"
221 continue
222 fi
223 fi
225 # process option
226 case $opt_MODE in
227 '.' )
228 # boolean option
229 eval "opt_${opt_OPT}=yes"
230 ;;
231 ':' )
232 # option with argument (multiple occurances override)
233 eval "opt_${opt_OPT}=\"\$opt_ARG\""
234 ;;
235 '+' )
236 # option with argument (multiple occurances append)
237 eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
238 ;;
239 * )
240 echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2
241 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man $prog_name' for details" 1>&2
242 exit 1
243 ;;
244 esac
245 done
246 if [ ".$opt_PREV" != . ]; then
247 echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2
248 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man $prog_name' for details" 1>&2
249 exit 1
250 fi
252 # process help option
253 if [ ".$opt_h" = .yes ]; then
254 echo "Usage: $toolcmdhelp $str_usage"
255 exit 0
256 fi
258 # complain about incorrect number of arguments
259 case $arg_MODE in
260 '=' )
261 if [ $# -ne $arg_NUMS ]; then
262 echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
263 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man $prog_name' for details" 1>&2
264 exit 1
265 fi
266 ;;
267 '+' )
268 if [ $# -lt $arg_NUMS ]; then
269 echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
270 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man $prog_name' for details" 1>&2
271 exit 1
272 fi
273 ;;
274 esac
276 # establish a temporary file on request
277 if [ ".$gen_tmpfile" = .yes ]; then
278 if [ ".$TMPDIR" != . ]; then
279 tmpdir="$TMPDIR"
280 else
281 tmpdir="/tmp"
282 fi
283 tmpfile="$tmpdir/.$prog_name.$$"
284 rm -f $tmpfile >/dev/null 2>&1
285 touch $tmpfile
286 fi
288 # provide a few useful variables
289 NL="
290 "
291 TAB=" "
292 DIFS=" ${TAB}${NL}"
294 # determine platform information
295 platform_machine=`(uname -m) 2>/dev/null` ||\
296 platform_machine=`(uname -p) 2>/dev/null` ||\
297 platform_machine='unknown'
298 if [ ".$platform_machine" = ".Power Macintosh" ]; then
299 platform_machine=`(uname -p) 2>/dev/null`
300 fi
301 platform_release=`(uname -r) 2>/dev/null` ||\
302 platform_release='unknown'
303 platform_system=`(uname -s) 2>/dev/null` ||\
304 platform_system='unknown'
305 platform_version=`(uname -v) 2>/dev/null` ||\
306 platform_version='unknown'
307 platform="${platform_machine}:${platform_system}:${platform_release}:${platform_version}"
309 # dispatch into tools
310 case $tool in
311 platform )
312 # provide unique platform id
313 m=`echo "$platform_machine" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
314 s=`echo "$platform_system" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
315 r=`echo "$platform_release" | sed -e 's;-.*$;;'`
316 echo "${m}-${s}${r}"
317 ;;
319 mflags )
320 tool="$1"
321 isgmake=no
322 if [ ".`$tool -v -f /dev/null 2>/dev/null | grep 'GNU Make'`" != . ]; then
323 isgmake=yes
324 fi
325 mflags=''
326 if [ ".$isgmake" = .yes ]; then
327 mflags="--no-print-directory"
328 fi
329 if [ ".$opt_O" = .yes ]; then
330 case $platform in
331 *:SunOS:5.*:* | *:OSF1:*:* )
332 if [ ".$isgmake" = .yes ]; then
333 n=`(/bin/uname -X) 2>/dev/null | grep -i NumCPU | awk '{ print $3; }'`
334 if [ ".$n" != . ]; then
335 if [ $n -gt 1 ]; then
336 n=`expr $n \* 2`
337 mflags="$mflags -j$n"
338 fi
339 fi
340 fi
341 ;;
342 *:FreeBSD:[4-8].*:* )
343 n=`/sbin/sysctl -n hw.ncpu`
344 if [ ".$n" != . ]; then
345 if [ $n -gt 1 ]; then
346 n=`expr $n \* 2`
347 mflags="$mflags -j$n"
348 if [ ".$isgmake" = .no ]; then
349 mflags="$mflags -B"
350 fi
351 fi
352 fi
353 ;;
354 *:NetBSD:1.[56]*:* | *:NetBSD:[2345].*:* )
355 n=`/sbin/sysctl -n hw.ncpu`
356 if [ ".$n" != . ]; then
357 if [ $n -gt 1 ]; then
358 n=`expr $n \* 2`
359 mflags="$mflags -j$n"
360 if [ ".$isgmake" = .no ]; then
361 mflags="$mflags -B"
362 fi
363 fi
364 fi
365 ;;
366 *:Linux:*:* )
367 n=`grep ^processor /proc/cpuinfo | wc -l | awk '{ print $1; }'`
368 if [ ".$n" != . ]; then
369 if [ $n -gt 1 ]; then
370 n=`expr $n \* 2`
371 mflags="$mflags -j$n"
372 fi
373 fi
374 ;;
375 *:HP-UX:*:* )
376 if [ ".$isgmake" = .yes ]; then
377 n=`ioscan -d processor -k -F | wc -l`
378 if [ ".$n" != . ]; then
379 if [ $n -gt 1 ]; then
380 n=`expr $n \* 2`
381 mflags="$mflags -j$n"
382 fi
383 fi
384 fi
385 ;;
386 *:IRIX64:6.*:* )
387 if [ ".$isgmake" = .yes ]; then
388 n=`/usr/sbin/sysconf | awk '/NUM_PROCESSORS/ { print $2; }'`
389 if [ ".$n" != . ]; then
390 if [ $n -gt 1 ]; then
391 n=`expr $n \* 2`
392 mflags="$mflags -j$n"
393 fi
394 fi
395 fi
396 ;;
397 *:Darwin:*:* )
398 n=`/usr/sbin/sysctl hw.ncpu | awk '{ print $3; }'`
399 if [ ".$n" != . ]; then
400 if [ $n -gt 1 ]; then
401 n=`expr $n \* 2`
402 mflags="$mflags -j$n"
403 if [ ".$isgmake" = .no ]; then
404 mflags="$mflags -B"
405 fi
406 fi
407 fi
408 ;;
409 *:AIX:*:* )
410 if [ ".$isgmake" = .yes ]; then
411 if [ -x /usr/sbin/lsdev ]; then
412 n=`/usr/sbin/lsdev -C -c processor -S available | wc -l | awk '{ print $1; }'`
413 if [ ".$n" != . ]; then
414 if [ $n -gt 1 ]; then
415 n=`expr $n \* 2`
416 mflags="$mflags -j$n"
417 fi
418 fi
419 fi
420 fi
421 ;;
422 esac
423 fi
424 echo "x$mflags" | sed -e 's;^x;;'
425 ;;
427 cflags )
428 tool="$1"
429 echo $tool | grep ^/ >/dev/null
430 if [ $? -eq 0 ]; then
431 if [ ! -x "$tool" -o -d "$tool" ]; then
432 echo "$msgprefix:Error: specified tool \`$tool' not found or not executable" 1>&2
433 exit 1
434 fi
435 else
436 shtool=`echo $prog_path | sed -e 's;/[^/]*$;/shtool;'`
437 sh $shtool path --suppress $tool
438 if [ $? -ne 0 ]; then
439 echo "$msgprefix:Error: specified tool \`$tool' not found in PATH" 1>&2
440 exit 1
441 fi
442 fi
443 isgcc=no
444 if [ ".`($tool -v; $tool --version) </dev/null 2>&1 | grep -i 'gcc'`" != . ]; then
445 isgcc=yes
446 fi
447 cflags=''
448 if [ ".$opt_O" = .yes ]; then
449 if [ ".$isgcc" = .yes ]; then
450 case "$platform:`$tool -dumpversion 2>/dev/null`" in
451 *:NetBSD:1.6*:*:2.* )
452 # NetBSD 1.6.x with GCC 2.95.x suffers from memory
453 # exhaustion problems under GCC optimizations.
454 ;;
455 * )
456 cflags="-O2"
457 ;;
458 esac
459 if [ ".`$tool -v 2>/dev/null | grep 'with-gnu-as'`" != . ] || \
460 [ ".`(as --version </dev/null) 2>/dev/null | grep 'GNU'`" != . ]; then
461 cflags="$cflags -pipe"
462 fi
463 else
464 cflags="-O"
465 fi
466 fi
467 case "$platform" in
468 amd64:FreeBSD:*:* | ia64:FreeBSD:*:* | sparc64:FreeBSD:*:* | x86_64:Linux:*:* )
469 # at least under FreeBSD on amd64, ia64 and sparc64
470 # the GNU binutils strictly require Position In-
471 # dependent Code (PIC) when Dynamic Shared Objects
472 # (DSO) are involved. As an ugly workaround we
473 # build everything with PIC there, although this is
474 # more than required. We also can assume that the C
475 # compiler is always GCC, either the OpenPKG one or
476 # the FreeBSD one.
477 cflags="-fPIC"
478 ;;
479 esac
480 echo "x$cflags" | sed -e 's;^x;;'
481 ;;
483 cppflags )
484 std=0
485 cppflags=""
486 for pkg in .. $*; do
487 [ ".$pkg" = ... ] && continue
488 if [ ".$pkg" = .. ]; then
489 cppflags="$cppflags -I${opt_p}/include"
490 std=1
491 else
492 cppflags="$cppflags -I${opt_p}/include/$pkg"
493 fi
494 done
495 if [ $std -eq 0 ]; then
496 cppflags="-I${opt_p}/include$cppflags"
497 fi
498 if [ ".$opt_i" = .yes ]; then
499 arch="unknown"; os_name="unknown"; os_vers="0"
500 shtool=`echo $prog_path | sed -e 's;/[^/]*$;/shtool;'`
501 eval `sh $shtool platform -U -S ":" -C "" -F "%<ac>:%<st>" |\
502 sed -e 's/^\(.*\):\(.*\):\(.*\)$/arch="\1"; os_name="\2"; os_vers="\3";/'`
503 V=0; R=0; L=0
504 eval `echo "$os_vers" |\
505 sed -e 's/^/X/' \
506 -e 's/^X[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\).*$/V="\1"; R="\2"; L="\3";/' \
507 -e 's/^X[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\).*$/V="\1"; R="\2";/' \
508 -e 's/^X[^0-9]*\([0-9][0-9]*\).*$/V="\1";/' \
509 -e 's/^X.*$/:/'`
510 os_vers=`echo . | awk '{ printf("%02d%02d%02d", V, R, L); }' V="$V" R="$R" L="$L"`
511 cppflags="$cppflags -D__OPENPKG_${arch} -D__OPENPKG_${os_name}=${os_vers}"
512 fi
513 echo "x$cppflags" | sed -e 's;^x;;' -e 's;^ *;;'
514 ;;
516 ldflags )
517 std=0
518 ldflags=""
519 for pkg in .. $*; do
520 [ ".$pkg" = ... ] && continue
521 if [ ".$pkg" = .. ]; then
522 ldflags="$ldflags -L${opt_p}/lib"
523 std=1
524 else
525 ldflags="$ldflags -L${opt_p}/lib/$pkg"
526 fi
527 done
528 if [ $std -eq 0 ]; then
529 ldflags="-L${opt_p}/lib$ldflags"
530 fi
531 echo "x$ldflags" | sed -e 's;^x;;' -e 's;^ *;;'
532 ;;
534 files )
535 # if a Perl interpreter is available, we perform the operation
536 # with it because Perl is a magnitude (factor 10!) faster than
537 # what we can do here in Bourne-Shell.
538 perl=''
539 for dir in `echo "$PATH:@l_prefix@/lib/openpkg" | sed -e 's/:/ /g'` .; do
540 [ ".$dir" = .. -o ".$dir" = . ] && continue
541 for tool in perl5 perl miniperl; do
542 if [ -f "$dir/$tool" ]; then
543 perl="$dir/$tool"
544 break
545 fi
546 done
547 if [ ".$perl" != . ]; then
548 break
549 fi
550 done
551 if [ ".$perl" != . ]; then
552 cat >$tmpfile <<'EOT'
553 ##
554 ## PERL IMPLEMENTATION (FAST)
555 ##
557 my $opt_v = 0;
558 my $opt_o = '';
559 my $opt_r = '';
560 while ($ARGV[0] =~ m|^-(.)(.*)$|) {
561 my ($opt, $arg) = ($1, $2);
562 shift(@ARGV);
563 unshift(@ARGV, $arg) if ($arg ne '');
564 $opt_v = 1 if ($opt eq 'v');
565 $opt_o = shift(@ARGV) if ($opt eq 'o');
566 $opt_r = shift(@ARGV) if ($opt eq 'r');
567 }
569 # remember the build root in a reasonable short variable ;)
570 my $br = "$opt_r";
572 # read input file list
573 my @L = ();
574 if ($#ARGV == -1 or ($#ARGV == 0 and $ARGV[0] eq "-")) {
575 # read file list from stdin
576 while (<STDIN>) {
577 s/\n$//s;
578 push(@L, $_);
579 }
580 }
581 else {
582 # read file list from argument line
583 @L = @ARGV;
584 }
586 # PASS 1: PREPARATION AND SYNTACTICAL EXPANSION
587 if ($opt_v == 1) {
588 print STDERR "rpmtool:files: pass 1 (preparation and syntactical expansions)\n";
589 }
590 my @T = ();
591 my $l;
592 foreach $l (@L) {
593 # replace tabs with spaces, reduce multiple spaces to single
594 # spaces, and remove leading and trailing spaces
595 $l =~ s|[ \t\n]+| |sg;
596 $l =~ s|^[ \t]+||sg;
597 $l =~ s|[ \t]+$||sg;
599 # move tags to end of entry for easier parsing
600 1 while ($l =~ s|^(%\S+) (.+)|$2 $1|);
602 # use `:' as a dummy path for tag-only entries (like `%defattr')
603 # to avoid special cases in the later processing
604 if ($l =~ m|^%.+|) {
605 $l = ": $l";
606 }
608 # split entry into path and optional tags
609 my ($p, $t) = ($l =~ m|^(\S+)(.*)$|);
611 # expand `{foo,bar,quux}' constructs in path (silent
612 # assumtion to make life easier is that the constructs
613 # occurs only once in a path!)
614 if ($p =~ m|^(.*)\{([^\}]+)\}(.*)$|) {
615 # split path into prolog, the set construct, and the epilog
616 my ($pro, $set, $epi) = ($1, $2, $3);
618 # repeat prolog and epilog for all elements in set
619 my $x;
620 foreach $x (split(/,/, $set)) {
621 push(@T, "${pro}${x}${epi}${t}");
622 }
623 }
624 else {
625 # else just take over the entry as is
626 push(@T, $l);
627 }
628 }
629 @L = @T;
631 # PASS 2: FILESYSTEM-BASED EXPANSIONS
632 if ($opt_v == 1) {
633 print STDERR "rpmtool:files: pass 2 (filesystem-based expansions)\n";
634 }
635 @T = ();
636 foreach $l (@L) {
637 # split entry into path and optional tags
638 my ($p, $t) = ($l =~ m|^(\S*)(.*)$|);
640 # expand...
641 if (-d "$br$p" and $t !~ m|.*%dir.*|) {
642 # expand path because it is not tagged with %dir
643 my @X = `cd "$br$p" && find . -print`;
644 my $x;
645 foreach $x (@X) {
646 $x =~ s|\n$||s;
647 $x =~ s|^\.|$p|s;
648 push(@T, "${x}${t}");
649 }
650 }
651 else {
652 # expand path wildcards (`*' and `[..]')
653 # (if not wildcards are present, this doesn't harm)
654 my @X = glob("$br$p");
655 my $x;
656 foreach $x (@X) {
657 my $brqm = quotemeta($br);
658 $x =~ s|^$brqm||s;
659 push(@T, "${x}${t}");
660 }
661 }
662 }
663 @L = @T;
665 # PASS 3: DUPLICATION REMOVAL AND CLEANUP
666 if ($opt_v == 1) {
667 print STDERR "rpmtool:files: pass 3 (duplication removal and cleanup)\n";
668 }
669 @T = ();
670 foreach $l (@L) {
671 # split entry into path and optional tags
672 my ($p, $t) = ($l =~ m|^(\S*)(.*)$|);
674 # add %dir tag if entry is a directory, but still not
675 # tagged as such (else RPM would again expand it recursively)
676 if (-d "$br$p") {
677 if ($t !~ m|%dir|) {
678 $t .= " %dir";
679 }
680 }
682 # remove duplicate entries in already processed part
683 # (but make sure we keep the entries with the dummy tags)
684 if ($p ne ":") {
685 my @T2 = ();
686 foreach $t (@T) {
687 my $pqm = quotemeta($p);
688 next if ($t =~ m|^$pqm | or $t eq $p);
689 push(@T2, $t);
690 }
691 @T = @T2;
692 }
694 # keep entry only if no %not tag is present
695 # (else all entries are removed)
696 if ($t !~ m|.*%not.*|) {
697 push(@T, "${p}${t}");
698 }
699 }
700 @L = @T;
702 # write out new file list
703 @T = ();
704 foreach $l (@L) {
705 $l =~ s|^(\S+) (.*)$|$2 $1|sg;
706 $l =~ s|^\s+||s;
707 $l =~ s|\s+$||s;
708 $l =~ s|\s+:$||s;
709 push(@T, $l);
710 }
711 @L = @T;
712 if ($opt_o eq '' or $opt_o eq '-') {
713 print STDOUT join("\n", @L)."\n";
714 }
715 else {
716 open(FP, ">$opt_o");
717 print FP join("\n", @L)."\n";
718 close(FP);
719 }
720 EOT
721 cmd="$perl $tmpfile";
722 if [ ".$opt_v" = .yes ]; then
723 cmd="$cmd -v"
724 fi
725 if [ ".$opt_o" != . ]; then
726 cmd="$cmd -o \"$opt_o\""
727 fi
728 if [ ".$opt_r" != . ]; then
729 cmd="$cmd -r \"$opt_r\""
730 fi
731 for arg
732 do
733 cmd="$cmd \"$arg\""
734 done
735 eval "$cmd"
736 else
737 ##
738 ## BOURNE-SHELL IMPLEMENTATION (PORTABLE)
739 ##
741 # remember the build root in a reasonable short variable ;)
742 br="$opt_r"
744 # make sure filename expansion is disabled per default
745 set -f
747 # read input file list
748 L=''
749 if [ $# -eq 0 ] || [ $# -eq 1 -a ".$1" = ".-" ]; then
750 # read file list from stdin
751 L=`cat`
752 else
753 # read file list from argument line
754 for arg
755 do
756 L="$L$NL$arg"
757 done
758 fi
760 # PASS 1: PREPARATION AND SYNTACTICAL EXPANSION
761 if [ ".$opt_v" = .yes ]; then
762 echo "rpmtool:files: pass 1 (preparation and syntactical expansions)" 1>&2
763 fi
764 T=''
765 OIFS="$IFS"; IFS="$NL"
766 for l in $L; do
767 [ ".$l" = . ] && continue
769 # replace tabs with spaces, reduce multiple spaces to single
770 # spaces, and remove leading and trailing spaces
771 l=`echo "$l" | sed -e "s;${TAB}; ;g" -e 's; *; ;g' -e 's;^ *;;' -e 's; *$;;'`
773 # move tags to end of entry for easier parsing
774 while [ ".`echo \"$l\" | grep '^%[^ ]* .*'`" != . ]; do
775 l=`echo "$l" | sed -e 's;^\(%[^ ]*\) \(.*\);\2 \1;'`
776 done
778 # use `:' as a dummy path for tag-only entries (like `%defattr')
779 # to avoid special cases in the later processing
780 if [ ".`echo \"$l\" | grep '^%.*'`" != . ]; then
781 l=": $l"
782 fi
784 # split entry into path and optional tags
785 eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'`
787 # expand `{foo,bar,quux}' constructs in path (silent
788 # assumtion to make life easier is that the constructs
789 # occurs only once in a path!)
790 if [ ".`echo \".$p\" | grep '^\..*{[^}]*}.*$'`" != . ]; then
792 # split path into prolog, the set construct, and the epilog
793 eval `echo ".$p" | sed -e 's;^\.\(.*\){\([^}]*\)}\(.*\)$;pro="\1" set="\2" epi="\3";'`
795 # repeat prolog and epilog for all elements in set
796 OIFS2="$IFS"; IFS=","
797 for x in $set; do
798 T="$T$NL${pro}${x}${epi}${t}"
799 done
800 IFS="$OIFS2"
801 else
802 # else just take over the entry as is
803 T="$T$NL$l"
804 fi
805 done
806 L="$T"
807 IFS="$OIFS"
809 # PASS 2: FILESYSTEM-BASED EXPANSIONS
810 if [ ".$opt_v" = .yes ]; then
811 echo "rpmtool:files: pass 2 (filesystem-based expansions)" 1>&2
812 fi
813 T=''
814 OIFS="$IFS"; IFS="$NL"
815 for l in $L; do
816 [ ".$l" = . ] && continue
818 # split entry into path and optional tags
819 eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'`
821 # expand...
822 if [ -d "$br$p" -a ".`expr \".$t\" : '\..*%dir.*'`" = .0 ]; then
823 # expand path because it is not tagged with %dir
824 OIFS2="$IFS"; IFS="$DIFS"
825 for x in `cd "$br$p" && find . -print | sed -e "s;^\\.;$p;"`; do
826 T="$T$NL${x}${t}"
827 done
828 IFS="$OIFS2"
829 else
830 # expand path wildcards (`*' and `[..]')
831 # (if not wildcards are present, this doesn't harm)
832 OIFS2="$IFS"; IFS="$DIFS"
833 for x in `(set +f; echo $br$p) | sed -e "s;^$br;;" -e "s; $br; ;g"`; do
834 T="$T$NL${x}${t}"
835 done
836 IFS="$OIFS2"
837 fi
838 done
839 IFS="$OIFS"
840 L="$T"
842 # PASS 3: DUPLICATION REMOVAL AND CLEANUP
843 if [ ".$opt_v" = .yes ]; then
844 echo "rpmtool:files: pass 3 (duplication removal and cleanup)" 1>&2
845 fi
846 T=''
847 OIFS="$IFS"; IFS="$NL"
848 for l in $L; do
849 [ ".$l" = . ] && continue
851 # split entry into path and optional tags
852 eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'`
854 # add %dir tag if entry is a directory, but still not
855 # tagged as such (else RPM would again expand it recursively)
856 if [ -d "$br$p" ]; then
857 if [ ".`expr \".$t\" : '\..*%dir.*'`" = .0 ]; then
858 t="$t %dir"
859 fi
860 fi
862 # remove duplicate entries in already processed part
863 # (but make sure we keep the entries with the dummy tags)
864 if [ ".$p" != ".:" ]; then
865 T=`echo "$T" | grep -v "^$p " | grep -v "^$p\$"`
866 fi
868 # keep entry only if no %not tag is present
869 # (else all entries are removed)
870 if [ ".`expr \".$t\" : '\..*%not.*'`" = .0 ]; then
871 T="$T$NL${p}${t}"
872 fi
873 done
874 IFS="$OIFS"
875 L="$T"
877 # write out new file list
878 if [ ".$opt_o" = . -o ".$opt_o" = ".-" ]; then
879 outcmd="cat"
880 else
881 outcmd="cat > $opt_o"
882 fi
883 echo "$L" |\
884 sed -e '/^$/d' \
885 -e 's;^\([^ ]*\) *\(.*\)$;\2 \1;g' \
886 -e 's;^ *;;' \
887 -e 's; *$;;' \
888 -e 's; *:$;;' | eval $outcmd
889 fi
890 ;;
892 signal )
893 if [ ".$opt_p" = . -a ".$opt_m" = . ]; then
894 echo "$msgprefix:Error: either option -p or -m has to be specified" 1>&2
895 exit 1
896 fi
897 case "$platform" in
898 *:FreeBSD:*:* | *:NetBSD:*:* )
899 cmd0="ps -ax -o pid"
900 cmd1="ps -ax -o command"
901 cmd2="ps -ax -o pid,command"
902 cmd3="ps -ax -o pid,ppid"
903 ;;
904 *:Linux:*:* | *:OSF1:5.*:* )
905 cmd0="ps axo pid"
906 cmd1="ps axo cmd"
907 cmd2="ps axo pid,cmd"
908 cmd3="ps axo pid,ppid"
909 ;;
910 *:SunOS:5.*:* )
911 cmd0="ps -ef -o pid"
912 cmd1="ps -ef -o args"
913 cmd2="ps -ef -o pid,args"
914 cmd3="ps -ef -o pid,ppid"
915 ;;
916 *:HP-UX:*:* )
917 cmd0="ps -ef" # FIXME
918 cmd1="ps -ef" # FIXME
919 cmd2="ps -ef" # FIXME
920 cmd3="ps -ef" # FIXME
921 ;;
922 *:IRIX64:6.*:* )
923 cmd0="ps -ef -o pid"
924 cmd1="ps -ef -o args"
925 cmd2="ps -ef -o pid,args"
926 cmd3="ps -ef -o pid,ppid"
927 ;;
928 *:Darwin:*:* )
929 cmd0="ps -ax -opid"
930 cmd1="ps -ax -ocommand"
931 cmd2="ps -ax -opid,command"
932 cmd3="ps -ax -opid,ppid"
933 esac
934 # try all signals in order
935 i=$#
936 for sig in "$@"; do
937 # check whether program is still running/active
938 active=""
939 if [ ".$opt_p" != . ]; then
940 active=`$cmd0 | grep "$opt_p" | grep -v grep | grep -v rpmtool`
941 elif [ ".$opt_m" != . ]; then
942 active=`$cmd1 | grep "$opt_m" | grep -v grep | grep -v rpmtool`
943 fi
944 if [ ".$active" = . ]; then
945 break
946 fi
948 # send signal to program
949 if [ ".$opt_p" != . ]; then
950 pids="$opt_p"
951 elif [ ".$opt_m" != . ]; then
952 pids=`$cmd2 | sed -e "s;^[ ${TAB}]*;;" | egrep "[0-9]* .*$opt_m" |\
953 grep -v grep | grep -v rpmtool |\
954 awk '{ printf("%s\n", $1); }'`
955 fi
956 for pid in $pids; do
957 if [ ".$opt_v" = .yes ]; then
958 echo "sending $sig signal to process $pid"
959 fi
960 if [ ".$opt_t" = .yes ]; then
961 echo "kill -$sig $pid"
962 fi
963 if [ ".$opt_n" = .no ]; then
964 eval "kill -$sig $pid"
965 fi
966 done
968 # optionally send signal to childs of program
969 if [ ".$opt_c" = .yes ]; then
970 for pid in $pids; do
971 cpids=`$cmd3 | sed -e "s;^[ ${TAB}]*;;" | egrep "[0-9]* $pid" |\
972 grep -v grep | grep -v rpmtool |\
973 awk '{ printf("%s\n", $1); }'`
974 for cpid in $cpids; do
975 if [ ".$opt_v" = .yes ]; then
976 echo "sending $sig signal to child process $cpid"
977 fi
978 if [ ".$opt_t" = .yes ]; then
979 echo "kill -$sig $cpid"
980 fi
981 if [ ".$opt_n" = .no ]; then
982 eval "kill -$sig $cpid >/dev/null 2>&1"
983 fi
984 done
985 done
986 fi
988 # perform optional delay
989 i=`expr $i - 1`
990 if [ $i -gt 0 ]; then
991 if [ ".$opt_d" != . -a ".$opt_d" != . ]; then
992 sleep $opt_d
993 fi
994 fi
995 done
996 ;;
998 config )
999 # usage consistency
1000 if [ ".$opt_a" = .no -a ".$opt_r" = .no ]; then
1001 echo "$msgprefix:Error: either option -a or -r has to be specified" 1>&2
1002 exit 1
1003 fi
1004 configfile="$1"
1006 # determine block markers
1007 block_start="${opt_p}<${opt_t}"
1008 if [ ".$opt_i" != . ]; then
1009 block_start="${block_start} id=\"${opt_i}\""
1010 fi
1011 block_start="${block_start}>"
1012 block_end="${opt_p}</${opt_t}>"
1014 # slash-escaped versions of block markers (for sed(3) call)
1015 block_start_esc=`echo "$block_start" | sed -e 's;/;\\\\/;g'`
1016 block_end_esc=`echo "$block_end" | sed -e 's;/;\\\\/;g'`
1018 # determine backup extension
1019 case "X$opt_b" in
1020 X ) ext=".bak" ;;
1021 X.* ) ext="$opt_b" ;;
1022 X* ) ext=".$opt_b" ;;
1023 esac
1025 # check for block in config file
1026 if [ -f $configfile ]; then
1027 check=`grep "^${block_start}" $configfile`
1028 else
1029 touch $configfile
1030 check=""
1031 fi
1033 # add entry
1034 if [ ".$opt_a" = .yes ]; then
1035 if [ ".$check" != . ]; then
1036 if [ ".$opt_s" = .yes ]; then
1037 exit 0
1038 else
1039 echo "$msgprefix:Error: config entry already exists" 1>&2
1040 exit 1
1041 fi
1042 fi
1043 cp $configfile $configfile$ext
1044 echo "${block_start}" >$tmpfile
1045 cat >>$tmpfile
1046 echo "${block_end}" >>$tmpfile
1047 cat $tmpfile >>$configfile
1049 # remove entry
1050 elif [ ".$opt_r" = .yes ]; then
1051 if [ ".$check" = . ]; then
1052 if [ ".$opt_s" = .yes ]; then
1053 exit 0
1054 else
1055 echo "$msgprefix:Error: config entry does not exist" 1>&2
1056 exit 1
1057 fi
1058 fi
1059 cp $configfile $configfile$ext
1060 sed -e "/^${block_start_esc}/,/^${block_end_esc}/d" \
1061 <$configfile$ext >$configfile
1062 fi
1064 # verbosity
1065 if [ ".$opt_v" = .yes ]; then
1066 (diff -u1 $configfile$ext $configfile >$tmpfile) 2>/dev/null
1067 if [ ".`cat $tmpfile`" = . ]; then
1068 (diff -C1 $configfile$ext $configfile >$tmpfile) 2>/dev/null
1069 if [ ".`cat $tmpfile`" = . ]; then
1070 if [ ".$opt_s" = .no ]; then
1071 echo "$msgprefix:Warning: unable to show difference for config file \`$configfile'" 1>&2
1072 fi
1073 fi
1074 fi
1075 echo "editing $configfile:"
1076 cat $tmpfile
1077 fi
1079 # optionally remove backup file
1080 if [ ".$opt_b" = . ]; then
1081 rm -f $configfile$ext
1082 fi
1083 ;;
1085 msg )
1086 # optionally beep before message
1087 if [ ".$opt_b" = .yes ]; then
1088 echo . | awk '{ printf("%c", 7); }'
1089 fi
1091 # determine title of message
1092 title=""
1093 case $opt_t in
1094 info ) title="-------" ;;
1095 notice ) title="Notice-" ;;
1096 warn ) title="Warning" ;;
1097 error ) title="Error--" ;;
1098 * ) echo "$msgprefix:Error: invalid message type \`$opt_t'" 1>&2; exit 1 ;;
1099 esac
1101 # display message
1102 if [ ".$opt_r" != .yes ]; then
1103 echo . | awk '{ printf("\r"); }'
1104 fi
1105 echo "+----------------------------------${title}------------------------------------+"
1106 expand -t 8 | sed -e 's; *$;;' | awk '{ printf("| %-75s |\n", substr($0, 0, 75)); }'
1107 echo "+-----------------------------------------------------------------------------+"
1108 ;;
1109 check-class )
1110 # check package class from within .spec file macro expansion for %prep section
1111 class="$1"; shift
1112 case "$class" in
1113 CORE|BASE )
1114 ;;
1115 PLUS )
1116 echo "set +x"
1117 ( echo "This OpenPKG package is of class PLUS."
1118 echo "It is still in a QUALITY ASSURANCE state,"
1119 echo "therefore it is NOT ready for careless use."
1120 echo "Do not use it in critical production environments."
1121 echo "This software might still be unstable at runtime."
1122 ) | sh $prog_path msg -r -t notice | sed -e 's;^;echo ";' -e 's;$;";'
1123 echo "set -x"
1124 ;;
1125 EVAL )
1126 echo "set +x"
1127 ( echo "This OpenPKG package is of class EVAL."
1128 echo "It is still in a EVALUATION and QA state,"
1129 echo "therefore it is NOT ready for general use."
1130 echo "Do not use it in production environments."
1131 echo "It might be unstable or incompletely packaged."
1132 ) | sh $prog_path msg -r -t warn | sed -e 's;^;echo ";' -e 's;$;";'
1133 echo "set -x"
1134 ;;
1135 JUNK )
1136 echo "set +x"
1137 ( echo "This OpenPKG package is of class JUNK."
1138 echo "It is still in DEVELOPMENT state,"
1139 echo "therefore it is NOT ready to be used."
1140 echo "Do not use it at all, except in development environments!"
1141 echo "This software is either unstable or incompletely packaged."
1142 ) | sh $prog_path msg -r -t warn | sed -e 's;^;echo ";' -e 's;$;";'
1143 echo "set -x"
1144 ;;
1145 esac
1146 ;;
1147 esac
1149 # cleanup
1150 if [ ".$gen_tmpfile" = .yes ]; then
1151 rm -f $tmpfile >/dev/null 2>&1
1152 fi
1154 # die gracefully ;)
1155 exit 0