OpenPKG CVS Repository
http://cvs.openpkg.org/
____________________________________________________________________________
Server: cvs.openpkg.org Name: Michael van Elst
Root: /e/openpkg/cvs Email: [EMAIL PROTECTED]
Module: openpkg-re Date: 25-Nov-2002 14:25:45
Branch: HEAD Handle: 2002112513254400
Modified files:
openpkg-re openpkg-index
Log:
now supports indexing of RPM files
Summary:
Revision Changes Path
1.14 +254 -32 openpkg-re/openpkg-index
____________________________________________________________________________
Index: openpkg-re/openpkg-index
============================================================
$ cvs diff -u -r1.13 -r1.14 openpkg-index
--- openpkg-re/openpkg-index 19 Nov 2002 22:35:27 -0000 1.13
+++ openpkg-re/openpkg-index 25 Nov 2002 13:25:44 -0000 1.14
@@ -27,14 +27,35 @@
use strict;
+use Getopt::Std;
+getopts('r:p:o:i');
+use vars qw/$opt_r $opt_p $opt_o $opt_i/;
+
+use FileHandle;
use DirHandle;
+my $RPM = 'rpm';
+my $R2C = 'rpm2cpio';
+
+#########################################################################
+
#
# escape XML special characters for output in RDF file
#
+# remove trailing whitespace
+# remove common leading whitespace
+#
sub e ($) {
my($s) = @_;
+ my($i);
+ $i = undef;
+ while ($s =~ /^(\s+)/g) {
+ $i = $1 if !defined $i || length($1) < length($i);
+ }
+
+ $s =~ s/^$i//mg;
+ $s =~ s/\s+$//mg;
$s =~ s/&/&/sg;
$s =~ s/</</sg;
$s =~ s/>/>/sg;
@@ -285,7 +306,7 @@
$o = find_options($map{'description'});
$a = package2data($map{'*'}, $o);
if (exists $map{'description'}) {
- $a->{'Description'} = $map{'description'};
+ $a->{'Description'} = { '' => [ $map{'description'} ] };
}
return $a;
@@ -334,10 +355,12 @@
$tag = $k unless defined $tag;
$i = ' ' x $i;
- $out = e($a->{$k});
- $out .= "\n" unless $out =~ /\n$/s;
+ $out = e(n($a,$k));
+ $out =~ s/\n+$//s;
- return "$i<$tag>\n$out$i</$tag>\n";
+ return if $out eq '';
+
+ return "$i<$tag>\n$out\n$i</$tag>\n";
}
#
@@ -403,18 +426,18 @@
#
sub xml_record ($$$) {
my($fh, $a, $href) = @_;
- my($maj,$min,$rel,$srcrpm);
+ my($maj,$min,$rel,$about);
- $srcrpm =
+ $about =
n($a,'Name').'-'.
n($a,'Version').'-'.
- n($a,'Release').'.src.rpm';
+ n($a,'Release');
unless (defined $href) {
# guess location from Information in Specfile
- $href = $srcrpm;
+ $href = "$about.src.rpm";
($maj,$min,$rel) = n($a,'Release') =~ /^(\d+)\.(\d+)\.(\d+)/;
if (defined $min) {
@@ -437,7 +460,7 @@
}
print $fh <<EOFEOF;
- <rdf:Description about="$srcrpm" href="$href">
+ <rdf:Description about="$about" href="$href">
EOFEOF
# fake Source attribute from Source\d attribtutes
@@ -462,6 +485,7 @@
/^Source\d*$/
} keys %$a
]};
+ delete $a->{'Source'} unless @{$a->{'Source'}->{''}};
print $fh
xml_tag(6, $a, 'Name'),
@@ -474,11 +498,23 @@
xml_tag(6, $a, 'Summary'),
xml_tag(6, $a, 'URL'),
xml_tag(6, $a, 'Vendor'),
+ xml_tag(6, $a, 'SourceRPM'),
+ xml_tag(6, $a, 'Arch'),
+ xml_tag(6, $a, 'Os'),
+ xml_tag(6, $a, 'BuildRoot'),
+ xml_tag(6, $a, 'BuildHost'),
+ xml_tag(6, $a, 'BuildSystem'),
+ xml_tag(6, $a, 'BuildTime'),
+ xml_tag(6, $a, 'Relocations'),
+ xml_tag(6, $a, 'Size'),
+ xml_tag(6, $a, 'Prefixes'),
+ xml_tag(6, $a, 'Platform'),
xml_bag(6, $a, 'BuildPreReq'),
xml_bag(6, $a, 'PreReq'),
xml_bag(6, $a, 'Provides'),
xml_bag(6, $a, 'Conflicts'),
xml_bag(6, $a, 'Source'),
+ xml_bag(6, $a, 'Filenames'),
xml_text(6, $a, 'Description');
print $fh <<EOFEOF;
@@ -488,38 +524,224 @@
#####################################################################
-my($prefix,$release,$dh,$d,$s,$a,$specpath);
+sub rpm2spec ($) {
+ my($fn) = @_;
+ my($pipe) = new FileHandle("$R2C '$fn' |")
+ or die "FATAL: cannot read '$fn' ($!)\n";
+ my($buf,@hdr,$n,$m,$name,$step);
+ my($spec);
+
+ while (read($pipe,$buf,110) == 110) {
+ @hdr = unpack('a6a8a8a8a8a8a8a8a8a8a8a8a8a8',$buf);
+ $n = hex($hdr[12]); # filename length
+ $m = int(($n+5)/4)*4-2; # filename size (padded)
+ last unless read($pipe,$buf,$m) == $m;
+ $name = substr($buf,0,$n-1);
+ $n = hex($hdr[7]); # file length
+ $m = int(($n+3)/4)*4; # file size (padded)
+ if ($name !~ /.spec$/) {
+ while ($m > 0) {
+ $step = $m > 8192 ? 8192 : $m;
+ last unless read($pipe,$buf,$step);
+ $m -= length($buf);
+ }
+ } else {
+ if (read($pipe,$buf,$n) == $n) {
+ $spec = $buf;
+ }
+ last;
+ }
+ }
+ $pipe->close;
-if ($#ARGV < 0) {
- print "usage: $0 [openpkg-src [release]]\n";
- die "\n";
+ return $spec;
}
-$prefix = $ARGV[0];
-die "FATAL: '$prefix' is not a directory\n" unless -d $prefix;
+#####################################################################
-if (defined $ARGV[1]) {
- $release = $ARGV[1];
-} else {
- ($release) = $prefix =~ /.*(\d+\.\d+)/;
+sub rpm2data ($$) {
+ my($fn,$platform) = @_;
+ my($q,$pipe,%a);
+ my($t,$v);
+
+ $q = <<EOFEOF;
+Name %{Name}
+Version %{Version}
+Release %{Release}
+URL %{URL}
+Summary %{Summary}
+Copyright %{Copyright}
+License %{License}
+Distribution %{Distribution}
+Vendor %{Vendor}
+Group %{Group}
+Packager %{Packager}
+Prefixes %{Prefixes}
+BuildRoot %{BuildRoot}
+BuildHost %{BuildHost}
+BuildTime %{BuildTime}
+Arch %{Arch}
+Os %{Os}
+Size %{Size}
+SigSize %{SigSize}
+SigMD5 %{SigMD5}
+SigPGP %{SigPGP}
+SigGPG %{SigGPG}
+SourceRPM %{SourceRPM}
+[Patch %{Patch}
+]
+[Source %{Source}
+]
+[Filenames %{Filenames}
+]
+[Conflicts %{CONFLICTNAME} %|CONFLICTFLAGS?{%{CONFLICTFLAGS:depflags}
%{CONFLICTVERSION}}:{}|
+]
+[PreReq %{REQUIRENAME} %|REQUIREFLAGS?{%{REQUIREFLAGS:depflags}
%{REQUIREVERSION}}:{}|
+]
+[Provides %{PROVIDENAME} %|PROVIDEFLAGS?{%{PROVIDEFLAGS:depflags}
%{PROVIDEVERSION}}:{}|
+]
+Description %{Description}
+EOFEOF
+
+ $pipe = new FileHandle("$RPM -qp --qf '$q' '$fn' |")
+ or die "FATAL: cannot read '$fn' ($!)\n";
+ while (<$pipe>) {
+ if (/^(\S+)\s+(.*?)\s*$/) {
+ $t = $1;
+ $v = $2;
+ } elsif (/^(\s+.+?)\s*$/) {
+ next unless defined $t;
+ $v = $1;
+ } else {
+ $t = undef;
+ next;
+ }
+
+ if (exists $a{$t}) {
+ $a{$t} .= "\n$v";
+ } else {
+ $a{$t} = $v;
+ }
+ }
+ $pipe->close;
+
+ %a = map { $_ => $a{$_} }
+ grep { $a{$_} ne '(none)' }
+ keys %a;
+ if ($a{'Relocations'} eq '(non relocatable)') {
+ delete $a{'Relocations'}
+ }
+ $a{'Platform'} = "$a{'Arch'}-$platform-$a{'Os'}";
+ $a{'PreReq'} =~ s/^rpmlib\(.*$//mg;
+ $a{'Description'} = [ $a{'Description'} ];
+
+ return { map {
+ $_ => { '' => (ref $a{$_} ? $a{$_} : [ split(/\n+/, $a{$_}) ]) }
+ } keys %a };
}
-$release = 'CURRENT' if $release eq '';
-$dh = new DirHandle($prefix)
- or die $!;
+#####################################################################
+
+sub list_specdir ($) {
+ my($dir) = @_;
+ my($dh,$d,$path);
+ my(@list);
+
+ $dh = new DirHandle($dir);
+ while ($d = $dh->read) {
+ next if $d =~ /^\.$/;
+ $path = "$dir/$d/$d.spec";
+ push @list, $path if -f $path;
+ }
-xml_head(\*STDOUT, $release);
-while ($d = $dh->read) {
- next if $d =~ /^\./;
- $specpath = "$prefix/$d/$d.spec";
- if (-f $specpath) {
- $s = `cat $specpath`;
- if ($a = spec2data($s)) {
- xml_record(\*STDOUT, $a, undef);
+ return \@list;
+}
+
+sub list_rpmdir ($) {
+ my($dir) = @_;
+ my($dh,$d,$path);
+ my(@list);
+
+ $dh = new DirHandle($dir);
+ while ($d = $dh->read) {
+ next if $d =~ /^\.$/ || $d !~ /\.rpm$/;
+ $path = "$dir/$d";
+ push @list, $path if -f $path;
+ }
+
+ return \@list;
+}
+
+sub readfile ($) {
+ my($fn) = @_;
+ my($fh) = new FileHandle $fn,'r'
+ or die "FATAL: cannot read '$fn' ($!)\n";
+ my(@l) = <$fh>;
+ $fh->close;
+ return join('',@l);
+}
+
+#####################################################################
+
+sub write_index ($$$$) {
+ my($fh,$release,$platform,$list) = @_;
+ my($a,$h,$s);
+
+ foreach (@$list) {
+ $a = undef;
+ $h = undef;
+ if (/\.spec$/) {
+ $s = readfile($_);
+ $a = spec2data($s);
+ } elsif (/([^\/]+\.src\.rpm)$/) {
+ $h = $1;
+ $s = rpm2spec($_);
+ $a = spec2data($s);
+ } elsif (/([^\/]+\.rpm)$/) {
+ $h = $1;
+ $a = rpm2data($_, $platform);
+ }
+ if ($a) {
+ xml_record($fh, $a, $h);
} else {
- die "ERROR: cannot parse $specpath\n";
+ warn "ERROR: cannot process $_\n";
}
}
}
-xml_foot(\*STDOUT);
+
+#####################################################################
+
+my($prefix,$list,$fh);
+
+if ($#ARGV < 0) {
+ print "usage: $0 [-r release] [-p platform] [-o index.rdf] [-i] dir ...\n";
+ die "\n";
+}
+
+$opt_r = 'CURRENT' unless defined $opt_r;
+$opt_p = 'unknown' unless defined $opt_p;
+
+if ($opt_r !~ /^(CURRENT|\d+\.\d+)$/) {
+ die "FATAL: you must specify a release tag (CURRENT or x.y)\n";
+}
+
+if (defined $opt_o) {
+ $fh = new FileHandle $opt_o,'w'
+ or die "FATAL: cannot write '$opt_o' ($!)\n";
+} else {
+ $fh = \*STDOUT;
+}
+
+xml_head($fh, $opt_r);
+foreach $prefix (@ARGV) {
+ die "FATAL: $prefix is not a directory\n" unless -d $prefix;
+ if ($opt_i) {
+ $list = list_rpmdir($prefix);
+ } else {
+ $list = list_specdir($prefix);
+ }
+ write_index($fh, $opt_r, $opt_p, $list);
+}
+xml_foot($fh);
+$fh->close if defined $opt_o;
______________________________________________________________________
The OpenPKG Project www.openpkg.org
CVS Repository Commit List [EMAIL PROTECTED]