initial import of perl-RPM2
CVS patchset: 5375 CVS date: 2002/04/07 06:45:24
This commit is contained in:
parent
e7b38bbd0c
commit
f5f18ee2a8
|
@ -0,0 +1,6 @@
|
||||||
|
Makefile.PL
|
||||||
|
MANIFEST
|
||||||
|
README
|
||||||
|
RPM2.pm
|
||||||
|
RPM2.xs
|
||||||
|
test.pl
|
|
@ -0,0 +1,13 @@
|
||||||
|
use ExtUtils::MakeMaker;
|
||||||
|
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||||
|
# the contents of the Makefile that is written.
|
||||||
|
WriteMakefile(
|
||||||
|
'NAME' => 'RPM2',
|
||||||
|
'VERSION_FROM' => 'RPM2.pm', # finds $VERSION
|
||||||
|
'PREREQ_PM' => {}, # e.g., Module::Name => 1.1
|
||||||
|
'LIBS' => ['-lpopt -lrpm -lrpmio -lrpmdb'], # e.g., '-lm'
|
||||||
|
'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
|
||||||
|
'INC' => '-I/usr/include/rpm', # e.g., '-I/usr/include/other'
|
||||||
|
'TYPEMAPS' => [ 'typemap' ],
|
||||||
|
'OPTIMIZE' => '-g'
|
||||||
|
);
|
|
@ -0,0 +1,35 @@
|
||||||
|
RPM2 version 0.01
|
||||||
|
=================
|
||||||
|
|
||||||
|
The README is used to introduce the module and provide instructions on
|
||||||
|
how to install the module, any machine dependencies it may have (for
|
||||||
|
example C compilers and installed libraries) and any other information
|
||||||
|
that should be provided before the module is installed.
|
||||||
|
|
||||||
|
A README file is required for CPAN modules since CPAN extracts the
|
||||||
|
README file from a module distribution so that people browsing the
|
||||||
|
archive can use it get an idea of the modules uses. It is usually a
|
||||||
|
good idea to provide version information here so that people can
|
||||||
|
decide whether fixes for the module are worth downloading.
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
|
||||||
|
To install this module type the following:
|
||||||
|
|
||||||
|
perl Makefile.PL
|
||||||
|
make
|
||||||
|
make test
|
||||||
|
make install
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
|
||||||
|
This module requires these other modules and libraries:
|
||||||
|
|
||||||
|
blah blah blah
|
||||||
|
|
||||||
|
COPYRIGHT AND LICENCE
|
||||||
|
|
||||||
|
Put the correct copyright and licence information here.
|
||||||
|
|
||||||
|
Copyright (C) 2001 A. U. Thor blah blah blah
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
package RPM2;
|
||||||
|
|
||||||
|
use 5.00503;
|
||||||
|
use strict;
|
||||||
|
use DynaLoader;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
use vars qw/$VERSION/;
|
||||||
|
$VERSION = '0.01';
|
||||||
|
use vars qw/@ISA/;
|
||||||
|
@ISA = qw/DynaLoader/;
|
||||||
|
|
||||||
|
bootstrap RPM2 $VERSION;
|
||||||
|
|
||||||
|
my %tagmap;
|
||||||
|
|
||||||
|
RPM2::_init_rpm();
|
||||||
|
RPM2::_populate_header_tags(\%tagmap);
|
||||||
|
|
||||||
|
sub open_rpm_db {
|
||||||
|
my $class = shift;
|
||||||
|
my %params = @_;
|
||||||
|
|
||||||
|
my $self = bless { }, $class;
|
||||||
|
$self->{db} = RPM2::_open_rpm_db($params{-path}, $params{-read_only} ? 0 : 1);
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub open_package_file {
|
||||||
|
my $class = shift;
|
||||||
|
my $file = shift;
|
||||||
|
|
||||||
|
open FH, "<$file"
|
||||||
|
or die "Can't open $file: $!";
|
||||||
|
|
||||||
|
my ($hdr, $sigs) = RPM2::_read_package_info(*FH);
|
||||||
|
close FH;
|
||||||
|
|
||||||
|
$hdr = RPM2::Header->_new_raw($hdr, 1);
|
||||||
|
$sigs = RPM2::Header->_new_raw($sigs, 1);
|
||||||
|
|
||||||
|
return ($hdr, $sigs);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub close_rpm_db {
|
||||||
|
my $self = shift;
|
||||||
|
die "db not open" unless $self->{db};
|
||||||
|
|
||||||
|
foreach my $iter (@{$self->{active_iterators}}) {
|
||||||
|
$iter->_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->{active_iterators} = [];
|
||||||
|
|
||||||
|
RPM2::_close_rpm_db($self->{db});
|
||||||
|
$self->{db} = undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub iterator {
|
||||||
|
my $self = shift;
|
||||||
|
my $str = shift;
|
||||||
|
|
||||||
|
die "db closed" unless $self->{db};
|
||||||
|
my $iter = RPM2::PackageIterator->new_iterator($self->{db}, $str);
|
||||||
|
push @{$self->{active_iterators}}, $iter;
|
||||||
|
|
||||||
|
return $iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _remove_iter {
|
||||||
|
my $self = shift;
|
||||||
|
my $iter = shift;
|
||||||
|
|
||||||
|
@{$self->{active_iterators}} = grep { $_ != $iter } @{$self->{active_iterators}};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DESTROY {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
if ($self->{db}) {
|
||||||
|
$self->close_rpm_db();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package RPM2::Header;
|
||||||
|
|
||||||
|
sub _new_raw {
|
||||||
|
my $class = shift;
|
||||||
|
my $c_header = shift;
|
||||||
|
my $need_free = shift;
|
||||||
|
|
||||||
|
my $self = bless { }, $class;
|
||||||
|
$self->{header} = $c_header;
|
||||||
|
$self->{need_free} = $need_free;
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub tag {
|
||||||
|
my $self = shift;
|
||||||
|
my $tag = shift;
|
||||||
|
|
||||||
|
$tag = uc "RPMTAG_$tag";
|
||||||
|
|
||||||
|
die "tag $tag invalid"
|
||||||
|
unless exists $tagmap{$tag};
|
||||||
|
|
||||||
|
return RPM2::_header_tag($self->{header}, $tagmap{$tag});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub as_nvre {
|
||||||
|
my $self = shift;
|
||||||
|
my $epoch = $self->tag('epoch');
|
||||||
|
my $epoch_str = '';
|
||||||
|
|
||||||
|
$epoch_str = "$epoch:" if defined $epoch;
|
||||||
|
|
||||||
|
my $ret = $epoch_str . join("-", map { $self->tag($_) } qw/name version release/);
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub files {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
if (not exists $self->{files}) {
|
||||||
|
my @base_names = $self->tag('basenames');
|
||||||
|
my @dir_names = $self->tag('dirnames');
|
||||||
|
my @dir_indexes = $self->tag('dirindexes');
|
||||||
|
|
||||||
|
my @files;
|
||||||
|
foreach (0 .. $#base_names) {
|
||||||
|
push @files, $dir_names[$dir_indexes[$_]] . $base_names[$_];
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->{files} = \@files;
|
||||||
|
}
|
||||||
|
|
||||||
|
return @{$self->{files}};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DESTROY {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
if ($self->{need_free}) {
|
||||||
|
RPM2::_free_header(delete $self->{header});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package RPM2::PackageIterator;
|
||||||
|
|
||||||
|
sub RPMDBI_PACKAGES { 0; }
|
||||||
|
|
||||||
|
sub new_iterator {
|
||||||
|
my $class = shift;
|
||||||
|
my $db = shift;
|
||||||
|
my $key = shift;
|
||||||
|
|
||||||
|
my $self = bless {}, $class;
|
||||||
|
$self->{iter} = RPM2::_init_iterator($db, RPM2::PackageIterator::RPMDBI_PACKAGES, $key, defined $key ? length $key : 0);
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub next {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
die "no iterator" unless $self->{iter};
|
||||||
|
|
||||||
|
my $hdr = RPM2::_iterator_next($self->{iter});
|
||||||
|
return unless $hdr;
|
||||||
|
|
||||||
|
return RPM2::Header->_new_raw($hdr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _cleanup {
|
||||||
|
my $self = shift;
|
||||||
|
return unless $self->{iter};
|
||||||
|
|
||||||
|
RPM2::_destroy_iterator($self->{iter});
|
||||||
|
|
||||||
|
delete $self->{$_} foreach keys %$self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DESTROY {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
$self->_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Preloaded methods go here.
|
||||||
|
|
||||||
|
1;
|
||||||
|
__END__
|
||||||
|
# Below is stub documentation for your module. You better edit it!
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
RPM2 - Perl extension for blah blah blah
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
use RPM2;
|
||||||
|
blah blah blah
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Stub documentation for RPM2, created by h2xs. It looks like the
|
||||||
|
author of the extension was negligent enough to leave the stub
|
||||||
|
unedited.
|
||||||
|
|
||||||
|
Blah blah blah.
|
||||||
|
|
||||||
|
=head2 EXPORT
|
||||||
|
|
||||||
|
None by default.
|
||||||
|
|
||||||
|
|
||||||
|
=head1 HISTORY
|
||||||
|
|
||||||
|
=over 8
|
||||||
|
|
||||||
|
=item 0.01
|
||||||
|
|
||||||
|
Original version; created by h2xs 1.21 with options
|
||||||
|
|
||||||
|
-AC
|
||||||
|
RPM2
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
A. U. Thor, E<lt>a.u.thor@a.galaxy.far.far.awayE<gt>
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
L<perl>.
|
||||||
|
|
||||||
|
=cut
|
|
@ -0,0 +1,171 @@
|
||||||
|
#include "rpmcli.h"
|
||||||
|
#include "rpmlib.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
#include "EXTERN.h"
|
||||||
|
#include "perl.h"
|
||||||
|
#include "XSUB.h"
|
||||||
|
|
||||||
|
const char *CLASS = "RPM2";
|
||||||
|
MODULE = RPM2 PACKAGE = RPM2
|
||||||
|
|
||||||
|
int
|
||||||
|
rpmvercmp(one, two)
|
||||||
|
char* one
|
||||||
|
char* two
|
||||||
|
|
||||||
|
void
|
||||||
|
_init_rpm()
|
||||||
|
CODE:
|
||||||
|
rpmReadConfigFiles(NULL, NULL);
|
||||||
|
|
||||||
|
void
|
||||||
|
_close_rpm_db(db)
|
||||||
|
rpmdb db
|
||||||
|
CODE:
|
||||||
|
rpmdbClose(db);
|
||||||
|
|
||||||
|
rpmdb
|
||||||
|
_open_rpm_db(path,for_write)
|
||||||
|
char *path
|
||||||
|
int for_write
|
||||||
|
PREINIT:
|
||||||
|
rpmdb db;
|
||||||
|
CODE:
|
||||||
|
if (rpmdbOpen(path, &db, for_write ? O_RDWR | O_CREAT : O_RDONLY, 0644)) {
|
||||||
|
croak("rpmdbOpen failed");
|
||||||
|
RETVAL = NULL;
|
||||||
|
}
|
||||||
|
RETVAL = db;
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
rpmdbMatchIterator
|
||||||
|
_init_iterator(db, rpmtag, key, len)
|
||||||
|
rpmdb db
|
||||||
|
int rpmtag
|
||||||
|
char *key
|
||||||
|
size_t len
|
||||||
|
CODE:
|
||||||
|
RETVAL = rpmdbInitIterator(db, rpmtag, key && *key ? key : NULL, len);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
void
|
||||||
|
_destroy_iterator(i)
|
||||||
|
rpmdbMatchIterator i
|
||||||
|
CODE:
|
||||||
|
rpmdbFreeIterator(i);
|
||||||
|
|
||||||
|
Header
|
||||||
|
_iterator_next(i)
|
||||||
|
rpmdbMatchIterator i
|
||||||
|
CODE:
|
||||||
|
RETVAL = rpmdbNextIterator(i);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
void
|
||||||
|
_read_package_info(fp)
|
||||||
|
FILE *fp
|
||||||
|
PREINIT:
|
||||||
|
Header ret;
|
||||||
|
Header sigs;
|
||||||
|
rpmRC rc;
|
||||||
|
FD_t fd;
|
||||||
|
PPCODE:
|
||||||
|
fd = fdDup(fileno(fp));
|
||||||
|
rc = rpmReadPackageInfo(fd, &sigs, &ret);
|
||||||
|
Fclose(fd);
|
||||||
|
|
||||||
|
if (rc == RPMRC_OK) {
|
||||||
|
SV *h_sv, *s_sv;
|
||||||
|
|
||||||
|
EXTEND(SP, 2);
|
||||||
|
|
||||||
|
h_sv = sv_newmortal();
|
||||||
|
s_sv = sv_newmortal();
|
||||||
|
sv_setref_pv(h_sv, "Header", (void *)ret);
|
||||||
|
sv_setref_pv(s_sv, "Header", (void *)sigs);
|
||||||
|
|
||||||
|
PUSHs(h_sv);
|
||||||
|
PUSHs(s_sv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
croak("error reading package");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_free_header(h)
|
||||||
|
Header h
|
||||||
|
CODE:
|
||||||
|
headerFree(h);
|
||||||
|
|
||||||
|
void
|
||||||
|
_header_tag(h, tag)
|
||||||
|
Header h
|
||||||
|
int tag
|
||||||
|
PREINIT:
|
||||||
|
void *ret = NULL;
|
||||||
|
int type;
|
||||||
|
int n;
|
||||||
|
int ok;
|
||||||
|
PPCODE:
|
||||||
|
ok = headerGetEntry(h, tag, &type, &ret, &n);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
/* nop, empty stack */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case RPM_STRING_ARRAY_TYPE:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **s;
|
||||||
|
|
||||||
|
EXTEND(SP, n);
|
||||||
|
s = (char **)ret;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
PUSHs(sv_2mortal(newSVpv(s[i], 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RPM_STRING_TYPE:
|
||||||
|
PUSHs(sv_2mortal(newSVpv((char *)ret, 0)));
|
||||||
|
break;
|
||||||
|
case RPM_CHAR_TYPE:
|
||||||
|
case RPM_INT8_TYPE:
|
||||||
|
case RPM_INT16_TYPE:
|
||||||
|
case RPM_INT32_TYPE:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int *r;
|
||||||
|
|
||||||
|
EXTEND(SP, n);
|
||||||
|
r = (int *)ret;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
PUSHs(sv_2mortal(newSViv(r[i])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
croak("unknown rpm tag type %d", type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headerFreeData(ret, type);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_populate_header_tags(href)
|
||||||
|
SV *href
|
||||||
|
PREINIT:
|
||||||
|
int i = 0;
|
||||||
|
HV *h;
|
||||||
|
CODE:
|
||||||
|
h = (HV *)SvRV(href);
|
||||||
|
for (i = 0; i < rpmTagTableSize; i++) {
|
||||||
|
hv_store(h, rpmTagTable[i].name, strlen(rpmTagTable[i].name), newSViv(rpmTagTable[i].val), 0);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Before `make install' is performed this script should be runnable with
|
||||||
|
# `make test'. After `make install' it should work as `perl test.pl'
|
||||||
|
|
||||||
|
#########################
|
||||||
|
|
||||||
|
# change 'tests => 1' to 'tests => last_test_to_print';
|
||||||
|
|
||||||
|
use Test;
|
||||||
|
use strict;
|
||||||
|
BEGIN { plan tests => 6 };
|
||||||
|
use RPM2;
|
||||||
|
ok(1); # If we made it this far, we're ok.
|
||||||
|
|
||||||
|
#########################
|
||||||
|
|
||||||
|
# Insert your test code below, the Test module is use()ed here so read
|
||||||
|
# its man page ( perldoc Test ) for help writing this test script.
|
||||||
|
|
||||||
|
ok(RPM2::rpmvercmp("1.0", "1.1") == -1);
|
||||||
|
ok(RPM2::rpmvercmp("1.1", "1.0") == 1);
|
||||||
|
ok(RPM2::rpmvercmp("1.0", "1.0") == 0);
|
||||||
|
ok(RPM2::rpmvercmp("1.a", "1.0") == RPM2::rpmvercmp("1.0", "1.a"));
|
||||||
|
|
||||||
|
my $db = RPM2->open_rpm_db(-read_only => 1);
|
||||||
|
ok(defined $db);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
my @h;
|
||||||
|
push @h, [ RPM2->open_package_file($_) ]
|
||||||
|
foreach <~/rhn/RPMS/*.rpm>;
|
||||||
|
|
||||||
|
print $_->[0]->as_nvre, "\n" foreach @h;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
my $i = $db->iterator();
|
||||||
|
while (my $h = $i->next) {
|
||||||
|
my $epoch = $h->tag('epoch');
|
||||||
|
my $epoch_str = '';
|
||||||
|
$epoch_str = "$epoch:" if defined $epoch;
|
||||||
|
|
||||||
|
print $epoch_str . join("-", map { $h->tag($_) } qw/name version release/);
|
||||||
|
my @files = $h->files;
|
||||||
|
my $n = scalar @files;
|
||||||
|
print " ($n files)";
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->close_rpm_db();
|
|
@ -0,0 +1,20 @@
|
||||||
|
TYPEMAP
|
||||||
|
rpmTransaction * O_OBJECT
|
||||||
|
rpmdb O_OBJECT
|
||||||
|
rpmdbMatchIterator O_OBJECT
|
||||||
|
Header O_OBJECT
|
||||||
|
|
||||||
|
INPUT
|
||||||
|
O_OBJECT
|
||||||
|
if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG))
|
||||||
|
$var = ($type)SvIV((SV*)SvRV( $arg ));
|
||||||
|
else {
|
||||||
|
warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
|
||||||
|
XSRETURN_UNDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
O_OBJECT
|
||||||
|
sv_setref_pv( $arg, (char *)CLASS, (void*)$var );
|
Loading…
Reference in New Issue