michael@13: #!@l_prefix@/lib/openpkg/bash michael@13: ## michael@13: ## rpmtool -- OpenPKG RPM Auxiliary Tool michael@13: ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. michael@13: ## Copyright (c) 2000-2007 Ralf S. Engelschall michael@13: ## michael@13: ## Permission to use, copy, modify, and distribute this software for michael@13: ## any purpose with or without fee is hereby granted, provided that michael@13: ## the above copyright notice and this permission notice appear in all michael@13: ## copies. michael@13: ## michael@13: ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED michael@13: ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF michael@13: ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. michael@13: ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR michael@13: ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@13: ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@13: ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF michael@13: ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND michael@13: ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, michael@13: ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT michael@13: ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF michael@13: ## SUCH DAMAGE. michael@13: ## michael@13: michael@13: prog_path="$0" michael@13: prog_name="rpmtool" michael@13: prog_vers="1.1.0" michael@13: prog_date="05-Mar-2007" michael@13: michael@13: if [ $# -eq 0 ]; then michael@13: echo "$0:Error: invalid command line" 1>&2 michael@13: echo "$0:Hint: run \`$0 -h' for usage" 1>&2 michael@13: exit 1 michael@13: fi michael@13: if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then michael@13: echo "This is $prog_name, version $prog_vers ($prog_date)" michael@13: echo "Copyright (c) 2000-2004 Ralf S. Engelschall " michael@13: echo '' michael@13: echo "Usage: $prog_name [] [ [] []]" michael@13: echo '' michael@13: echo 'Available global :' michael@13: echo ' -d, --debug enable internal debugging' michael@13: echo ' -v, --version display version information' michael@13: echo ' -h, --help display usage help page (this one)' michael@13: echo '' michael@13: echo 'Available [] []:' michael@13: echo ' platform' michael@13: echo ' mflags [-O] ' michael@13: echo ' cflags [-O] ' michael@13: echo ' cppflags [-p ] [ ...]' michael@13: echo ' ldflags [-p ] [ ...]' michael@13: echo ' files [-v] [-o ] [-r ] []' michael@13: echo ' signal [-v] [-t] [-n] [-c] [-d ] [-p ] [-m ] [ ...]' michael@13: echo ' config [-v] [-s] [-a] [-r] [-b ] [-p ] [-t ] [-i ] ' michael@13: echo ' msg [-b] [-r] [-t ]' michael@13: echo '' michael@13: exit 0 michael@13: fi michael@13: if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then michael@13: echo "$prog_name $prog_vers ($prog_date)" michael@13: exit 0 michael@13: fi michael@13: if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then michael@13: shift michael@13: set -x michael@13: fi michael@13: michael@13: tool="$1" michael@13: shift michael@13: arg_spec="" michael@13: opt_spec="" michael@13: gen_tmpfile=no michael@13: michael@13: # configure tool specific option parsing michael@13: case $tool in michael@13: platform ) michael@13: str_usage="" michael@13: arg_spec="0=" michael@13: opt_spec="" michael@13: ;; michael@13: mflags ) michael@13: str_usage="[-O] " michael@13: arg_spec="1=" michael@13: opt_spec="O." michael@13: opt_O=no michael@13: ;; michael@13: cflags ) michael@13: str_usage="[-O] " michael@13: arg_spec="1=" michael@13: opt_spec="O." michael@13: opt_O=no michael@13: ;; michael@13: cppflags ) michael@13: str_usage="[-p ] [-i] [ ...]" michael@13: arg_spec="0+" michael@13: opt_spec="p:i." michael@13: opt_p="/" michael@13: ;; michael@13: ldflags ) michael@13: str_usage="[-p ] [ ...]" michael@13: arg_spec="0+" michael@13: opt_spec="p:" michael@13: opt_p="/" michael@13: ;; michael@13: files ) michael@13: gen_tmpfile=yes michael@13: str_usage="[-v] [-o ] [-r ] []" michael@13: arg_spec="0+" michael@13: opt_spec="v.o:r:" michael@13: opt_v=no michael@13: opt_o='' michael@13: opt_r='' michael@13: ;; michael@13: signal ) michael@13: str_usage="[-v] [-t] [-n] [-c] [-d ] [-p ] [-m ] [ ...]" michael@13: arg_spec="1+" michael@13: opt_spec="v.t.n.c.d:p:m:" michael@13: opt_v=no michael@13: opt_t=no michael@13: opt_n=no michael@13: opt_c=no michael@13: opt_d=1 michael@13: opt_p="" michael@13: opt_m="" michael@13: ;; michael@13: config ) michael@13: str_usage="[-v] [-s] [-a] [-r] [-b ] [-p ] [-t ] [-i ] " michael@13: arg_spec="1=" michael@13: opt_spec="v.s.a.r.b:p:t:i:c:" michael@13: opt_v=no michael@13: opt_s=no michael@13: opt_a=no michael@13: opt_r=no michael@13: opt_b="" michael@13: opt_p="#" michael@13: opt_t="OpenPKG" michael@13: opt_i="" michael@13: gen_tmpfile=yes michael@13: ;; michael@13: msg ) michael@13: str_usage="[-b] [-r] [-t ]" michael@13: arg_spec="0=" michael@13: opt_spec="b.r.t:" michael@13: opt_b=no michael@13: opt_r=no michael@13: opt_t=info michael@13: ;; michael@13: check-class ) michael@13: str_usage="" michael@13: arg_spec="1=" michael@13: opt_spec="" michael@13: ;; michael@13: -* ) michael@13: echo "$prog_name:Error: unknown option \`$tool'" 2>&1 michael@13: echo "$prog_name:Hint: run \`$0 -h' for usage" 2>&1 michael@13: exit 1 michael@13: ;; michael@13: * ) michael@13: echo "$prog_name:Error: unknown command \`$tool'" 2>&1 michael@13: echo "$prog_name:Hint: run \`$0 -h' for usage" 2>&1 michael@13: exit 1 michael@13: ;; michael@13: esac michael@13: michael@13: # tool information michael@13: toolcmd="$0 $tool" michael@13: toolcmdhelp="$prog_name $tool" michael@13: msgprefix="$prog_name:$tool" michael@13: michael@13: # parse argument specification string michael@13: eval `echo $arg_spec |\ michael@13: sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` michael@13: michael@13: # parse option specification string michael@13: eval `echo h.$opt_spec |\ michael@13: sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` michael@13: michael@13: # iterate over argument line michael@13: opt_PREV='' michael@13: while [ $# -gt 0 ]; do michael@13: # special option stops processing michael@13: if [ ".$1" = ".--" ]; then michael@13: shift michael@13: break michael@13: fi michael@13: michael@13: # determine option and argument michael@13: opt_ARG_OK=no michael@13: if [ ".$opt_PREV" != . ]; then michael@13: # merge previous seen option with argument michael@13: opt_OPT="$opt_PREV" michael@13: opt_ARG="$1" michael@13: opt_ARG_OK=yes michael@13: opt_PREV='' michael@13: else michael@13: # split argument into option and argument michael@13: case "$1" in michael@13: -[a-zA-Z0-9]*) michael@13: eval `echo "x$1" |\ michael@13: sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ michael@13: -e 's/";\(.*\)$/"; opt_ARG="\1"/'` michael@13: ;; michael@13: -[a-zA-Z0-9]) michael@13: opt_OPT=`echo "x$1" | cut -c3-` michael@13: opt_ARG='' michael@13: ;; michael@13: *) michael@13: break michael@13: ;; michael@13: esac michael@13: fi michael@13: michael@13: # eat up option michael@13: shift michael@13: michael@13: # determine whether option needs an argument michael@13: eval "opt_MODE=\$opt_MODE_${opt_OPT}" michael@13: if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then michael@13: if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then michael@13: opt_PREV="$opt_OPT" michael@13: continue michael@13: fi michael@13: fi michael@13: michael@13: # process option michael@13: case $opt_MODE in michael@13: '.' ) michael@13: # boolean option michael@13: eval "opt_${opt_OPT}=yes" michael@13: ;; michael@13: ':' ) michael@13: # option with argument (multiple occurances override) michael@13: eval "opt_${opt_OPT}=\"\$opt_ARG\"" michael@13: ;; michael@13: '+' ) michael@13: # option with argument (multiple occurances append) michael@13: eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" michael@13: ;; michael@13: * ) michael@13: echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2 michael@13: echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man $prog_name' for details" 1>&2 michael@13: exit 1 michael@13: ;; michael@13: esac michael@13: done michael@13: if [ ".$opt_PREV" != . ]; then michael@13: echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2 michael@13: echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man $prog_name' for details" 1>&2 michael@13: exit 1 michael@13: fi michael@13: michael@13: # process help option michael@13: if [ ".$opt_h" = .yes ]; then michael@13: echo "Usage: $toolcmdhelp $str_usage" michael@13: exit 0 michael@13: fi michael@13: michael@13: # complain about incorrect number of arguments michael@13: case $arg_MODE in michael@13: '=' ) michael@13: if [ $# -ne $arg_NUMS ]; then michael@13: echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 michael@13: echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man $prog_name' for details" 1>&2 michael@13: exit 1 michael@13: fi michael@13: ;; michael@13: '+' ) michael@13: if [ $# -lt $arg_NUMS ]; then michael@13: echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 michael@13: echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man $prog_name' for details" 1>&2 michael@13: exit 1 michael@13: fi michael@13: ;; michael@13: esac michael@13: michael@13: # establish a temporary file on request michael@13: if [ ".$gen_tmpfile" = .yes ]; then michael@13: if [ ".$TMPDIR" != . ]; then michael@13: tmpdir="$TMPDIR" michael@13: else michael@13: tmpdir="/tmp" michael@13: fi michael@13: tmpfile="$tmpdir/.$prog_name.$$" michael@13: rm -f $tmpfile >/dev/null 2>&1 michael@13: touch $tmpfile michael@13: fi michael@13: michael@13: # provide a few useful variables michael@13: NL=" michael@13: " michael@13: TAB=" " michael@13: DIFS=" ${TAB}${NL}" michael@13: michael@13: # determine platform information michael@13: platform_machine=`(uname -m) 2>/dev/null` ||\ michael@13: platform_machine=`(uname -p) 2>/dev/null` ||\ michael@13: platform_machine='unknown' michael@13: if [ ".$platform_machine" = ".Power Macintosh" ]; then michael@13: platform_machine=`(uname -p) 2>/dev/null` michael@13: fi michael@13: platform_release=`(uname -r) 2>/dev/null` ||\ michael@13: platform_release='unknown' michael@13: platform_system=`(uname -s) 2>/dev/null` ||\ michael@13: platform_system='unknown' michael@13: platform_version=`(uname -v) 2>/dev/null` ||\ michael@13: platform_version='unknown' michael@13: platform="${platform_machine}:${platform_system}:${platform_release}:${platform_version}" michael@13: michael@13: # dispatch into tools michael@13: case $tool in michael@13: platform ) michael@13: # provide unique platform id michael@13: m=`echo "$platform_machine" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` michael@13: s=`echo "$platform_system" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` michael@13: r=`echo "$platform_release" | sed -e 's;-.*$;;'` michael@13: echo "${m}-${s}${r}" michael@13: ;; michael@13: michael@13: mflags ) michael@13: tool="$1" michael@13: isgmake=no michael@13: if [ ".`$tool -v -f /dev/null 2>/dev/null | grep 'GNU Make'`" != . ]; then michael@13: isgmake=yes michael@13: fi michael@13: mflags='' michael@13: if [ ".$isgmake" = .yes ]; then michael@13: mflags="--no-print-directory" michael@13: fi michael@13: if [ ".$opt_O" = .yes ]; then michael@13: case $platform in michael@13: *:SunOS:5.*:* | *:OSF1:*:* ) michael@13: if [ ".$isgmake" = .yes ]; then michael@13: n=`(/bin/uname -X) 2>/dev/null | grep -i NumCPU | awk '{ print $3; }'` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: *:FreeBSD:[4-8].*:* ) michael@13: n=`/sbin/sysctl -n hw.ncpu` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: if [ ".$isgmake" = .no ]; then michael@13: mflags="$mflags -B" michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: *:NetBSD:1.[56]*:* | *:NetBSD:[2345].*:* ) michael@13: n=`/sbin/sysctl -n hw.ncpu` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: if [ ".$isgmake" = .no ]; then michael@13: mflags="$mflags -B" michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: *:Linux:*:* ) michael@13: n=`grep ^processor /proc/cpuinfo | wc -l | awk '{ print $1; }'` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: fi michael@13: fi michael@13: ;; michael@13: *:HP-UX:*:* ) michael@13: if [ ".$isgmake" = .yes ]; then michael@13: n=`ioscan -d processor -k -F | wc -l` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: *:IRIX64:6.*:* ) michael@13: if [ ".$isgmake" = .yes ]; then michael@13: n=`/usr/sbin/sysconf | awk '/NUM_PROCESSORS/ { print $2; }'` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: *:Darwin:*:* ) michael@13: n=`/usr/sbin/sysctl hw.ncpu | awk '{ print $3; }'` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: if [ ".$isgmake" = .no ]; then michael@13: mflags="$mflags -B" michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: *:AIX:*:* ) michael@13: if [ ".$isgmake" = .yes ]; then michael@13: if [ -x /usr/sbin/lsdev ]; then michael@13: n=`/usr/sbin/lsdev -C -c processor -S available | wc -l | awk '{ print $1; }'` michael@13: if [ ".$n" != . ]; then michael@13: if [ $n -gt 1 ]; then michael@13: n=`expr $n \* 2` michael@13: mflags="$mflags -j$n" michael@13: fi michael@13: fi michael@13: fi michael@13: fi michael@13: ;; michael@13: esac michael@13: fi michael@13: echo "x$mflags" | sed -e 's;^x;;' michael@13: ;; michael@13: michael@13: cflags ) michael@13: tool="$1" michael@13: echo $tool | grep ^/ >/dev/null michael@13: if [ $? -eq 0 ]; then michael@13: if [ ! -x "$tool" -o -d "$tool" ]; then michael@13: echo "$msgprefix:Error: specified tool \`$tool' not found or not executable" 1>&2 michael@13: exit 1 michael@13: fi michael@13: else michael@13: shtool=`echo $prog_path | sed -e 's;/[^/]*$;/shtool;'` michael@13: sh $shtool path --suppress $tool michael@13: if [ $? -ne 0 ]; then michael@13: echo "$msgprefix:Error: specified tool \`$tool' not found in PATH" 1>&2 michael@13: exit 1 michael@13: fi michael@13: fi michael@13: isgcc=no michael@13: if [ ".`($tool -v; $tool --version) &1 | grep -i 'gcc'`" != . ]; then michael@13: isgcc=yes michael@13: fi michael@13: cflags='' michael@13: if [ ".$opt_O" = .yes ]; then michael@13: if [ ".$isgcc" = .yes ]; then michael@13: case "$platform:`$tool -dumpversion 2>/dev/null`" in michael@13: *:NetBSD:1.6*:*:2.* ) michael@13: # NetBSD 1.6.x with GCC 2.95.x suffers from memory michael@13: # exhaustion problems under GCC optimizations. michael@13: ;; michael@13: * ) michael@13: cflags="-O2" michael@13: ;; michael@13: esac michael@13: if [ ".`$tool -v 2>/dev/null | grep 'with-gnu-as'`" != . ] || \ michael@13: [ ".`(as --version /dev/null | grep 'GNU'`" != . ]; then michael@13: cflags="$cflags -pipe" michael@13: fi michael@13: else michael@13: cflags="-O" michael@13: fi michael@13: fi michael@13: case "$platform" in michael@13: amd64:FreeBSD:*:* | ia64:FreeBSD:*:* | sparc64:FreeBSD:*:* | x86_64:Linux:*:* ) michael@13: # at least under FreeBSD on amd64, ia64 and sparc64 michael@13: # the GNU binutils strictly require Position In- michael@13: # dependent Code (PIC) when Dynamic Shared Objects michael@13: # (DSO) are involved. As an ugly workaround we michael@13: # build everything with PIC there, although this is michael@13: # more than required. We also can assume that the C michael@13: # compiler is always GCC, either the OpenPKG one or michael@13: # the FreeBSD one. michael@13: cflags="-fPIC" michael@13: ;; michael@13: esac michael@13: echo "x$cflags" | sed -e 's;^x;;' michael@13: ;; michael@13: michael@13: cppflags ) michael@13: std=0 michael@13: cppflags="" michael@13: for pkg in .. $*; do michael@13: [ ".$pkg" = ... ] && continue michael@13: if [ ".$pkg" = .. ]; then michael@13: cppflags="$cppflags -I${opt_p}/include" michael@13: std=1 michael@13: else michael@13: cppflags="$cppflags -I${opt_p}/include/$pkg" michael@13: fi michael@13: done michael@13: if [ $std -eq 0 ]; then michael@13: cppflags="-I${opt_p}/include$cppflags" michael@13: fi michael@13: if [ ".$opt_i" = .yes ]; then michael@13: arch="unknown"; os_name="unknown"; os_vers="0" michael@13: shtool=`echo $prog_path | sed -e 's;/[^/]*$;/shtool;'` michael@13: eval `sh $shtool platform -U -S ":" -C "" -F "%:%" |\ michael@13: sed -e 's/^\(.*\):\(.*\):\(.*\)$/arch="\1"; os_name="\2"; os_vers="\3";/'` michael@13: V=0; R=0; L=0 michael@13: eval `echo "$os_vers" |\ michael@13: sed -e 's/^/X/' \ michael@13: -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";/' \ michael@13: -e 's/^X[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\).*$/V="\1"; R="\2";/' \ michael@13: -e 's/^X[^0-9]*\([0-9][0-9]*\).*$/V="\1";/' \ michael@13: -e 's/^X.*$/:/'` michael@13: os_vers=`echo . | awk '{ printf("%02d%02d%02d", V, R, L); }' V="$V" R="$R" L="$L"` michael@13: cppflags="$cppflags -D__OPENPKG_${arch} -D__OPENPKG_${os_name}=${os_vers}" michael@13: fi michael@13: echo "x$cppflags" | sed -e 's;^x;;' -e 's;^ *;;' michael@13: ;; michael@13: michael@13: ldflags ) michael@13: std=0 michael@13: ldflags="" michael@13: for pkg in .. $*; do michael@13: [ ".$pkg" = ... ] && continue michael@13: if [ ".$pkg" = .. ]; then michael@13: ldflags="$ldflags -L${opt_p}/lib" michael@13: std=1 michael@13: else michael@13: ldflags="$ldflags -L${opt_p}/lib/$pkg" michael@13: fi michael@13: done michael@13: if [ $std -eq 0 ]; then michael@13: ldflags="-L${opt_p}/lib$ldflags" michael@13: fi michael@13: echo "x$ldflags" | sed -e 's;^x;;' -e 's;^ *;;' michael@13: ;; michael@13: michael@13: files ) michael@13: # if a Perl interpreter is available, we perform the operation michael@13: # with it because Perl is a magnitude (factor 10!) faster than michael@13: # what we can do here in Bourne-Shell. michael@13: perl='' michael@13: for dir in `echo "$PATH:@l_prefix@/lib/openpkg" | sed -e 's/:/ /g'` .; do michael@13: [ ".$dir" = .. -o ".$dir" = . ] && continue michael@13: for tool in perl5 perl miniperl; do michael@13: if [ -f "$dir/$tool" ]; then michael@13: perl="$dir/$tool" michael@13: break michael@13: fi michael@13: done michael@13: if [ ".$perl" != . ]; then michael@13: break michael@13: fi michael@13: done michael@13: if [ ".$perl" != . ]; then michael@13: cat >$tmpfile <<'EOT' michael@13: ## michael@13: ## PERL IMPLEMENTATION (FAST) michael@13: ## michael@13: michael@13: my $opt_v = 0; michael@13: my $opt_o = ''; michael@13: my $opt_r = ''; michael@13: while ($ARGV[0] =~ m|^-(.)(.*)$|) { michael@13: my ($opt, $arg) = ($1, $2); michael@13: shift(@ARGV); michael@13: unshift(@ARGV, $arg) if ($arg ne ''); michael@13: $opt_v = 1 if ($opt eq 'v'); michael@13: $opt_o = shift(@ARGV) if ($opt eq 'o'); michael@13: $opt_r = shift(@ARGV) if ($opt eq 'r'); michael@13: } michael@13: michael@13: # remember the build root in a reasonable short variable ;) michael@13: my $br = "$opt_r"; michael@13: michael@13: # read input file list michael@13: my @L = (); michael@13: if ($#ARGV == -1 or ($#ARGV == 0 and $ARGV[0] eq "-")) { michael@13: # read file list from stdin michael@13: while () { michael@13: s/\n$//s; michael@13: push(@L, $_); michael@13: } michael@13: } michael@13: else { michael@13: # read file list from argument line michael@13: @L = @ARGV; michael@13: } michael@13: michael@13: # PASS 1: PREPARATION AND SYNTACTICAL EXPANSION michael@13: if ($opt_v == 1) { michael@13: print STDERR "rpmtool:files: pass 1 (preparation and syntactical expansions)\n"; michael@13: } michael@13: my @T = (); michael@13: my $l; michael@13: foreach $l (@L) { michael@13: # replace tabs with spaces, reduce multiple spaces to single michael@13: # spaces, and remove leading and trailing spaces michael@13: $l =~ s|[ \t\n]+| |sg; michael@13: $l =~ s|^[ \t]+||sg; michael@13: $l =~ s|[ \t]+$||sg; michael@13: michael@13: # move tags to end of entry for easier parsing michael@13: 1 while ($l =~ s|^(%\S+) (.+)|$2 $1|); michael@13: michael@13: # use `:' as a dummy path for tag-only entries (like `%defattr') michael@13: # to avoid special cases in the later processing michael@13: if ($l =~ m|^%.+|) { michael@13: $l = ": $l"; michael@13: } michael@13: michael@13: # split entry into path and optional tags michael@13: my ($p, $t) = ($l =~ m|^(\S+)(.*)$|); michael@13: michael@13: # expand `{foo,bar,quux}' constructs in path (silent michael@13: # assumtion to make life easier is that the constructs michael@13: # occurs only once in a path!) michael@13: if ($p =~ m|^(.*)\{([^\}]+)\}(.*)$|) { michael@13: # split path into prolog, the set construct, and the epilog michael@13: my ($pro, $set, $epi) = ($1, $2, $3); michael@13: michael@13: # repeat prolog and epilog for all elements in set michael@13: my $x; michael@13: foreach $x (split(/,/, $set)) { michael@13: push(@T, "${pro}${x}${epi}${t}"); michael@13: } michael@13: } michael@13: else { michael@13: # else just take over the entry as is michael@13: push(@T, $l); michael@13: } michael@13: } michael@13: @L = @T; michael@13: michael@13: # PASS 2: FILESYSTEM-BASED EXPANSIONS michael@13: if ($opt_v == 1) { michael@13: print STDERR "rpmtool:files: pass 2 (filesystem-based expansions)\n"; michael@13: } michael@13: @T = (); michael@13: foreach $l (@L) { michael@13: # split entry into path and optional tags michael@13: my ($p, $t) = ($l =~ m|^(\S*)(.*)$|); michael@13: michael@13: # expand... michael@13: if (-d "$br$p" and $t !~ m|.*%dir.*|) { michael@13: # expand path because it is not tagged with %dir michael@13: my @X = `cd "$br$p" && find . -print`; michael@13: my $x; michael@13: foreach $x (@X) { michael@13: $x =~ s|\n$||s; michael@13: $x =~ s|^\.|$p|s; michael@13: push(@T, "${x}${t}"); michael@13: } michael@13: } michael@13: else { michael@13: # expand path wildcards (`*' and `[..]') michael@13: # (if not wildcards are present, this doesn't harm) michael@13: my @X = glob("$br$p"); michael@13: my $x; michael@13: foreach $x (@X) { michael@13: my $brqm = quotemeta($br); michael@13: $x =~ s|^$brqm||s; michael@13: push(@T, "${x}${t}"); michael@13: } michael@13: } michael@13: } michael@13: @L = @T; michael@13: michael@13: # PASS 3: DUPLICATION REMOVAL AND CLEANUP michael@13: if ($opt_v == 1) { michael@13: print STDERR "rpmtool:files: pass 3 (duplication removal and cleanup)\n"; michael@13: } michael@13: @T = (); michael@13: foreach $l (@L) { michael@13: # split entry into path and optional tags michael@13: my ($p, $t) = ($l =~ m|^(\S*)(.*)$|); michael@13: michael@13: # add %dir tag if entry is a directory, but still not michael@13: # tagged as such (else RPM would again expand it recursively) michael@13: if (-d "$br$p") { michael@13: if ($t !~ m|%dir|) { michael@13: $t .= " %dir"; michael@13: } michael@13: } michael@13: michael@13: # remove duplicate entries in already processed part michael@13: # (but make sure we keep the entries with the dummy tags) michael@13: if ($p ne ":") { michael@13: my @T2 = (); michael@13: foreach $t (@T) { michael@13: my $pqm = quotemeta($p); michael@13: next if ($t =~ m|^$pqm | or $t eq $p); michael@13: push(@T2, $t); michael@13: } michael@13: @T = @T2; michael@13: } michael@13: michael@13: # keep entry only if no %not tag is present michael@13: # (else all entries are removed) michael@13: if ($t !~ m|.*%not.*|) { michael@13: push(@T, "${p}${t}"); michael@13: } michael@13: } michael@13: @L = @T; michael@13: michael@13: # write out new file list michael@13: @T = (); michael@13: foreach $l (@L) { michael@13: $l =~ s|^(\S+) (.*)$|$2 $1|sg; michael@13: $l =~ s|^\s+||s; michael@13: $l =~ s|\s+$||s; michael@13: $l =~ s|\s+:$||s; michael@13: push(@T, $l); michael@13: } michael@13: @L = @T; michael@13: if ($opt_o eq '' or $opt_o eq '-') { michael@13: print STDOUT join("\n", @L)."\n"; michael@13: } michael@13: else { michael@13: open(FP, ">$opt_o"); michael@13: print FP join("\n", @L)."\n"; michael@13: close(FP); michael@13: } michael@13: EOT michael@13: cmd="$perl $tmpfile"; michael@13: if [ ".$opt_v" = .yes ]; then michael@13: cmd="$cmd -v" michael@13: fi michael@13: if [ ".$opt_o" != . ]; then michael@13: cmd="$cmd -o \"$opt_o\"" michael@13: fi michael@13: if [ ".$opt_r" != . ]; then michael@13: cmd="$cmd -r \"$opt_r\"" michael@13: fi michael@13: for arg michael@13: do michael@13: cmd="$cmd \"$arg\"" michael@13: done michael@13: eval "$cmd" michael@13: else michael@13: ## michael@13: ## BOURNE-SHELL IMPLEMENTATION (PORTABLE) michael@13: ## michael@13: michael@13: # remember the build root in a reasonable short variable ;) michael@13: br="$opt_r" michael@13: michael@13: # make sure filename expansion is disabled per default michael@13: set -f michael@13: michael@13: # read input file list michael@13: L='' michael@13: if [ $# -eq 0 ] || [ $# -eq 1 -a ".$1" = ".-" ]; then michael@13: # read file list from stdin michael@13: L=`cat` michael@13: else michael@13: # read file list from argument line michael@13: for arg michael@13: do michael@13: L="$L$NL$arg" michael@13: done michael@13: fi michael@13: michael@13: # PASS 1: PREPARATION AND SYNTACTICAL EXPANSION michael@13: if [ ".$opt_v" = .yes ]; then michael@13: echo "rpmtool:files: pass 1 (preparation and syntactical expansions)" 1>&2 michael@13: fi michael@13: T='' michael@13: OIFS="$IFS"; IFS="$NL" michael@13: for l in $L; do michael@13: [ ".$l" = . ] && continue michael@13: michael@13: # replace tabs with spaces, reduce multiple spaces to single michael@13: # spaces, and remove leading and trailing spaces michael@13: l=`echo "$l" | sed -e "s;${TAB}; ;g" -e 's; *; ;g' -e 's;^ *;;' -e 's; *$;;'` michael@13: michael@13: # move tags to end of entry for easier parsing michael@13: while [ ".`echo \"$l\" | grep '^%[^ ]* .*'`" != . ]; do michael@13: l=`echo "$l" | sed -e 's;^\(%[^ ]*\) \(.*\);\2 \1;'` michael@13: done michael@13: michael@13: # use `:' as a dummy path for tag-only entries (like `%defattr') michael@13: # to avoid special cases in the later processing michael@13: if [ ".`echo \"$l\" | grep '^%.*'`" != . ]; then michael@13: l=": $l" michael@13: fi michael@13: michael@13: # split entry into path and optional tags michael@13: eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'` michael@13: michael@13: # expand `{foo,bar,quux}' constructs in path (silent michael@13: # assumtion to make life easier is that the constructs michael@13: # occurs only once in a path!) michael@13: if [ ".`echo \".$p\" | grep '^\..*{[^}]*}.*$'`" != . ]; then michael@13: michael@13: # split path into prolog, the set construct, and the epilog michael@13: eval `echo ".$p" | sed -e 's;^\.\(.*\){\([^}]*\)}\(.*\)$;pro="\1" set="\2" epi="\3";'` michael@13: michael@13: # repeat prolog and epilog for all elements in set michael@13: OIFS2="$IFS"; IFS="," michael@13: for x in $set; do michael@13: T="$T$NL${pro}${x}${epi}${t}" michael@13: done michael@13: IFS="$OIFS2" michael@13: else michael@13: # else just take over the entry as is michael@13: T="$T$NL$l" michael@13: fi michael@13: done michael@13: L="$T" michael@13: IFS="$OIFS" michael@13: michael@13: # PASS 2: FILESYSTEM-BASED EXPANSIONS michael@13: if [ ".$opt_v" = .yes ]; then michael@13: echo "rpmtool:files: pass 2 (filesystem-based expansions)" 1>&2 michael@13: fi michael@13: T='' michael@13: OIFS="$IFS"; IFS="$NL" michael@13: for l in $L; do michael@13: [ ".$l" = . ] && continue michael@13: michael@13: # split entry into path and optional tags michael@13: eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'` michael@13: michael@13: # expand... michael@13: if [ -d "$br$p" -a ".`expr \".$t\" : '\..*%dir.*'`" = .0 ]; then michael@13: # expand path because it is not tagged with %dir michael@13: OIFS2="$IFS"; IFS="$DIFS" michael@13: for x in `cd "$br$p" && find . -print | sed -e "s;^\\.;$p;"`; do michael@13: T="$T$NL${x}${t}" michael@13: done michael@13: IFS="$OIFS2" michael@13: else michael@13: # expand path wildcards (`*' and `[..]') michael@13: # (if not wildcards are present, this doesn't harm) michael@13: OIFS2="$IFS"; IFS="$DIFS" michael@13: for x in `(set +f; echo $br$p) | sed -e "s;^$br;;" -e "s; $br; ;g"`; do michael@13: T="$T$NL${x}${t}" michael@13: done michael@13: IFS="$OIFS2" michael@13: fi michael@13: done michael@13: IFS="$OIFS" michael@13: L="$T" michael@13: michael@13: # PASS 3: DUPLICATION REMOVAL AND CLEANUP michael@13: if [ ".$opt_v" = .yes ]; then michael@13: echo "rpmtool:files: pass 3 (duplication removal and cleanup)" 1>&2 michael@13: fi michael@13: T='' michael@13: OIFS="$IFS"; IFS="$NL" michael@13: for l in $L; do michael@13: [ ".$l" = . ] && continue michael@13: michael@13: # split entry into path and optional tags michael@13: eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'` michael@13: michael@13: # add %dir tag if entry is a directory, but still not michael@13: # tagged as such (else RPM would again expand it recursively) michael@13: if [ -d "$br$p" ]; then michael@13: if [ ".`expr \".$t\" : '\..*%dir.*'`" = .0 ]; then michael@13: t="$t %dir" michael@13: fi michael@13: fi michael@13: michael@13: # remove duplicate entries in already processed part michael@13: # (but make sure we keep the entries with the dummy tags) michael@13: if [ ".$p" != ".:" ]; then michael@13: T=`echo "$T" | grep -v "^$p " | grep -v "^$p\$"` michael@13: fi michael@13: michael@13: # keep entry only if no %not tag is present michael@13: # (else all entries are removed) michael@13: if [ ".`expr \".$t\" : '\..*%not.*'`" = .0 ]; then michael@13: T="$T$NL${p}${t}" michael@13: fi michael@13: done michael@13: IFS="$OIFS" michael@13: L="$T" michael@13: michael@13: # write out new file list michael@13: if [ ".$opt_o" = . -o ".$opt_o" = ".-" ]; then michael@13: outcmd="cat" michael@13: else michael@13: outcmd="cat > $opt_o" michael@13: fi michael@13: echo "$L" |\ michael@13: sed -e '/^$/d' \ michael@13: -e 's;^\([^ ]*\) *\(.*\)$;\2 \1;g' \ michael@13: -e 's;^ *;;' \ michael@13: -e 's; *$;;' \ michael@13: -e 's; *:$;;' | eval $outcmd michael@13: fi michael@13: ;; michael@13: michael@13: signal ) michael@13: if [ ".$opt_p" = . -a ".$opt_m" = . ]; then michael@13: echo "$msgprefix:Error: either option -p or -m has to be specified" 1>&2 michael@13: exit 1 michael@13: fi michael@13: case "$platform" in michael@13: *:FreeBSD:*:* | *:NetBSD:*:* ) michael@13: cmd0="ps -ax -o pid" michael@13: cmd1="ps -ax -o command" michael@13: cmd2="ps -ax -o pid,command" michael@13: cmd3="ps -ax -o pid,ppid" michael@13: ;; michael@13: *:Linux:*:* | *:OSF1:5.*:* ) michael@13: cmd0="ps axo pid" michael@13: cmd1="ps axo cmd" michael@13: cmd2="ps axo pid,cmd" michael@13: cmd3="ps axo pid,ppid" michael@13: ;; michael@13: *:SunOS:5.*:* ) michael@13: cmd0="ps -ef -o pid" michael@13: cmd1="ps -ef -o args" michael@13: cmd2="ps -ef -o pid,args" michael@13: cmd3="ps -ef -o pid,ppid" michael@13: ;; michael@13: *:HP-UX:*:* ) michael@13: cmd0="ps -ef" # FIXME michael@13: cmd1="ps -ef" # FIXME michael@13: cmd2="ps -ef" # FIXME michael@13: cmd3="ps -ef" # FIXME michael@13: ;; michael@13: *:IRIX64:6.*:* ) michael@13: cmd0="ps -ef -o pid" michael@13: cmd1="ps -ef -o args" michael@13: cmd2="ps -ef -o pid,args" michael@13: cmd3="ps -ef -o pid,ppid" michael@13: ;; michael@13: *:Darwin:*:* ) michael@13: cmd0="ps -ax -opid" michael@13: cmd1="ps -ax -ocommand" michael@13: cmd2="ps -ax -opid,command" michael@13: cmd3="ps -ax -opid,ppid" michael@13: esac michael@13: # try all signals in order michael@13: i=$# michael@13: for sig in "$@"; do michael@13: # check whether program is still running/active michael@13: active="" michael@13: if [ ".$opt_p" != . ]; then michael@13: active=`$cmd0 | grep "$opt_p" | grep -v grep | grep -v rpmtool` michael@13: elif [ ".$opt_m" != . ]; then michael@13: active=`$cmd1 | grep "$opt_m" | grep -v grep | grep -v rpmtool` michael@13: fi michael@13: if [ ".$active" = . ]; then michael@13: break michael@13: fi michael@13: michael@13: # send signal to program michael@13: if [ ".$opt_p" != . ]; then michael@13: pids="$opt_p" michael@13: elif [ ".$opt_m" != . ]; then michael@13: pids=`$cmd2 | sed -e "s;^[ ${TAB}]*;;" | egrep "[0-9]* .*$opt_m" |\ michael@13: grep -v grep | grep -v rpmtool |\ michael@13: awk '{ printf("%s\n", $1); }'` michael@13: fi michael@13: for pid in $pids; do michael@13: if [ ".$opt_v" = .yes ]; then michael@13: echo "sending $sig signal to process $pid" michael@13: fi michael@13: if [ ".$opt_t" = .yes ]; then michael@13: echo "kill -$sig $pid" michael@13: fi michael@13: if [ ".$opt_n" = .no ]; then michael@13: eval "kill -$sig $pid" michael@13: fi michael@13: done michael@13: michael@13: # optionally send signal to childs of program michael@13: if [ ".$opt_c" = .yes ]; then michael@13: for pid in $pids; do michael@13: cpids=`$cmd3 | sed -e "s;^[ ${TAB}]*;;" | egrep "[0-9]* $pid" |\ michael@13: grep -v grep | grep -v rpmtool |\ michael@13: awk '{ printf("%s\n", $1); }'` michael@13: for cpid in $cpids; do michael@13: if [ ".$opt_v" = .yes ]; then michael@13: echo "sending $sig signal to child process $cpid" michael@13: fi michael@13: if [ ".$opt_t" = .yes ]; then michael@13: echo "kill -$sig $cpid" michael@13: fi michael@13: if [ ".$opt_n" = .no ]; then michael@13: eval "kill -$sig $cpid >/dev/null 2>&1" michael@13: fi michael@13: done michael@13: done michael@13: fi michael@13: michael@13: # perform optional delay michael@13: i=`expr $i - 1` michael@13: if [ $i -gt 0 ]; then michael@13: if [ ".$opt_d" != . -a ".$opt_d" != . ]; then michael@13: sleep $opt_d michael@13: fi michael@13: fi michael@13: done michael@13: ;; michael@13: michael@13: config ) michael@13: # usage consistency michael@13: if [ ".$opt_a" = .no -a ".$opt_r" = .no ]; then michael@13: echo "$msgprefix:Error: either option -a or -r has to be specified" 1>&2 michael@13: exit 1 michael@13: fi michael@13: configfile="$1" michael@13: michael@13: # determine block markers michael@13: block_start="${opt_p}<${opt_t}" michael@13: if [ ".$opt_i" != . ]; then michael@13: block_start="${block_start} id=\"${opt_i}\"" michael@13: fi michael@13: block_start="${block_start}>" michael@13: block_end="${opt_p}" michael@13: michael@13: # slash-escaped versions of block markers (for sed(3) call) michael@13: block_start_esc=`echo "$block_start" | sed -e 's;/;\\\\/;g'` michael@13: block_end_esc=`echo "$block_end" | sed -e 's;/;\\\\/;g'` michael@13: michael@13: # determine backup extension michael@13: case "X$opt_b" in michael@13: X ) ext=".bak" ;; michael@13: X.* ) ext="$opt_b" ;; michael@13: X* ) ext=".$opt_b" ;; michael@13: esac michael@13: michael@13: # check for block in config file michael@13: if [ -f $configfile ]; then michael@13: check=`grep "^${block_start}" $configfile` michael@13: else michael@13: touch $configfile michael@13: check="" michael@13: fi michael@13: michael@13: # add entry michael@13: if [ ".$opt_a" = .yes ]; then michael@13: if [ ".$check" != . ]; then michael@13: if [ ".$opt_s" = .yes ]; then michael@13: exit 0 michael@13: else michael@13: echo "$msgprefix:Error: config entry already exists" 1>&2 michael@13: exit 1 michael@13: fi michael@13: fi michael@13: cp $configfile $configfile$ext michael@13: echo "${block_start}" >$tmpfile michael@13: cat >>$tmpfile michael@13: echo "${block_end}" >>$tmpfile michael@13: cat $tmpfile >>$configfile michael@13: michael@13: # remove entry michael@13: elif [ ".$opt_r" = .yes ]; then michael@13: if [ ".$check" = . ]; then michael@13: if [ ".$opt_s" = .yes ]; then michael@13: exit 0 michael@13: else michael@13: echo "$msgprefix:Error: config entry does not exist" 1>&2 michael@13: exit 1 michael@13: fi michael@13: fi michael@13: cp $configfile $configfile$ext michael@13: sed -e "/^${block_start_esc}/,/^${block_end_esc}/d" \ michael@13: <$configfile$ext >$configfile michael@13: fi michael@13: michael@13: # verbosity michael@13: if [ ".$opt_v" = .yes ]; then michael@13: (diff -u1 $configfile$ext $configfile >$tmpfile) 2>/dev/null michael@13: if [ ".`cat $tmpfile`" = . ]; then michael@13: (diff -C1 $configfile$ext $configfile >$tmpfile) 2>/dev/null michael@13: if [ ".`cat $tmpfile`" = . ]; then michael@13: if [ ".$opt_s" = .no ]; then michael@13: echo "$msgprefix:Warning: unable to show difference for config file \`$configfile'" 1>&2 michael@13: fi michael@13: fi michael@13: fi michael@13: echo "editing $configfile:" michael@13: cat $tmpfile michael@13: fi michael@13: michael@13: # optionally remove backup file michael@13: if [ ".$opt_b" = . ]; then michael@13: rm -f $configfile$ext michael@13: fi michael@13: ;; michael@13: michael@13: msg ) michael@13: # optionally beep before message michael@13: if [ ".$opt_b" = .yes ]; then michael@13: echo . | awk '{ printf("%c", 7); }' michael@13: fi michael@13: title="" michael@13: case $opt_t in michael@13: info ) title="-------" ;; michael@13: notice ) title="Notice-" ;; michael@13: warn ) title="Warning" ;; michael@13: error ) title="Error--" ;; michael@13: * ) echo "$msgprefix:Error: invalid message type \`$opt_t'" 1>&2; exit 1 ;; michael@13: esac michael@13: michael@13: # display message michael@13: if [ ".$opt_r" != .yes ]; then michael@13: echo . | awk '{ printf("\r"); }' michael@13: fi michael@13: echo "+----------------------------------${title}------------------------------------+" michael@13: expand -t 8 | sed -e 's; *$;;' | awk '{ printf("| %-75s |\n", substr($0, 0, 75)); }' michael@13: echo "+-----------------------------------------------------------------------------+" michael@13: ;; michael@13: check-class ) michael@13: # check package class from within .spec file macro expansion for %prep section michael@13: class="$1"; shift michael@13: case "$class" in michael@13: CORE|BASE ) michael@13: ;; michael@13: PLUS ) michael@13: echo "set +x" michael@13: ( echo "This OpenPKG package is of class PLUS." michael@346: echo "It is still in a QUALITY ASSURANCE state," michael@346: echo "therefore it is NOT ready for careless use." michael@13: echo "Do not use it in critical production environments." michael@346: echo "This software might still be unstable at runtime." michael@13: ) | sh $prog_path msg -r -t notice | sed -e 's;^;echo ";' -e 's;$;";' michael@13: echo "set -x" michael@13: ;; michael@13: EVAL ) michael@13: echo "set +x" michael@13: ( echo "This OpenPKG package is of class EVAL." michael@346: echo "It is still in a EVALUATION and QA state," michael@346: echo "therefore it is NOT ready for general use." michael@13: echo "Do not use it in production environments." michael@346: echo "It might be unstable or incompletely packaged." michael@13: ) | sh $prog_path msg -r -t warn | sed -e 's;^;echo ";' -e 's;$;";' michael@13: echo "set -x" michael@13: ;; michael@13: JUNK ) michael@13: echo "set +x" michael@13: ( echo "This OpenPKG package is of class JUNK." michael@346: echo "It is still in DEVELOPMENT state," michael@346: echo "therefore it is NOT ready to be used." michael@13: echo "Do not use it at all, except in development environments!" michael@346: echo "This software is either unstable or incompletely packaged." michael@13: ) | sh $prog_path msg -r -t warn | sed -e 's;^;echo ";' -e 's;$;";' michael@13: echo "set -x" michael@13: ;; michael@13: esac michael@13: ;; michael@13: esac michael@13: michael@13: # cleanup michael@13: if [ ".$gen_tmpfile" = .yes ]; then michael@13: rm -f $tmpfile >/dev/null 2>&1 michael@13: fi michael@13: michael@13: # die gracefully ;) michael@13: exit 0 michael@13: