Ver código fonte

- fix packaging list because of new <prefix>/include/rpm - add mkproxyrpm.pk stuff as "rpm --makeproxy" for building proxy packages

Ralf S. Engelschall 24 anos atrás
pai
commit
78ebf152a7
4 arquivos alterados com 557 adições e 3 exclusões
  1. 496 0
      openpkg/mkproxyrpm.pl
  2. 8 2
      openpkg/openpkg.spec
  3. 26 0
      openpkg/rpmpopt
  4. 27 1
      openpkg/rpmx.pl

+ 496 - 0
openpkg/mkproxyrpm.pl

@@ -0,0 +1,496 @@
+#!/bin/sh -- # -*- perl -*-
+eval 'exec perl -S $0 ${1+"$@"}'
+    if $running_under_some_shell;
+##
+##  mkproxyrpm -- Make OpenPKG Proxy RPM Package
+##  Copyright (c) 2002 The OpenPKG Project <http://www.openpkg.org/>
+##  Copyright (c) 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.
+##
+
+require 5.003;
+use strict;
+use Getopt::Long;
+use IO;
+
+my $progname = "mkproxyrpm";
+my $progvers = "0.9.1";
+
+#   parameters (defaults)
+my $version = 0;
+my $verbose = 0;
+my $debug   = 0;
+my $help    = 0;
+my $rpm     = 'rpm';
+my $tmpdir  = ($ENV{TMPDIR} || $ENV{TEMPDIR} || "/tmp") . "/$progname";
+my $output  = '.';
+my $input   = '-';
+
+#   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
+) || 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";
+    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("rm -rf $tmpdir");
+}
+&verbose("-- $tmpdir"); 
+
+#   determine RPM program
+if (not -x $rpm) {
+    $rpm = &fullpath($rpm);
+}
+my $rpmvers = `$rpm --version 2>/dev/null`; 
+$rpmvers =~ s|^RPM version\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("mkdir $tmpdir/src");
+&runcmd("mkdir $tmpdir/tmp");
+&runcmd("mkdir $tmpdir/bld");
+&runcmd("mkdir $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");
+    }
+}
+&runcmd("ln -s $rprefix $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<->]
+[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.
+
+=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>, C<$TEMPDIR> 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>rse@engelschall.comE<gt> for the B<OpenPKG>
+project after an idea for virtual packages by Thomas Lotterer
+E<lt>thomas.lotterer@cw.comE<gt>.
+
+=head1 AUTHOR
+
+ Ralf S. Engelschall
+ rse@engelschall.com
+ www.engelschall.com
+
+=cut
+

+ 8 - 2
openpkg/openpkg.spec

@@ -39,8 +39,8 @@
 #   o any cc(1)
 
 #   the package version and release
-%define       V_openpkg 20020403
-%define       R_openpkg 20020403
+%define       V_openpkg 20020404
+%define       R_openpkg 20020404
 
 #   the used software versions
 %define       V_rpm     4.0.2
@@ -110,6 +110,7 @@ Source39:     db-%{V_db}.patch
 Source40:     rc.conf
 Source41:     aux.prereq.sh
 Source42:     aux.usrgrp.sh
+Source43:     mkproxyrpm.pl
 
 #   build information
 Prefix:       %{l_prefix}
@@ -557,6 +558,9 @@ Provides:     OpenPKG
     sed -e "s;@l_prefix@;%{l_prefix};g" \
         <`SOURCE rpmx.pl` >$RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/rpmx.pl
     chmod a+x $RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/rpmx.pl
+    sed -e "s;@l_prefix@;%{l_prefix};g" \
+        <`SOURCE mkproxyrpm.pl` >$RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/mkproxyrpm.pl
+    chmod a+x $RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/mkproxyrpm.pl
   
     #   install an own copy of shtool
     cp $shtool $RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/shtool
@@ -656,6 +660,7 @@ Provides:     OpenPKG
     %{l_prefix}/etc/openpkg/openpkg.pgp
     %dir %{l_prefix}/include
     %{l_prefix}/include/popt.h
+    %dir %{l_prefix}/include/rpm
     %{l_prefix}/include/rpm/header.h
     %{l_prefix}/include/rpm/misc.h
     %{l_prefix}/include/rpm/rpmbuild.h
@@ -688,6 +693,7 @@ Provides:     OpenPKG
     %{l_prefix}/lib/openpkg/rpmv
     %{l_prefix}/lib/openpkg/rpmx.sh
     %{l_prefix}/lib/openpkg/rpmx.pl
+    %{l_prefix}/lib/openpkg/mkproxyrpm.pl
     %{l_prefix}/lib/openpkg/curl
     %{l_prefix}/lib/openpkg/gzip
     %{l_prefix}/lib/openpkg/bzip2

+ 26 - 0
openpkg/rpmpopt

@@ -0,0 +1,26 @@
+
+#   link extension into "rpm" command line
+rpm     alias -r           --repo
+rpm     alias -s           --smart
+rpm     exec  --stowaway   rpmx.sh --stowaway
+rpm     exec  --makeindex  rpmx.sh --makeindex
+rpm     exec  --makeproxy  rpmx.sh --makeproxy
+rpm     exec  --update     rpmx.sh --update
+rpm     exec  --fetch      rpmx.sh --fetch
+rpm     exec  --repo       rpmx.sh --repo
+rpm     exec  --smart      rpmx.sh --smart
+
+#   override -i/--info display
+rpmq alias --info --qf '\
+Name:    %-27{NAME} Source RPM:   %{SOURCERPM}\n\
+Version: %-27{VERSION} Packager:     %{PACKAGER}\n\
+Release: %-27{RELEASE} Build Host:   %{BUILDHOST}\n\
+Group:   %-27{GROUP} Build System: %{ARCH}-%{OS}\n\
+Distrib: %-27{DISTRIBUTION} Build Time:   %{BUILDTIME:date}\n\
+License: %-27{LICENSE} Relocations:  %|PREFIXES?{[%{PREFIXES}]}:{(not relocateable)}|\n\
+Vendor:  %-27{VENDOR} Install Size: %{SIZE} bytes\n\
+URL:     %-27{URL} Install Time: %|INSTALLTIME?{%{INSTALLTIME:date}}:{(not installed)}|\n\
+Summary: %{SUMMARY}\n\
+Description:\n%{DESCRIPTION}\n\
+'
+

+ 27 - 1
openpkg/rpmx.pl

@@ -14,6 +14,9 @@
 ##  update the package sources by downloading missing files
 ##  $ rpm --fetch <spec-file>
 ##
+##  make a proxy package
+##  $ rpm --makeproxy <binary-rpm>
+##
 ##  query repository information
 ##  $ rpm -rqa
 ##  $ rpm -rqai
@@ -93,7 +96,7 @@ my $isopt = 1;
 my $optname = '';
 my $arg;
 foreach $arg (@ARGV) {
-    if ($arg =~ m/^--(stowaway|makeindex|update|fetch|repo|smart)$/) {
+    if ($arg =~ m/^--(stowaway|makeindex|update|fetch|makeproxy|repo|smart)$/) {
         $op = $1;
         next;
     }
@@ -135,6 +138,9 @@ else {
     elsif ($op eq 'fetch') {
         $rc = &op_fetch($CFG);
     }
+    elsif ($op eq 'makeproxy') {
+        $rc = &op_makeproxy($CFG);
+    }
     elsif ($op eq 'repo') {
         $rc = &op_repo($CFG);
     }
@@ -563,6 +569,26 @@ sub op_fetch {
     return 0;
 }
 
+##  ______________________________________________________________________
+##
+##  Make Proxy Operation
+##  ______________________________________________________________________
+##
+
+sub op_makeproxy {
+    my ($CFG) = @_;
+
+    if ($#{$CFG->{ARG}} ne 0) {
+        print STDERR "rpm: option --makeproxy requires at least one argument\n";
+        return 1;
+    }
+    my $perl    = $^X;
+    my $prefix  = $CFG->{RC}->{"l_prefix"};
+    my $rpm     = $CFG->{PRG}->{"rpm"};
+    my $tmpdir  = $CFG->{RC}->{"_tmppath"};
+    exec $perl, "$prefix/lib/openpkg/mkproxyrpm.pl", "--rpm=$rpm", "--tmpdir=$tmpdir", @{$CFG->{ARG}};
+}
+
 ##  ______________________________________________________________________
 ##
 ##  Smart Operations