12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160 |
- #!/bin/sh
- ##
- ## rpmtool -- RPM Auxiliary Tool
- ## Copyright (c) 2000-2002 Cable & Wireless Deutschland GmbH
- ## Copyright (c) 2000-2002 The OpenPKG Project <http://www.openpkg.org/>
- ## Copyright (c) 2000-2002 Ralf S. Engelschall <rse@engelschall.com>
- ##
- ## Permission to use, copy, modify, and distribute this software for
- ## any purpose with or without fee is hereby granted, provided that
- ## the above copyright notice and this permission notice appear in all
- ## copies.
- ##
- ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
- ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- ## SUCH DAMAGE.
- ##
- prog_name="rpmtool"
- prog_vers="1.0.2"
- prog_date="03-Aug-2001"
- if [ $# -eq 0 ]; then
- echo "$0:Error: invalid command line" 1>&2
- echo "$0:Hint: run \`$0 -h' for usage" 1>&2
- exit 1
- fi
- if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
- echo "This is $prog_name, version $prog_vers ($prog_date)"
- echo "Copyright (c) 2000-2001 Ralf S. Engelschall <rse@engelschall.com>"
- echo ''
- echo "Usage: $prog_name [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]"
- echo ''
- echo 'Available global <options>:'
- echo ' -d, --debug enable internal debugging'
- echo ' -v, --version display version information'
- echo ' -h, --help display usage help page (this one)'
- echo ''
- echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
- echo ' platform'
- echo ' subst [-v] [-t] [-s] <sed-cmd> [...] -- <file> [...]'
- echo ' flags [-m] [-c] [-O] <tool>'
- echo ' files [-v] [-o <outfile>] [-r <buildroot>] [<filelist>]'
- echo ' user [-c] [-d] [-p <passwd>] [-n <realname>] [-d <homedir>]'
- echo ' [-s <shell>] [-u <min-uid>] <username>'
- echo ' group [-c] [-d] <groupname> <min-gid> [<username> ...]'
- echo ' signal [-v] [-t] [-n] [-c] [-d <delay>] [-p <pid>] [-m <pattern>] <sig> [<sig> ...]'
- echo ' config [-v] [-s] [-a] [-r] [-b <ext>] [-p <tagprefix>] [-t <tagname>] [-i <tagid>] <file>'
- echo ''
- exit 0
- fi
- if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then
- echo "$prog_name $prog_vers ($prog_date)"
- exit 0
- fi
- if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then
- shift
- set -x
- fi
- tool="$1"
- shift
- arg_spec=""
- opt_spec=""
- gen_tmpfile=no
- # configure tool specific option parsing
- case $tool in
- platform )
- str_usage=""
- arg_spec="0="
- opt_spec=""
- ;;
- subst )
- str_usage="[-v] [-t] [-s] <sed-cmd> [...] -- <file> [...]"
- arg_spec="3+"
- opt_spec="v.t.s."
- opt_v=no
- opt_t=no
- opt_s=no
- gen_tmpfile=yes
- ;;
- flags )
- str_usage="[-m] [-c] [-O] <tool>"
- arg_spec="1="
- opt_spec="m.c.O."
- opt_m=no
- opt_c=no
- opt_O=no
- ;;
- files )
- gen_tmpfile=yes
- str_usage="[-v] [-o <outfile>] [-r <buildroot>] [<filelist>]"
- arg_spec="0+"
- opt_spec="v.o:r:"
- opt_v=no
- opt_o=''
- opt_r=''
- ;;
- user )
- str_usage="[-a] [-r] [-p <passwd>] [-n <realname>] [-d <homedir>] [-s <shell>] [-u <min-uid>] <username>"
- arg_spec="1="
- opt_spec="a.r.p:n:d:s:u:"
- opt_a=no
- opt_r=no
- opt_p=''
- opt_n=''
- opt_d=''
- opt_s=''
- opt_u=1000
- ;;
- group )
- str_usage="[-a] [-r] [-g <min-gid>] <groupname> [<username> ...]"
- arg_spec="1+"
- opt_spec="a.r.g:"
- opt_a=no
- opt_r=no
- opt_g=1000
- ;;
- signal )
- str_usage="[-v] [-t] [-n] [-c] [-d <delay>] [-p <pid>] [-m <pattern>] <sig> [<sig> ...]"
- arg_spec="1+"
- opt_spec="v.t.n.c.d:p:m:"
- opt_v=no
- opt_t=no
- opt_n=no
- opt_c=no
- opt_d=1
- opt_p=""
- opt_m=""
- ;;
- config )
- str_usage="[-v] [-s] [-a] [-r] [-b <ext>] [-p <tagprefix>] [-t <tagname>] [-i <tagid>] <file>"
- arg_spec="1="
- opt_spec="v.s.a.r.b:p:t:i:c:"
- opt_v=no
- opt_s=no
- opt_a=no
- opt_r=no
- opt_b=""
- opt_p="#"
- opt_t="OpenPKG"
- opt_i=""
- gen_tmpfile=yes
- ;;
- -* )
- echo "$prog_name:Error: unknown option \`$tool'" 2>&1
- echo "$prog_name:Hint: run \`$0 -h' for usage" 2>&1
- exit 1
- ;;
- * )
- echo "$prog_name:Error: unknown command \`$tool'" 2>&1
- echo "$prog_name:Hint: run \`$0 -h' for usage" 2>&1
- exit 1
- ;;
- esac
- # tool information
- toolcmd="$0 $tool"
- toolcmdhelp="$prog_name $tool"
- msgprefix="$prog_name:$tool"
- # parse argument specification string
- eval `echo $arg_spec |\
- sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
- # parse option specification string
- eval `echo h.$opt_spec |\
- sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
- # interate over argument line
- opt_PREV=''
- while [ $# -gt 0 ]; do
- # special option stops processing
- if [ ".$1" = ".--" ]; then
- shift
- break
- fi
- # determine option and argument
- opt_ARG_OK=no
- if [ ".$opt_PREV" != . ]; then
- # merge previous seen option with argument
- opt_OPT="$opt_PREV"
- opt_ARG="$1"
- opt_ARG_OK=yes
- opt_PREV=''
- else
- # split argument into option and argument
- case "$1" in
- -[a-zA-Z0-9]*)
- eval `echo "x$1" |\
- sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
- -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
- ;;
- -[a-zA-Z0-9])
- opt_OPT=`echo "x$1" | cut -c3-`
- opt_ARG=''
- ;;
- *)
- break
- ;;
- esac
- fi
- # eat up option
- shift
- # determine whether option needs an argument
- eval "opt_MODE=\$opt_MODE_${opt_OPT}"
- if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then
- if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then
- opt_PREV="$opt_OPT"
- continue
- fi
- fi
- # process option
- case $opt_MODE in
- '.' )
- # boolean option
- eval "opt_${opt_OPT}=yes"
- ;;
- ':' )
- # option with argument (multiple occurances override)
- eval "opt_${opt_OPT}=\"\$opt_ARG\""
- ;;
- '+' )
- # option with argument (multiple occurances append)
- eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
- ;;
- * )
- echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2
- echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man $prog_name' for details" 1>&2
- exit 1
- ;;
- esac
- done
- if [ ".$opt_PREV" != . ]; then
- echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2
- echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man $prog_name' for details" 1>&2
- exit 1
- fi
- # process help option
- if [ ".$opt_h" = .yes ]; then
- echo "Usage: $toolcmdhelp $str_usage"
- exit 0
- fi
- # complain about incorrect number of arguments
- case $arg_MODE in
- '=' )
- if [ $# -ne $arg_NUMS ]; then
- echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
- echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man $prog_name' for details" 1>&2
- exit 1
- fi
- ;;
- '+' )
- if [ $# -lt $arg_NUMS ]; then
- echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
- echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man $prog_name' for details" 1>&2
- exit 1
- fi
- ;;
- esac
- # establish a temporary file on request
- if [ ".$gen_tmpfile" = .yes ]; then
- if [ ".$TMPDIR" != . ]; then
- tmpdir="$TMPDIR"
- elif [ ".$TEMPDIR" != . ]; then
- tmpdir="$TEMPDIR"
- else
- tmpdir="/tmp"
- fi
- tmpfile="$tmpdir/.$prog_name.$$"
- rm -f $tmpfile >/dev/null 2>&1
- touch $tmpfile
- fi
- # provide a few useful variables
- NL="
- "
- TAB=" "
- DIFS=" ${TAB}${NL}"
- # determine platform information
- platform_machine=`(uname -m) 2>/dev/null` ||\
- platform_machine=`(uname -p) 2>/dev/null` ||\
- platform_machine='unknown'
- platform_release=`(uname -r) 2>/dev/null` ||\
- platform_release='unknown'
- platform_system=`(uname -s) 2>/dev/null` ||\
- platform_system='unknown'
- platform_version=`(uname -v) 2>/dev/null` ||\
- platform_version='unknown'
- platform="${platform_machine}:${platform_system}:${platform_release}:${platform_version}"
- # dispatch into tools
- case $tool in
- platform )
- # provide unique platform id
- m=`echo "$platform_machine" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- s=`echo "$platform_system" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- r=`echo "$platform_release" | sed -e 's;-.*$;;'`
- echo "${m}-${s}${r}"
- ;;
- subst )
- # substitute variables (in-place)
- ops=""
- files=""
- isop=1
- for arg
- do
- if [ ".$arg" = ".--" ]; then
- isop=0
- continue
- fi
- if [ ".$isop" = .1 ]; then
- ops="$ops%$arg"
- else
- files="$files%$arg"
- fi
- done
- cmd='sed'
- OIFS="$IFS"; IFS="%"
- for op in $ops; do
- test ".$op" = . && continue
- cmd="$cmd -e '$op'"
- done
- IFS="$OIFS"
- for file in `IFS="%"; echo $files`; do
- test ".$file" = . && continue
- if [ ! -f $file ]; then
- echo "$msgprefix:Warning: file \`$file' not found" 1>&2
- continue
- fi
- if [ ".$opt_v" = .yes ]; then
- echo "patching file \`$file'" 1>&2
- fi
- if [ ".$opt_t" = .yes ]; then
- echo "\$ cp -p $file $file.orig"
- echo "\$ $cmd <$file.orig >$file"
- fi
- cp -p $file $file.orig
- eval "$cmd <$file.orig >$file"
- if [ ".$opt_s" = .yes ]; then
- if [ ".$opt_t" = .yes ]; then
- echo "\$ touch -r $file.orig $file"
- fi
- touch -r $file.orig $file
- fi
- done
- ;;
-
- flags )
- tool="$1"
- if [ ".$opt_m" = .yes ]; then
- isgmake=no
- if [ ".`$tool -v 2>/dev/null | grep 'GNU Make'`" != . ]; then
- isgmake=yes
- fi
- mflags=''
- if [ ".$isgmake" = .yes ]; then
- mflags="--no-print-directory"
- fi
- if [ ".$opt_O" = .yes ]; then
- case $platform in
- *:SunOS:5.*:* | *:OSF1:*:* )
- if [ ".$isgmake" = .yes ]; then
- n=`(/bin/uname -X) 2>/dev/null | grep -i NumCPU | awk '{ print $3; }'`
- if [ ".$n" != . ]; then
- if [ $n -gt 1 ]; then
- n=`expr $n \* 2`
- mflags="$mflags -j$n"
- fi
- fi
- fi
- ;;
- *:FreeBSD:4.*:* )
- n=`/sbin/sysctl hw.ncpu | awk '{ print $2; }'`
- if [ ".$n" != . ]; then
- if [ $n -gt 1 ]; then
- n=`expr $n \* 2`
- mflags="$mflags -j$n"
- if [ ".$isgmake" = .no ]; then
- mflags="$mflags -B"
- fi
- fi
- fi
- ;;
- *:NetBSD:1.5*:* )
- n=`/sbin/sysctl hw.ncpu | awk '{ print $3; }'`
- if [ ".$n" != . ]; then
- if [ $n -gt 1 ]; then
- n=`expr $n \* 2`
- mflags="$mflags -j$n"
- if [ ".$isgmake" = .no ]; then
- mflags="$mflags -B"
- fi
- fi
- fi
- ;;
- *:Linux:*:* )
- n=`cat /proc/cpuinfo | grep processor | wc -l | awk '{ print $1; }'`
- if [ ".$n" != . ]; then
- if [ $n -gt 1 ]; then
- n=`expr $n \* 2`
- mflags="$mflags -j$n"
- fi
- fi
- ;;
- *:HP-UX:*:* )
- n=1 # FIXME
- ;;
- esac
- fi
- echo "$mflags"
- elif [ ".$opt_c" = .yes ]; then
- isgcc=no
- if [ ".`$tool --version 2>/dev/null | egrep '(2.[789]|3.[01])'`" != . ]; then
- isgcc=yes
- fi
- cflags=''
- if [ ".$opt_O" = .yes ]; then
- if [ ".$isgcc" = .yes ]; then
- cflags="-O2 -pipe"
- else
- cflags="-O"
- fi
- fi
- echo "$cflags"
- fi
- ;;
-
- files )
- # if a Perl interpreter is available, we perform the operation
- # with it because Perl is a magnitude (factor 10!) faster than
- # what we can do here in Bourne-Shell.
- perl=''
- for dir in `echo $PATH | sed -e 's/:/ /g'` .; do
- for tool in perl5 perl miniperl; do
- if [ -f "$dir/$tool" ]; then
- perl="$dir/$tool"
- break
- fi
- done
- if [ ".$perl" != . ]; then
- break
- fi
- done
- if [ ".$perl" != . ]; then
- cat >$tmpfile <<'EOT'
- ##
- ## PERL IMPLEMENTATION (FAST)
- ##
- my $opt_v = 0;
- my $opt_o = '';
- my $opt_r = '';
- while ($ARGV[0] =~ m|^-(.)(.*)$|) {
- my ($opt, $arg) = ($1, $2);
- shift(@ARGV);
- unshift(@ARGV, $arg) if ($arg ne '');
- $opt_v = 1 if ($opt eq 'v');
- $opt_o = shift(@ARGV) if ($opt eq 'o');
- $opt_r = shift(@ARGV) if ($opt eq 'r');
- }
- # remember the build root in a reasonable short variable ;)
- my $br = "$opt_r";
- # read input file list
- my @L = ();
- if ($#ARGV == -1 or ($#ARGV == 0 and $ARGV[0] eq "-")) {
- # read file list from stdin
- while (<STDIN>) {
- s/\n$//s;
- push(@L, $_);
- }
- }
- else {
- # read file list from argument line
- @L = @ARGV;
- }
- # PASS 1: PREPARATION AND SYNTACTICAL EXPANSION
- if ($opt_v == 1) {
- print STDERR "rpmtool:files: pass 1 (preparation and syntactical expansions)\n";
- }
- my @T = ();
- my $l;
- foreach $l (@L) {
- # replace tabs with spaces, reduce multiple spaces to single
- # spaces, and remove leading and trailing spaces
- $l =~ s|[ \t\n]+| |sg;
- $l =~ s|^[ \t]+||sg;
- $l =~ s|[ \t]+$||sg;
- # move tags to end of entry for easier parsing
- 1 while ($l =~ s|^(%\S+) (.+)|$2 $1|);
- # use `:' as a dummy path for tag-only entries (like `%defattr')
- # to avoid special cases in the later processing
- if ($l =~ m|^%.+|) {
- $l = ": $l";
- }
- # split entry into path and optional tags
- my ($p, $t) = ($l =~ m|^(\S+)(.*)$|);
- # expand `{foo,bar,quux}' constructs in path (silent
- # assumtion to make life easier is that the constructs
- # occurs only once in a path!)
- if ($p =~ m|^(.*)\{([^\}]+)\}(.*)$|) {
- # split path into prolog, the set construct, and the epilog
- my ($pro, $set, $epi) = ($1, $2, $3);
- # repeat prolog and epilog for all elements in set
- my $x;
- foreach $x (split(/,/, $set)) {
- push(@T, "${pro}${x}${epi}${t}");
- }
- }
- else {
- # else just take over the entry as is
- push(@T, $l);
- }
- }
- @L = @T;
- # PASS 2: FILESYSTEM-BASED EXPANSIONS
- if ($opt_v == 1) {
- print STDERR "rpmtool:files: pass 2 (filesystem-based expansions)\n";
- }
- @T = ();
- foreach $l (@L) {
- # split entry into path and optional tags
- my ($p, $t) = ($l =~ m|^(\S*)(.*)$|);
- # expand...
- if (-d "$br$p" and $t !~ m|.*%dir.*|) {
- # expand path because it is not tagged with %dir
- my @X = `cd "$br$p" && find . -print`;
- my $x;
- foreach $x (@X) {
- $x =~ s|\n$||s;
- $x =~ s|^\.|$p|s;
- push(@T, "${x}${t}");
- }
- }
- else {
- # expand path wildcards (`*' and `[..]')
- # (if not wildcards are present, this doesn't harm)
- my @X = glob("$br$p");
- my $x;
- foreach $x (@X) {
- my $brqm = quotemeta($br);
- $x =~ s|^$brqm||s;
- push(@T, "${x}${t}");
- }
- }
- }
- @L = @T;
- # PASS 3: DUPLICATION REMOVAL AND CLEANUP
- if ($opt_v == 1) {
- print STDERR "rpmtool:files: pass 3 (duplication removal and cleanup)\n";
- }
- @T = ();
- foreach $l (@L) {
- # split entry into path and optional tags
- my ($p, $t) = ($l =~ m|^(\S*)(.*)$|);
- # add %dir tag if entry is a directory, but still not
- # tagged as such (else RPM would again expand it recursively)
- if (-d "$br$p") {
- if ($t !~ m|%dir|) {
- $t .= " %dir";
- }
- }
- # remove duplicate entries in already processed part
- # (but make sure we keep the entries with the dummy tags)
- if ($p ne ":") {
- my @T2 = ();
- foreach $t (@T) {
- my $pqm = quotemeta($p);
- next if ($t =~ m|^$pqm | or $t eq $p);
- push(@T2, $t);
- }
- @T = @T2;
- }
- # keep entry only if no %not tag is present
- # (else all entries are removed)
- if ($t !~ m|.*%not.*|) {
- push(@T, "${p}${t}");
- }
- }
- @L = @T;
- # write out new file list
- @T = ();
- foreach $l (@L) {
- $l =~ s|^(\S+) (.*)$|$2 $1|sg;
- $l =~ s|^\s+||s;
- $l =~ s|\s+$||s;
- $l =~ s|\s+:$||s;
- push(@T, $l);
- }
- @L = @T;
- if ($opt_o eq '' or $opt_o eq '-') {
- print STDOUT join("\n", @L)."\n";
- }
- else {
- open(FP, ">$opt_o");
- print FP join("\n", @L)."\n";
- close(FP);
- }
- EOT
- cmd="$perl $tmpfile";
- if [ ".$opt_v" = .yes ]; then
- cmd="$cmd -v"
- fi
- if [ ".$opt_o" != . ]; then
- cmd="$cmd -o \"$opt_o\""
- fi
- if [ ".$opt_r" != . ]; then
- cmd="$cmd -r \"$opt_r\""
- fi
- for arg
- do
- cmd="$cmd \"$arg\""
- done
- eval $cmd
- else
- ##
- ## BOURNE-SHELL IMPLEMENTATION (PORTABLE)
- ##
- # remember the build root in a reasonable short variable ;)
- br="$opt_r"
-
- # make sure filename expansion is disabled per default
- set -f
-
- # read input file list
- L=''
- if [ $# -eq 0 ] || [ $# -eq 1 -a ".$1" = ".-" ]; then
- # read file list from stdin
- L=`cat`
- else
- # read file list from argument line
- for arg
- do
- L="$L$NL$arg"
- done
- fi
-
- # PASS 1: PREPARATION AND SYNTACTICAL EXPANSION
- if [ ".$opt_v" = .yes ]; then
- echo "rpmtool:files: pass 1 (preparation and syntactical expansions)" 1>&2
- fi
- T=''
- OIFS="$IFS"; IFS="$NL"
- for l in $L; do
- [ ".$l" = . ] && continue
-
- # replace tabs with spaces, reduce multiple spaces to single
- # spaces, and remove leading and trailing spaces
- l=`echo "$l" | sed -e "s;${TAB}; ;g" -e 's; *; ;g' -e 's;^ *;;' -e 's; *$;;'`
-
- # move tags to end of entry for easier parsing
- while [ ".`echo \"$l\" | grep '^%[^ ]* .*'`" != . ]; do
- l=`echo "$l" | sed -e 's;^\(%[^ ]*\) \(.*\);\2 \1;'`
- done
-
- # use `:' as a dummy path for tag-only entries (like `%defattr')
- # to avoid special cases in the later processing
- if [ ".`echo \"$l\" | grep '^%.*'`" != . ]; then
- l=": $l"
- fi
-
- # split entry into path and optional tags
- eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'`
-
- # expand `{foo,bar,quux}' constructs in path (silent
- # assumtion to make life easier is that the constructs
- # occurs only once in a path!)
- if [ ".`echo \".$p\" | grep '^\..*{[^}]*}.*$'`" != . ]; then
-
- # split path into prolog, the set construct, and the epilog
- eval `echo ".$p" | sed -e 's;^\.\(.*\){\([^}]*\)}\(.*\)$;pro="\1" set="\2" epi="\3";'`
-
- # repeat prolog and epilog for all elements in set
- OIFS2="$IFS"; IFS=","
- for x in $set; do
- T="$T$NL${pro}${x}${epi}${t}"
- done
- IFS="$OIFS2"
- else
- # else just take over the entry as is
- T="$T$NL$l"
- fi
- done
- L="$T"
- IFS="$OIFS"
-
- # PASS 2: FILESYSTEM-BASED EXPANSIONS
- if [ ".$opt_v" = .yes ]; then
- echo "rpmtool:files: pass 2 (filesystem-based expansions)" 1>&2
- fi
- T=''
- OIFS="$IFS"; IFS="$NL"
- for l in $L; do
- [ ".$l" = . ] && continue
-
- # split entry into path and optional tags
- eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'`
-
- # expand...
- if [ -d "$br$p" -a ".`expr \".$t\" : '\..*%dir.*'`" = .0 ]; then
- # expand path because it is not tagged with %dir
- OIFS2="$IFS"; IFS="$DIFS"
- for x in `cd "$br$p" && find . -print | sed -e "s;^\\.;$p;"`; do
- T="$T$NL${x}${t}"
- done
- IFS="$OIFS2"
- else
- # expand path wildcards (`*' and `[..]')
- # (if not wildcards are present, this doesn't harm)
- OIFS2="$IFS"; IFS="$DIFS"
- for x in `(set +f; echo $br$p) | sed -e "s;^$br;;" -e "s; $br; ;g"`; do
- T="$T$NL${x}${t}"
- done
- IFS="$OIFS2"
- fi
- done
- IFS="$OIFS"
- L="$T"
-
- # PASS 3: DUPLICATION REMOVAL AND CLEANUP
- if [ ".$opt_v" = .yes ]; then
- echo "rpmtool:files: pass 3 (duplication removal and cleanup)" 1>&2
- fi
- T=''
- OIFS="$IFS"; IFS="$NL"
- for l in $L; do
- [ ".$l" = . ] && continue
-
- # split entry into path and optional tags
- eval `echo ".$l" | sed -e 's;^\.\([^ ]*\)\(.*\)$;p="\1" t="\2";'`
-
- # add %dir tag if entry is a directory, but still not
- # tagged as such (else RPM would again expand it recursively)
- if [ -d "$br$p" ]; then
- if [ ".`expr \".$t\" : '\..*%dir.*'`" = .0 ]; then
- t="$t %dir"
- fi
- fi
-
- # remove duplicate entries in already processed part
- # (but make sure we keep the entries with the dummy tags)
- if [ ".$p" != ".:" ]; then
- T=`echo "$T" | grep -v "^$p " | grep -v "^$p\$"`
- fi
-
- # keep entry only if no %not tag is present
- # (else all entries are removed)
- if [ ".`expr \".$t\" : '\..*%not.*'`" = .0 ]; then
- T="$T$NL${p}${t}"
- fi
- done
- IFS="$OIFS"
- L="$T"
-
- # write out new file list
- if [ ".$opt_o" = . -o ".$opt_o" = ".-" ]; then
- outcmd="cat"
- else
- outcmd="cat > $opt_o"
- fi
- echo "$L" |\
- sed -e '/^$/d' \
- -e 's;^\([^ ]*\) *\(.*\)$;\2 \1;g' \
- -e 's;^ *;;' \
- -e 's; *$;;' \
- -e 's; *:$;;' | eval $outcmd
- fi
- ;;
-
- user )
- # calling convention
- if [ ".$opt_a" = .no -a ".$opt_r" = .no ]; then
- echo "$msgprefix:Error: either -a or -r has to be given" 1>&2
- exit 1
- fi
- if [ ".$opt_a" = .yes -a ".$opt_r" = .yes ]; then
- echo "$msgprefix:Error: only -a or -r can be given" 1>&2
- exit 1
- fi
- user=$1
- # default values
- if [ ".$opt_n" = . ]; then
- opt_n="$user"
- fi
- if [ ".$opt_s" = . ]; then
- opt_s=`which false 2>/dev/null`
- if [ ".$opt_s" = . ]; then
- opt_s="/bin/false"
- fi
- fi
- if [ ".$opt_d" = . ]; then
- opt_d="/nowhere"
- fi
- # add user
- if [ ".$opt_a" = .yes ]; then
- exists=`grep "^$user:" /etc/passwd`
- if [ ".$exists" != . ]; then
- echo "$msgprefix:Error: user $user already exists" 1>&2
- exit 1
- fi
- # seek for next free uid
- uid=$opt_u
- ok=0
- while [ ".$ok" = .0 ]; do
- u_exists=`grep "^[^:]*:[^:]*:$uid:" /etc/passwd`
- g_exists=`grep "^[^:]*:[^:]*:$uid:" /etc/group`
- if [ ".$u_exists" = . -a ".$g_exists" = . ]; then
- ok=1
- break
- fi
- uid=`expr $uid + 1`
- done
- # add entry to passwd database
- case "$platform" in
- *:FreeBSD:[456].*:* | *:NetBSD:1.*:* )
- echo "${user}:*:${uid}:${uid}::0:0:${opt_n}:${opt_d}:${opt_s}" >>/etc/master.passwd
- (PATH="$PATH:/usr/sbin"; pwd_mkdb -p /etc/master.passwd)
- ;;
- *:Linux:2.*:* )
- echo "${user}:*:${uid}:${uid}::${opt_n}:${opt_d}:${opt_s}" >>/etc/passwd
- (PATH="$PATH:/usr/sbin"; pwconv)
- ;;
- *:SunOS:5.*:* )
- echo "${user}:*:${uid}:${uid}:${opt_n}:${opt_d}:${opt_s}" >>/etc/passwd
- (PATH="$PATH:/usr/sbin"; pwconv)
- ;;
- *:OSF1:5.*:* )
- echo "${user}:*:${uid}:${uid}:${opt_n}:${opt_d}:${opt_s}" >>/etc/passwd
- (PATH="$PATH:/usr/sbin"; mkpasswd /etc/passwd)
- ;;
- *:HP-UX:*:* )
- echo "${user}:*:${uid}:${uid}:${opt_n}:${opt_d}:${opt_s}" >>/etc/passwd
- ;;
- esac
- # add corresponding entry to group database
- echo "${user}:*:${uid}:${user}" >>/etc/group
-
- # remove user
- elif [ ".$opt_r" = .yes ]; then
- exists=`grep "^$user:" /etc/passwd`
- if [ ".$exists" = . ]; then
- echo "$msgprefix:Error: user $user does not exist" 1>&2
- exit 1
- fi
-
- # remove entry from passwd database
- case "$platform" in
- *:FreeBSD:[456].*:* | *:NetBSD:1.*:* )
- cp /etc/master.passwd /etc/master.passwd.old
- grep -v "^${user}:" /etc/master.passwd.old >/etc/master.passwd
- (PATH="$PATH:/usr/sbin"; pwd_mkdb -p /etc/master.passwd)
- rm -f /etc/master.passwd.old
- ;;
- *:Linux:2.*:* | *:SunOS:5.*:* )
- cp /etc/passwd /etc/passwd.old
- grep -v "^${user}:" /etc/passwd.old >/etc/passwd
- (PATH="$PATH:/usr/sbin"; pwconv)
- rm -f /etc/passwd.old
- ;;
- *:OSF1:5.*:* )
- cp /etc/passwd /etc/passwd.old
- grep -v "^${user}:" /etc/passwd.old >/etc/passwd
- (PATH="$PATH:/usr/sbin"; mkpasswd /etc/passwd)
- rm -f /etc/passwd.old
- ;;
- *:HP-UX:*:* )
- cp /etc/passwd /etc/passwd.old
- grep -v "^${user}:" /etc/passwd.old >/etc/passwd
- rm -f /etc/passwd.old
- ;;
- esac
- # remove corresponding entry from group database
- cp /etc/group /etc/group.old
- grep -v "^${user}:" /etc/group.old >/etc/group
- rm -f /etc/group.old
- fi
- ;;
-
- group )
- if [ ".$opt_a" = .no -a ".$opt_r" = .no ]; then
- echo "$msgprefix:Error: either -a or -r has to be given" 1>&2
- exit 1
- fi
- if [ ".$opt_a" = .yes -a ".$opt_r" = .yes ]; then
- echo "$msgprefix:Error: only -a or -r can be given" 1>&2
- exit 1
- fi
- group=$1
- # add group
- if [ ".$opt_a" = .yes ]; then
- exists=`grep "^$group:" /etc/group`
- if [ ".$exists" != . ]; then
- echo "$msgprefix:Error: group $group already exists" 1>&2
- exit 1
- fi
- # seek for next free gid
- gid=$opt_g
- ok=0
- while [ ".$ok" = .0 ]; do
- exists=`grep "^[^:]*:[^:]*:$gid:" /etc/group`
- if [ ".$exists" = . ]; then
- ok=1
- break
- fi
- gid=`expr $gid + 1`
- done
- # add entry to group database
- echo "${group}:*:${gid}:$*" >>/etc/group
- # remove group
- elif [ ".$opt_r" = .yes ]; then
- exists=`grep "^$group:" /etc/group`
- if [ ".$exists" = . ]; then
- echo "$msgprefix:Error: group $group does not exist" 1>&2
- exit 1
- fi
- # remove entry from group database
- cp /etc/group /etc/group.old
- grep -v "^${group}:" /etc/group.old >/etc/group
- rm -f /etc/group.old
- fi
- ;;
- signal )
- if [ ".$opt_p" = . -a ".$opt_m" = . ]; then
- echo "$msgprefix:Error: either option -p or -m has to be specified" 1>&2
- exit 1
- fi
- case "$platform" in
- *:FreeBSD:*:* | *:NetBSD:*:* )
- cmd0="ps -ax -o pid"
- cmd1="ps -ax -o command"
- cmd2="ps -ax -o pid,command"
- cmd3="ps -ax -o pid,ppid"
- ;;
- *:Linux:*:* | *:OSF1:5.*:* )
- cmd0="ps axo pid"
- cmd1="ps axo cmd"
- cmd2="ps axo pid,cmd"
- cmd3="ps axo pid,ppid"
- ;;
- *:SunOS:5.*:* )
- cmd0="ps -ef -o pid"
- cmd1="ps -ef -o args"
- cmd2="ps -ef -o pid,args"
- cmd3="ps -ef -o pid,ppid"
- ;;
- *:HP-UX:*:* )
- cmd0="ps -ef" # FIXME
- cmd1="ps -ef" # FIXME
- cmd2="ps -ef" # FIXME
- cmd3="ps -ef" # FIXME
- ;;
- esac
- # try all signals in order
- i=$#
- for sig in "$@"; do
- # check whether program is still running/active
- active=""
- if [ ".$opt_p" != . ]; then
- active=`$cmd0 | grep "$opt_p" | grep -v grep | grep -v rpmtool`
- elif [ ".$opt_m" != . ]; then
- active=`$cmd1 | grep "$opt_m" | grep -v grep | grep -v rpmtool`
- fi
- if [ ".$active" = . ]; then
- break
- fi
- # send signal to program
- if [ ".$opt_p" != . ]; then
- pids="$opt_p"
- elif [ ".$opt_m" != . ]; then
- pids=`$cmd2 | sed -e "s;^[ ${TAB}]*;;" | egrep "[0-9]* .*$opt_m" |\
- grep -v grep | grep -v rpmtool |\
- awk '{ printf("%s\n", $1); }'`
- fi
- for pid in $pids; do
- if [ ".$opt_v" = .yes ]; then
- echo "sending $sig signal to process $pid"
- fi
- if [ ".$opt_t" = .yes ]; then
- echo "kill -$sig $pid"
- fi
- if [ ".$opt_n" = .no ]; then
- eval "kill -$sig $pid"
- fi
- done
- # optionally send signal to childs of program
- if [ ".$opt_c" = .yes ]; then
- for pid in $pids; do
- cpids=`$cmd3 | sed -e "s;^[ ${TAB}]*;;" | egrep "[0-9]* $pid" |\
- grep -v grep | grep -v rpmtool |\
- awk '{ printf("%s\n", $1); }'`
- for cpid in $cpids; do
- if [ ".$opt_v" = .yes ]; then
- echo "sending $sig signal to child process $cpid"
- fi
- if [ ".$opt_t" = .yes ]; then
- echo "kill -$sig $cpid"
- fi
- if [ ".$opt_n" = .no ]; then
- eval "kill -$sig $cpid >/dev/null 2>&1"
- fi
- done
- done
- fi
-
- # perform optional delay
- i=`expr $i - 1`
- if [ $i -gt 0 ]; then
- if [ ".$opt_d" != . -a ".$opt_d" != . ]; then
- sleep $opt_d
- fi
- fi
- done
- ;;
- config )
- # usage consistency
- if [ ".$opt_a" = .no -a ".$opt_r" = .no ]; then
- echo "$msgprefix:Error: either option -a or -r has to be specified" 1>&2
- exit 1
- fi
- configfile="$1"
- # determine block markers
- block_start="${opt_p}<${opt_t}"
- if [ ".$opt_i" != . ]; then
- block_start="${block_start} id=\"${opt_i}\""
- fi
- block_start="${block_start}>"
- block_end="${opt_p}</${opt_t}>"
- # slash-escaped versions of block markers (for sed(3) call)
- block_start_esc=`echo "$block_start" | sed -e 's;/;\\\\/;g'`
- block_end_esc=`echo "$block_end" | sed -e 's;/;\\\\/;g'`
- # determine backup extension
- case "X$opt_b" in
- X ) ext=".bak" ;;
- X.* ) ext="$opt_b" ;;
- X* ) ext=".$opt_b" ;;
- esac
- # check for block in config file
- if [ -f $configfile ]; then
- check=`grep "^${block_start}" $configfile`
- else
- touch $configfile
- check=""
- fi
- # add entry
- if [ ".$opt_a" = .yes ]; then
- if [ ".$check" != . ]; then
- if [ ".$opt_s" = .yes ]; then
- exit 0
- else
- echo "$msgprefix:Error: config entry already exists" 1>&2
- exit 1
- fi
- fi
- cp $configfile $configfile$ext
- echo "${block_start}" >$tmpfile
- cat >>$tmpfile
- echo "${block_end}" >>$tmpfile
- cat $tmpfile >>$configfile
- # remove entry
- elif [ ".$opt_r" = .yes ]; then
- if [ ".$check" = . ]; then
- if [ ".$opt_s" = .yes ]; then
- exit 0
- else
- echo "$msgprefix:Error: config entry does not exist" 1>&2
- exit 1
- fi
- fi
- cp $configfile $configfile$ext
- sed -e "/^${block_start_esc}/,/^${block_end_esc}/d" \
- <$configfile$ext >$configfile
- fi
- # verbosity
- if [ ".$opt_v" = .yes ]; then
- (diff -u1 $configfile$ext $configfile >$tmpfile) 2>/dev/null
- if [ ".`cat $tmpfile`" = . ]; then
- (diff -C1 $configfile$ext $configfile >$tmpfile) 2>/dev/null
- if [ ".`cat $tmpfile`" = . ]; then
- if [ ".$opt_s" = .no ]; then
- echo "$msgprefix:Warning: unable to show difference for config file \`$configfile'" 1>&2
- fi
- fi
- fi
- echo "editing $configfile:"
- cat $tmpfile
- fi
- # optionally remove backup file
- if [ ".$opt_b" = . ]; then
- rm -f $configfile$ext
- fi
- ;;
- esac
- # cleanup
- if [ ".$gen_tmpfile" = .yes ]; then
- rm -f $tmpfile >/dev/null 2>&1
- fi
- # die gracefully ;)
- exit 0
|