Added rpmdb traversal

CVS patchset: 3173
CVS date: 1999/07/16 08:44:54
This commit is contained in:
gafton 1999-07-16 08:44:54 +00:00
parent dfb29dcf5b
commit 1d18d03f9d
8 changed files with 379 additions and 249 deletions

View File

@ -8,3 +8,5 @@ test.pl
typemap
foo.i386.rpm
junk.xs
transaction.xs
header.xs

View File

@ -1,11 +1,18 @@
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'rpm',
'OBJECT' => 'rpm.o constant.o',
'VERSION_FROM' => 'rpm.pm', # finds $VERSION
'LIBS' => ['-lrpm -lz'], # e.g., '-lm'
'DEFINE' => '-Wall', # e.g., '-DHAVE_SOMETHING'
'INC' => '-I/usr/include/rpm', # e.g., '-I/usr/include/other'
'LIBS' => ['-lrpm -lz -ldb1'], # e.g., '-lm'
'CCFLAGS' => '-Dbool=char -DHAS_BOOL',
'OPTIMIZE'=> '-Wall -g',
#'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
'INC' => '-I/usr/include/rpm', # e.g., '-I/usr/include/other'
'depend' => { 'rpm.c' => 'transaction.xs header.xs db.xs' },
);
# $self->{'MAP_PRELIBS'} = ['-lnsl -lndbm -lgdbm -ldb1 -ldl -lm -lc -lposix -lcrypt -lrpm -lz'];

View File

@ -7,15 +7,19 @@ my $testfile = "foo.i386.rpm";
my $header = rpm::Header($testfile);
print "Test No. 1\n";
if ($header) {
my @foo_test = ();
my %foo_test = ();
my $key;
print "call to the header function SUCCEEDED\n";
@foo_test = $header->ItemByVal(1081);
print "values returned ", @foo_test, "\n\n\n";
@foo_test = $header->ItemByVal(1027);
print "values returned by ItemByVal(1027) ", join(' ',@foo_test), "\n\n\n";
@foo_test = $header->ItemByName("Filenames");
print "values returned by ItemByName(\"Filenames\") ", join(' ',@foo_test), "\n\n\n";
print "\n\nTest No. 2\n";
%foo_test = $header->List();
foreach $key (sort keys %foo_test) {
my $foo_it;
@ -26,8 +30,23 @@ if ($header) {
print "\n";
}
print "\n\nTest No. 3\n";
print "The number of header tags is: ", scalar $header->Tags(), "\n";
print "\n\nTest No. 4\n";
rpm::Debug();
my $db = rpm::dbOpen();
if ($db) {
my $rec = $db->First();
while ($rec != 0) {
my $hdr = $db->Record($rec);
print "Found header: Name=[", $hdr->ItemByName("Name"), "]\n";
$rec = $db->Next($rec);
}
$db->Close();
} else {
print "Could not open the RPM database! Error code: ", rpm::Error(), "\n";
}
} else {
print "call to the header function FAILED\n";
}

211
perl/header.xs Normal file
View File

@ -0,0 +1,211 @@
MODULE = rpm PACKAGE = Header PREFIX = Header
AV *
HeaderItemByValRef(header, item)
Header header
int item
PREINIT:
int_32 count, type;
int rc;
void * value;
char ** src;
AV * array;
CODE:
rc = headerGetEntry(header, item, &type, &value, &count);
array = newAV();
if (rc != 0) {
switch(type) {
case RPM_CHAR_TYPE:
while (count-- > 0) {
av_push(array, newSViv((char) (int) value));
value++;
}
break;
case RPM_INT8_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_8) (int) value));
value++;
}
break;
case RPM_INT16_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_16) (int) value));
value++;
}
break;
case RPM_INT32_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_32)value));
value++;
}
break;
case RPM_STRING_TYPE:
av_push(array, newSVpv((char *)value, 0));
break;
case RPM_BIN_TYPE:
/* XXX: this looks mostly unused - how do we deal with it? */
break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
src = (char **) value;
while (count--) {
av_push(array, newSVpv(*src++, 0));
}
free(value);
break;
}
}
RETVAL = array;
OUTPUT:
RETVAL
AV *
HeaderItemByNameRef(header, tag)
Header header
const char * tag
PREINIT:
int_32 count, type, item = -1;
int rc, i;
void * value;
char ** src;
AV * array;
CODE:
/* walk first through the list of items and get the proper value */
for (i = 0; i < rpmTagTableSize; i++) {
if (rpmTagTable[i].name != NULL && strcasecmp(tag, rpmTagTable[i].name + 7) == 0) {
item = rpmTagTable[i].val;
break;
}
}
rc = headerGetEntry(header, item, &type, &value, &count);
array = newAV();
if (rc != 0) {
switch(type) {
case RPM_CHAR_TYPE:
while (count-- > 0) {
av_push(array, newSViv((char) (int) value));
value++;
}
break;
case RPM_INT8_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_8) (int) value));
value++;
}
break;
case RPM_INT16_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_16) (int) value));
value++;
}
break;
case RPM_INT32_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_32)value));
value++;
}
break;
case RPM_STRING_TYPE:
av_push(array, newSVpv((char *)value, 0));
break;
case RPM_BIN_TYPE:
/* XXX: this looks mostly unused - how do we deal with it? */
break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
src = (char **) value;
while (count--) {
av_push(array, newSVpv(*src++, 0));
}
free(value);
break;
}
}
RETVAL = array;
OUTPUT:
RETVAL
HV *
HeaderListRef(header)
Header header
PREINIT:
HeaderIterator iterator;
int_32 tag, type, count;
void *value;
CODE:
RETVAL = newHV();
iterator = headerInitIterator(header);
while (headerNextIterator(iterator, &tag, &type, &value, &count)) {
SV ** sv;
AV * array;
char ** src;
char * tagStr = tagName(tag);
array = newAV();
switch(type) {
case RPM_CHAR_TYPE:
while (count-- > 0) {
av_push(array, newSViv((char) (int) value));
value++;
}
break;
case RPM_INT8_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_8) (int) value));
value++;
}
break;
case RPM_INT16_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_16) (int) value));
value++;
}
break;
case RPM_INT32_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_32)value));
value++;
}
break;
case RPM_STRING_TYPE:
av_push(array, newSVpv((char *)value, 0));
break;
case RPM_BIN_TYPE:
/* XXX: this looks mostly unused - how do we deal with it? */
break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
/* we have to build an array first */
src = (char **) value;
while (count--) {
av_push(array, newSVpv(*src++, 0));
}
free(value);
break;
}
sv = hv_store(RETVAL, tagStr, strlen(tagStr), newRV_inc((SV*)array), 0);
}
headerFreeIterator(iterator);
OUTPUT:
RETVAL
AV *
HeaderTagsRef(header)
Header header
PREINIT:
HeaderIterator iterator;
int_32 tag, type;
void *value;
CODE:
RETVAL = newAV();
iterator = headerInitIterator(header);
while (headerNextIterator(iterator, &tag, &type, &value, NULL)) {
av_push(RETVAL, newSVpv(tagName(tag), 0));
if (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE)
free(value);
}
headerFreeIterator(iterator);
OUTPUT:
RETVAL

View File

@ -44,7 +44,7 @@ bootstrap rpm $VERSION;
# Preloaded methods go here.
sub HeaderPtr::ItemByName {
sub Header::ItemByName {
my $header = shift;
my $item = shift;
my $item_index = shift;
@ -56,7 +56,7 @@ sub HeaderPtr::ItemByName {
}
}
sub HeaderPtr::ItemByVal {
sub Header::ItemByVal {
my $header = shift;
my $item = shift;
my $item_index = shift;
@ -68,13 +68,13 @@ sub HeaderPtr::ItemByVal {
}
}
sub HeaderPtr::List {
sub Header::List {
my $header = shift;
return %{$header->ListRef()};
}
sub HeaderPtr::Tags {
sub Header::Tags {
my $header = shift;
return @{$header->TagsRef()};

View File

@ -1,7 +1,7 @@
/*
* Perl interface to rpmlib
*
* $Id: rpm.xs,v 1.3 1999/07/14 22:06:21 gafton Exp $
* $Id: rpm.xs,v 1.4 1999/07/16 08:44:54 gafton Exp $
*/
#include "EXTERN.h"
@ -18,8 +18,6 @@
#include <sys/stat.h>
#include <fcntl.h>
typedef rpmTransactionSet_s * Transaction;
/*
* External functions
*/
@ -30,12 +28,19 @@ MODULE = rpm PACKAGE = rpm
PROTOTYPES: ENABLE
BOOT:
# The following message will be printed when the
# bootstrap function executes.
if (rpmReadConfigFiles(NULL, NULL) != 0) {
XSRETURN_NO;
}
double
constant(name,arg)
char * name
int arg
Header *
Header
Header(package)
const char * package
PREINIT:
@ -44,10 +49,10 @@ Header(package)
int isSource;
int had_error = 0;
CODE:
New(1,RETVAL,1,Header);
/* New(1,RETVAL,1,Header); */
file_desc = fdOpen(package, O_RDONLY, 0);
if (file_desc != NULL && RETVAL != NULL) {
rc = rpmReadPackageHeader(file_desc, RETVAL, &isSource, NULL, NULL);
rc = rpmReadPackageHeader(file_desc, &RETVAL, &isSource, NULL, NULL);
if (rc != 0) {
had_error++;
}
@ -61,255 +66,84 @@ Header(package)
if (had_error) {
ST(0) = &PL_sv_undef;
} else {
sv_setref_pv(ST(0), "HeaderPtr", (void*)RETVAL);
sv_setref_pv(ST(0), "Header", (void*)RETVAL);
}
Transaction *
rpmTransactionSet
Transaction(header)
Header * header
MODULE = rpm PACKAGE = HeaderPtr PREFIX = Header
AV *
HeaderItemByValRef(header, item)
Header * header
int item
PREINIT:
int_32 count, type;
int rc;
void * value;
char ** src;
AV * array;
CODE:
rc = headerGetEntry(*header, item, &type, &value, &count);
array = newAV();
if (rc != 0) {
switch(type) {
case RPM_CHAR_TYPE:
while (count-- > 0) {
av_push(array, newSViv((char) (int) value));
value++;
}
break;
case RPM_INT8_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_8) (int) value));
value++;
}
break;
case RPM_INT16_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_16) (int) value));
value++;
}
break;
case RPM_INT32_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_32)value));
value++;
}
break;
case RPM_STRING_TYPE:
av_push(array, newSVpv((char *)value, 0));
break;
case RPM_BIN_TYPE:
/* XXX: this looks mostly unused - how do we deal with it? */
break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
src = (char **) value;
while (count--) {
av_push(array, newSVpv(*src++, 0));
}
free(value);
break;
}
}
RETVAL = array;
OUTPUT:
RETVAL
AV *
HeaderItemByNameRef(header, tag)
Header * header
const char * tag
PREINIT:
int_32 count, type, item = -1;
int rc, i;
void * value;
char ** src;
AV * array;
Header header
CODE:
/* walk first through the list of items and get the proper value */
for (i = 0; i < rpmTagTableSize; i++) {
if (strcasecmp(tag, rpmTagTable[i].name) == 0) {
item = rpmTagTable[i].val;
break;
}
}
rc = headerGetEntry(*header, item, &type, &value, &count);
array = newAV();
if (rc != 0) {
switch(type) {
case RPM_CHAR_TYPE:
while (count-- > 0) {
av_push(array, newSViv((char) (int) value));
value++;
}
break;
case RPM_INT8_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_8) (int) value));
value++;
}
break;
case RPM_INT16_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_16) (int) value));
value++;
}
break;
case RPM_INT32_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_32)value));
value++;
}
break;
case RPM_STRING_TYPE:
av_push(array, newSVpv((char *)value, 0));
break;
case RPM_BIN_TYPE:
/* XXX: this looks mostly unused - how do we deal with it? */
break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
src = (char **) value;
while (count--) {
av_push(array, newSVpv(*src++, 0));
}
free(value);
break;
}
}
RETVAL = array;
OUTPUT:
RETVAL
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
HV *
HeaderListRef(header)
Header * header
rpmdb
dbOpen(root = "", forWrite = 0)
const char * root
int forWrite
PREINIT:
HeaderIterator iterator;
int_32 tag, type, count;
void *value;
int retval;
CODE:
RETVAL = newHV();
iterator = headerInitIterator(*header);
while (headerNextIterator(iterator, &tag, &type, &value, &count)) {
SV ** sv;
AV * array;
char ** src;
char * tagStr = tagName(tag);
array = newAV();
switch(type) {
case RPM_CHAR_TYPE:
while (count-- > 0) {
av_push(array, newSViv((char) (int) value));
value++;
}
break;
case RPM_INT8_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_8) (int) value));
value++;
}
break;
case RPM_INT16_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_16) (int) value));
value++;
}
break;
case RPM_INT32_TYPE:
while (count-- > 0) {
av_push(array, newSViv((int_32)value));
value++;
}
break;
case RPM_STRING_TYPE:
av_push(array, newSVpv((char *)value, 0));
break;
case RPM_BIN_TYPE:
/* XXX: this looks mostly unused - how do we deal with it? */
break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
/* we have to build an array first */
src = (char **) value;
while (count--) {
av_push(array, newSVpv(*src++, 0));
}
free(value);
break;
}
sv = hv_store(RETVAL, tagStr, strlen(tagStr), newRV_inc((SV*)array), 0);
retval = rpmdbOpen(root, &RETVAL, forWrite ? O_RDWR | O_CREAT : O_RDONLY, 0644);
printf("\nretval is %d\n", retval);
ST(0) = sv_newmortal();
if (retval != 0) {
ST(0) = &PL_sv_undef;
} else {
sv_setref_pv(ST(0), "rpmdb", (void *)RETVAL);
}
headerFreeIterator(iterator);
int
dbInit(root = NULL)
char * root
CODE:
RETVAL = rpmdbInit(root, 0);
OUTPUT:
RETVAL
AV *
HeaderTagsRef(header)
Header * header
PREINIT:
HeaderIterator iterator;
int_32 tag, type;
void *value;
CODE:
RETVAL = newAV();
iterator = headerInitIterator(*header);
while (headerNextIterator(iterator, &tag, &type, &value, NULL)) {
av_push(RETVAL, newSVpv(tagName(tag), 0));
if (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE)
free(value);
}
headerFreeIterator(iterator);
int
dbRebuild(root = NULL)
char * root
CODE:
RETVAL = rpmdbRebuild(root);
OUTPUT:
RETVAL
MODULE = rpm PACKAGE = TransactionPtr PREFIX = Trans
int
TransAdd(trans, header)
Transaction * trans
Header * header
Error()
CODE:
RETVAL = rpmErrorCode();
OUTPUT:
RETVAL
int
TransDepCheck(trans)
Transaction * trans
void
Debug(enable = 1)
int enable
CODE:
if (enable) {
rpmSetVerbosity(RPMMESS_DEBUG);
} else {
rpmSetVerbosity(RPMMESS_QUIET);
}
int
TransRun(trans)
Transaction * trans
char *
GetVar(var)
int var
CODE:
RETVAL = rpmGetVar(var);
OUTPUT:
RETVAL
Transaction *
TransOrder(trans)
Transaction *trans
void
SetVar(var, value)
int var
char * value
CODE:
rpmSetVar(var, value);
int
TransDealloc(trans)
Transaction * trans
INCLUDE: db.xs
INCLUDE: header.xs
INCLUDE: transaction.xs
int
TransGetAttr(trans, name)
Transaction * trans
const char * name
int
TransSetAttr(trans, name, val)
Transaction * trans
const char * name
void * val

56
perl/transaction.xs Normal file
View File

@ -0,0 +1,56 @@
MODULE = rpm PACKAGE = rpmTransactionSet PREFIX = Transaction
int
TransactionAdd(trans, header)
rpmTransactionSet trans
Header header
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
int
TransactionDepCheck(trans)
rpmTransactionSet trans
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
int
TransactionRun(trans)
rpmTransactionSet trans
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
rpmTransactionSet
TransactionOrder(trans)
rpmTransactionSet trans
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
int
TransactionDealloc(trans)
rpmTransactionSet trans
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
int
TransactionGetAttr(trans, name)
rpmTransactionSet trans
const char * name
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;
int
TransactionSetAttr(trans, name, val)
rpmTransactionSet trans
const char * name
void * val
CODE:
ST(0) = sv_newmortal();
ST(0) = &PL_sv_undef;

View File

@ -1,8 +1,9 @@
/* $Id: typemap,v 1.3 1999/07/14 22:06:21 gafton Exp $ */
/* $Id: typemap,v 1.4 1999/07/16 08:44:54 gafton Exp $ */
TYPEMAP
Header * T_PTROBJ
const char * T_PV
Transaction * T_PTROBJ
Header T_PTROBJ
rpmTransactionSet T_PTROBJ
rpmdb T_PTROBJ
const char * T_PV