7 changed files with 2932 additions and 0 deletions
@ -0,0 +1,4 @@
|
||||
|
||||
openpkg.1: openpkg.pod |
||||
pod2man --section=1 --quotes=none --release="openpkg-tool" --center="OpenPKG Maintainance" openpkg.pod >openpkg.1
|
||||
|
||||
@ -0,0 +1,866 @@
|
||||
## |
||||
## openpkg-index -- create index from spec files |
||||
## |
||||
## 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. |
||||
## |
||||
|
||||
require 5; |
||||
|
||||
use strict; |
||||
|
||||
use Getopt::Std; |
||||
getopts('r:p:C:o:ci'); |
||||
use vars qw/$opt_r $opt_p $opt_C $opt_o $opt_c $opt_i/; |
||||
|
||||
use FileHandle; |
||||
use DirHandle; |
||||
|
||||
my $RPM = 'rpm'; |
||||
my $R2C = 'rpm2cpio'; |
||||
my $BZ = 'bzip2 -9'; |
||||
|
||||
######################################################################### |
||||
|
||||
# |
||||
# escape XML special characters for output in RDF file |
||||
# |
||||
# remove trailing whitespace |
||||
# remove common leading whitespace |
||||
# |
||||
sub e ($) { |
||||
my($s) = @_; |
||||
my($i); |
||||
|
||||
$s =~ s/\n+$//sg; |
||||
$s =~ s/\s+$//mg; |
||||
|
||||
$i = undef; |
||||
while ($s =~ /^(\s+)/mg) { |
||||
$i = $1 if !defined $i || length($1) < length($i); |
||||
} |
||||
|
||||
$s =~ s/^\Q$i\E//mg if defined $i; |
||||
$s =~ s/&/&/sg; |
||||
$s =~ s/</</sg; |
||||
$s =~ s/>/>/sg; |
||||
|
||||
return $s; |
||||
} |
||||
|
||||
sub commasep ($$) { |
||||
my($k,$v) = @_; |
||||
|
||||
if ($k =~ /^(PreReq|BuildPreReq|Provides|Conflicts)$/) { |
||||
return split(/\s*,\s*/, $v); |
||||
} |
||||
|
||||
return $v; |
||||
} |
||||
|
||||
sub vsub ($$) { |
||||
my($var,$v) = @_; |
||||
|
||||
$v =~ s/\%\{([^}]+)\}/exists $var->{$1} ? $var->{$1} : '%{'.$1.'}'/emg; |
||||
|
||||
return $v; |
||||
} |
||||
|
||||
sub upn ($) { |
||||
my($t) = @_; |
||||
my(@tok) = $t =~ /(\(|\)|\&\&|\|\||\!|\S+)/g; |
||||
my(@out,$op,$o); |
||||
my(@save); |
||||
|
||||
$op = []; |
||||
foreach (@tok) { |
||||
if ($_ eq '(') { |
||||
push @save, $op; |
||||
$op = []; |
||||
} elsif ($_ eq ')') { |
||||
die "FATAL: unresolved operators in: @tok\n" if @$op; |
||||
$op = pop @save |
||||
or die "FATAL: parenthesis stack underflow in: @tok\n"; |
||||
while ($o = pop @$op) { |
||||
push @out, $o->[0]; |
||||
last if $o->[1]; |
||||
} |
||||
} elsif ($_ eq '&&') { |
||||
push @$op, [ '+', 1 ] ; |
||||
} elsif ($_ eq '||') { |
||||
push @$op, [ '|', 1 ] ; |
||||
} elsif ($_ eq '!') { |
||||
push @$op, [ '!', 0 ]; |
||||
} elsif (/^\%\{(\S*?)\}$/) { |
||||
push @out, $1; |
||||
while ($o = pop @$op) { |
||||
push @out, $o->[0]; |
||||
last if $o->[1]; # binop |
||||
} |
||||
} |
||||
} |
||||
|
||||
return join (' ',@out); |
||||
} |
||||
|
||||
# |
||||
# deduce external variables from description |
||||
# |
||||
sub find_options ($) { |
||||
my($descr) = @_; |
||||
my(%evar); |
||||
|
||||
%evar = map { |
||||
$1 => '%{'.$1.'}' |
||||
} $descr =~ /--define\s*'(\S+)\s*\%\{\1\}'/; |
||||
|
||||
return \%evar; |
||||
} |
||||
|
||||
# |
||||
# translate default section from spec-file |
||||
# into a hash |
||||
# %if/%ifdef/%define... are translated to #if/#ifdef/#define |
||||
# |
||||
# #defines are interpolated (correct ?) |
||||
# |
||||
# #if/#ifdef/... sections are stripped |
||||
# result is the same as if all conditions evaluate false (!) |
||||
# |
||||
# all attributes are of the form key: value |
||||
# repeated attributes are coalesced into a list |
||||
# |
||||
sub package2data ($$) { |
||||
my($s,$evar) = @_; |
||||
my(%var); |
||||
my(@term, $term); |
||||
my(%attr); |
||||
my($l, $v, $cond, $d, $p); |
||||
my($re,@defs); |
||||
|
||||
# combine multilines |
||||
$s =~ s/\\\n/ /sg; |
||||
|
||||
# |
||||
# map conditional variable macros |
||||
# |
||||
$s =~ s/^#\{\!\?([^:]*):\s*%(.*?)\s*\}\s*$/#ifndef $1\n#$2\n#endif/mg; |
||||
$s =~ s/^#\{\!\?([^:]*):\s*(.*?)\s*\}\s*$/#ifndef $1\n$2\n#endif/mg; |
||||
|
||||
# |
||||
# guess more external parameters by scanning for "default" sections. |
||||
# |
||||
$re = '^\#ifndef\s+[\w\_]+\s*\n((?:\#define\s+[\w\_]+\s.*\n)+)\#endif\n'; |
||||
@defs = $s =~ /$re/gm; |
||||
foreach (@defs) { |
||||
while (/^\#define\s+([\w\_]+)\s(.*?)\s*$/mg) { |
||||
$evar->{$1} = '%{'.$1.'}'; |
||||
} |
||||
} |
||||
$s =~ s/$re//gm; |
||||
|
||||
# |
||||
# add everything looking like a with_ variable |
||||
# |
||||
$re = '%{(with\_[\w\_]+)}'; |
||||
@defs = $s =~ /$re/gm; |
||||
foreach (@defs) { |
||||
$evar->{$1} = '%{'.$1.'}'; |
||||
} |
||||
|
||||
|
||||
# |
||||
# extract all conditional sections |
||||
# |
||||
@term = (); |
||||
%var = (); |
||||
$cond = ''; |
||||
foreach $l (split(/\n/, $s)) { |
||||
$v = vsub(\%var,$l); |
||||
|
||||
if (($p) = $v =~ /^\#if\s+(.*?)\s*$/) { |
||||
# |
||||
# normalize #if expressions |
||||
# "%{variable}" == "yes" |
||||
# "%{variable}" == "no" |
||||
# operators ! && || |
||||
# |
||||
$term = ''; |
||||
while ($p =~ /(!=)|(\!|\|\||\&\&|\(|\))|"\%\{([^}]+)\}"\s*==\s*"(yes|no)"|(\S+)/g) { |
||||
if (defined $1) { |
||||
warn "WARNING: unknown token '$1':\n< $l\n> $v\n"; |
||||
} elsif (defined $5) { |
||||
warn "WARNING: unknown token '$5':\n< $l\n> $v\n"; |
||||
} elsif (defined $2) { |
||||
$term .= " $2 "; |
||||
} elsif (exists $evar->{$3}) { |
||||
$term .= ($4 eq 'no' ? '! ' : '').vsub($evar,'%{'.$3.'}'); |
||||
} else { |
||||
warn "WARNING: unknown conditional '$2':\n< $l\n> $v\n"; |
||||
} |
||||
} |
||||
|
||||
# |
||||
# join with previous conditions for this #if/#endif block |
||||
# |
||||
if ($term ne '') { |
||||
push @term, "( $term )"; |
||||
$cond = join(' && ', grep { $_ ne '' } @term).''; |
||||
} else { |
||||
push @term, ''; |
||||
} |
||||
} elsif ($v =~ /^\#else\s*$/) { |
||||
# |
||||
# reverse last condition |
||||
# |
||||
if (@term) { |
||||
$term[-1] = ' ! '.$term[-1]; |
||||
$cond = join(' && ', grep { $_ ne '' } @term).''; |
||||
} else { |
||||
die "FATAL: else without if\n"; |
||||
} |
||||
} elsif ($v =~ /^\#endif\s*$/) { |
||||
# |
||||
# unwind last #if expression |
||||
# |
||||
pop @term; |
||||
$cond = join(' && ', grep { $_ ne '' } @term).''; |
||||
|
||||
} elsif ($v =~ /^\#(?:define)\s*(\S+)\s*(.*?)\s*$/) { |
||||
|
||||
# |
||||
# define conditional variables |
||||
# truth-value becomes current condition |
||||
# |
||||
# define internal variables |
||||
# -> store for subsequent substitution |
||||
# |
||||
if (exists $evar->{$1}) { |
||||
if ($2 eq 'yes') { |
||||
$evar->{$1} = "( \%\{$1\} || ( $cond ) )"; |
||||
} elsif ($2 eq 'no') { |
||||
$evar->{$1} = "( %\{$1\} && ! ( $cond ) )"; |
||||
} else { |
||||
warn "WARNING: logic too complex for '$1':\n< $l\n> $v\n"; |
||||
} |
||||
} else { |
||||
$var{$1} = $2; |
||||
} |
||||
} elsif ($v =~ /^\s*([^\#]\S*)\s*:\s*(.*?)\s*$/) { |
||||
|
||||
# |
||||
# store attribute=value for current condition |
||||
# |
||||
push @{$attr{$1}->{$cond}}, commasep($1,$2); |
||||
} |
||||
} |
||||
|
||||
return \%attr; |
||||
} |
||||
|
||||
# |
||||
# split spec file into sections starting with a %word |
||||
# |
||||
# concatenate extended lines |
||||
# strip comment lines |
||||
# map %command to #command |
||||
# split sections |
||||
# |
||||
# return package2data from default section. |
||||
# |
||||
sub spec2data ($) { |
||||
my($s) = @_; |
||||
my(%map); |
||||
my($a,$o); |
||||
|
||||
# remove comments |
||||
$s =~ s/^\s*#.*?\n//mg; |
||||
|
||||
# map commands |
||||
$s =~ s/^%(ifdef|ifndef|if|define|else|endif|\{)/#$1/mg; |
||||
|
||||
# split sections |
||||
foreach (split(/^(?=%\w+\s*\n)/m, $s)) { |
||||
if (/^%(\w+)\s*\n/) { |
||||
$map{$1} .= $'; |
||||
} else { |
||||
$map{'*'} .= $_; |
||||
} |
||||
} |
||||
|
||||
$o = find_options($map{'description'}); |
||||
$a = package2data($map{'*'}, $o); |
||||
if (exists $map{'description'}) { |
||||
$a->{'Description'} = { '' => [ $map{'description'} ] }; |
||||
} |
||||
|
||||
return $a; |
||||
} |
||||
|
||||
########################################################################## |
||||
|
||||
# |
||||
# start of XML file |
||||
# |
||||
sub xml_head ($$) { |
||||
my($fh,$res) = @_; |
||||
print $fh <<EOFEOF; |
||||
<?xml version="1.0" encoding="iso-8859-1"?> |
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
||||
xmlns="http://www.openpkg.org/xml-rdf-index/0.9"> |
||||
<Repository rdf:resource="$res"> |
||||
EOFEOF |
||||
} |
||||
|
||||
# |
||||
# end of XML file, corresponds with start tags |
||||
# |
||||
sub xml_foot ($) { |
||||
my($fh) = @_; |
||||
print $fh <<EOFEOF; |
||||
</Repository> |
||||
</rdf:RDF> |
||||
EOFEOF |
||||
} |
||||
|
||||
sub n($$) { |
||||
my($a,$k) = @_; |
||||
return unless $a->{$k}; |
||||
return unless $a->{$k}->{''}; |
||||
return $a->{$k}->{''}->[0]; |
||||
} |
||||
|
||||
# |
||||
# send out $a->{$k} as text-style tag |
||||
# |
||||
sub xml_text ($$$;$) { |
||||
my($i,$a,$k,$tag) = @_; |
||||
my($out); |
||||
return "" unless exists $a->{$k}; |
||||
$tag = $k unless defined $tag; |
||||
$i = ' ' x $i; |
||||
|
||||
$out = e(n($a,$k)); |
||||
|
||||
return if $out eq ''; |
||||
|
||||
return "$i<$tag>\n$out\n$i</$tag>\n"; |
||||
} |
||||
|
||||
# |
||||
# send out @{$a->{$k}} as body of an XML tag |
||||
# $k is the name of the tag unless overridden by $tag |
||||
# $i denotes the depth of indentation to form nicely |
||||
# looking files. |
||||
# |
||||
# all data from the list is flattened into a single |
||||
# body, separated by LF and escaped for XML metachars. |
||||
# |
||||
sub xml_tag ($$$;$) { |
||||
my($i,$a,$k,$tag) = @_; |
||||
my($out,$cond,$upn); |
||||
return "" unless exists $a->{$k}; |
||||
$tag = $k unless defined $tag; |
||||
$out = ''; |
||||
$i = ' ' x $i; |
||||
|
||||
foreach $cond (sort keys %{$a->{$k}}) { |
||||
$upn = e(upn($cond)); |
||||
$out .= $i. |
||||
($cond ne '' ? "<$tag cond=\"$upn\">" : "<$tag>"). |
||||
join("\n", map { e($_) } @{$a->{$k}->{$cond}}). |
||||
"</$tag>\n"; |
||||
} |
||||
|
||||
return $out; |
||||
} |
||||
|
||||
# |
||||
# send out @{$a->{$k}} as a rdf:bag |
||||
# $k is the name of the outer tag unless overriden by $tag |
||||
# $i denotes the depth of indentation, inner tags are indented |
||||
# 2 or 4 more character positions. |
||||
# |
||||
sub xml_bag ($$$;$) { |
||||
my($i,$a,$k,$tag) = @_; |
||||
my($out,$cond,$upn); |
||||
return "" unless exists $a->{$k}; |
||||
$tag = $k unless defined $tag; |
||||
$out = ''; |
||||
$i = ' ' x $i; |
||||
|
||||
foreach $cond (sort keys %{$a->{$k}}) { |
||||
$upn = e(upn($cond)); |
||||
$out .= $i. |
||||
($cond ne '' ? "<$tag cond=\"$upn\">\n" : "<$tag>\n"). |
||||
"$i <rdf:bag>\n". |
||||
join("", |
||||
map { "$i <rdf:li>".e($_)."</rdf:li>\n" } |
||||
@{$a->{$k}->{$cond}}). |
||||
"$i </rdf:bag>\n". |
||||
"$i</$tag>\n"; |
||||
} |
||||
|
||||
return $out; |
||||
} |
||||
|
||||
# |
||||
# send out reference to another RDF |
||||
# |
||||
sub xml_reference ($$$) { |
||||
my($fh, $res, $href) = @_; |
||||
|
||||
print $fh <<EOFEOF; |
||||
<Repository rdf:resource="$res" href="$href"/> |
||||
EOFEOF |
||||
} |
||||
|
||||
# |
||||
# translate attributes from %$a as generated by package2data |
||||
# into XML and write to file $fh |
||||
# |
||||
sub xml_record ($$$) { |
||||
my($fh, $a, $href) = @_; |
||||
my($maj,$min,$rel,$about); |
||||
|
||||
$about = |
||||
n($a,'Name').'-'. |
||||
n($a,'Version').'-'. |
||||
n($a,'Release'); |
||||
|
||||
unless (defined $href) { |
||||
|
||||
# guess location from Information in Specfile |
||||
|
||||
$href = "$about.src.rpm"; |
||||
($maj,$min,$rel) = n($a,'Release') =~ /^(\d+)\.(\d+)\.(\d+)/; |
||||
|
||||
if (defined $min) { |
||||
if ($maj > 1 || ($maj == 1 && $min > 0)) { |
||||
# 1.1 or later |
||||
if (n($a,'Distribution') =~ /\[PLUS\]/) { |
||||
$href = 'PLUS/'.$href; |
||||
} |
||||
} |
||||
if ($maj > 1 || ($maj == 1 && $min >= 0)) { |
||||
# 1.0 or later |
||||
if ($rel > 0) { |
||||
$href = 'UPD/'.$href; |
||||
} |
||||
} |
||||
} else { |
||||
# current |
||||
} |
||||
|
||||
} |
||||
|
||||
print $fh <<EOFEOF; |
||||
<rdf:Description about="$about" href="$href"> |
||||
EOFEOF |
||||
|
||||
# fake Source attribute from Source\d attribtutes |
||||
# XXX only default conditional |
||||
$a->{'Source'} = { '' => [ |
||||
map { |
||||
s/\Q%{name}\E/n($a,'Name')/esg; |
||||
s/\Q%{version}\E/n($a,'Version')/esg; |
||||
s/\Q%{release}\E/n($a,'Release')/esg; |
||||
s/.*\///; |
||||
$_; |
||||
} |
||||
map { |
||||
$a->{$_}->{''} ? @{$a->{$_}->{''}} : () |
||||
} |
||||
sort { |
||||
my($x) = $a =~ /^(\d*)$/; |
||||
my($y) = $b =~ /^(\d*)$/; |
||||
return $x <=> $y; |
||||
} |
||||
grep { |
||||
/^Source\d*$/ |
||||
} keys %$a |
||||
]}; |
||||
delete $a->{'Source'} unless @{$a->{'Source'}->{''}}; |
||||
|
||||
print $fh |
||||
xml_tag(6, $a, 'Name'), |
||||
xml_tag(6, $a, 'Version'), |
||||
xml_tag(6, $a, 'Release'), |
||||
xml_tag(6, $a, 'Distribution'), |
||||
xml_tag(6, $a, 'Group'), |
||||
xml_tag(6, $a, 'License'), |
||||
xml_tag(6, $a, 'Packager'), |
||||
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_tag(6, $a, 'SigSize'), |
||||
xml_tag(6, $a, 'SigMD5'), |
||||
xml_tag(6, $a, 'SigPGP'), |
||||
xml_tag(6, $a, 'SigGPG'), |
||||
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; |
||||
</rdf:Description> |
||||
EOFEOF |
||||
} |
||||
|
||||
##################################################################### |
||||
|
||||
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; |
||||
|
||||
return $spec; |
||||
} |
||||
|
||||
##################################################################### |
||||
|
||||
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'}; |
||||
} |
||||
if ($a{'SigMD5'} eq '(unknown type)') { |
||||
delete $a{'SigMD5'}; |
||||
} |
||||
$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 }; |
||||
} |
||||
|
||||
##################################################################### |
||||
|
||||
sub getindex ($) { |
||||
my($dir) = @_; |
||||
my(@idx) = sort { -M $a <=> -M $b; } |
||||
grep { -f $_ } |
||||
( <$dir/00INDEX.rdf>, <$dir/00INDEX.rdf.*> ); |
||||
|
||||
return unless @idx; |
||||
return $idx[0]; |
||||
} |
||||
|
||||
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; |
||||
} |
||||
|
||||
return \@list; |
||||
} |
||||
|
||||
sub list_rpmdir ($) { |
||||
my($dir) = @_; |
||||
my($dh,$d,$path); |
||||
my(@list,$idx,$sub); |
||||
|
||||
$dh = new DirHandle($dir); |
||||
while ($d = $dh->read) { |
||||
next if $d =~ /^\./; |
||||
$path = "$dir/$d"; |
||||
if (-d $path) { |
||||
$idx = getindex($path); |
||||
if (defined $idx) { |
||||
push @list, $idx; |
||||
} else { |
||||
$sub = list_rpmdir($path); |
||||
push @list, @$sub; |
||||
undef $sub; |
||||
} |
||||
} else { |
||||
next unless $d =~ /\.rpm$/ && -f $path; |
||||
push @list, $path; |
||||
} |
||||
} |
||||
|
||||
return \@list; |
||||
} |
||||
|
||||
##################################################################### |
||||
|
||||
sub readfile ($) { |
||||
my($fn) = @_; |
||||
my($fh) = new FileHandle "< $fn" |
||||
or die "FATAL: cannot read '$fn' ($!)\n"; |
||||
my(@l) = <$fh>; |
||||
$fh->close; |
||||
return join('',@l); |
||||
} |
||||
|
||||
sub relpath ($$) { |
||||
my($prefix,$path) = @_; |
||||
$path =~ s/^\Q$prefix\E\///s; |
||||
return $path; |
||||
} |
||||
|
||||
sub dirname ($) { |
||||
my($path) = @_; |
||||
$path =~ s/\/[^\/]*$//s; |
||||
return $path.'/'; |
||||
} |
||||
|
||||
sub getresource ($) { |
||||
my($fn) = @_; |
||||
my($fh, $buf); |
||||
|
||||
if ($fn =~ /\.bz2$/) { |
||||
$fh = new FileHandle "$BZ -dc $fn |" |
||||
or die "FATAL: cannot read '$fn' ($!)\n"; |
||||
} else { |
||||
$fh = new FileHandle "< $fn" |
||||
or die "FATAL: cannot read '$fn' ($!)\n"; |
||||
} |
||||
$fh->read($buf, 1024); |
||||
$fh->close; |
||||
|
||||
if ($buf =~ /<Repository.*?rdf:resource="([^"]+)"/) { |
||||
return $1; |
||||
} |
||||
|
||||
return undef; |
||||
} |
||||
|
||||
##################################################################### |
||||
|
||||
sub write_index ($$$$$$) { |
||||
my($fh,$prefix,$resource,$platform,$list,$cache) = @_; |
||||
my($a,$h,$r,$spec); |
||||
my($mtime); |
||||
|
||||
foreach (@$list) { |
||||
$a = undef; |
||||
$h = undef; |
||||
$r = undef; |
||||
if (/\.spec$/) { |
||||
$spec = readfile($_); |
||||
$a = spec2data($spec); |
||||
} elsif (/([^\/]+\.src\.rpm)$/) { |
||||
$h = relpath($prefix, $_); |
||||
if ($cache) { |
||||
$mtime = (stat $_)[9]; |
||||
if (exists $cache->{"M$_"} && |
||||
$cache->{"M$_"} == $mtime) { |
||||
$spec = $cache->{"S$_"}; |
||||
} else { |
||||
$spec = rpm2spec($_); |
||||
$cache->{"S$_"} = $spec; |
||||
$cache->{"M$_"} = $mtime; |
||||
} |
||||
} else { |
||||
$spec = rpm2spec($_); |
||||
} |
||||
$a = spec2data($spec); |
||||
} elsif (/([^\/]+\.rpm)$/) { |
||||
$h = relpath($prefix, $_); |
||||
$a = rpm2data($_, $platform); |
||||
} elsif (/([^\/]+\.rdf[^\/]*)$/) { |
||||
$h = relpath($prefix, $_); |
||||
$r = getresource($_) || $resource.dirname($h); |
||||
} |
||||
|
||||
if ($a) { |
||||
xml_record($fh, $a, $h); |
||||
} elsif ($r) { |
||||
xml_reference($fh, $r, $h); |
||||
} else { |
||||
warn "ERROR: cannot process $_\n"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
##################################################################### |
||||
|
||||
my($prefix,$list,$fh,%cache,$tmpo); |
||||
|
||||
if ($#ARGV < 0) { |
||||
print "openpkg:index:USAGE: $0 [-r resource] [-p platform] [-C cache.db] [-o index.rdf] [-c] [-i] dir ...\n"; |
||||
die "\n"; |
||||
} |
||||
|
||||
if ($opt_C) { |
||||
require DB_File; |
||||
tie %cache, 'DB_File', $opt_C, O_CREAT|O_RDWR, 0666, $DB_File::DB_HASH |
||||
or die "FATAL: cannot tie cache '$opt_C' ($!)\n"; |
||||
} |
||||
|
||||
$opt_r = 'OpenPKG-CURRENT/Source/' unless defined $opt_r; |
||||
$opt_p = 'unknown' unless defined $opt_p; |
||||
|
||||
if (defined $opt_o) { |
||||
$tmpo = $opt_o . '.tmp'; |
||||
if ($opt_c) { |
||||
$fh = new FileHandle "| $BZ -c > '$tmpo'" |
||||
or die "FATAL: cannot write '$tmpo' ($!)\n"; |
||||
} else { |
||||
$fh = new FileHandle "> $tmpo" |
||||
or die "FATAL: cannot write '$tmpo' ($!)\n"; |
||||
} |
||||
} else { |
||||
if ($opt_c) { |
||||
$fh = new FileHandle "| $BZ -c" |
||||
or die "FATAL: cannot write to stdout ($!)\n"; |
||||
} else { |
||||
$fh = new FileHandle ">&=1" |
||||
or die "FATAL: cannot write to stdout ($!)\n"; |
||||
} |
||||
} |
||||
|
||||
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, $prefix, $opt_r, $opt_p, $list, $opt_C ? \%cache : undef); |
||||
} |
||||
xml_foot($fh); |
||||
|
||||
$fh->close |
||||
or die "FATAL: write error on output ($!)\n"; |
||||
|
||||
if (defined $tmpo) { |
||||
rename $tmpo,$opt_o |
||||
or die "FATAL: cannot rename $tmpo to $opt_o ($!)\n"; |
||||
} |
||||
|
||||
@ -0,0 +1,89 @@
|
||||
## |
||||
## openpkg-tool.spec -- OpenPKG RPM Specification |
||||
## 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. |
||||
## |
||||
|
||||
# package information |
||||
Name: openpkg-tool |
||||
Summary: OpenPKG Tool |
||||
URL: http://www.openpkg.org/ |
||||
Vendor: The OpenPKG Project |
||||
Packager: The OpenPKG Project |
||||
Distribution: OpenPKG [EVAL] |
||||
Group: Bootstrapping |
||||
License: GPL |
||||
Version: 20021126 |
||||
Release: 20021126 |
||||
|
||||
# list of sources |
||||
Source0: openpkg.sh |
||||
Source1: openpkg-index.pl |
||||
Source2: openpkg-build.pl |
||||
Source3: openpkg.pod |
||||
Source4: openpkg.1 |
||||
Source5: Makefile |
||||
|
||||
# build information |
||||
Prefix: %{l_prefix} |
||||
BuildRoot: %{l_buildroot} |
||||
BuildPreReq: OpenPKG, openpkg >= 20020206 |
||||
PreReq: OpenPKG, openpkg >= 20020206 |
||||
AutoReq: no |
||||
AutoReqProv: no |
||||
|
||||
%description |
||||
The OpenPKG tool is a helper utility for managing an OpenPKG instance. |
||||
|
||||
%prep |
||||
|
||||
%build |
||||
|
||||
%install |
||||
rm -rf $RPM_BUILD_ROOT |
||||
%{l_shtool} mkdir -f -p -m 755 \ |
||||
$RPM_BUILD_ROOT%{l_prefix}/bin \ |
||||
$RPM_BUILD_ROOT%{l_prefix}/lib/openpkg \ |
||||
$RPM_BUILD_ROOT%{l_prefix}/man/man1 |
||||
%{l_shtool} install -c -m 755 \ |
||||
-e 's;@l_prefix@;%{l_prefix};g' \ |
||||
-e 's;@version@;%{version};g' \ |
||||
%{SOURCE openpkg.sh} $RPM_BUILD_ROOT%{l_prefix}/bin/openpkg |
||||
%{l_shtool} install -c -m 644 \ |
||||
-e 's;@l_prefix@;%{l_prefix};g' \ |
||||
-e 's;@version@;%{version};g' \ |
||||
%{SOURCE openpkg.1} $RPM_BUILD_ROOT%{l_prefix}/man/man1/ |
||||
%{l_shtool} install -c -m 755 \ |
||||
%{SOURCE openpkg-index.pl} \ |
||||
$RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/ |
||||
%{l_shtool} install -c -m 755 \ |
||||
%{SOURCE openpkg-build.pl} \ |
||||
$RPM_BUILD_ROOT%{l_prefix}/lib/openpkg/ |
||||
%{l_rpmtool} files -v -ofiles -r$RPM_BUILD_ROOT \ |
||||
%{l_files_std} \ |
||||
'%not %dir %{l_prefix}/lib/openpkg' |
||||
|
||||
%files -f files |
||||
|
||||
%clean |
||||
rm -rf $RPM_BUILD_ROOT |
||||
|
||||
@ -0,0 +1,327 @@
|
||||
.\" Automatically generated by Pod::Man v1.34, Pod::Parser v1.13 |
||||
.\" |
||||
.\" Standard preamble: |
||||
.\" ======================================================================== |
||||
.de Sh \" Subsection heading |
||||
.br |
||||
.if t .Sp |
||||
.ne 5 |
||||
.PP |
||||
\fB\\$1\fR |
||||
.PP |
||||
.. |
||||
.de Sp \" Vertical space (when we can't use .PP) |
||||
.if t .sp .5v |
||||
.if n .sp |
||||
.. |
||||
.de Vb \" Begin verbatim text |
||||
.ft CW |
||||
.nf |
||||
.ne \\$1 |
||||
.. |
||||
.de Ve \" End verbatim text |
||||
.ft R |
||||
.fi |
||||
.. |
||||
.\" Set up some character translations and predefined strings. \*(-- will |
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left |
||||
.\" double quote, and \*(R" will give a right double quote. | will give a |
||||
.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to |
||||
.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' |
||||
.\" expand to `' in nroff, nothing in troff, for use with C<>. |
||||
.tr \(*W-|\(bv\*(Tr |
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' |
||||
.ie n \{\ |
||||
. ds -- \(*W- |
||||
. ds PI pi |
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch |
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch |
||||
. ds L" "" |
||||
. ds R" "" |
||||
. ds C` |
||||
. ds C' |
||||
'br\} |
||||
.el\{\ |
||||
. ds -- \|\(em\| |
||||
. ds PI \(*p |
||||
. ds L" `` |
||||
. ds R" '' |
||||
'br\} |
||||
.\" |
||||
.\" If the F register is turned on, we'll generate index entries on stderr for |
||||
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index |
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the |
||||
.\" output yourself in some meaningful fashion. |
||||
.if \nF \{\ |
||||
. de IX |
||||
. tm Index:\\$1\t\\n%\t"\\$2" |
||||
.. |
||||
. nr % 0 |
||||
. rr F |
||||
.\} |
||||
.\" |
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes |
||||
.\" way too many mistakes in technical documents. |
||||
.hy 0 |
||||
.if n .na |
||||
.\" |
||||
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). |
||||
.\" Fear. Run. Save yourself. No user-serviceable parts. |
||||
. \" fudge factors for nroff and troff |
||||
.if n \{\ |
||||
. ds #H 0 |
||||
. ds #V .8m |
||||
. ds #F .3m |
||||
. ds #[ \f1 |
||||
. ds #] \fP |
||||
.\} |
||||
.if t \{\ |
||||
. ds #H ((1u-(\\\\n(.fu%2u))*.13m) |
||||
. ds #V .6m |
||||
. ds #F 0 |
||||
. ds #[ \& |
||||
. ds #] \& |
||||
.\} |
||||
. \" simple accents for nroff and troff |
||||
.if n \{\ |
||||
. ds ' \& |
||||
. ds ` \& |
||||
. ds ^ \& |
||||
. ds , \& |
||||
. ds ~ ~ |
||||
. ds / |
||||
.\} |
||||
.if t \{\ |
||||
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" |
||||
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' |
||||
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' |
||||
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' |
||||
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' |
||||
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' |
||||
.\} |
||||
. \" troff and (daisy-wheel) nroff accents |
||||
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' |
||||
.ds 8 \h'\*(#H'\(*b\h'-\*(#H' |
||||
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] |
||||
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' |
||||
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' |
||||
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] |
||||
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] |
||||
.ds ae a\h'-(\w'a'u*4/10)'e |
||||
.ds Ae A\h'-(\w'A'u*4/10)'E |
||||
. \" corrections for vroff |
||||
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' |
||||
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' |
||||
. \" for low resolution devices (crt and lpr) |
||||
.if \n(.H>23 .if \n(.V>19 \ |
||||
\{\ |
||||
. ds : e |
||||
. ds 8 ss |
||||
. ds o a |
||||
. ds d- d\h'-1'\(ga |
||||
. ds D- D\h'-1'\(hy |
||||
. ds th \o'bp' |
||||
. ds Th \o'LP' |
||||
. ds ae ae |
||||
. ds Ae AE |
||||
.\} |
||||
.rm #[ #] #H #V #F C |
||||
.\" ======================================================================== |
||||
.\" |
||||
.IX Title "OPENPKG 1" |
||||
.TH OPENPKG 1 "2002-11-26" "openpkg-tool" "OpenPKG Maintainance" |
||||
.SH "NAME" |
||||
\&\fBopenpkg\fR \- \fBOpenPKG\fR maintainance utility |
||||
.SH "VERSION" |
||||
.IX Header "VERSION" |
||||
openpkg-tool \f(CW@version\fR@ |
||||
.SH "SYNOPSIS" |
||||
.IX Header "SYNOPSIS" |
||||
\&\fBopenpkg\fR |
||||
\&\fBindex\fR |
||||
[\fB\-r\fR \fIresource\fR] |
||||
[\fB\-p\fR \fIplatform\fR] |
||||
[\fB\-C\fR \fIcache.db\fR] |
||||
[\fB\-o\fR \fIindex.rdf\fR] |
||||
[\fB\-c\fR] |
||||
[\fB\-i\fR] |
||||
\&\fIdir\fR ... |
||||
.PP |
||||
\&\fBopenpkg\fR |
||||
\&\fBbuild\fR |
||||
[\fB\-R\fR \fIrpm\fR] |
||||
[\fB\-r\fR \fIrepository\fR] |
||||
[\fB\-f\fR \fIindex.rdf\fR] |
||||
[\fB\-u\fR] |
||||
[\fB\-U\fR] |
||||
[\fB\-z\fR] |
||||
[\fB\-Z\fR] |
||||
[\fB\-i\fR] |
||||
[\fB\-q\fR] |
||||
[\fB\-P\fR \fIpriv-cmd\fR] |
||||
[\fB\-N\fR \fInon-priv-cmd\fR] |
||||
[\fB\-p\fR \fIplatform\fR] |
||||
[\fB\-D\fR\fIvar\fR=\fIval\fR ...] |
||||
[\fB\-E\fR \fIname\fR ...] |
||||
([\fB\-a\fR] [\fB\-A\fR] | \fIpatternlist\fR) |
||||
.SH "DESCRIPTION" |
||||
.IX Header "DESCRIPTION" |
||||
\&\fBopenpkg\fR is a frontend utility for maintaining an \fBOpenPKG\fR instance. |
||||
It currenty provides indexing of \s-1RPM\s0 files (\fBopenpkg index\fR) and |
||||
automated recursive from-scratch installation and updating of existing |
||||
\&\s-1RPM\s0 packages (\fBopenpkg build\fR). |
||||
.SH "COMMANDS" |
||||
.IX Header "COMMANDS" |
||||
.Sh "\s-1OPENPKG\s0 \s-1INDEX\s0" |
||||
.IX Subsection "OPENPKG INDEX" |
||||
\&\fBopenpkg-index\fR creates an \s-1XML/RDF\s0 based resource index for \s-1RPM\s0 |
||||
\&\fI.spec\fR files in a source tree or from an \s-1RPM\s0 package repository. The |
||||
index holds enough information to support an automated build process by |
||||
\&\fBopenpkg build\fR. |
||||
.PP |
||||
The following command line options exist: |
||||
.IP "\fB\-r\fR \fIresource\fR" 4 |
||||
.IX Item "-r resource" |
||||
The name of the resource stored in the index. The default is |
||||
"\f(CW\*(C`OpenPKG\-CURRENT/Source/\*(C'\fR". |
||||
.IP "\fB\-p\fR \fIplatform\fR" 4 |
||||
.IX Item "-p platform" |
||||
\&\fBopenpkg index\fR adds a platform attribute for binary RPMs. The |
||||
attribute is built as \fI%{arch}\fR\f(CW\*(C`\-\*(C'\fR\fIplatform\fR\f(CW\*(C`\-\*(C'\fR\fI%{os}\fR where |
||||
\&\fI%{arch}\fR and \fI%{os}\fR are taken from the \s-1RPM\s0 header and \fIplatform\fR is |
||||
the value of the \fB\-p\fR option. The default value is "\f(CW\*(C`unkown\*(C'\fR". This |
||||
must be used to distinguish between platforms that support the same |
||||
Architecture and \s-1OS\s0 name like various Linux distributions. |
||||
.IP "\fB\-C\fR \fIcache.db\fR" 4 |
||||
.IX Item "-C cache.db" |
||||
Cache all \fI.spec\fR files into this Berkeley-DB file when indexing source |
||||
RPMs. The cache is refreshed automatically when the source RPMs are more |
||||
recent than the cache entry. |
||||
.IP "\fB\-o\fR \fIindex.rdf\fR" 4 |
||||
.IX Item "-o index.rdf" |
||||
Name of the output \s-1XML/RDF\s0 file, default is to write to \fIstdout\fR. |
||||
.IP "\fB\-c\fR" 4 |
||||
.IX Item "-c" |
||||
Compress output with \f(CW\*(C`bzip2\*(C'\fR. Use the \fB\-o\fR option to specify a \fI.bz2\fR |
||||
suffix. |
||||
.IP "\fB\-i\fR" 4 |
||||
.IX Item "-i" |
||||
The specified directories are \s-1RPM\s0 repositories. Build index over |
||||
all \fI.rpm\fR files in these directories and all subdirectories. |
||||
If a subdirectory already contains a \f(CW\*(C`00INDEX.rdf\*(C'\fR or \f(CW\*(C`00INDEX.rdf.*\*(C'\fR |
||||
file then skip scanning the subdirectory, instead add a reference |
||||
to the index file into the new index. |
||||
.Sp |
||||
Without this option the directories are source trees with a subdirectory |
||||
per package and a \fIpackage\fR\f(CW\*(C`.spec\*(C'\fR file inside each subdirectory. |
||||
.Sh "\s-1OPENPKG\s0 \s-1BUILD\s0" |
||||
.IX Subsection "OPENPKG BUILD" |
||||
\&\fBopenpkg build\fR writes a shell script to standard output that installs |
||||
or upgrades software packages including all dependencies. Packages that |
||||
are upgraded automatically trigger rebuilds of all packages that depend |
||||
on the upgraded package (\*(L"reverse dependencies\*(R"). The dependency |
||||
information is read from an index generated by \fBopenpkg index\fR. |
||||
.PP |
||||
The following command line options exist: |
||||
.IP "\fB\-R\fR \fIrpm\fR" 4 |
||||
.IX Item "-R rpm" |
||||
Specify a path to the installed \fBOpenPKG\fR \f(CW\*(C`rpm\*(C'\fR executable. Several |
||||
other internal paths are deduced from the \fIrpm\fR path, so this should be |
||||
something like \fI%{l_prefix}\fR\f(CW\*(C`/bin/rpm\*(C'\fR. |
||||
.IP "\fB\-r\fR \fIrepository\fR" 4 |
||||
.IX Item "-r repository" |
||||
Specify a path to an \s-1RPM\s0 repository, this can be a \s-1URL\s0 or a directory |
||||
path. The name of the package file is appended to this path. |
||||
The default is to use a \s-1URL\s0 pointing to the \fBOpenPKG\fR \s-1FTP\s0 server. |
||||
.IP "\fB\-f\fR \fIindex.rdf\fR" 4 |
||||
.IX Item "-f index.rdf" |
||||
Specify a path to the primary \s-1XML/RDF\s0 index, this can be a \s-1URL\s0 or a |
||||
file path. If the index contains references to aother indexes these are |
||||
included automatically. The default is to use a \s-1URL\s0 pointing to the |
||||
\&\fBOpenPKG\fR \s-1FTP\s0 server for the \fBOpenPKG\fR release you are using. |
||||
.IP "\fB\-u\fR" 4 |
||||
.IX Item "-u" |
||||
The generated script will ignore binary RPMs that are stored on |
||||
your system. Instead it will either fetch binary RPMs or rebuild |
||||
from source RPMs fetched from the repository. |
||||
.IP "\fB\-U\fR" 4 |
||||
.IX Item "-U" |
||||
The generated script will try to upgrade all selected packages |
||||
including their dependencies to the most recent version. |
||||
.IP "\fB\-z\fR" 4 |
||||
.IX Item "-z" |
||||
The generated script will rebuild all selected packages |
||||
including their dependencies even when the most recent version |
||||
is already installed. |
||||
.IP "\fB\-Z\fR" 4 |
||||
.IX Item "-Z" |
||||
\&\fBopenpkg build\fR ignores a installed packages, the |
||||
script will rebuild all selected packages from scratch. |
||||
Note that this doesn't work together with the \fB\-a\fR option. |
||||
.IP "\fB\-i\fR" 4 |
||||
.IX Item "-i" |
||||
The generated script will ignore errors. However, if a build |
||||
phase fails the install phase is still skipped. |
||||
.IP "\fB\-q\fR" 4 |
||||
.IX Item "-q" |
||||
Ignore all reverse dependencies. |
||||
\&\fI\s-1ATTENTION:\s0 this might break already installed packages!\fR |
||||
.IP "\fB\-P\fR \fIpriv-cmd\fR" 4 |
||||
.IX Item "-P priv-cmd" |
||||
Command prefix to use for install commands that require elevated |
||||
privileges. The most common tool for this is \fIsudo\fR\|(1). |
||||
.IP "\fB\-N\fR \fInon-priv-cmd\fR" 4 |
||||
.IX Item "-N non-priv-cmd" |
||||
Command prefix to use for install commands that do not require elevated |
||||
privileges. The most common tool for this is \fIsudo\fR\|(1). |
||||
.IP "\fB\-p\fR \fIplatform\fR" 4 |
||||
.IX Item "-p platform" |
||||
The platform string that is matched against the index for binary |
||||
packages. Default is to use the \fI%{_target_platform}\fR variable. |
||||
.IP "\fB\-D\fR\fIvar\fR=\fIval\fR" 4 |
||||
.IX Item "-Dvar=val" |
||||
Specify configuration options for all selected packages. This can be |
||||
either \fB\-D\fR\f(CW\*(C`with_\*(C'\fR\fIxxx\fR\f(CW\*(C`=\*(C'\fR\fIyyy\fR or just \fB\-D\fR\f(CW\*(C`with_\*(C'\fR\fIxxx\fR, the |
||||
latter is equivalent to a \fB\-D\fR\f(CW\*(C`with_\*(C'\fR\fIxxx\fR\f(CW\*(C`=\*(C'\fR\f(CW\*(C`yes\*(C'\fR. The parameters |
||||
are matched against selected packages that are already installed. If |
||||
they do indicate a change the package is rebuild. There can be multiple |
||||
\&\fB\-D\fR options. |
||||
.IP "\fB\-E\fR \fIname\fR" 4 |
||||
.IX Item "-E name" |
||||
Ignore a package with the specified \fIname\fR. This can be used to avoid |
||||
upgrading to a broken package in the repository. There can be multiple |
||||
\&\fB\-E\fR options. |
||||
.IP "\fB\-a\fR" 4 |
||||
.IX Item "-a" |
||||
Select all installed packages. Do not specify a pattern list together |
||||
with the \fB\-a\fR option. |
||||
.IP "\fB\-A\fR" 4 |
||||
.IX Item "-A" |
||||
Select all packages in the repository. Do not specify a pattern list together |
||||
with the \fB\-a\fR option. |
||||
.SH "CONFIGURATION" |
||||
.IX Header "CONFIGURATION" |
||||
\&\fBopenpkg build\fR reads the configuration file \fI$HOME/.openpkg/build\fR. |
||||
The file lists default options, one option per line and section tags |
||||
of the form \f(CW\*(C`[\*(C'\fR\fIprefix\fR\f(CW\*(C`]\*(C'\fR. Options following such a tag are only |
||||
evaluated if the selected \s-1RPM\s0 path matches the prefix so that you can |
||||
define default options for multiple \fBOpenPKG\fR hierarchies. |
||||
.SH "CAVEATS" |
||||
.IX Header "CAVEATS" |
||||
Parallel execution of \fBopenpkg build\fR causes undefined effects. |
||||
.SH "SEE ALSO" |
||||
.IX Header "SEE ALSO" |
||||
\&\fIrpm\fR\|(1), \fIsudo\fR\|(1) |
||||
.SH "HISTORY" |
||||
.IX Header "HISTORY" |
||||
The \fBopenpkg index\fR and \fBopenpkg build\fR command |
||||
was invented in November 2002 by \fIMichael van Elst\fR |
||||
<mlelstv@dev.de.cw.net> under contract with \fICable & Wireless |
||||
Germany\fR <http://www.cw.com/de> for use inside the \fBOpenPKG\fR |
||||
project <http://www.openpkg.org/>. |
||||
.SH "AUTHORS" |
||||
.IX Header "AUTHORS" |
||||
.Vb 2 |
||||
\& Michael van Elst |
||||
\& mlelstv@dev.de.cw.net |
||||
.Ve |
||||
@ -0,0 +1,265 @@
|
||||
## |
||||
## openpkg.pod -- OpenPKG maintainance utility (frontend manual page) |
||||
## |
||||
## 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. |
||||
## |
||||
|
||||
=pod |
||||
|
||||
=head1 NAME |
||||
|
||||
B<openpkg> - B<OpenPKG> maintainance utility |
||||
|
||||
=head1 VERSION |
||||
|
||||
openpkg-tool @version@ |
||||
|
||||
=head1 SYNOPSIS |
||||
|
||||
B<openpkg> |
||||
B<index> |
||||
[B<-r> I<resource>] |
||||
[B<-p> I<platform>] |
||||
[B<-C> I<cache.db>] |
||||
[B<-o> I<index.rdf>] |
||||
[B<-c>] |
||||
[B<-i>] |
||||
I<dir> ... |
||||
|
||||
B<openpkg> |
||||
B<build> |
||||
[B<-R> I<rpm>] |
||||
[B<-r> I<repository>] |
||||
[B<-f> I<index.rdf>] |
||||
[B<-u>] |
||||
[B<-U>] |
||||
[B<-z>] |
||||
[B<-Z>] |
||||
[B<-i>] |
||||
[B<-q>] |
||||
[B<-P> I<priv-cmd>] |
||||
[B<-N> I<non-priv-cmd>] |
||||
[B<-p> I<platform>] |
||||
[B<-D>I<var>=I<val> ...] |
||||
[B<-E> I<name> ...] |
||||
([B<-a>] [B<-A>] | I<patternlist>) |
||||
|
||||
=head1 DESCRIPTION |
||||
|
||||
B<openpkg> is a frontend utility for maintaining an B<OpenPKG> instance. |
||||
It currenty provides indexing of RPM files (B<openpkg index>) and |
||||
automated recursive from-scratch installation and updating of existing |
||||
RPM packages (B<openpkg build>). |
||||
|
||||
=head1 COMMANDS |
||||
|
||||
=head2 OPENPKG INDEX |
||||
|
||||
B<openpkg-index> creates an XML/RDF based resource index for RPM |
||||
F<.spec> files in a source tree or from an RPM package repository. The |
||||
index holds enough information to support an automated build process by |
||||
B<openpkg build>. |
||||
|
||||
The following command line options exist: |
||||
|
||||
=over 4 |
||||
|
||||
=item B<-r> I<resource> |
||||
|
||||
The name of the resource stored in the index. The default is |
||||
"C<OpenPKG-CURRENT/Source/>". |
||||
|
||||
=item B<-p> I<platform> |
||||
|
||||
B<openpkg index> adds a platform attribute for binary RPMs. The |
||||
attribute is built as I<%{arch}>C<->I<platform>C<->I<%{os}> where |
||||
I<%{arch}> and I<%{os}> are taken from the RPM header and I<platform> is |
||||
the value of the B<-p> option. The default value is "C<unkown>". This |
||||
must be used to distinguish between platforms that support the same |
||||
Architecture and OS name like various Linux distributions. |
||||
|
||||
=item B<-C> I<cache.db> |
||||
|
||||
Cache all F<.spec> files into this Berkeley-DB file when indexing source |
||||
RPMs. The cache is refreshed automatically when the source RPMs are more |
||||
recent than the cache entry. |
||||
|
||||
=item B<-o> I<index.rdf> |
||||
|
||||
Name of the output XML/RDF file, default is to write to F<stdout>. |
||||
|
||||
=item B<-c> |
||||
|
||||
Compress output with C<bzip2>. Use the B<-o> option to specify a F<.bz2> |
||||
suffix. |
||||
|
||||
=item B<-i> |
||||
|
||||
The specified directories are RPM repositories. Build index over |
||||
all F<.rpm> files in these directories and all subdirectories. |
||||
If a subdirectory already contains a C<00INDEX.rdf> or C<00INDEX.rdf.*> |
||||
file then skip scanning the subdirectory, instead add a reference |
||||
to the index file into the new index. |
||||
|
||||
Without this option the directories are source trees with a subdirectory |
||||
per package and a I<package>C<.spec> file inside each subdirectory. |
||||
|
||||
=back |
||||
|
||||
=head2 OPENPKG BUILD |
||||
|
||||
B<openpkg build> writes a shell script to standard output that installs |
||||
or upgrades software packages including all dependencies. Packages that |
||||
are upgraded automatically trigger rebuilds of all packages that depend |
||||
on the upgraded package ("reverse dependencies"). The dependency |
||||
information is read from an index generated by B<openpkg index>. |
||||
|
||||
The following command line options exist: |
||||
|
||||
=over 4 |
||||
|
||||
=item B<-R> I<rpm> |
||||
|
||||
Specify a path to the installed B<OpenPKG> C<rpm> executable. Several |
||||
other internal paths are deduced from the I<rpm> path, so this should be |
||||
something like I<%{l_prefix}>C</bin/rpm>. |
||||
|
||||
=item B<-r> I<repository> |
||||
|
||||
Specify a path to an RPM repository, this can be a URL or a directory |
||||
path. The name of the package file is appended to this path. |
||||
The default is to use a URL pointing to the B<OpenPKG> FTP server. |
||||
|
||||
=item B<-f> I<index.rdf> |
||||
|
||||
Specify a path to the primary XML/RDF index, this can be a URL or a |
||||
file path. If the index contains references to aother indexes these are |
||||
included automatically. The default is to use a URL pointing to the |
||||
B<OpenPKG> FTP server for the B<OpenPKG> release you are using. |
||||
|
||||
=item B<-u> |
||||
|
||||
The generated script will ignore binary RPMs that are stored on |
||||
your system. Instead it will either fetch binary RPMs or rebuild |
||||
from source RPMs fetched from the repository. |
||||
|
||||
=item B<-U> |
||||
|
||||
The generated script will try to upgrade all selected packages |
||||
including their dependencies to the most recent version. |
||||
|
||||
=item B<-z> |
||||
|
||||
The generated script will rebuild all selected packages |
||||
including their dependencies even when the most recent version |
||||
is already installed. |
||||
|
||||
=item B<-Z> |
||||
|
||||
B<openpkg build> ignores a installed packages, the |
||||
script will rebuild all selected packages from scratch. |
||||
Note that this doesn't work together with the B<-a> option. |
||||
|
||||
=item B<-i> |
||||
|
||||
The generated script will ignore errors. However, if a build |
||||
phase fails the install phase is still skipped. |
||||
|
||||
=item B<-q> |
||||
|
||||
Ignore all reverse dependencies. |
||||
I<ATTENTION: this might break already installed packages!> |
||||
|
||||
=item B<-P> I<priv-cmd> |
||||
|
||||
Command prefix to use for install commands that require elevated |
||||
privileges. The most common tool for this is sudo(1). |
||||
|
||||
=item B<-N> I<non-priv-cmd> |
||||
|
||||
Command prefix to use for install commands that do not require elevated |
||||
privileges. The most common tool for this is sudo(1). |
||||
|
||||
=item B<-p> I<platform> |
||||
|
||||
The platform string that is matched against the index for binary |
||||
packages. Default is to use the I<%{_target_platform}> variable. |
||||
|
||||
=item B<-D>I<var>=I<val> |
||||
|
||||
Specify configuration options for all selected packages. This can be |
||||
either B<-D>C<with_>I<xxx>C<=>I<yyy> or just B<-D>C<with_>I<xxx>, the |
||||
latter is equivalent to a B<-D>C<with_>I<xxx>C<=>C<yes>. The parameters |
||||
are matched against selected packages that are already installed. If |
||||
they do indicate a change the package is rebuild. There can be multiple |
||||
B<-D> options. |
||||
|
||||
=item B<-E> I<name> |
||||
|
||||
Ignore a package with the specified I<name>. This can be used to avoid |
||||
upgrading to a broken package in the repository. There can be multiple |
||||
B<-E> options. |
||||
|
||||
=item B<-a> |
||||
|
||||
Select all installed packages. Do not specify a pattern list together |
||||
with the B<-a> option. |
||||
|
||||
=item B<-A> |
||||
|
||||
Select all packages in the repository. Do not specify a pattern list together |
||||
with the B<-a> option. |
||||
|
||||
=back |
||||
|
||||
=head1 CONFIGURATION |
||||
|
||||
B<openpkg build> reads the configuration file I<$HOME/.openpkg/build>. |
||||
The file lists default options, one option per line and section tags |
||||
of the form C<[>I<prefix>C<]>. Options following such a tag are only |
||||
evaluated if the selected RPM path matches the prefix so that you can |
||||
define default options for multiple B<OpenPKG> hierarchies. |
||||
|
||||
=head1 CAVEATS |
||||
|
||||
Parallel execution of B<openpkg build> causes undefined effects. |
||||
|
||||
=head1 SEE ALSO |
||||
|
||||
rpm(1), sudo(1) |
||||
|
||||
=head1 HISTORY |
||||
|
||||
The B<openpkg index> and B<openpkg build> command |
||||
was invented in November 2002 by I<Michael van Elst> |
||||
E<lt>mlelstv@dev.de.cw.netE<gt> under contract with I<Cable & Wireless |
||||
Germany> E<lt>http://www.cw.com/deE<gt> for use inside the B<OpenPKG> |
||||
project E<lt>http://www.openpkg.org/E<gt>. |
||||
|
||||
=head1 AUTHORS |
||||
|
||||
Michael van Elst |
||||
mlelstv@dev.de.cw.net |
||||
|
||||
=cut |
||||
|
||||
@ -0,0 +1,90 @@
|
||||
#!@l_prefix@/lib/openpkg/bash |
||||
## |
||||
## openpkg.sh -- OpenPKG maintainance utility (frontend) |
||||
## |
||||
## 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. |
||||
## |
||||
|
||||
# program information |
||||
progname="openpkg" |
||||
progvers="@version@" |
||||
l_prefix="@l_prefix@" |
||||
|
||||
# try to determine Perl interpreter |
||||
perl="" |
||||
for dir in $l_prefix/bin `echo $PATH | sed -e 's;:; ;g'` /bin /usr/bin /usr/local/bin; do |
||||
if [ -f "$dir/perl" ]; then |
||||
perl="$dir/perl" |
||||
break |
||||
fi |
||||
done |
||||
|
||||
# command line option parsing |
||||
if [ $# -eq 0 ]; then |
||||
echo "$progname:USAGE: $progname index|build [options]" |
||||
exit 0 |
||||
fi |
||||
while [ ".$1" != . ]; do |
||||
case "$1" in |
||||
-h ) |
||||
echo "$progname:USAGE: $progname index|build [options]" |
||||
exit 0 |
||||
;; |
||||
-v ) |
||||
echo "$progname $progvers (OpenPKG instance: $l_prefix)" |
||||
exit 0 |
||||
;; |
||||
-* ) |
||||
echo "$progname:ERROR: invalid option \"$1\"" 1>&2 |
||||
exit 1 |
||||
;; |
||||
* ) |
||||
break |
||||
;; |
||||
esac |
||||
done |
||||
|
||||
# command dispatching |
||||
case "$1" in |
||||
index ) |
||||
if [ ".$perl" = . ]; then |
||||
echo "$progname:ERROR: \"index\" command requires a Perl interpreter" 1>&2 |
||||
exit 1 |
||||
fi |
||||
shift |
||||
exec $perl ${l_prefix}/lib/openpkg/openpkg-index.pl ${1+"$@"} |
||||
;; |
||||
build ) |
||||
if [ ".$perl" = . ]; then |
||||
echo "$progname:ERROR: \"build\" command requires a Perl interpreter" 1>&2 |
||||
exit 1 |
||||
fi |
||||
shift |
||||
exec $perl ${l_prefix}/lib/openpkg/openpkg-build.pl ${1+"$@"} |
||||
;; |
||||
* ) |
||||
echo "$progname:ERROR: invalid command \"$1\"" 1>&2 |
||||
exit 1 |
||||
;; |
||||
esac |
||||
|
||||
Loading…
Reference in new issue