OpenPKG CVS Repository
  http://cvs.openpkg.org/
  ____________________________________________________________________________

  Server: cvs.openpkg.org                  Name:   Ralf S. Engelschall
  Root:   /e/openpkg/cvs                   Email:  [EMAIL PROTECTED]
  Module: openpkg-tools                    Date:   09-Apr-2004 21:44:21
  Branch: HEAD                             Handle: 2004040920442100

  Added files:
    openpkg-tools/cmd       fetch.pl makeproxy.pl
  Modified files:
    openpkg-tools/cmd       dev.sh

  Log:
    add makeproxy and fetch commands here and use them from within dev

  Summary:
    Revision    Changes     Path
    1.5         +2  -2      openpkg-tools/cmd/dev.sh
    1.1         +256 -0     openpkg-tools/cmd/fetch.pl
    1.1         +507 -0     openpkg-tools/cmd/makeproxy.pl
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openpkg-tools/cmd/dev.sh
  ============================================================================
  $ cvs diff -u -r1.4 -r1.5 dev.sh
  --- openpkg-tools/cmd/dev.sh  9 Apr 2004 08:18:30 -0000       1.4
  +++ openpkg-tools/cmd/dev.sh  9 Apr 2004 19:44:21 -0000       1.5
  @@ -1682,7 +1682,7 @@
           if [ ! -f "$rpmdir/$rpmfile" -o $force -ne 0 ]; then
               echo "++ building $package ($rpmfile)"
               opt="`echo ${opt} | tr ' ' '\n' | ${EGREP} . | sed -e 's;^;--define 
\";' -e 's;=; ;' -e 's;$;\";' | tr '\n' ' '`"
  -            (builtin cd ${OPENPKG_WORK}/src/${name} && rpm --fetch ${name}.spec)
  +            (builtin cd ${OPENPKG_WORK}/src/${name} && openpkg fetch ${name}.spec)
               (builtin cd ${OPENPKG_WORK}/src/${name} && eval "rpm -ba ${opt} 
${name}.spec")
               if [ ! -f "$rpmdir/$rpmfile" ]; then
                   warn "failed to build $package ($rpmfile)"
  @@ -1980,7 +1980,7 @@
                   done
               fi
               echo "++ Fetching files for package specification: $file"
  -            rpm --fetch ${file}
  +            openpkg fetch ${file}
               if [ $? -gt 0 -a $force -ne 1 ]; then
                   die "fetching sources for ${file} failed"
               fi
  @@ .
  patch -p0 <<'@@ .'
  Index: openpkg-tools/cmd/fetch.pl
  ============================================================================
  $ cvs diff -u -r0 -r1.1 fetch.pl
  --- /dev/null 2004-04-09 21:44:21.000000000 +0200
  +++ fetch.pl  2004-04-09 21:44:21.000000000 +0200
  @@ -0,0 +1,256 @@
  +##
  +##  openpkg -- OpenPKG Tool Chain
  +##  Copyright (c) 2000-2004 The OpenPKG Project <http://www.openpkg.org/>
  +##  Copyright (c) 2000-2004 Ralf S. Engelschall <[EMAIL PROTECTED]>
  +##  Copyright (c) 2000-2004 Cable & Wireless <http://www.cw.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.
  +##
  +
  +require 5;
  +use strict;
  +use OpenPKG::Ctx;
  +
  +#   determine OpenPKG information
  +my $ctx = new OpenPKG::Ctx;
  +my $prefix = $ctx->prefix();
  +my $me = $ctx->cmdprog() . " " . $ctx->cmdname();
  +my $rpm = $ctx->cmdprog() . " " . "rpm";
  +my $curl = "$prefix/lib/openpkg/curl";
  +
  +#   FIXME: hack for "openpkg dev"
  +delete $ENV{'OPENPKG_TOOLS'};
  +
  +#   command line parsing
  +if (@ARGV != 1) {
  +    print STDERR "openpkg:fetch:ERROR: requires an argument\n";
  +    print STDERR "openpkg:fetch:USAGE: \"$me <name>.spec\"\n";
  +    exit(1);
  +}
  +my $spec = @ARGV[0];
  +if (not -f $spec) {
  +    print STDERR "openpkg:fetch:ERROR: spec file \"$spec\" not found\n";
  +    exit(1);
  +}
  +
  +#   determine package name
  +my $name = $spec;
  +$name =~ s|\.[^.]+$||;
  +$name =~ s|^.+/([^/]+)$|$1|;
  +
  +#   determine source directories
  +my $local_srcdir  = `$rpm --define 'name $name' --eval '%_sourcedir'`;
  +my $local_specdir = `$rpm --define 'name $name' --eval '%_specdir'`;
  +$local_srcdir  =~ s|\n+$||s;
  +$local_specdir =~ s|\n+$||s;
  +
  +#   make sure source and spec directory actually exists
  +if (not -d $local_srcdir) {
  +    print(STDERR "openpkg:fetch: creating directory $local_srcdir\n");
  +    system("mkdir $local_srcdir");
  +}
  +if (not -d $local_specdir) {
  +    print(STDERR "openpkg:fetch: creating directory $local_specdir\n");
  +    system("mkdir $local_specdir");
  +}
  +
  +#   determine some RC parameters
  +my $RC = {};
  +my $var;
  +my $vars = '';
  +foreach $var (qw(
  +    _dbpath _rpmdir _srcrpmdir _tmppath
  +    _target
  +    l_prefix
  +    l_fetch_mirror_0 l_fetch_mirror_1 l_fetch_mirror_2 l_fetch_mirror_3 
l_fetch_mirror_4
  +    l_fetch_mirror_5 l_fetch_mirror_6 l_fetch_mirror_7 l_fetch_mirror_8 
l_fetch_mirror_9
  +    l_fetch_backup_0 l_fetch_backup_1 l_fetch_backup_2 l_fetch_backup_3 
l_fetch_backup_4
  +    l_fetch_backup_5 l_fetch_backup_6 l_fetch_backup_7 l_fetch_backup_8 
l_fetch_backup_9
  +    _httpproxy _httpport
  +    _ftpproxy _ftpport
  +)) {
  +    $vars .= "${var}=\%{${var}};";
  +}
  +my @assign = split(/;/, `$rpm --eval '$vars'`);
  +foreach my $assign (@assign) {
  +    if ($assign =~ m|^(\S+)=(.*)$|s) {
  +        if ($2 ne '%{'.$1.'}') {
  +             $RC->{$1} = $2;
  +        }
  +    }
  +}
  +
  +#   parse spec file
  +my $DEF = {};
  +my $SRC = {};
  +open(SPEC, "<$spec");
  +while (<SPEC>) {
  +    s|\n+$||s;
  +    if (m/^([a-zA-Z_][a-zA-Z0-9_]*):\s*(.+?)\s*$/) {
  +        $DEF->{lc($1)} = $2;
  +    }
  +    if (m/^%define\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+(.+?)\s*$/) {
  +        $DEF->{lc($1)} = $2;
  +    }
  +    if (m/^((Source|Patch)[0-9]+?):\s*(.+?)\s*$/i) {
  +        my ($remote_srcid, $remote_srcurl) = ($1, $3);
  +
  +        #   determine expanded remote source location
  +        1 while ($remote_srcurl =~ 
s|%{?([a-zA-Z_][a-zA-Z0-9_]*)}?|$DEF->{lc($1)}|sge);
  +        my $remote_srcdir  = '';
  +        my $remote_srcfile = $remote_srcurl;
  +        if ($remote_srcfile =~ m|^(.+)/([^/]+)$|) {
  +            $remote_srcdir  = $1;
  +            $remote_srcfile = $2;
  +        }
  +
  +        #   display remote source location
  +        my $file = $remote_srcfile;
  +        $file = substr($file, 0, 40) if (length($file) > 40);
  +        printf(STDERR "++ %-9s %-40s ", "$remote_srcid:";, $file);
  +
  +        if (-f "$local_srcdir/$remote_srcfile" or -f 
"$local_specdir/$remote_srcfile") {
  +            #   source already on local filesystem
  +            my $size;
  +            if (-f "$local_srcdir/$remote_srcfile") {
  +                $size = (stat("$local_srcdir/$remote_srcfile"))[7];
  +            }
  +            else {
  +                $size = (stat("$local_specdir/$remote_srcfile"))[7];
  +            }
  +            if ($size > 1024*1024) {
  +                $size = sprintf("%.1fMB", $size / (1024*1024));
  +            }
  +            elsif ($size > 1024) {
  +                $size = sprintf("%.0fKB", $size / 1024);
  +            }
  +            else {
  +                $size = sprintf("%d", $size);
  +            }
  +            print STDERR "...OK [$size]\n";
  +        }
  +        else {
  +            #   fetch source onto local filesystem
  +            print STDERR "...MISSING\n";
  +
  +            #   determine prioritized list of possible source locations
  +            my @fetch_srcdir = ();
  +            for (my $i = 0; $i <= 9; $i++) {
  +                my $url = $RC->{"l_fetch_mirror_$i"};
  +                next if (not defined($url) or $url eq '' or $url eq '-');
  +                1 while ($url =~ 
s|%{?([a-zA-Z_][a-zA-Z0-9_]*)}?|$DEF->{lc($1)}|sge);
  +                push(@fetch_srcdir, $url);
  +            }
  +            push(@fetch_srcdir, $remote_srcdir);
  +            for (my $i = 0; $i <= 9; $i++) {
  +                my $url = $RC->{"l_fetch_backup_$i"};
  +                next if (not defined($url) or $url eq '' or $url eq '-');
  +                1 while ($url =~ 
s|%{?([a-zA-Z_][a-zA-Z0-9_]*)}?|$DEF->{lc($1)}|sge);
  +                push(@fetch_srcdir, $url);
  +            }
  +
  +            #   try to fetch from all possible locations
  +            foreach my $fetch_srcdir (@fetch_srcdir) {
  +                $fetch_srcdir =~ s|/+$||s;
  +                print STDERR "openpkg:fetch: fetching from $fetch_srcdir/\n";
  +                if ((my $err = &fetch_url("$fetch_srcdir/$remote_srcfile", 
"$local_srcdir/$remote_srcfile"))) {
  +                    $err = substr($err, 0, 37)."..." if (length($err) > 40);
  +                    print STDOUT "openpkg:fetch:ERROR: $err\n";
  +                    next;
  +                }
  +                last;
  +            }
  +            if (not -f "$local_srcdir/$remote_srcfile") {
  +                print STDERR "openpkg:fetch: failed to fetch source file 
`$remote_srcfile'\n";
  +                return 1;
  +            }
  +        }
  +    }
  +}
  +close(SPEC);
  +exit(0);
  +
  +sub fetch_url {
  +    my ($src, $dst) = @_;
  +
  +    #   make sure file URLs have a fully-qualified scheme.
  +    if ($src =~ m|^/.+|) {
  +        $src = "file://$src"
  +    }
  +
  +    #   make sure only schemes curl(1) supports are used.
  +    if ($src !~ m;^(file|http|ftp)://.+;) {
  +        return "invalid URL - only file, http and ftp schemes supported";
  +    }
  +
  +    my $rc;
  +    {
  +        my $hpxy = $RC->{"_httpproxy"};
  +        my $hprt = $RC->{"_httpport"};
  +        my $fpxy = $RC->{"_ftpproxy"};
  +        my $fprt = $RC->{"_ftpport"};
  +    
  +        $hprt = 80 unless $hprt > 0;
  +        $fprt = 21 unless $fprt > 0;
  +    
  +        if (defined $hpxy && defined $hprt) {
  +            $hpxy .= ":$hprt";
  +        }
  +        if (defined $fpxy && defined $fprt) {
  +            $fpxy .= ":$fprt";
  +        }
  +    
  +        local($ENV{'http_proxy'}) = $hpxy;
  +        local($ENV{'ftp_proxy'}) = $fpxy;
  +    
  +        #   try to fetch the URL
  +        unlink("$dst.hdr");
  +        $rc = system($curl
  +                     " --location" .
  +                     " --max-time 1800" .
  +                     " --connect-timeout 20" .
  +                     " --dump-header $dst.hdr" .
  +                     " --output '$dst' '$src'");
  +    
  +    }
  +
  +    #   check whether command failed
  +    if ($rc != 0) {
  +        return "cURL error";
  +    }
  +
  +    #   check whether remote sites failed
  +    if (-s "$dst.hdr") {
  +        open(FP, "<$dst.hdr");
  +        my $response = <FP>;
  +        close(FP);
  +        if ($response =~ m|^HTTP/[\d.]+\s+(\d+)|) {
  +            if ($1 ne 200) {
  +                $response =~ s|\n$||;
  +                unlink($dst);
  +                return $response;
  +            }
  +        }
  +    }
  +
  +    #   cleanup
  +    unlink("$dst.hdr");
  +
  +    return '';
  +}
  @@ .
  patch -p0 <<'@@ .'
  Index: openpkg-tools/cmd/makeproxy.pl
  ============================================================================
  $ cvs diff -u -r0 -r1.1 makeproxy.pl
  --- /dev/null 2004-04-09 21:44:21.000000000 +0200
  +++ makeproxy.pl      2004-04-09 21:44:21.000000000 +0200
  @@ -0,0 +1,507 @@
  +##
  +##  openpkg -- OpenPKG Tool Chain
  +##  Copyright (c) 2000-2004 The OpenPKG Project <http://www.openpkg.org/>
  +##  Copyright (c) 2000-2004 Ralf S. Engelschall <[EMAIL PROTECTED]>
  +##  Copyright (c) 2000-2004 Cable & Wireless <http://www.cw.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.
  +##
  +
  +require 5.003;
  +use strict;
  +use Getopt::Long;
  +use IO;
  +
  +my $progname = "makeproxy";
  +my $progvers = "0.9.4";
  +
  +#   parameters (defaults)
  +my $version = 0;
  +my $verbose = 0;
  +my $debug   = 0;
  +my $help    = 0;
  +my $rpm     = 'rpm';
  +my $tmpdir  = ($ENV{TMPDIR} || "/tmp") . "/$progname";
  +my $output  = '.';
  +my $input   = '-';
  +my $prefix  = '';
  +
  +#   cleanup support
  +my @cleanup = ();
  +sub cleanup_remember {
  +    my ($cmd) = @_;
  +    push(@cleanup, $cmd);
  +}
  +sub cleanup_perform {
  +    foreach my $cmd (@cleanup) {
  +        &runcmd($cmd);
  +    }
  +}
  +
  +#   exception handling support
  +$SIG{__DIE__} = sub {
  +    my ($err) = @_;
  +    $err =~ s|\s+at\s+.*||s if (not $verbose);
  +    print STDERR "$progname:ERROR: $err ". ($! ? "($!)" : "") . "\n";
  +    &cleanup_perform() if (not $verbose);
  +    exit(1);
  +};
  +
  +#   verbose message printing
  +sub verbose {
  +    my ($msg) = @_;
  +    print STDERR "$msg\n" if ($verbose);
  +}
  +
  +#   execution of external commands
  +sub runcmd {
  +    my ($cmd) = @_;
  +    print STDERR "\$ $cmd\n" if ($debug);
  +    $cmd = "($cmd) >/dev/null 2>&1" if (not $debug);
  +    return (system($cmd) == 0);
  +}
  +
  +#   expand into a full filesystem path
  +sub fullpath {
  +    my ($prog) = @_;
  +    my $fullprog = '';
  +    foreach my $path (split(/:/, $ENV{PATH})) {
  +        if (-x "$path/$prog") {
  +            $fullprog = "$path/$prog";
  +            last;
  +        }
  +    }
  +    return $fullprog;
  +}
  +
  +#   convert a subdirectory (a/b/c/)
  +#   into a corresponding reverse path (../../../)
  +sub sub2rev {
  +    my ($sub) = @_;
  +    my $rev = '';
  +    $sub =~ s|^/+||s;
  +    $sub =~ s|/+$||s;
  +    while ($sub =~ s|/[^/]+||) {
  +        $rev .= "../";
  +    }
  +    if ($sub ne '') {
  +        $rev .= "../";
  +    }
  +    $rev =~ s|/$||s;
  +    return $rev;
  +}
  +
  +#   create a directory (plus its missing parent dirs)
  +sub mkdirp {
  +    my ($dir) = @_;
  +    my $pdir = $dir;
  +    $pdir =~ s|/[^/]*$||s;
  +    if (not -d $pdir) {
  +        &mkdirp($pdir);
  +    }
  +    if (not -d $dir) {
  +        &runcmd("mkdir $dir");
  +    }
  +}
  +
  +#   command line parsing
  +Getopt::Long::Configure("bundling");
  +my $result = GetOptions(
  +    'V|version'     => \$version,
  +    'h|help'        => \$help,
  +    'd|debug'       => \$debug,
  +    'v|verbose'     => \$verbose,
  +    'r|rpm=s'       => \$rpm,
  +    't|tmpdir=s'    => \$tmpdir,
  +    'o|output=s'    => \$output,
  +    'p|prefix=s'    => \$prefix
  +) || die "option parsing failed";
  +if ($help) {
  +    print "Usage: $progname [options] [FILE]\n" .
  +          "Available options:\n" .
  +          " -h,--help          print out this usage page\n" .
  +          " -v,--verbose       enable verbose run-time mode\n" .
  +          " -r,--rpm=FILE      filesystem path to RPM program\n" .
  +          " -t,--tmpdir=PATH   filesystem path to temporary directory\n" .
  +          " -o,--output=FILE   filesystem path to output RPM file\n";
  +          " -p,--prefix=PATH   filesystem path to referenced master hierarchy\n";
  +    exit(0);
  +}
  +if ($version) {
  +    print "OpenPKG $progname $progvers\n";
  +    exit(0);
  +}
  +if ($#ARGV == 0) {
  +    $input = shift(@ARGV);
  +}
  +if ($#ARGV != -1) {
  +    die "invalid number of command line arguments";
  +}
  +
  +#   prepare temporary location
  +&verbose("++ prepare temporary directory");
  +if (not -d $tmpdir) {
  +    &runcmd("mkdir $tmpdir && chmod 0700 $tmpdir")
  +        || die "cannot create temporary directory '$tmpdir'";
  +    &cleanup_remember("rmdir $tmpdir");
  +}
  +&verbose("-- $tmpdir");
  +
  +#   determine RPM program
  +if (not -x $rpm) {
  +    $rpm = &fullpath($rpm);
  +}
  +my $rpmvers = `$rpm --version 2>/dev/null`;
  +$rpmvers =~ s|^OpenPKG\s+RPM\s+([0-9.]+)\s*$|$1|s || die "program '$rpm' seems to 
be not RPM";
  +&verbose("++ determining RPM program");
  +&verbose("-- $rpm ($rpmvers)");
  +
  +#   determine input and output RPM
  +&verbose("++ determining RPM package files");
  +&verbose("-- input/original RPM: $input");
  +&verbose("-- output/proxy RPM: $output");
  +if ($input eq '-') {
  +    $input = "$tmpdir/input.rpm";
  +    &runcmd("cat >$input");
  +}
  +if (not -f $input) {
  +    die "input RPM does not exist: '$input'";
  +}
  +
  +#   helper function for parsing the query outputs
  +sub parseresponse {
  +    my ($r, $o) = @_;
  +    $o =~ s|([SM])-([^:]+):<(.*?)>\n|&parseline($r, $1, $2, $3, '')|egs;
  +    sub parseline {
  +        my ($r, $t, $k, $v) = @_;
  +        $v =~ s|^\s+||s;
  +        $v =~ s|\s+$||s;
  +        if ($t eq 'S') {     # single-value results
  +            $r->{$k} = $v;
  +        }
  +        elsif ($t eq 'M') {  # multi-value results
  +            $r->{$k} = [] if (not defined($r->{$k}));
  +            push(@{$r->{$k}}, $v);
  +        }
  +    }
  +    return $r;
  +}
  +
  +#   query input RPM package
  +&verbose("++ query information from input RPM");
  +my $q = '';
  +foreach my $t (qw(
  +    NAME SUMMARY URL VENDOR PACKAGER DISTRIBUTION GROUP LICENSE VERSION RELEASE
  +    DESCRIPTION
  +)) {
  +    $q .= "S-$t:<%{$t}>\n";
  +}
  +$q .= "[M-PREREQ:<%{REQUIRENAME} %|REQUIREFLAGS?{%{REQUIREFLAGS:depflags} 
%{REQUIREVERSION}}:{}|>\n]";
  +$q .= "[M-PREFIXES:<%{PREFIXES}>\n]";
  +my $o = `$rpm -qp --qf "$q" $input`;
  +$o =~ s|M-PREREQ:<rpmlib\(.*?\).*?>\n||gs;
  +my $r = {};
  +$r = &parseresponse($r, $o);
  +my $BD = '';
  +my $ID = '';
  +foreach my $d (@{$r->{PREREQ}}) {
  +    if ($d =~ m|^OpenPKG|i) {
  +        $BD .= ", " if ($BD ne '');
  +        $BD .= $d;
  +    }
  +    $ID .= ", " if ($ID ne '');
  +    $ID .= $d;
  +}
  +my $rprefix = ${$r->{PREFIXES}}[0];
  +$rprefix =~ s|/+$||s;
  +&verbose("-- remote OpenPKG prefix: $rprefix");
  +&verbose("++ query information from target OpenPKG");
  +$q = '';
  +foreach my $t (qw(
  +    l_prefix
  +)) {
  +    $q .= "S-$t:<%{$t}>\n";
  +}
  +$o = `$rpm --eval "$q"`;
  +$r = &parseresponse($r, $o);
  +my $lprefix = $r->{l_prefix};
  +$lprefix =~ s|/+$||s;
  +&verbose("-- local OpenPKG prefix: $lprefix");
  +
  +#   prepare build environment
  +&verbose("++ establishing temporary RPM environment");
  +&runcmd("rm -rf $tmpdir/src; mkdir $tmpdir/src");
  +&runcmd("rm -rf $tmpdir/tmp; mkdir $tmpdir/tmp");
  +&runcmd("rm -rf $tmpdir/bld; mkdir $tmpdir/bld");
  +&runcmd("rm -rf $tmpdir/pkg; mkdir $tmpdir/pkg");
  +&cleanup_remember("rm -rf $tmpdir/src");
  +&cleanup_remember("rm -rf $tmpdir/tmp");
  +&cleanup_remember("rm -rf $tmpdir/bld");
  +&cleanup_remember("rm -rf $tmpdir/pkg");
  +my $macro = new IO::File (">$tmpdir/.rpmmacros");
  +$macro->print("%_sourcedir $tmpdir/src\n" .
  +              "%_specdir   $tmpdir/src\n" .
  +              "%_builddir  $tmpdir/tmp\n" .
  +              "%_tmppath   $tmpdir/tmp\n" .
  +              "%_rpmdir    $tmpdir/pkg\n" .
  +              "%_srcrpmdir $tmpdir/pkg\n");
  +$macro->close;
  +$ENV{HOME} = $tmpdir;
  +&verbose("-- temporary sourcedir/specdir: $tmpdir/src");
  +&verbose("-- temporary builddir/tmppath:  $tmpdir/tmp");
  +&verbose("-- temporary rpmdir/srcrpmdir:  $tmpdir/pkg");
  +
  +#   generate .spec file for proxy RPM package
  +&verbose("++ generating RPM specification for proxy RPM");
  +my $S = '';
  +$S .= "Name:         ".$r->{NAME}."\n";
  +$S .= "Summary:      ".$r->{SUMMARY}."\n";
  +$S .= "URL:          ".$r->{URL}."\n";
  +$S .= "Vendor:       ".$r->{VENDOR}."\n";
  +$S .= "Packager:     ".$r->{PACKAGER}."\n";
  +$S .= "Distribution: ".$r->{DISTRIBUTION}."\n";
  +$S .= "Group:        ".$r->{GROUP}."\n";
  +$S .= "License:      ".$r->{LICENSE}."\n";
  +$S .= "Version:      ".$r->{VERSION}."\n";
  +$S .= "Release:      ".$r->{RELEASE}."+PROXY\n";
  +$S .= "\n";
  +$S .= "Prefix:       %{l_prefix}\n";
  +$S .= "BuildRoot:    $tmpdir/bld\n";
  +$S .= "BuildPreReq:  $BD\n";
  +$S .= "PreReq:       $ID\n";
  +$S .= "AutoReq:      no\n";
  +$S .= "AutoReqProv:  no\n";
  +#$S .= "Provides:     ".$r->{NAME}.", 
".$r->{NAME}."-".$r->{VERSION}."-".$r->{RELEASE}."\n";
  +$S .= "\n";
  +$S .= "%description\n";
  +$S .= "    ".$r->{DESCRIPTION}."\n";
  +$S .= "\n";
  +$S .= "%install\n";
  +$S .= "    %{l_rpmtool} files -v -ofiles -r\$RPM_BUILD_ROOT %{l_files_std}\n";
  +$S .= "\n";
  +$S .= "%files -f files\n";
  +$S .= "\n";
  +my $spec = new IO::File (">$tmpdir/src/".$r->{NAME}.".spec");
  +$spec->print($S);
  +$spec->close;
  +&verbose("-- $tmpdir/src/".$r->{NAME}.".spec");
  +
  +#   creating shadow tree of original contents
  +&verbose("++ creating shadow tree from original contents");
  +my @FL = `$rpm -qp --qf '[%{FILEMODES:perms} %{FILENAMES}\n]' $input`;
  +my $FD = [];
  +my $FR = [];
  +foreach my $fl (@FL) {
  +    $fl =~ s|\n$||s;
  +    if ($fl =~ m|^(d\S+)\s+$rprefix(.*)$|) {
  +        &mkdirp("$tmpdir/bld$lprefix$2");
  +        &verbose("-- | PHYS $1 $lprefix$2");
  +    }
  +    elsif ($fl =~ m|^(\S+)\s+$rprefix(.*?)([^/\s]+)$|) {
  +        my ($subdir, $file) = ($2, $3);
  +        my $target = sub2rev($subdir)."/.prefix-".$r->{NAME}.$subdir.$file;
  +        &mkdirp("$tmpdir/bld$lprefix$subdir");
  +        &runcmd("ln -s $target $tmpdir/bld$lprefix$subdir$file");
  +        &verbose("-- | VIRT $1 $lprefix$subdir$file");
  +    }
  +}
  +
  +#   create master-reference symbolic link
  +my $xprefix = $rprefix;
  +$xprefix = $prefix if ($prefix ne '');
  +&runcmd("ln -s $xprefix $tmpdir/bld$lprefix/.prefix-".$r->{NAME});
  +
  +#   rolling output proxy RPM package
  +&verbose("++ rolling output proxy RPM package");
  +&runcmd("cd $tmpdir/src && $rpm -bb --nodeps ".$r->{NAME}.".spec");
  +
  +#   providing output
  +&verbose("++ providing output");
  +if ($output eq '-') {
  +    &runcmd("cat $tmpdir/pkg/*.rpm");
  +}
  +else {
  +    &runcmd("cp $tmpdir/pkg/*.rpm $output");
  +}
  +
  +#   die gracefully...
  +&verbose("++ cleaning up environment");
  +&cleanup_perform();
  +exit(0);
  +
  +__END__
  +
  +=pod
  +
  +=head1 NAME
  +
  +B<mkproxyrpm> -- Make OpenPKG Proxy RPM Package
  +
  +=head1 SYNOPSIS
  +
  +B<mkproxyrpm>
  +[B<--verbose>]
  +[B<--debug>]
  +[B<--help>]
  +[B<--rpm>=I<FILE>]
  +[B<--tmpdir>=I<DIR>]
  +[B<--output>=I<DIR>|I<FILE>|C<->]
  +[B<--prefix>=I<RPREFIX>]
  +[I<FILE>|C<->]
  +
  +=head1 DESCRIPTION
  +
  +B<mkproxyrpm> creates an B<OpenPKG> proxy package by translating a
  +binary RPM file into a proxy binary RPM file. A proxy package contains
  +(virtually) the same contents as the original package in the form
  +of a shadow tree. Such a shadow tree consists of the same physical
  +directories as the original tree but with all other files replaced by
  +symbolic links pointing to the original files in the remote B<OpenPKG>
  +instance.
  +
  +A proxy package is useful if multiple B<OpenPKG> instances are installed on
  +the same system. In this case lots of dependent (and this way required,
  +although not explicitly wanted) packages have to be installed in every
  +instance. Think about packages like B<openssl>, B<perl>, B<gcc>, etc. This can
  +be both very time-consuming and can become a maintainance nightmare.
  +Instead, you can select a master (or remote) B<OpenPKG> instance,
  +install those packages physically there only and install a simple proxy
  +packages for them in all other (local) B<OpenPKG> instances.
  +
  +Keep in mind that this obviously works correctly for packages which do not
  +have hard-coded dependencies to their B<OpenPKG> instance (like configuration
  +files, etc.). For other packages it might also work, but be at least warned
  +about side-effects. Additionally, make sure you always keep (local) proxy
  +packages in sync with the (remote) master package.
  +
  +=head1 SHADOW TREE
  +
  +The symbolic links in the shadow tree of the proxy package B<foo> are of
  +the form:
  +
  +I<lprefix>[/I<dir>]/I<file> -> I<revdir>C</.prefix->B<foo>[/I<dir>]/I<file>
  +
  +And to make them working, there is the following additional symbolic
  +link installed:
  +
  +I<lprefix>C</.prefix->B<foo> -> I<rprefix>
  +
  +Here I<lprefix> is the prefix of the local B<OpenPKG> instance and
  +I<rprefix> is the prefix of the remote B<OpenPKG> instance. This allows
  +one to redirect a whole package to a different B<OpenPKG> instance by
  +just changing the I<lprefix>C</.prefix->B<foo> symbolic link. The idea
  +is that later this link even could be automatically controlled by a
  +higher-level facility. The I<rprefix> target of the symbolic link can be
  +overridden at build-time with the B<--prefix>=I<RPREFIX> option.
  +
  +=head1 OPTIONS
  +
  +The following command line options and arguments are supported:
  +
  +=over 4
  +
  +=item B<--verbose>
  +
  +Enable verbose messages on F<stderr> summarizing the internal processing.
  +
  +=item B<--debug>
  +
  +Enable debugging messages on F<stderr> showing the executed shell commands.
  +
  +=item B<--help>
  +
  +Print the usage message and immediately exit.
  +
  +=item B<--rpm>=I<FILE>
  +
  +Set a particular B<RPM> program to use. The default is the program
  +"C<rpm>" in C<$PATH>. This has to be the C<rpm> of the target B<OpenPKG>
  +instance where the proxy package will be installed later.
  +
  +=item B<--tmpdir>=I<DIR>
  +
  +Set a particular temporary directory. The default is determined from
  +C<$TMPDIR>, or C</tmp> (in that order).
  +
  +=item B<--output>=I<DIR>|I<FILE>|C<->
  +
  +Set the location where to write the output
  +proxy RPM package. If the input RPM is named
  +"I<name>C<->I<version>C<->I<release>C<.>I<arch>C<->I<os>C<->I<id1>C<.rpm
  +>" the output RPM is named
  +"I<name>C<->I<version>C<->I<release>C<+PROXY>C<.>I<arch>C<->I<os>C<->I<i
  +d2>C<.rpm>" (I<id1> is the identification of the master B<OpenPKG>
  +instance, I<id2> is the identification of the B<OpenPKG> instance for
  +which the proxy package is built). The special argument "C<->" indicates
  +that the output RPM is written to F<stdout>. The default is "C<.>" (the
  +current working directory).
  +
  +=item I<FILE>|C<->
  +
  +Set the location where to read the input RPM package. The special
  +argument "C<->" indicates that the input RPM is read from F<stdin> (the
  +default).
  +
  +=back
  +
  +=head1 EXAMPLE
  +
  +Assume you have three B<OpenPKG> instances on a system: C</usr/opkg>
  +(the master instance), C</e/foo/sw> (a project instance), and C</e/bar/sw>
  +(another project instance). Now let us install the C<bash> package in
  +all three locations, but only once physically.
  +
  + # build and install binary RPM for /usr/opkg instance
  + $ /usr/opkg/bin/rpm --rebuild \
  +   ftp://ftp.openpkg.org/release/1.0/SRC/bash-2.05a-1.0.0.src.rpm
  + $ /usr/opkg/bin/rpm -Uvh \
  +   /usr/opkg/RPM/PKG/bash-2.05a-1.0.0.*.rpm
  +
  + # build and install proxy RPM for /e/foo/sw instance
  + $ mkproxyrpm --rpm=/e/foo/sw/bin/rpm --output=/e/foo/RPM/PKG/ \
  +   /usr/opkg/RPM/PKG/bash-2.05a-1.0.0.*.rpm
  + $ /e/foo/sw/bin/rpm -Uvh \
  +   /e/foo/RPM/PKG/bash-2.05a-1.0.0+PROXY.*.rpm
  +
  + # build and install proxy RPM for /e/bar/sw instance
  + $ mkproxyrpm --rpm=/e/bar/sw/bin/rpm --output=/e/bar/RPM/PKG/ \
  +   /usr/opkg/RPM/PKG/bash-2.05a-1.0.0.*.rpm
  + $ /e/bar/sw/bin/rpm -Uvh \
  +   /e/bar/RPM/PKG/bash-2.05a-1.0.0+PROXY.*.rpm
  +
  +=head1 SEE ALSO
  +
  +B<OpenPKG> http://www.openpkg.org/,
  +rpm(3), ln(1).
  +
  +=head1 HISTORY
  +
  +B<mkproxyrpm> was developed in February 2002 by Ralf S.
  +Engelschall E<lt>[EMAIL PROTECTED]<gt> for the B<OpenPKG>
  +project after an idea for virtual packages by Thomas Lotterer
  +E<lt>[EMAIL PROTECTED]<gt>.
  +
  +=head1 AUTHOR
  +
  + Ralf S. Engelschall
  + [EMAIL PROTECTED]
  + www.engelschall.com
  +
  +=cut
  +
  @@ .
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     [EMAIL PROTECTED]

Reply via email to