summaryrefslogtreecommitdiff
path: root/Perl-RPM
diff options
context:
space:
mode:
authorrjray <devnull@localhost>2000-05-27 03:54:14 +0000
committerrjray <devnull@localhost>2000-05-27 03:54:14 +0000
commitb040c6b8b73fe32d637132e76386bfd2e8a11340 (patch)
treed9352258c58c4836e29c7308f5ff35bfc95c0933 /Perl-RPM
parentd8b0bb0bb10bcd821256967e78738f8d20ea6bb2 (diff)
downloadrpm-b040c6b8b73fe32d637132e76386bfd2e8a11340.tar.gz
rpm-b040c6b8b73fe32d637132e76386bfd2e8a11340.tar.bz2
rpm-b040c6b8b73fe32d637132e76386bfd2e8a11340.zip
merged here from individual dirs
CVS patchset: 3757 CVS date: 2000/05/27 03:54:14
Diffstat (limited to 'Perl-RPM')
-rw-r--r--Perl-RPM/RPM/Constants.pm1601
-rw-r--r--Perl-RPM/RPM/Constants.xs1842
-rw-r--r--Perl-RPM/RPM/Database.pm176
-rw-r--r--Perl-RPM/RPM/Database.xs513
-rw-r--r--Perl-RPM/RPM/Header.pm196
-rw-r--r--Perl-RPM/RPM/Header.xs1060
6 files changed, 5388 insertions, 0 deletions
diff --git a/Perl-RPM/RPM/Constants.pm b/Perl-RPM/RPM/Constants.pm
new file mode 100644
index 000000000..6a25ad464
--- /dev/null
+++ b/Perl-RPM/RPM/Constants.pm
@@ -0,0 +1,1601 @@
+###############################################################################
+#
+# (c) Copyright @ 2000, Red Hat Software, Inc.,
+# All Rights Reserved
+#
+###############################################################################
+#
+# $Id: Constants.pm,v 1.1 2000/05/27 03:54:14 rjray Exp $
+#
+# Description: Constants for the RPM package
+#
+# Functions: None-- constants are implemented as pseudo-functions
+#
+# Libraries: RPM (to force bootstrapping)
+#
+###############################################################################
+
+package RPM::Constants;
+
+use strict;
+use vars qw(@ISA @EXPORT_OK %EXPORT_TAGS $VERSION $revision $AUTOLOAD);
+
+require Exporter;
+
+use RPM;
+
+@ISA = qw(Exporter);
+
+$VERSION = $RPM::VERSION;
+$revision = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
+
+@EXPORT_OK = qw(
+ ADD_SIGNATURE
+ CHECKSIG_GPG
+ CHECKSIG_MD5
+ CHECKSIG_PGP
+ INSTALL_HASH
+ INSTALL_LABEL
+ INSTALL_NODEPS
+ INSTALL_NOORDER
+ INSTALL_PERCENT
+ INSTALL_UPGRADE
+ NEW_SIGNATURE
+ QUERY_FOR_CONFIG
+ QUERY_FOR_DOCS
+ QUERY_FOR_DUMPFILES
+ QUERY_FOR_LIST
+ QUERY_FOR_STATE
+ RPM_NULL_TYPE
+ RPM_CHAR_TYPE
+ RPM_INT8_TYPE
+ RPM_INT16_TYPE
+ RPM_INT32_TYPE
+ RPM_STRING_TYPE
+ RPM_BIN_TYPE
+ RPM_STRING_ARRAY_TYPE
+ RPM_I18NSTRING_TYPE
+ RPMERR_BADARG
+ RPMERR_BADDEV
+ RPMERR_BADFILENAME
+ RPMERR_BADMAGIC
+ RPMERR_BADRELOCATE
+ RPMERR_BADSIGTYPE
+ RPMERR_BADSPEC
+ RPMERR_CHOWN
+ RPMERR_CPIO
+ RPMERR_CREATE
+ RPMERR_DBCORRUPT
+ RPMERR_DBGETINDEX
+ RPMERR_DBOPEN
+ RPMERR_DBPUTINDEX
+ RPMERR_EXEC
+ RPMERR_FILECONFLICT
+ RPMERR_FLOCK
+ RPMERR_FORK
+ RPMERR_GDBMOPEN
+ RPMERR_GDBMREAD
+ RPMERR_GDBMWRITE
+ RPMERR_GZIP
+ RPMERR_INTERNAL
+ RPMERR_LDD
+ RPMERR_MKDIR
+ RPMERR_MTAB
+ RPMERR_NEWPACKAGE
+ RPMERR_NOCREATEDB
+ RPMERR_NOGROUP
+ RPMERR_NORELOCATE
+ RPMERR_NOSPACE
+ RPMERR_NOSPEC
+ RPMERR_NOTSRPM
+ RPMERR_NOUSER
+ RPMERR_OLDDB
+ RPMERR_OLDDBCORRUPT
+ RPMERR_OLDDBMISSING
+ RPMERR_OLDPACKAGE
+ RPMERR_PKGINSTALLED
+ RPMERR_READERROR
+ RPMERR_RENAME
+ RPMERR_RMDIR
+ RPMERR_RPMRC
+ RPMERR_SCRIPT
+ RPMERR_SIGGEN
+ RPMERR_STAT
+ RPMERR_UNKNOWNARCH
+ RPMERR_UNKNOWNOS
+ RPMERR_UNLINK
+ RPMERR_UNMATCHEDIF
+ RPMFILE_CONFIG
+ RPMFILE_DOC
+ RPMFILE_DONOTUSE
+ RPMFILE_GHOST
+ RPMFILE_LICENSE
+ RPMFILE_MISSINGOK
+ RPMFILE_NOREPLACE
+ RPMFILE_README
+ RPMFILE_SPECFILE
+ RPMFILE_STATE_NETSHARED
+ RPMFILE_STATE_NORMAL
+ RPMFILE_STATE_NOTINSTALLED
+ RPMFILE_STATE_REPLACED
+ RPMLEAD_BINARY
+ RPMLEAD_MAGIC0
+ RPMLEAD_MAGIC1
+ RPMLEAD_MAGIC2
+ RPMLEAD_MAGIC3
+ RPMLEAD_SIZE
+ RPMLEAD_SOURCE
+ RPMMESS_ALTNAME
+ RPMMESS_BACKUP
+ RPMMESS_DEBUG
+ RPMMESS_ERROR
+ RPMMESS_FATALERROR
+ RPMMESS_NORMAL
+ RPMMESS_PREREQLOOP
+ RPMMESS_QUIET
+ RPMMESS_VERBOSE
+ RPMMESS_WARNING
+ RPMPROB_FILTER_DISKSPACE
+ RPMPROB_FILTER_FORCERELOCATE
+ RPMPROB_FILTER_IGNOREARCH
+ RPMPROB_FILTER_IGNOREOS
+ RPMPROB_FILTER_OLDPACKAGE
+ RPMPROB_FILTER_REPLACENEWFILES
+ RPMPROB_FILTER_REPLACEOLDFILES
+ RPMPROB_FILTER_REPLACEPKG
+ RPMSENSE_EQUAL
+ RPMSENSE_GREATER
+ RPMSENSE_LESS
+ RPMSENSE_OBSOLETES
+ RPMSENSE_PREREQ
+ RPMSENSE_SENSEMASK
+ RPMSENSE_TRIGGER
+ RPMSENSE_TRIGGERIN
+ RPMSENSE_TRIGGERPOSTUN
+ RPMSENSE_TRIGGERUN
+ RPMSIGTAG_GPG
+ RPMSIGTAG_LEMD5_1
+ RPMSIGTAG_LEMD5_2
+ RPMSIGTAG_MD5
+ RPMSIGTAG_PGP
+ RPMSIGTAG_PGP5
+ RPMSIGTAG_SIZE
+ RPMSIG_BAD
+ RPMSIG_NOKEY
+ RPMSIG_NOTTRUSTED
+ RPMSIG_OK
+ RPMSIG_UNKNOWN
+ RPMTAG_ARCH
+ RPMTAG_ARCHIVESIZE
+ RPMTAG_BASENAMES
+ RPMTAG_BUILDARCHS
+ RPMTAG_BUILDHOST
+ RPMTAG_BUILDMACROS
+ RPMTAG_BUILDROOT
+ RPMTAG_BUILDTIME
+ RPMTAG_CAPABILITY
+ RPMTAG_CHANGELOGNAME
+ RPMTAG_CHANGELOGTEXT
+ RPMTAG_CHANGELOGTIME
+ RPMTAG_CONFLICTFLAGS
+ RPMTAG_CONFLICTNAME
+ RPMTAG_CONFLICTVERSION
+ RPMTAG_COOKIE
+ RPMTAG_DEFAULTPREFIX
+ RPMTAG_DESCRIPTION
+ RPMTAG_DIRINDEXES
+ RPMTAG_DIRNAMES
+ RPMTAG_DISTRIBUTION
+ RPMTAG_DOCDIR
+ RPMTAG_EPOCH
+ RPMTAG_EXCLUDE
+ RPMTAG_EXCLUDEARCH
+ RPMTAG_EXCLUDEOS
+ RPMTAG_EXCLUSIVE
+ RPMTAG_EXCLUSIVEARCH
+ RPMTAG_EXCLUSIVEOS
+ RPMTAG_EXTERNAL_TAG
+ RPMTAG_FILEDEVICES
+ RPMTAG_FILEFLAGS
+ RPMTAG_FILEGIDS
+ RPMTAG_FILEGROUPNAME
+ RPMTAG_FILEINODES
+ RPMTAG_FILELANGS
+ RPMTAG_FILELINKTOS
+ RPMTAG_FILEMD5S
+ RPMTAG_FILEMODES
+ RPMTAG_FILEMTIMES
+ RPMTAG_FILERDEVS
+ RPMTAG_FILESIZES
+ RPMTAG_FILESTATES
+ RPMTAG_FILEUIDS
+ RPMTAG_FILEUSERNAME
+ RPMTAG_FILEVERIFYFLAGS
+ RPMTAG_FIRSTFREE_TAG
+ RPMTAG_GIF
+ RPMTAG_GROUP
+ RPMTAG_HASH_BASE
+ RPMTAG_HASH_HAVAL_5_160
+ RPMTAG_HASH_MD2
+ RPMTAG_HASH_MD5
+ RPMTAG_HASH_RIPEMD160
+ RPMTAG_HASH_SHA1
+ RPMTAG_HASH_TIGER192
+ RPMTAG_ICON
+ RPMTAG_INSTALLPREFIX
+ RPMTAG_INSTALLTIME
+ RPMTAG_INSTPREFIXES
+ RPMTAG_LICENSE
+ RPMTAG_NAME
+ RPMTAG_NOPATCH
+ RPMTAG_NOSOURCE
+ RPMTAG_OBSOLETEFLAGS
+ RPMTAG_OBSOLETENAME
+ RPMTAG_OBSOLETEVERSION
+ RPMTAG_ORIGBASENAMES
+ RPMTAG_ORIGDIRINDEXES
+ RPMTAG_ORIGDIRNAMES
+ RPMTAG_OS
+ RPMTAG_PACKAGER
+ RPMTAG_PATCH
+ RPMTAG_PK_BASE
+ RPMTAG_PK_DH
+ RPMTAG_PK_DSA
+ RPMTAG_PK_ECDSA
+ RPMTAG_PK_ELGAMAL_E
+ RPMTAG_PK_ELGAMAL_ES
+ RPMTAG_PK_ELLIPTIC
+ RPMTAG_PK_RSA_E
+ RPMTAG_PK_RSA_ES
+ RPMTAG_PK_RSA_S
+ RPMTAG_POSTIN
+ RPMTAG_POSTINPROG
+ RPMTAG_POSTUN
+ RPMTAG_POSTUNPROG
+ RPMTAG_PREFIXES
+ RPMTAG_PREIN
+ RPMTAG_PREINPROG
+ RPMTAG_PREREQ
+ RPMTAG_PREUN
+ RPMTAG_PREUNPROG
+ RPMTAG_PROVIDEFLAGS
+ RPMTAG_PROVIDENAME
+ RPMTAG_PROVIDEVERSION
+ RPMTAG_RELEASE
+ RPMTAG_REQUIREFLAGS
+ RPMTAG_REQUIRENAME
+ RPMTAG_REQUIREVERSION
+ RPMTAG_RPMVERSION
+ RPMTAG_SIZE
+ RPMTAG_SOURCE
+ RPMTAG_SOURCEPACKAGE
+ RPMTAG_SOURCERPM
+ RPMTAG_SUMMARY
+ RPMTAG_TRIGGERFLAGS
+ RPMTAG_TRIGGERIN
+ RPMTAG_TRIGGERINDEX
+ RPMTAG_TRIGGERNAME
+ RPMTAG_TRIGGERPOSTUN
+ RPMTAG_TRIGGERSCRIPTPROG
+ RPMTAG_TRIGGERSCRIPTS
+ RPMTAG_TRIGGERUN
+ RPMTAG_TRIGGERVERSION
+ RPMTAG_URL
+ RPMTAG_VENDOR
+ RPMTAG_VERIFYSCRIPT
+ RPMTAG_VERIFYSCRIPTPROG
+ RPMTAG_VERSION
+ RPMTAG_XPM
+ RPMTRANS_FLAG_ALLFILES
+ RPMTRANS_FLAG_BUILD_PROBS
+ RPMTRANS_FLAG_JUSTDB
+ RPMTRANS_FLAG_KEEPOBSOLETE
+ RPMTRANS_FLAG_NODOCS
+ RPMTRANS_FLAG_NOSCRIPTS
+ RPMTRANS_FLAG_NOTRIGGERS
+ RPMTRANS_FLAG_TEST
+ RPMVERIFY_ALL
+ RPMVERIFY_FILESIZE
+ RPMVERIFY_GROUP
+ RPMVERIFY_LINKTO
+ RPMVERIFY_LSTATFAIL
+ RPMVERIFY_MD5
+ RPMVERIFY_MODE
+ RPMVERIFY_MTIME
+ RPMVERIFY_NONE
+ RPMVERIFY_RDEV
+ RPMVERIFY_READFAIL
+ RPMVERIFY_READLINKFAIL
+ RPMVERIFY_USER
+ UNINSTALL_ALLMATCHES
+ UNINSTALL_NODEPS
+ VERIFY_DEPS
+ VERIFY_FILES
+ VERIFY_MD5
+ VERIFY_SCRIPT
+ );
+
+#
+# To create the %EXPORT_TAGS table, we're going to create a temp hash with
+# the tags broken down into groupings. Then when the "known" groupings are
+# done, whatever is left can go in "misc"
+#
+my %groups = ();
+my %consts = map { $_, 1 } @EXPORT_OK;
+for my $group (qw(install query rpmerr rpmfile rpmlead rpmmess rpmprob_filter
+ rpmsense rpmsigtag rpmsig rpmtag rpmtrans_flag
+ rpmverify uninstall verify))
+{
+ my $pat = qr/^$group/i;
+ my $list = [];
+
+ for (grep($_ =~ $pat, sort keys %consts))
+ {
+ push(@$list, $_);
+ delete $consts{$_};
+ }
+
+ $groups{$group} = $list;
+}
+
+# Types didn't fit neatly into the above logic-loop
+$groups{rpmtype} = [];
+for (grep($_ =~ /^RPM_.*_TYPE/, sort keys %consts))
+{
+ push(@{$groups{rpmtype}}, $_);
+ delete $consts{$_};
+}
+
+# Pick up any stragglers
+$groups{misc} = [ sort keys %consts ];
+
+# Merge the install and uninstall groups
+push(@{$groups{install}}, @{$groups{uninstall}});
+delete $groups{uninstall};
+
+%EXPORT_TAGS = (
+ all => [ @EXPORT_OK ],
+ %groups
+ );
+
+sub AUTOLOAD {
+ my $constname;
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ die "& not defined" if $constname eq 'constant';
+ my $val = constant($constname, @_ ? $_[0] : 0);
+ if ($! != 0) {
+ if ($! =~ /Invalid/) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+ goto &AutoLoader::AUTOLOAD;
+ }
+ else {
+ die "Your vendor has not defined RPM macro $constname";
+ }
+ }
+ no strict 'refs';
+ *$AUTOLOAD = sub { $val };
+ goto &$AUTOLOAD;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+RPM::Constants - Groups of RPM-defined symbols
+
+=head1 SYNOPSIS
+
+ use RPM::Constants qw(:rpmerr :rpmtypes);
+
+=head1 DESCRIPTION
+
+This package is a collection of the constants defined by B<rpm> itself that
+may be of use to those developing with the B<RPM> Perl bindings.
+
+=head1 GROUPS
+
+For ease of use and uderstanding (at last count, the total number of
+constants was 293), the constants are broken up into several smaller groups:
+
+=head2 Header Tag Identifiers
+
+The following symbols may be imported via the tag B<:rpmtag>, and represent
+the various elements that may be present in a package header:
+
+=over
+
+=item RPMTAG_ARCH
+
+Name of the architecture that the package was built for. If the package
+is architecture-independant, the value should read "noarch".
+
+=item RPMTAG_ARCHIVESIZE
+
+Size of the archive portion of the file (total file size minus header data).
+
+=item RPMTAG_BASENAMES
+
+A list of the base (leaf) names of the files contained within the package.
+These are combined with the values from B<RPMTAG_DIRNAMES> using a mapping
+provided by B<RPMTAG_DIRINDEXES>.
+
+=item RPMTAG_BUILDARCHS
+
+Not documented yet.
+
+=item RPMTAG_BUILDHOST
+
+Name of the host the package was built on.
+
+=item RPMTAG_BUILDMACROS
+
+Not documented yet.
+
+=item RPMTAG_BUILDROOT
+
+Specifies the root at which the package is built.
+
+=item RPMTAG_BUILDTIME
+
+The time/date when the package was created, expressed as a C<time()> value
+(seconds since the epoch).
+
+=item RPMTAG_CAPABILITY
+
+Not certain. See the B<RPMTAG_PROVIDE*> and B<RPMTAG_REQUIRE*> groups.
+
+=item RPMTAG_CHANGELOGNAME
+
+=item RPMTAG_CHANGELOGTEXT
+
+=item RPMTAG_CHANGELOGTIME
+
+These three items should be taken together. Each should have the same number
+of items, and the items at corresponding indices should be taken together.
+Taken this way, they provide a small-scale changelog for the package, detailing
+the name of the person making the entry, the text of the entry and the time
+of the entry, in the respective order given above.
+
+=item RPMTAG_CONFLICTFLAGS
+
+Not documented yet.
+
+=item RPMTAG_CONFLICTNAME
+
+Not documented yet.
+
+=item RPMTAG_CONFLICTVERSION
+
+Not documented yet.
+
+=item RPMTAG_COOKIE
+
+Not documented yet.
+
+=item RPMTAG_DEFAULTPREFIX
+
+Not documented yet.
+
+=item RPMTAG_DESCRIPTION
+
+A textual description of the package.
+
+=item RPMTAG_DIRINDEXES
+
+This data should have a one-to-one correspondance with B<RPMTAG_BASENAMES>,
+above. Each item here is a numerical index into the list of directories named
+in B<RPMTAG_DIRNAMES> below. It indicates which of the directories is to be
+prepended to the corresponding base file name in order to create the full
+pathname.
+
+=item RPMTAG_DIRNAMES
+
+This is a list of all directories into which the package would install files.
+This list is used with B<RPMTAG_BASENAMES> to create full paths, indexed by
+way of B<RPMTAG_DIRINDEXES> above.
+
+=item RPMTAG_DISTRIBUTION
+
+Not documented yet.
+
+=item RPMTAG_DOCDIR
+
+Not documented yet.
+
+=item RPMTAG_EPOCH
+
+Not documented yet.
+
+=item RPMTAG_EXCLUDE
+
+Not documented yet.
+
+=item RPMTAG_EXCLUDEARCH
+
+Not documented yet.
+
+=item RPMTAG_EXCLUDEOS
+
+Not documented yet.
+
+=item RPMTAG_EXCLUSIVE
+
+Not documented yet.
+
+=item RPMTAG_EXCLUSIVEARCH
+
+Not documented yet.
+
+=item RPMTAG_EXCLUSIVEOS
+
+Not documented yet.
+
+=item RPMTAG_EXTERNAL_TAG
+
+Not documented yet.
+
+=item RPMTAG_FILEDEVICES
+
+Not documented yet.
+
+=item RPMTAG_FILEFLAGS
+
+Not documented yet.
+
+=item RPMTAG_FILEGIDS
+
+Not documented yet.
+
+=item RPMTAG_FILEGROUPNAME
+
+Not documented yet.
+
+=item RPMTAG_FILEINODES
+
+Not documented yet.
+
+=item RPMTAG_FILELANGS
+
+Not documented yet.
+
+=item RPMTAG_FILELINKTOS
+
+Not documented yet.
+
+=item RPMTAG_FILEMD5S
+
+Not documented yet.
+
+=item RPMTAG_FILEMODES
+
+Not documented yet.
+
+=item RPMTAG_FILEMTIMES
+
+Not documented yet.
+
+=item RPMTAG_FILERDEVS
+
+Not documented yet.
+
+=item RPMTAG_FILESIZES
+
+Not documented yet.
+
+=item RPMTAG_FILESTATES
+
+Not documented yet.
+
+=item RPMTAG_FILEUIDS
+
+Not documented yet.
+
+=item RPMTAG_FILEUSERNAME
+
+Not documented yet.
+
+=item RPMTAG_FILEVERIFYFLAGS
+
+Not documented yet.
+
+=item RPMTAG_FIRSTFREE_TAG
+
+=item RPMTAG_GIF
+
+Not directly used by the B<rpm> library. Likely intended to hold a GIF
+image that external software could make use of. See C<RPMTAG_XPM> below.
+
+=item RPMTAG_GROUP
+
+Not documented yet.
+
+=item RPMTAG_HASH_BASE
+
+Not documented yet.
+
+=item RPMTAG_HASH_HAVAL_5_160
+
+Not documented yet.
+
+=item RPMTAG_HASH_MD2
+
+Not documented yet.
+
+=item RPMTAG_HASH_MD5
+
+Not documented yet.
+
+=item RPMTAG_HASH_RIPEMD160
+
+Not documented yet.
+
+=item RPMTAG_HASH_SHA1
+
+Not documented yet.
+
+=item RPMTAG_HASH_TIGER192
+
+Not documented yet.
+
+=item RPMTAG_ICON
+
+Not directly used by the B<rpm> library. Likely intended to hold an image
+of some neutral format that external software could make use of.
+See C<RPMTAG_XPM> below and C<RPMTAG_GIF> above.
+
+=item RPMTAG_INSTALLPREFIX
+
+Not documented yet.
+
+=item RPMTAG_INSTALLTIME
+
+Not documented yet.
+
+=item RPMTAG_INSTPREFIXES
+
+Not documented yet.
+
+=item RPMTAG_LICENSE
+
+The license and/or restrictions under which the package is distributed.
+
+=item RPMTAG_NAME
+
+The name of the package. This is the first part of a triple used to uniquely
+identify a given package. It is used in conjunction with B<RPMTAG_VERSION>
+and B<RPMTAG_RELEASE>, in that order.
+
+=item RPMTAG_NOPATCH
+
+Not documented yet.
+
+=item RPMTAG_NOSOURCE
+
+Not documented yet.
+
+=item RPMTAG_OBSOLETEFLAGS
+
+Not documented yet.
+
+=item RPMTAG_OBSOLETENAME
+
+Not documented yet.
+
+=item RPMTAG_OBSOLETEVERSION
+
+Not documented yet.
+
+=item RPMTAG_ORIGBASENAMES
+
+Not documented yet.
+
+=item RPMTAG_ORIGDIRINDEXES
+
+Not documented yet.
+
+=item RPMTAG_ORIGDIRNAMES
+
+Not documented yet.
+
+=item RPMTAG_OS
+
+The name of the O/S for which the package is intended.
+
+=item RPMTAG_PACKAGER
+
+Name of the group/company/individual who built the package.
+
+=item RPMTAG_PATCH
+
+Not documented yet.
+
+=item RPMTAG_PK_BASE
+
+Not documented yet.
+
+=item RPMTAG_PK_DH
+
+Not documented yet.
+
+=item RPMTAG_PK_DSA
+
+Not documented yet.
+
+=item RPMTAG_PK_ECDSA
+
+Not documented yet.
+
+=item RPMTAG_PK_ELGAMAL_E
+
+Not documented yet.
+
+=item RPMTAG_PK_ELGAMAL_ES
+
+Not documented yet.
+
+=item RPMTAG_PK_ELLIPTIC
+
+Not documented yet.
+
+=item RPMTAG_PK_RSA_E
+
+Not documented yet.
+
+=item RPMTAG_PK_RSA_ES
+
+Not documented yet.
+
+=item RPMTAG_PK_RSA_S
+
+Not documented yet.
+
+=item RPMTAG_POSTIN
+
+Not documented yet.
+
+=item RPMTAG_POSTINPROG
+
+Not documented yet.
+
+=item RPMTAG_POSTUN
+
+Not documented yet.
+
+=item RPMTAG_POSTUNPROG
+
+Not documented yet.
+
+=item RPMTAG_PREFIXES
+
+Not documented yet.
+
+=item RPMTAG_PREIN
+
+Not documented yet.
+
+=item RPMTAG_PREINPROG
+
+Not documented yet.
+
+=item RPMTAG_PREREQ
+
+Not documented yet.
+
+=item RPMTAG_PREUN
+
+Not documented yet.
+
+=item RPMTAG_PREUNPROG
+
+Not documented yet.
+
+=item RPMTAG_PROVIDEFLAGS
+
+Not documented yet.
+
+=item RPMTAG_PROVIDENAME
+
+Not documented yet.
+
+=item RPMTAG_PROVIDEVERSION
+
+Not documented yet.
+
+=item RPMTAG_RELEASE
+
+The release part of the identifying triple for a package. This is combined
+with the B<RPMTAG_NAME> and B<RPMTAG_VERSION> tags to create a unique
+identification for each package.
+
+=item RPMTAG_REQUIREFLAGS
+
+=item RPMTAG_REQUIRENAME
+
+=item RPMTAG_REQUIREVERSION
+
+These three items are used in conjunction to specify packages and/or individual
+files on which the package itself depends. Of the three, only
+B<RPMTAG_REQUIRENAME> is required to have data in all elements of the array.
+The other two wil have the same number of elements, though some (or most) may
+be null.
+
+=item RPMTAG_RPMVERSION
+
+The version of B<rpm> used when bundling the package.
+
+=item RPMTAG_SIZE
+
+Total size of the package, when existant as a disk file.
+
+=item RPMTAG_SOURCE
+
+An integer value that should be treated as a boolean, true (1) if the package
+is a source-RPM (SRPM) and false (0) if it is not. Generally, if it is not a
+source-RPM then this tag will simply not be present on the header.
+
+=item RPMTAG_SOURCERPM
+
+The source-RPM (SRPM) file used to build this package. If the file being
+queried is itself a source-RPM, this tag will be non-existent or null in
+value.
+
+=item RPMTAG_SUMMARY
+
+A one line summary description of the package.
+
+=item RPMTAG_TRIGGERFLAGS
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERIN
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERINDEX
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERNAME
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERPOSTUN
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERSCRIPTPROG
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERSCRIPTS
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERUN
+
+Not documented yet.
+
+=item RPMTAG_TRIGGERVERSION
+
+Not documented yet.
+
+=item RPMTAG_URL
+
+A Uniform Resource Locator (generally a WWW page) for the vendor/individual
+or for the software project itself.
+
+=item RPMTAG_VENDOR
+
+An alternate identifier for the company that created and provided the package.
+
+=item RPMTAG_VERIFYSCRIPT
+
+Not documented yet.
+
+=item RPMTAG_VERIFYSCRIPTPROG
+
+Not documented yet.
+
+=item RPMTAG_VERSION
+
+The package version, the second part (with B<RPMTAG_NAME> and
+B<RPMTAG_RELEASE>) of the triple used to uniquely identify packages.
+
+=item RPMTAG_XPM
+
+Not directly used by the B<rpm> library. Likely intended to hold an XPM
+image that external software could make use of. See C<RPMTAG_GIF> above.
+
+=back
+
+=head2 Header Data Types
+
+The following symbols may be imported via the tag B<:rpmtype>, and represent
+the different types of which the various header tags (described above) may
+return data:
+
+=over
+
+=item RPM_NULL_TYPE
+
+This is used internally by the C-level B<rpm> library.
+
+=item RPM_CHAR_TYPE
+
+This type represents single-character data.
+
+=item RPM_INT8_TYPE
+
+All items of this type are 8-bit integers.
+
+=item RPM_INT16_TYPE
+
+This type represents 16-bit integers.
+
+=item RPM_INT32_TYPE
+
+This type represents 32-bit integers.
+
+=item RPM_BIN_TYPE
+
+Data of this type represents a chunk of binary data without any further
+decoding or translation. It is stored as a string in Perl terms, and the
+C<length> keyword should return the size of the chunk.
+
+=item RPM_STRING_TYPE
+
+=item RPM_STRING_ARRAY_TYPE
+
+=item RPM_I18NSTRING_TYPE
+
+These data types represent strings of text. Each are stored and treated the
+same internally by Perl.
+
+=back
+
+=head2 Error Codes
+
+The following symbols may be imported via the tag B<:rpmerr>. They represent
+the set of pre-defined error conditions that the B<rpm> system anticipates
+as possibly occuring:
+
+=over
+
+=item RPMERR_BADARG
+
+Not documented yet.
+
+=item RPMERR_BADDEV
+
+Not documented yet.
+
+=item RPMERR_BADFILENAME
+
+Not documented yet.
+
+=item RPMERR_BADMAGIC
+
+Not documented yet.
+
+=item RPMERR_BADRELOCATE
+
+Not documented yet.
+
+=item RPMERR_BADSIGTYPE
+
+Not documented yet.
+
+=item RPMERR_BADSPEC
+
+Not documented yet.
+
+=item RPMERR_CHOWN
+
+Not documented yet.
+
+=item RPMERR_CPIO
+
+Not documented yet.
+
+=item RPMERR_CREATE
+
+Not documented yet.
+
+=item RPMERR_DBCORRUPT
+
+Not documented yet.
+
+=item RPMERR_DBGETINDEX
+
+Not documented yet.
+
+=item RPMERR_DBOPEN
+
+Not documented yet.
+
+=item RPMERR_DBPUTINDEX
+
+Not documented yet.
+
+=item RPMERR_EXEC
+
+Not documented yet.
+
+=item RPMERR_FILECONFLICT
+
+Not documented yet.
+
+=item RPMERR_FLOCK
+
+Not documented yet.
+
+=item RPMERR_FORK
+
+Not documented yet.
+
+=item RPMERR_GDBMOPEN
+
+Not documented yet.
+
+=item RPMERR_GDBMREAD
+
+Not documented yet.
+
+=item RPMERR_GDBMWRITE
+
+Not documented yet.
+
+=item RPMERR_GZIP
+
+Not documented yet.
+
+=item RPMERR_INTERNAL
+
+Not documented yet.
+
+=item RPMERR_LDD
+
+Not documented yet.
+
+=item RPMERR_MKDIR
+
+Not documented yet.
+
+=item RPMERR_MTAB
+
+Not documented yet.
+
+=item RPMERR_NEWPACKAGE
+
+Not documented yet.
+
+=item RPMERR_NOCREATEDB
+
+Not documented yet.
+
+=item RPMERR_NOGROUP
+
+Not documented yet.
+
+=item RPMERR_NORELOCATE
+
+Not documented yet.
+
+=item RPMERR_NOSPACE
+
+Not documented yet.
+
+=item RPMERR_NOSPEC
+
+Not documented yet.
+
+=item RPMERR_NOTSRPM
+
+Not documented yet.
+
+=item RPMERR_NOUSER
+
+Not documented yet.
+
+=item RPMERR_OLDDB
+
+Not documented yet.
+
+=item RPMERR_OLDDBCORRUPT
+
+Not documented yet.
+
+=item RPMERR_OLDDBMISSING
+
+Not documented yet.
+
+=item RPMERR_OLDPACKAGE
+
+Not documented yet.
+
+=item RPMERR_PKGINSTALLED
+
+Not documented yet.
+
+=item RPMERR_READERROR
+
+Not documented yet.
+
+=item RPMERR_RENAME
+
+Not documented yet.
+
+=item RPMERR_RMDIR
+
+Not documented yet.
+
+=item RPMERR_RPMRC
+
+Not documented yet.
+
+=item RPMERR_SCRIPT
+
+Not documented yet.
+
+=item RPMERR_SIGGEN
+
+Not documented yet.
+
+=item RPMERR_STAT
+
+Not documented yet.
+
+=item RPMERR_UNKNOWNARCH
+
+Not documented yet.
+
+=item RPMERR_UNKNOWNOS
+
+Not documented yet.
+
+=item RPMERR_UNLINK
+
+Not documented yet.
+
+=item RPMERR_UNMATCHEDIF
+
+Not documented yet.
+
+=back
+
+=head2 Pre-requisite Sense Flags
+
+The following values may be imported via the tag B<:rpmsense>, and are
+used with the values from B<RPMTAG_REQUIREFLAGS> to establish the nature
+of the requirement relationship:
+
+=over
+
+=item RPMSENSE_SENSEMASK
+
+This is a mask that, when applied to a value from B<RPMTAG_REQUIREFLAGS>,
+masks out all bits except for the following three values:
+
+=item RPMSENSE_EQUAL
+
+=item RPMSENSE_GREATER
+
+=item RPMSENSE_LESS
+
+These values are used to check the corresponding entries from
+B<RPMTAG_REQUIRENAME> and B<RPMTAG_REQUIREVERSION>, and specify whether
+the existing file should be of a version equal to, greater than or less than
+the version specified. More than one flag may be present.
+
+=item RPMSENSE_PREREQ
+
+The corresponding item from B<RPMTAG_REQUIRENAME> is a simple pre-requisite,
+generally without specific version checking.
+
+=item RPMSENSE_TRIGGER
+
+Not documented yet.
+
+=item RPMSENSE_TRIGGERIN
+
+Not documented yet.
+
+=item RPMSENSE_TRIGGERPOSTUN
+
+Not documented yet.
+
+=item RPMSENSE_TRIGGERUN
+
+Not documented yet.
+
+=back
+
+=head2 Not Yet Defined
+
+=over
+
+=item ADD_SIGNATURE
+
+Not documented yet.
+
+=item CHECKSIG_GPG
+
+Not documented yet.
+
+=item CHECKSIG_MD5
+
+Not documented yet.
+
+=item CHECKSIG_PGP
+
+Not documented yet.
+
+=item INSTALL_HASH
+
+Not documented yet.
+
+=item INSTALL_LABEL
+
+Not documented yet.
+
+=item INSTALL_NODEPS
+
+Not documented yet.
+
+=item INSTALL_NOORDER
+
+Not documented yet.
+
+=item INSTALL_PERCENT
+
+Not documented yet.
+
+=item INSTALL_UPGRADE
+
+Not documented yet.
+
+=item NEW_SIGNATURE
+
+Not documented yet.
+
+=item QUERY_FOR_CONFIG
+
+Not documented yet.
+
+=item QUERY_FOR_DOCS
+
+Not documented yet.
+
+=item QUERY_FOR_DUMPFILES
+
+Not documented yet.
+
+=item QUERY_FOR_LIST
+
+Not documented yet.
+
+=item QUERY_FOR_STATE
+
+Not documented yet.
+
+=item RPMFILE_CONFIG
+
+Not documented yet.
+
+=item RPMFILE_DOC
+
+Not documented yet.
+
+=item RPMFILE_DONOTUSE
+
+Not documented yet.
+
+=item RPMFILE_GHOST
+
+Not documented yet.
+
+=item RPMFILE_LICENSE
+
+Not documented yet.
+
+=item RPMFILE_MISSINGOK
+
+Not documented yet.
+
+=item RPMFILE_NOREPLACE
+
+Not documented yet.
+
+=item RPMFILE_README
+
+Not documented yet.
+
+=item RPMFILE_SPECFILE
+
+Not documented yet.
+
+=item RPMFILE_STATE_NETSHARED
+
+Not documented yet.
+
+=item RPMFILE_STATE_NORMAL
+
+Not documented yet.
+
+=item RPMFILE_STATE_NOTINSTALLED
+
+Not documented yet.
+
+=item RPMFILE_STATE_REPLACED
+
+Not documented yet.
+
+=item RPMLEAD_BINARY
+
+Not documented yet.
+
+=item RPMLEAD_MAGIC0
+
+Not documented yet.
+
+=item RPMLEAD_MAGIC1
+
+Not documented yet.
+
+=item RPMLEAD_MAGIC2
+
+Not documented yet.
+
+=item RPMLEAD_MAGIC3
+
+Not documented yet.
+
+=item RPMLEAD_SIZE
+
+Not documented yet.
+
+=item RPMLEAD_SOURCE
+
+Not documented yet.
+
+=item RPMMESS_ALTNAME
+
+Not documented yet.
+
+=item RPMMESS_BACKUP
+
+Not documented yet.
+
+=item RPMMESS_DEBUG
+
+Not documented yet.
+
+=item RPMMESS_ERROR
+
+Not documented yet.
+
+=item RPMMESS_FATALERROR
+
+Not documented yet.
+
+=item RPMMESS_NORMAL
+
+Not documented yet.
+
+=item RPMMESS_PREREQLOOP
+
+Not documented yet.
+
+=item RPMMESS_QUIET
+
+Not documented yet.
+
+=item RPMMESS_VERBOSE
+
+Not documented yet.
+
+=item RPMMESS_WARNING
+
+Not documented yet.
+
+=item RPMPROB_FILTER_DISKSPACE
+
+Not documented yet.
+
+=item RPMPROB_FILTER_FORCERELOCATE
+
+Not documented yet.
+
+=item RPMPROB_FILTER_IGNOREARCH
+
+Not documented yet.
+
+=item RPMPROB_FILTER_IGNOREOS
+
+Not documented yet.
+
+=item RPMPROB_FILTER_OLDPACKAGE
+
+Not documented yet.
+
+=item RPMPROB_FILTER_REPLACENEWFILES
+
+Not documented yet.
+
+=item RPMPROB_FILTER_REPLACEOLDFILES
+
+Not documented yet.
+
+=item RPMPROB_FILTER_REPLACEPKG
+
+Not documented yet.
+
+=item RPMSIGTAG_GPG
+
+Not documented yet.
+
+=item RPMSIGTAG_LEMD5_1
+
+Not documented yet.
+
+=item RPMSIGTAG_LEMD5_2
+
+Not documented yet.
+
+=item RPMSIGTAG_MD5
+
+Not documented yet.
+
+=item RPMSIGTAG_PGP
+
+Not documented yet.
+
+=item RPMSIGTAG_PGP5
+
+Not documented yet.
+
+=item RPMSIGTAG_SIZE
+
+Not documented yet.
+
+=item RPMSIG_BAD
+
+Not documented yet.
+
+=item RPMSIG_NOKEY
+
+Not documented yet.
+
+=item RPMSIG_NOTTRUSTED
+
+Not documented yet.
+
+=item RPMSIG_OK
+
+Not documented yet.
+
+=item RPMSIG_UNKNOWN
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_ALLFILES
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_BUILD_PROBS
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_JUSTDB
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_KEEPOBSOLETE
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_NODOCS
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_NOSCRIPTS
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_NOTRIGGERS
+
+Not documented yet.
+
+=item RPMTRANS_FLAG_TEST
+
+Not documented yet.
+
+=item RPMVERIFY_ALL
+
+Not documented yet.
+
+=item RPMVERIFY_FILESIZE
+
+Not documented yet.
+
+=item RPMVERIFY_GROUP
+
+Not documented yet.
+
+=item RPMVERIFY_LINKTO
+
+Not documented yet.
+
+=item RPMVERIFY_LSTATFAIL
+
+Not documented yet.
+
+=item RPMVERIFY_MD5
+
+Not documented yet.
+
+=item RPMVERIFY_MODE
+
+Not documented yet.
+
+=item RPMVERIFY_MTIME
+
+Not documented yet.
+
+=item RPMVERIFY_NONE
+
+Not documented yet.
+
+=item RPMVERIFY_RDEV
+
+Not documented yet.
+
+=item RPMVERIFY_READFAIL
+
+Not documented yet.
+
+=item RPMVERIFY_READLINKFAIL
+
+Not documented yet.
+
+=item RPMVERIFY_USER
+
+Not documented yet.
+
+=item UNINSTALL_ALLMATCHES
+
+Not documented yet.
+
+=item UNINSTALL_NODEPS
+
+Not documented yet.
+
+=item VERIFY_DEPS
+
+Not documented yet.
+
+=item VERIFY_FILES
+
+Not documented yet.
+
+=item VERIFY_MD5
+
+Not documented yet.
+
+=item VERIFY_SCRIPT
+
+Not documented yet.
+
+=back
+
+=head1 SEE ALSO
+
+L<RPM>, L<perl>, L<rpm>
+
+=head1 AUTHOR
+
+Randy J. Ray <rjray@blackperl.com>
+
+=cut
diff --git a/Perl-RPM/RPM/Constants.xs b/Perl-RPM/RPM/Constants.xs
new file mode 100644
index 000000000..882725fd2
--- /dev/null
+++ b/Perl-RPM/RPM/Constants.xs
@@ -0,0 +1,1842 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "RPM.h"
+
+static char * const rcsid = "$Id: Constants.xs,v 1.1 2000/05/27 03:54:14 rjray Exp $";
+
+static int
+not_here(char *s)
+{
+ croak("%s not implemented on this architecture", s);
+ return -1;
+}
+
+static int
+constant(char *name, int arg)
+{
+ errno = 0;
+ switch (*name) {
+ case 'A':
+ if (strEQ(name, "ADD_SIGNATURE"))
+#ifdef ADD_SIGNATURE
+ return ADD_SIGNATURE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'B':
+ break;
+ case 'C':
+ if (strEQ(name, "CHECKSIG_GPG"))
+#ifdef CHECKSIG_GPG
+ return CHECKSIG_GPG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "CHECKSIG_MD5"))
+#ifdef CHECKSIG_MD5
+ return CHECKSIG_MD5;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "CHECKSIG_PGP"))
+#ifdef CHECKSIG_PGP
+ return CHECKSIG_PGP;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'D':
+ break;
+ case 'E':
+ break;
+ case 'F':
+ break;
+ case 'G':
+ break;
+ case 'H':
+ break;
+ case 'I':
+ if (strEQ(name, "INSTALL_HASH"))
+#ifdef INSTALL_HASH
+ return INSTALL_HASH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "INSTALL_LABEL"))
+#ifdef INSTALL_LABEL
+ return INSTALL_LABEL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "INSTALL_NODEPS"))
+#ifdef INSTALL_NODEPS
+ return INSTALL_NODEPS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "INSTALL_NOORDER"))
+#ifdef INSTALL_NOORDER
+ return INSTALL_NOORDER;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "INSTALL_PERCENT"))
+#ifdef INSTALL_PERCENT
+ return INSTALL_PERCENT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "INSTALL_UPGRADE"))
+#ifdef INSTALL_UPGRADE
+ return INSTALL_UPGRADE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'J':
+ break;
+ case 'K':
+ break;
+ case 'L':
+ break;
+ case 'M':
+ break;
+ case 'N':
+ if (strEQ(name, "NEW_SIGNATURE"))
+#ifdef NEW_SIGNATURE
+ return NEW_SIGNATURE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'O':
+ break;
+ case 'P':
+ break;
+ case 'Q':
+ if (strEQ(name, "QUERY_FOR_CONFIG"))
+#ifdef QUERY_FOR_CONFIG
+ return QUERY_FOR_CONFIG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "QUERY_FOR_DOCS"))
+#ifdef QUERY_FOR_DOCS
+ return QUERY_FOR_DOCS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "QUERY_FOR_DUMPFILES"))
+#ifdef QUERY_FOR_DUMPFILES
+ return QUERY_FOR_DUMPFILES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "QUERY_FOR_LIST"))
+#ifdef QUERY_FOR_LIST
+ return QUERY_FOR_LIST;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "QUERY_FOR_STATE"))
+#ifdef QUERY_FOR_STATE
+ return QUERY_FOR_STATE;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'R':
+ if (strEQ(name, "RPM_NULL_TYPE"))
+#ifdef RPM_NULL_TYPE
+ return RPM_NULL_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_CHAR_TYPE"))
+#ifdef RPM_CHAR_TYPE
+ return RPM_CHAR_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_INT8_TYPE"))
+#ifdef RPM_INT8_TYPE
+ return RPM_INT8_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_INT16_TYPE"))
+#ifdef RPM_INT16_TYPE
+ return RPM_INT16_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_INT32_TYPE"))
+#ifdef RPM_INT32_TYPE
+ return RPM_INT32_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_STRING_TYPE"))
+#ifdef RPM_STRING_TYPE
+ return RPM_STRING_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_BIN_TYPE"))
+#ifdef RPM_BIN_TYPE
+ return RPM_BIN_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_STRING_ARRAY_TYPE"))
+#ifdef RPM_STRING_ARRAY_TYPE
+ return RPM_STRING_ARRAY_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_I18NSTRING_TYPE"))
+#ifdef RPM_I18NSTRING_TYPE
+ return RPM_I18NSTRING_TYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADARG"))
+#ifdef RPMERR_BADARG
+ return RPMERR_BADARG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADDEV"))
+#ifdef RPMERR_BADDEV
+ return RPMERR_BADDEV;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADFILENAME"))
+#ifdef RPMERR_BADFILENAME
+ return RPMERR_BADFILENAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADMAGIC"))
+#ifdef RPMERR_BADMAGIC
+ return RPMERR_BADMAGIC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADRELOCATE"))
+#ifdef RPMERR_BADRELOCATE
+ return RPMERR_BADRELOCATE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADSIGTYPE"))
+#ifdef RPMERR_BADSIGTYPE
+ return RPMERR_BADSIGTYPE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_BADSPEC"))
+#ifdef RPMERR_BADSPEC
+ return RPMERR_BADSPEC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_CHOWN"))
+#ifdef RPMERR_CHOWN
+ return RPMERR_CHOWN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_CPIO"))
+#ifdef RPMERR_CPIO
+ return RPMERR_CPIO;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_CREATE"))
+#ifdef RPMERR_CREATE
+ return RPMERR_CREATE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_DBCORRUPT"))
+#ifdef RPMERR_DBCORRUPT
+ return RPMERR_DBCORRUPT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_DBGETINDEX"))
+#ifdef RPMERR_DBGETINDEX
+ return RPMERR_DBGETINDEX;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_DBOPEN"))
+#ifdef RPMERR_DBOPEN
+ return RPMERR_DBOPEN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_DBPUTINDEX"))
+#ifdef RPMERR_DBPUTINDEX
+ return RPMERR_DBPUTINDEX;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_EXEC"))
+#ifdef RPMERR_EXEC
+ return RPMERR_EXEC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_FILECONFLICT"))
+#ifdef RPMERR_FILECONFLICT
+ return RPMERR_FILECONFLICT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_FLOCK"))
+#ifdef RPMERR_FLOCK
+ return RPMERR_FLOCK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_FORK"))
+#ifdef RPMERR_FORK
+ return RPMERR_FORK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_GDBMOPEN"))
+#ifdef RPMERR_GDBMOPEN
+ return RPMERR_GDBMOPEN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_GDBMREAD"))
+#ifdef RPMERR_GDBMREAD
+ return RPMERR_GDBMREAD;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_GDBMWRITE"))
+#ifdef RPMERR_GDBMWRITE
+ return RPMERR_GDBMWRITE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_GZIP"))
+#ifdef RPMERR_GZIP
+ return RPMERR_GZIP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_INTERNAL"))
+#ifdef RPMERR_INTERNAL
+ return RPMERR_INTERNAL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_LDD"))
+#ifdef RPMERR_LDD
+ return RPMERR_LDD;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_MKDIR"))
+#ifdef RPMERR_MKDIR
+ return RPMERR_MKDIR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_MTAB"))
+#ifdef RPMERR_MTAB
+ return RPMERR_MTAB;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NEWPACKAGE"))
+#ifdef RPMERR_NEWPACKAGE
+ return RPMERR_NEWPACKAGE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NOCREATEDB"))
+#ifdef RPMERR_NOCREATEDB
+ return RPMERR_NOCREATEDB;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NOGROUP"))
+#ifdef RPMERR_NOGROUP
+ return RPMERR_NOGROUP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NORELOCATE"))
+#ifdef RPMERR_NORELOCATE
+ return RPMERR_NORELOCATE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NOSPACE"))
+#ifdef RPMERR_NOSPACE
+ return RPMERR_NOSPACE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NOSPEC"))
+#ifdef RPMERR_NOSPEC
+ return RPMERR_NOSPEC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NOTSRPM"))
+#ifdef RPMERR_NOTSRPM
+ return RPMERR_NOTSRPM;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_NOUSER"))
+#ifdef RPMERR_NOUSER
+ return RPMERR_NOUSER;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_OLDDB"))
+#ifdef RPMERR_OLDDB
+ return RPMERR_OLDDB;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_OLDDBCORRUPT"))
+#ifdef RPMERR_OLDDBCORRUPT
+ return RPMERR_OLDDBCORRUPT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_OLDDBMISSING"))
+#ifdef RPMERR_OLDDBMISSING
+ return RPMERR_OLDDBMISSING;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_OLDPACKAGE"))
+#ifdef RPMERR_OLDPACKAGE
+ return RPMERR_OLDPACKAGE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_PKGINSTALLED"))
+#ifdef RPMERR_PKGINSTALLED
+ return RPMERR_PKGINSTALLED;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_READERROR"))
+#ifdef RPMERR_READERROR
+ return RPMERR_READERROR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_RENAME"))
+#ifdef RPMERR_RENAME
+ return RPMERR_RENAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_RMDIR"))
+#ifdef RPMERR_RMDIR
+ return RPMERR_RMDIR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_RPMRC"))
+#ifdef RPMERR_RPMRC
+ return RPMERR_RPMRC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_SCRIPT"))
+#ifdef RPMERR_SCRIPT
+ return RPMERR_SCRIPT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_SIGGEN"))
+#ifdef RPMERR_SIGGEN
+ return RPMERR_SIGGEN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_STAT"))
+#ifdef RPMERR_STAT
+ return RPMERR_STAT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_UNKNOWNARCH"))
+#ifdef RPMERR_UNKNOWNARCH
+ return RPMERR_UNKNOWNARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_UNKNOWNOS"))
+#ifdef RPMERR_UNKNOWNOS
+ return RPMERR_UNKNOWNOS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_UNLINK"))
+#ifdef RPMERR_UNLINK
+ return RPMERR_UNLINK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMERR_UNMATCHEDIF"))
+#ifdef RPMERR_UNMATCHEDIF
+ return RPMERR_UNMATCHEDIF;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_CONFIG"))
+#ifdef RPMFILE_CONFIG
+ return RPMFILE_CONFIG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_DOC"))
+#ifdef RPMFILE_DOC
+ return RPMFILE_DOC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_DONOTUSE"))
+#ifdef RPMFILE_DONOTUSE
+ return RPMFILE_DONOTUSE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_GHOST"))
+#ifdef RPMFILE_GHOST
+ return RPMFILE_GHOST;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_LICENSE"))
+#ifdef RPMFILE_LICENSE
+ return RPMFILE_LICENSE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_MISSINGOK"))
+#ifdef RPMFILE_MISSINGOK
+ return RPMFILE_MISSINGOK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_NOREPLACE"))
+#ifdef RPMFILE_NOREPLACE
+ return RPMFILE_NOREPLACE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_README"))
+#ifdef RPMFILE_README
+ return RPMFILE_README;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_SPECFILE"))
+#ifdef RPMFILE_SPECFILE
+ return RPMFILE_SPECFILE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_STATE_NETSHARED"))
+#ifdef RPMFILE_STATE_NETSHARED
+ return RPMFILE_STATE_NETSHARED;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_STATE_NORMAL"))
+#ifdef RPMFILE_STATE_NORMAL
+ return RPMFILE_STATE_NORMAL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_STATE_NOTINSTALLED"))
+#ifdef RPMFILE_STATE_NOTINSTALLED
+ return RPMFILE_STATE_NOTINSTALLED;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMFILE_STATE_REPLACED"))
+#ifdef RPMFILE_STATE_REPLACED
+ return RPMFILE_STATE_REPLACED;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_BINARY"))
+#ifdef RPMLEAD_BINARY
+ return RPMLEAD_BINARY;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_MAGIC0"))
+#ifdef RPMLEAD_MAGIC0
+ return RPMLEAD_MAGIC0;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_MAGIC1"))
+#ifdef RPMLEAD_MAGIC1
+ return RPMLEAD_MAGIC1;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_MAGIC2"))
+#ifdef RPMLEAD_MAGIC2
+ return RPMLEAD_MAGIC2;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_MAGIC3"))
+#ifdef RPMLEAD_MAGIC3
+ return RPMLEAD_MAGIC3;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_SIZE"))
+#ifdef RPMLEAD_SIZE
+ return RPMLEAD_SIZE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMLEAD_SOURCE"))
+#ifdef RPMLEAD_SOURCE
+ return RPMLEAD_SOURCE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_ALTNAME"))
+#ifdef RPMMESS_ALTNAME
+ return RPMMESS_ALTNAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_BACKUP"))
+#ifdef RPMMESS_BACKUP
+ return RPMMESS_BACKUP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_DEBUG"))
+#ifdef RPMMESS_DEBUG
+ return RPMMESS_DEBUG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_ERROR"))
+#ifdef RPMMESS_ERROR
+ return RPMMESS_ERROR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_FATALERROR"))
+#ifdef RPMMESS_FATALERROR
+ return RPMMESS_FATALERROR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_NORMAL"))
+#ifdef RPMMESS_NORMAL
+ return RPMMESS_NORMAL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_PREREQLOOP"))
+#ifdef RPMMESS_PREREQLOOP
+ return RPMMESS_PREREQLOOP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_QUIET"))
+#ifdef RPMMESS_QUIET
+ return RPMMESS_QUIET;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_VERBOSE"))
+#ifdef RPMMESS_VERBOSE
+ return RPMMESS_VERBOSE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMMESS_WARNING"))
+#ifdef RPMMESS_WARNING
+ return RPMMESS_WARNING;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_DISKSPACE"))
+#ifdef RPMPROB_FILTER_DISKSPACE
+ return RPMPROB_FILTER_DISKSPACE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_FORCERELOCATE"))
+#ifdef RPMPROB_FILTER_FORCERELOCATE
+ return RPMPROB_FILTER_FORCERELOCATE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_IGNOREARCH"))
+#ifdef RPMPROB_FILTER_IGNOREARCH
+ return RPMPROB_FILTER_IGNOREARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_IGNOREOS"))
+#ifdef RPMPROB_FILTER_IGNOREOS
+ return RPMPROB_FILTER_IGNOREOS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_OLDPACKAGE"))
+#ifdef RPMPROB_FILTER_OLDPACKAGE
+ return RPMPROB_FILTER_OLDPACKAGE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_REPLACENEWFILES"))
+#ifdef RPMPROB_FILTER_REPLACENEWFILES
+ return RPMPROB_FILTER_REPLACENEWFILES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_REPLACEOLDFILES"))
+#ifdef RPMPROB_FILTER_REPLACEOLDFILES
+ return RPMPROB_FILTER_REPLACEOLDFILES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMPROB_FILTER_REPLACEPKG"))
+#ifdef RPMPROB_FILTER_REPLACEPKG
+ return RPMPROB_FILTER_REPLACEPKG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_EQUAL"))
+#ifdef RPMSENSE_EQUAL
+ return RPMSENSE_EQUAL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_GREATER"))
+#ifdef RPMSENSE_GREATER
+ return RPMSENSE_GREATER;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_LESS"))
+#ifdef RPMSENSE_LESS
+ return RPMSENSE_LESS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_PREREQ"))
+#ifdef RPMSENSE_PREREQ
+ return RPMSENSE_PREREQ;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_SENSEMASK"))
+#ifdef RPMSENSE_SENSEMASK
+ return RPMSENSE_SENSEMASK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_TRIGGER"))
+#ifdef RPMSENSE_TRIGGER
+ return RPMSENSE_TRIGGER;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_TRIGGERIN"))
+#ifdef RPMSENSE_TRIGGERIN
+ return RPMSENSE_TRIGGERIN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_TRIGGERPOSTUN"))
+#ifdef RPMSENSE_TRIGGERPOSTUN
+ return RPMSENSE_TRIGGERPOSTUN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSENSE_TRIGGERUN"))
+#ifdef RPMSENSE_TRIGGERUN
+ return RPMSENSE_TRIGGERUN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_GPG"))
+#ifdef RPMSIGTAG_GPG
+ return RPMSIGTAG_GPG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_LEMD5_1"))
+#ifdef RPMSIGTAG_LEMD5_1
+ return RPMSIGTAG_LEMD5_1;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_LEMD5_2"))
+#ifdef RPMSIGTAG_LEMD5_2
+ return RPMSIGTAG_LEMD5_2;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_MD5"))
+#ifdef RPMSIGTAG_MD5
+ return RPMSIGTAG_MD5;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_PGP"))
+#ifdef RPMSIGTAG_PGP
+ return RPMSIGTAG_PGP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_PGP5"))
+#ifdef RPMSIGTAG_PGP5
+ return RPMSIGTAG_PGP5;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIGTAG_SIZE"))
+#ifdef RPMSIGTAG_SIZE
+ return RPMSIGTAG_SIZE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIG_BAD"))
+#ifdef RPMSIG_BAD
+ return RPMSIG_BAD;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIG_NOKEY"))
+#ifdef RPMSIG_NOKEY
+ return RPMSIG_NOKEY;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIG_NOTTRUSTED"))
+#ifdef RPMSIG_NOTTRUSTED
+ return RPMSIG_NOTTRUSTED;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIG_OK"))
+#ifdef RPMSIG_OK
+ return RPMSIG_OK;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMSIG_UNKNOWN"))
+#ifdef RPMSIG_UNKNOWN
+ return RPMSIG_UNKNOWN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_ARCH"))
+#ifdef RPMTAG_ARCH
+ return RPMTAG_ARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_ARCHIVESIZE"))
+#ifdef RPMTAG_ARCHIVESIZE
+ return RPMTAG_ARCHIVESIZE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_BASENAMES"))
+#ifdef RPMTAG_BASENAMES
+ return RPMTAG_BASENAMES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_BUILDARCHS"))
+#ifdef RPMTAG_BUILDARCHS
+ return RPMTAG_BUILDARCHS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_BUILDHOST"))
+#ifdef RPMTAG_BUILDHOST
+ return RPMTAG_BUILDHOST;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_BUILDMACROS"))
+#ifdef RPMTAG_BUILDMACROS
+ return RPMTAG_BUILDMACROS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_BUILDROOT"))
+#ifdef RPMTAG_BUILDROOT
+ return RPMTAG_BUILDROOT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_BUILDTIME"))
+#ifdef RPMTAG_BUILDTIME
+ return RPMTAG_BUILDTIME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CAPABILITY"))
+#ifdef RPMTAG_CAPABILITY
+ return RPMTAG_CAPABILITY;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CHANGELOGNAME"))
+#ifdef RPMTAG_CHANGELOGNAME
+ return RPMTAG_CHANGELOGNAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CHANGELOGTEXT"))
+#ifdef RPMTAG_CHANGELOGTEXT
+ return RPMTAG_CHANGELOGTEXT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CHANGELOGTIME"))
+#ifdef RPMTAG_CHANGELOGTIME
+ return RPMTAG_CHANGELOGTIME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CONFLICTFLAGS"))
+#ifdef RPMTAG_CONFLICTFLAGS
+ return RPMTAG_CONFLICTFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CONFLICTNAME"))
+#ifdef RPMTAG_CONFLICTNAME
+ return RPMTAG_CONFLICTNAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_CONFLICTVERSION"))
+#ifdef RPMTAG_CONFLICTVERSION
+ return RPMTAG_CONFLICTVERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_COOKIE"))
+#ifdef RPMTAG_COOKIE
+ return RPMTAG_COOKIE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_DEFAULTPREFIX"))
+#ifdef RPMTAG_DEFAULTPREFIX
+ return RPMTAG_DEFAULTPREFIX;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_DESCRIPTION"))
+#ifdef RPMTAG_DESCRIPTION
+ return RPMTAG_DESCRIPTION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_DIRINDEXES"))
+#ifdef RPMTAG_DIRINDEXES
+ return RPMTAG_DIRINDEXES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_DIRNAMES"))
+#ifdef RPMTAG_DIRNAMES
+ return RPMTAG_DIRNAMES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_DISTRIBUTION"))
+#ifdef RPMTAG_DISTRIBUTION
+ return RPMTAG_DISTRIBUTION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_DOCDIR"))
+#ifdef RPMTAG_DOCDIR
+ return RPMTAG_DOCDIR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EPOCH"))
+#ifdef RPMTAG_EPOCH
+ return RPMTAG_EPOCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXCLUDE"))
+#ifdef RPMTAG_EXCLUDE
+ return RPMTAG_EXCLUDE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXCLUDEARCH"))
+#ifdef RPMTAG_EXCLUDEARCH
+ return RPMTAG_EXCLUDEARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXCLUDEOS"))
+#ifdef RPMTAG_EXCLUDEOS
+ return RPMTAG_EXCLUDEOS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXCLUSIVE"))
+#ifdef RPMTAG_EXCLUSIVE
+ return RPMTAG_EXCLUSIVE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXCLUSIVEARCH"))
+#ifdef RPMTAG_EXCLUSIVEARCH
+ return RPMTAG_EXCLUSIVEARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXCLUSIVEOS"))
+#ifdef RPMTAG_EXCLUSIVEOS
+ return RPMTAG_EXCLUSIVEOS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_EXTERNAL_TAG"))
+#ifdef RPMTAG_EXTERNAL_TAG
+ return RPMTAG_EXTERNAL_TAG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEDEVICES"))
+#ifdef RPMTAG_FILEDEVICES
+ return RPMTAG_FILEDEVICES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEFLAGS"))
+#ifdef RPMTAG_FILEFLAGS
+ return RPMTAG_FILEFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEGIDS"))
+#ifdef RPMTAG_FILEGIDS
+ return RPMTAG_FILEGIDS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEGROUPNAME"))
+#ifdef RPMTAG_FILEGROUPNAME
+ return RPMTAG_FILEGROUPNAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEINODES"))
+#ifdef RPMTAG_FILEINODES
+ return RPMTAG_FILEINODES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILELANGS"))
+#ifdef RPMTAG_FILELANGS
+ return RPMTAG_FILELANGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILELINKTOS"))
+#ifdef RPMTAG_FILELINKTOS
+ return RPMTAG_FILELINKTOS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEMD5S"))
+#ifdef RPMTAG_FILEMD5S
+ return RPMTAG_FILEMD5S;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEMODES"))
+#ifdef RPMTAG_FILEMODES
+ return RPMTAG_FILEMODES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEMTIMES"))
+#ifdef RPMTAG_FILEMTIMES
+ return RPMTAG_FILEMTIMES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILERDEVS"))
+#ifdef RPMTAG_FILERDEVS
+ return RPMTAG_FILERDEVS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILESIZES"))
+#ifdef RPMTAG_FILESIZES
+ return RPMTAG_FILESIZES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILESTATES"))
+#ifdef RPMTAG_FILESTATES
+ return RPMTAG_FILESTATES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEUIDS"))
+#ifdef RPMTAG_FILEUIDS
+ return RPMTAG_FILEUIDS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEUSERNAME"))
+#ifdef RPMTAG_FILEUSERNAME
+ return RPMTAG_FILEUSERNAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FILEVERIFYFLAGS"))
+#ifdef RPMTAG_FILEVERIFYFLAGS
+ return RPMTAG_FILEVERIFYFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_FIRSTFREE_TAG"))
+#ifdef RPMTAG_FIRSTFREE_TAG
+ return RPMTAG_FIRSTFREE_TAG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_GIF"))
+#ifdef RPMTAG_GIF
+ return RPMTAG_GIF;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_GROUP"))
+#ifdef RPMTAG_GROUP
+ return RPMTAG_GROUP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_BASE"))
+#ifdef RPMTAG_HASH_BASE
+ return RPMTAG_HASH_BASE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_HAVAL_5_160"))
+#ifdef RPMTAG_HASH_HAVAL_5_160
+ return RPMTAG_HASH_HAVAL_5_160;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_MD2"))
+#ifdef RPMTAG_HASH_MD2
+ return RPMTAG_HASH_MD2;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_MD5"))
+#ifdef RPMTAG_HASH_MD5
+ return RPMTAG_HASH_MD5;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_RIPEMD160"))
+#ifdef RPMTAG_HASH_RIPEMD160
+ return RPMTAG_HASH_RIPEMD160;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_SHA1"))
+#ifdef RPMTAG_HASH_SHA1
+ return RPMTAG_HASH_SHA1;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_HASH_TIGER192"))
+#ifdef RPMTAG_HASH_TIGER192
+ return RPMTAG_HASH_TIGER192;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_ICON"))
+#ifdef RPMTAG_ICON
+ return RPMTAG_ICON;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_INSTALLPREFIX"))
+#ifdef RPMTAG_INSTALLPREFIX
+ return RPMTAG_INSTALLPREFIX;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_INSTALLTIME"))
+#ifdef RPMTAG_INSTALLTIME
+ return RPMTAG_INSTALLTIME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_INSTPREFIXES"))
+#ifdef RPMTAG_INSTPREFIXES
+ return RPMTAG_INSTPREFIXES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_LICENSE"))
+#ifdef RPMTAG_LICENSE
+ return RPMTAG_LICENSE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_NAME"))
+#ifdef RPMTAG_NAME
+ return RPMTAG_NAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_NOPATCH"))
+#ifdef RPMTAG_NOPATCH
+ return RPMTAG_NOPATCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_NOSOURCE"))
+#ifdef RPMTAG_NOSOURCE
+ return RPMTAG_NOSOURCE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_OBSOLETEFLAGS"))
+#ifdef RPMTAG_OBSOLETEFLAGS
+ return RPMTAG_OBSOLETEFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_OBSOLETENAME"))
+#ifdef RPMTAG_OBSOLETENAME
+ return RPMTAG_OBSOLETENAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_OBSOLETEVERSION"))
+#ifdef RPMTAG_OBSOLETEVERSION
+ return RPMTAG_OBSOLETEVERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_ORIGBASENAMES"))
+#ifdef RPMTAG_ORIGBASENAMES
+ return RPMTAG_ORIGBASENAMES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_ORIGDIRINDEXES"))
+#ifdef RPMTAG_ORIGDIRINDEXES
+ return RPMTAG_ORIGDIRINDEXES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_ORIGDIRNAMES"))
+#ifdef RPMTAG_ORIGDIRNAMES
+ return RPMTAG_ORIGDIRNAMES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_OS"))
+#ifdef RPMTAG_OS
+ return RPMTAG_OS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PACKAGER"))
+#ifdef RPMTAG_PACKAGER
+ return RPMTAG_PACKAGER;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PATCH"))
+#ifdef RPMTAG_PATCH
+ return RPMTAG_PATCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_BASE"))
+#ifdef RPMTAG_PK_BASE
+ return RPMTAG_PK_BASE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_DH"))
+#ifdef RPMTAG_PK_DH
+ return RPMTAG_PK_DH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_DSA"))
+#ifdef RPMTAG_PK_DSA
+ return RPMTAG_PK_DSA;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_ECDSA"))
+#ifdef RPMTAG_PK_ECDSA
+ return RPMTAG_PK_ECDSA;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_ELGAMAL_E"))
+#ifdef RPMTAG_PK_ELGAMAL_E
+ return RPMTAG_PK_ELGAMAL_E;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_ELGAMAL_ES"))
+#ifdef RPMTAG_PK_ELGAMAL_ES
+ return RPMTAG_PK_ELGAMAL_ES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_ELLIPTIC"))
+#ifdef RPMTAG_PK_ELLIPTIC
+ return RPMTAG_PK_ELLIPTIC;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_RSA_E"))
+#ifdef RPMTAG_PK_RSA_E
+ return RPMTAG_PK_RSA_E;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_RSA_ES"))
+#ifdef RPMTAG_PK_RSA_ES
+ return RPMTAG_PK_RSA_ES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PK_RSA_S"))
+#ifdef RPMTAG_PK_RSA_S
+ return RPMTAG_PK_RSA_S;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_POSTIN"))
+#ifdef RPMTAG_POSTIN
+ return RPMTAG_POSTIN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_POSTINPROG"))
+#ifdef RPMTAG_POSTINPROG
+ return RPMTAG_POSTINPROG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_POSTUN"))
+#ifdef RPMTAG_POSTUN
+ return RPMTAG_POSTUN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_POSTUNPROG"))
+#ifdef RPMTAG_POSTUNPROG
+ return RPMTAG_POSTUNPROG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PREFIXES"))
+#ifdef RPMTAG_PREFIXES
+ return RPMTAG_PREFIXES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PREIN"))
+#ifdef RPMTAG_PREIN
+ return RPMTAG_PREIN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PREINPROG"))
+#ifdef RPMTAG_PREINPROG
+ return RPMTAG_PREINPROG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PREREQ"))
+#ifdef RPMTAG_PREREQ
+ return RPMTAG_PREREQ;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PREUN"))
+#ifdef RPMTAG_PREUN
+ return RPMTAG_PREUN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PREUNPROG"))
+#ifdef RPMTAG_PREUNPROG
+ return RPMTAG_PREUNPROG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PROVIDEFLAGS"))
+#ifdef RPMTAG_PROVIDEFLAGS
+ return RPMTAG_PROVIDEFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PROVIDENAME"))
+#ifdef RPMTAG_PROVIDENAME
+ return RPMTAG_PROVIDENAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_PROVIDEVERSION"))
+#ifdef RPMTAG_PROVIDEVERSION
+ return RPMTAG_PROVIDEVERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_RELEASE"))
+#ifdef RPMTAG_RELEASE
+ return RPMTAG_RELEASE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_REQUIREFLAGS"))
+#ifdef RPMTAG_REQUIREFLAGS
+ return RPMTAG_REQUIREFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_REQUIRENAME"))
+#ifdef RPMTAG_REQUIRENAME
+ return RPMTAG_REQUIRENAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_REQUIREVERSION"))
+#ifdef RPMTAG_REQUIREVERSION
+ return RPMTAG_REQUIREVERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_RPMVERSION"))
+#ifdef RPMTAG_RPMVERSION
+ return RPMTAG_RPMVERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_SIZE"))
+#ifdef RPMTAG_SIZE
+ return RPMTAG_SIZE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_SOURCE"))
+#ifdef RPMTAG_SOURCE
+ return RPMTAG_SOURCE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_SOURCEPACKAGE"))
+#ifdef RPMTAG_SOURCEPACKAGE
+ return RPMTAG_SOURCEPACKAGE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_SOURCERPM"))
+#ifdef RPMTAG_SOURCERPM
+ return RPMTAG_SOURCERPM;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_SUMMARY"))
+#ifdef RPMTAG_SUMMARY
+ return RPMTAG_SUMMARY;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERFLAGS"))
+#ifdef RPMTAG_TRIGGERFLAGS
+ return RPMTAG_TRIGGERFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERIN"))
+#ifdef RPMTAG_TRIGGERIN
+ return RPMTAG_TRIGGERIN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERINDEX"))
+#ifdef RPMTAG_TRIGGERINDEX
+ return RPMTAG_TRIGGERINDEX;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERNAME"))
+#ifdef RPMTAG_TRIGGERNAME
+ return RPMTAG_TRIGGERNAME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERPOSTUN"))
+#ifdef RPMTAG_TRIGGERPOSTUN
+ return RPMTAG_TRIGGERPOSTUN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERSCRIPTPROG"))
+#ifdef RPMTAG_TRIGGERSCRIPTPROG
+ return RPMTAG_TRIGGERSCRIPTPROG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERSCRIPTS"))
+#ifdef RPMTAG_TRIGGERSCRIPTS
+ return RPMTAG_TRIGGERSCRIPTS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERUN"))
+#ifdef RPMTAG_TRIGGERUN
+ return RPMTAG_TRIGGERUN;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_TRIGGERVERSION"))
+#ifdef RPMTAG_TRIGGERVERSION
+ return RPMTAG_TRIGGERVERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_URL"))
+#ifdef RPMTAG_URL
+ return RPMTAG_URL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_VENDOR"))
+#ifdef RPMTAG_VENDOR
+ return RPMTAG_VENDOR;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_VERIFYSCRIPT"))
+#ifdef RPMTAG_VERIFYSCRIPT
+ return RPMTAG_VERIFYSCRIPT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_VERIFYSCRIPTPROG"))
+#ifdef RPMTAG_VERIFYSCRIPTPROG
+ return RPMTAG_VERIFYSCRIPTPROG;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_VERSION"))
+#ifdef RPMTAG_VERSION
+ return RPMTAG_VERSION;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTAG_XPM"))
+#ifdef RPMTAG_XPM
+ return RPMTAG_XPM;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_ALLFILES"))
+#ifdef RPMTRANS_FLAG_ALLFILES
+ return RPMTRANS_FLAG_ALLFILES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_BUILD_PROBS"))
+#ifdef RPMTRANS_FLAG_BUILD_PROBS
+ return RPMTRANS_FLAG_BUILD_PROBS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_JUSTDB"))
+#ifdef RPMTRANS_FLAG_JUSTDB
+ return RPMTRANS_FLAG_JUSTDB;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_KEEPOBSOLETE"))
+#ifdef RPMTRANS_FLAG_KEEPOBSOLETE
+ return RPMTRANS_FLAG_KEEPOBSOLETE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_NODOCS"))
+#ifdef RPMTRANS_FLAG_NODOCS
+ return RPMTRANS_FLAG_NODOCS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_NOSCRIPTS"))
+#ifdef RPMTRANS_FLAG_NOSCRIPTS
+ return RPMTRANS_FLAG_NOSCRIPTS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_NOTRIGGERS"))
+#ifdef RPMTRANS_FLAG_NOTRIGGERS
+ return RPMTRANS_FLAG_NOTRIGGERS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMTRANS_FLAG_TEST"))
+#ifdef RPMTRANS_FLAG_TEST
+ return RPMTRANS_FLAG_TEST;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVAR_INCLUDE"))
+#ifdef RPMVAR_INCLUDE
+ return RPMVAR_INCLUDE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVAR_MACROFILES"))
+#ifdef RPMVAR_MACROFILES
+ return RPMVAR_MACROFILES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVAR_NUM"))
+#ifdef RPMVAR_NUM
+ return RPMVAR_NUM;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVAR_OPTFLAGS"))
+#ifdef RPMVAR_OPTFLAGS
+ return RPMVAR_OPTFLAGS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVAR_PROVIDES"))
+#ifdef RPMVAR_PROVIDES
+ return RPMVAR_PROVIDES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_ALL"))
+#ifdef RPMVERIFY_ALL
+ return RPMVERIFY_ALL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_FILESIZE"))
+#ifdef RPMVERIFY_FILESIZE
+ return RPMVERIFY_FILESIZE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_GROUP"))
+#ifdef RPMVERIFY_GROUP
+ return RPMVERIFY_GROUP;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_LINKTO"))
+#ifdef RPMVERIFY_LINKTO
+ return RPMVERIFY_LINKTO;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_LSTATFAIL"))
+#ifdef RPMVERIFY_LSTATFAIL
+ return RPMVERIFY_LSTATFAIL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_MD5"))
+#ifdef RPMVERIFY_MD5
+ return RPMVERIFY_MD5;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_MODE"))
+#ifdef RPMVERIFY_MODE
+ return RPMVERIFY_MODE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_MTIME"))
+#ifdef RPMVERIFY_MTIME
+ return RPMVERIFY_MTIME;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_NONE"))
+#ifdef RPMVERIFY_NONE
+ return RPMVERIFY_NONE;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_RDEV"))
+#ifdef RPMVERIFY_RDEV
+ return RPMVERIFY_RDEV;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_READFAIL"))
+#ifdef RPMVERIFY_READFAIL
+ return RPMVERIFY_READFAIL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_READLINKFAIL"))
+#ifdef RPMVERIFY_READLINKFAIL
+ return RPMVERIFY_READLINKFAIL;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPMVERIFY_USER"))
+#ifdef RPMVERIFY_USER
+ return RPMVERIFY_USER;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_MACHTABLE_BUILDARCH"))
+#ifdef RPM_MACHTABLE_BUILDARCH
+ return RPM_MACHTABLE_BUILDARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_MACHTABLE_BUILDOS"))
+#ifdef RPM_MACHTABLE_BUILDOS
+ return RPM_MACHTABLE_BUILDOS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_MACHTABLE_COUNT"))
+#ifdef RPM_MACHTABLE_COUNT
+ return RPM_MACHTABLE_COUNT;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_MACHTABLE_INSTARCH"))
+#ifdef RPM_MACHTABLE_INSTARCH
+ return RPM_MACHTABLE_INSTARCH;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "RPM_MACHTABLE_INSTOS"))
+#ifdef RPM_MACHTABLE_INSTOS
+ return RPM_MACHTABLE_INSTOS;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'S':
+ break;
+ case 'T':
+ break;
+ case 'U':
+ if (strEQ(name, "UNINSTALL_ALLMATCHES"))
+#ifdef UNINSTALL_ALLMATCHES
+ return UNINSTALL_ALLMATCHES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "UNINSTALL_NODEPS"))
+#ifdef UNINSTALL_NODEPS
+ return UNINSTALL_NODEPS;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'V':
+ if (strEQ(name, "VERIFY_DEPS"))
+#ifdef VERIFY_DEPS
+ return VERIFY_DEPS;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "VERIFY_FILES"))
+#ifdef VERIFY_FILES
+ return VERIFY_FILES;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "VERIFY_MD5"))
+#ifdef VERIFY_MD5
+ return VERIFY_MD5;
+#else
+ goto not_there;
+#endif
+ if (strEQ(name, "VERIFY_SCRIPT"))
+#ifdef VERIFY_SCRIPT
+ return VERIFY_SCRIPT;
+#else
+ goto not_there;
+#endif
+ break;
+ case 'W':
+ break;
+ case 'X':
+ break;
+ case 'Y':
+ break;
+ case 'Z':
+ break;
+ }
+ errno = EINVAL;
+ return 0;
+
+not_there:
+ errno = ENOENT;
+ return 0;
+}
+
+
+MODULE = RPM::Constants PACKAGE = RPM::Constants
+
+
+int
+constant(name,arg)
+ char * name
+ int arg
+ PROTOTYPE: $;$
diff --git a/Perl-RPM/RPM/Database.pm b/Perl-RPM/RPM/Database.pm
new file mode 100644
index 000000000..94edc2d8d
--- /dev/null
+++ b/Perl-RPM/RPM/Database.pm
@@ -0,0 +1,176 @@
+###############################################################################
+#
+# (c) Copyright @ 2000, Red Hat Software, Inc.,
+# All Rights Reserved
+#
+###############################################################################
+#
+# $Id: Database.pm,v 1.1 2000/05/27 03:54:14 rjray Exp $
+#
+# Description: The RPM::Database class provides access to the RPM database
+# as a tied hash, whose keys are taken as the names of
+# packages installed and whose values are RPM::Header
+# objects.
+#
+# Functions: new
+# STORE
+# CLEAR
+# DELETE
+#
+# Libraries: RPM::Header
+#
+# Global Consts: None.
+#
+# Environment: Just stuff from the RPM config.
+#
+###############################################################################
+
+package RPM::Database;
+
+require 5.005;
+
+use strict;
+use vars qw($VERSION $revision);
+use subs qw(new);
+
+require RPM;
+require RPM::Header;
+
+$VERSION = $RPM::VERSION;
+$revision = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
+
+1;
+
+sub new
+{
+ my $class = shift;
+ my %hash = ();
+
+ tie %hash, $class;
+ return (tied %hash);
+}
+
+__END__
+
+=head1 NAME
+
+RPM::Database - Access to the RPM database of installed packages
+
+=head1 SYNOPSIS
+
+ use RPM::Database;
+
+ tie %RPM, "RPM::Database" or die "$RPM::err";
+
+ for (sort keys %RPM)
+ {
+ ...
+ }
+
+=head1 DESCRIPTION
+
+The B<RPM::Database> package provides access to the database of installed
+packages on a system. The database may be accessed as either a tied hash
+or as a blessed reference to a hash. The keys of the hash represent
+packages on the system. The order in which they are returned by any of
+C<keys>, C<each> or C<values>, is determined by the internal database
+ordering. Unlike the keys in B<RPM::Header> (see L<RPM::Header>), the
+keys here are in fact case-sensitive.
+
+The return value corresponding to each key is a reference to a
+B<RPM::Header> object. The header object is marked read-only, as the
+RPM database is not directly modifiable via this interface.
+
+There are also a number of class methods implemented, which are described in
+the next section.
+
+=head1 USAGE
+
+=head2 Creating an Object
+
+An object may be created one of two ways:
+
+ tie %D, "RPM::Database";
+
+ $dataref = new RPM::Database;
+
+The latter approach offers more direct access to the class methods, while
+also permitting the usual tied-hash operations such as fetching:
+
+ $dataref->{package} # Such as "rpm" or "perl"
+
+=head2 Class Methods
+
+The following methods are available to objects of this class, in addition to
+the tied-hash suite of operations. If the object is a hash instead of a
+hash reference, it can be used to call these methods via:
+
+ (tied %hash)->method_name(...)
+
+=over
+
+=item init
+
+This causes a complete initialization of the RPM database. It must be run
+with sufficient permissions to create/update the relevant files. It must
+also be called as a static method, to avoid having any file descriptors
+open on the database at the time.
+
+=item rebuild
+
+This rebuilds the database (same as "rpm --rebuilddb"). As with B<init>
+above, this requires adequate permissions and must be invoked as a static
+method.
+
+=item FindByFile(file)
+
+Returns a list of B<RPM::Header> objects that correspond to the package(s)
+claiming ownership of the file "file".
+
+=item FindByGroup(group)
+
+Returns of a list of headers for all packages flagged as being in the
+group specified.
+
+=item FindByProvides(provides)
+
+Search as above, but based on which packages provide the file/object
+specified as "provides".
+
+=item FindByRequiredBy(requires)
+
+Return a list of headers for the packages that directly depend on the
+specified package for installation and operation.
+
+=item FindByConflicts(conflicts)
+
+List those packages that have conflicts based on the value of "conflicts".
+
+=item FindByPackage(package)
+
+This performs the search by a specific package name. This is the API call
+used by the FETCH tied-hash method, but this differs in that if there is
+in fact more than one matching record, all are returned.
+
+=back
+
+=head1 DIAGNOSTICS
+
+Direct binding to the internal error-management of B<rpm> is still under
+development. At present, most operations generate their diagnostics to
+STDERR.
+
+=head1 CAVEATS
+
+This is currently regarded as alpha-quality software. The interface is
+subject to change in future releases.
+
+=head1 SEE ALSO
+
+L<RPM>, L<RPM::Header>, L<perl>, L<rpm>
+
+=head1 AUTHOR
+
+Randy J. Ray <rjray@blackperl.com>
+
+=cut
diff --git a/Perl-RPM/RPM/Database.xs b/Perl-RPM/RPM/Database.xs
new file mode 100644
index 000000000..627275b56
--- /dev/null
+++ b/Perl-RPM/RPM/Database.xs
@@ -0,0 +1,513 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <fcntl.h>
+#include "RPM.h"
+
+static char * const rcsid = "$Id: Database.xs,v 1.1 2000/05/27 03:54:15 rjray Exp $";
+
+//
+// Use this define for deriving the saved rpmdb struct, rather than coding
+// it a dozen places. Note that the hv_fetch call is the no-magic one defined
+// in RPM.h
+//
+#define dbstruct_from_object_ret(s_ptr, rdb, object, err_ret) \
+ hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
+ (rdb) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Database *)SvIV(*(s_ptr)) : NULL; \
+ if (! (rdb)) return (err_ret);
+// And a no-return-value version:
+#define dbstruct_from_object(s_ptr, rdb, object) \
+ hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
+ (rdb) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Database *)SvIV(*(s_ptr)) : NULL; \
+ if (! (rdb)) return;
+
+//
+// rpmdb_TIEHASH
+//
+// This is the implementation of the tied-hash class constructor. The XS
+// wrapper will verify that the value of class is correct, then massage the
+// arguments as needed. The return value is expected to be either NULL or a
+// valid RPM__Database value (which the XS wrapper will fix up).
+//
+RPM__Database rpmdb_TIEHASH(char* class, SV* opts)
+{
+ char* root = (char *)NULL;
+ int mode = O_RDONLY;
+ mode_t perms = 0;
+ HV* opt_hash;
+ SV* value;
+ SV** svp;
+ int root_len;
+ RPM_Database* dbstruct;
+ RPM__Database TIEHASH;
+
+ new_RPM__Database(TIEHASH);
+ // The dbstruct is used for the C-level rpmlib information on databases
+ dbstruct = safemalloc(sizeof(RPM_Database));
+ Zero(dbstruct, 1, RPM_Database);
+ if (opts)
+ {
+ if (SvROK(opts) && (SvTYPE(opts) == SVt_PVHV))
+ {
+ // This is a hash reference. We are concerned only with
+ // the keys "root", "mode" and "perms".
+ opt_hash = (HV*)SvRV(opts);
+
+ svp = hv_fetch(opt_hash, "root", 4, FALSE);
+ if (svp && SvPOK(*svp))
+ root = SvPV(*svp, root_len);
+ svp = hv_fetch(opt_hash, "mode", 4, FALSE);
+ if (svp && SvIOK(*svp))
+ mode = SvIV(*svp);
+ svp = hv_fetch(opt_hash, "perms", 5, FALSE);
+ if (svp && SvIOK(*svp))
+ perms = (mode_t)SvIV(*svp);
+ }
+ else if (SvPOK(opts))
+ {
+ // They passed a scalar, assumed to be the "root"
+ root = SvPV(opts, root_len);
+ }
+ else
+ {
+ warn("Wrong type for argument 2 to TIEHASH");
+ return ((RPM__Database)NULL);
+ }
+ }
+
+ // With that all processed, attempt to open the actual RPM DB
+ if (rpmdbOpen(root, &dbstruct->dbp, mode, perms) != 0)
+ {
+ warn("rpmdb_TIEHASH: rpmdbOpen failed");
+ return ((RPM__Database)NULL);
+ }
+ else
+ {
+ dbstruct->current_rec = 0;
+ dbstruct->index_set = (void *)NULL;
+ }
+
+ // STRUCT_KEY is used to stash the C-level struct on the TIEHASH obj
+ hv_store_nomg(TIEHASH,
+ STRUCT_KEY, STRUCT_KEY_LEN, newSViv((unsigned)dbstruct),
+ FALSE);
+ return TIEHASH;
+}
+
+RPM__Header rpmdb_FETCH(RPM__Database self, SV* key)
+{
+ const char* name = NULL; // For the actual name out of (SV *)key
+ int namelen; // Arg for SvPV(..., len)
+ int offset; // In case they pass an integer offset
+ Header hdr; // For rpmdbGetRecord() calls
+ SV** svp;
+ RPM__Header FETCH;
+ RPM_Database* dbstruct; // This is the struct used to hold C-level data
+
+ // Any successful operation will re-assign this
+ FETCH = (RPM__Header)newSVsv(&sv_undef);
+
+ dbstruct_from_object_ret(svp, dbstruct, self, FETCH);
+ // De-reference key, if it is a reference
+ if (SvROK(key))
+ key = SvRV(key);
+
+ // For sake of flexibility (and because it's almost zero overhead),
+ // allow the request to be by name -or- by an offset number
+ if (SvPOK(key))
+ {
+ int result;
+
+ name = SvPV(key, namelen);
+
+ // Step 1: Check to see if this has already been requested and is
+ // thus cached on the hash itself
+ hv_fetch_nomg(svp, self, (char *)name, namelen, FALSE);
+ if (svp && SvOK(*svp))
+ {
+ FETCH = (RPM__Header)SvIV(*svp);
+ return FETCH;
+ }
+
+ // Create an index set if we don't already have one
+ if (! dbstruct->index_set)
+ {
+ dbstruct->index_set =
+ (dbiIndexSet *)safemalloc(sizeof(dbiIndexSet));
+ Zero(dbstruct->index_set, 1, dbiIndexSet);
+ }
+ // Run the search
+ result = rpmdbFindPackage(dbstruct->dbp, name, dbstruct->index_set);
+ if (result)
+ {
+ // Some sort of error occured when reading the DB or the
+ // name was not found.
+ return FETCH;
+ }
+ else
+ {
+ // There may have been more than one match, but for now
+ // I can only take the first one off the list.
+ if (dbstruct->index_set->count)
+ {
+ offset = dbstruct->index_set->recs[0].recOffset;
+ }
+ else
+ {
+ // In theory, this wouldn't happen since zero matches
+ // would mean a return value of 1 from the library.
+ // But I ain't betting the core on that...
+ return FETCH;
+ }
+ }
+ }
+ else if (SvIOK(key))
+ {
+ // This is actually a lot easier than fetch-by-name, which is
+ // why I've thrown it in
+ offset = SvIV(key);
+ }
+ else
+ {
+ warn("RPM::Database::FETCH: Second arg should be name or offset");
+ return FETCH;
+ }
+
+ hdr = rpmdbGetRecord(dbstruct->dbp, offset);
+ // An error results in hdr getting NULL, which is just fine
+ if (hdr)
+ {
+ FETCH = rpmhdr_TIEHASH(sv_2mortal(newSVpv("RPM::Header", 12)),
+ sv_2mortal(newRV((SV *)hdr)),
+ RPM_HEADER_FROM_REF | RPM_HEADER_READONLY);
+ // If name is no longer NULL, it means our vector in was a string
+ // (key), so put the result back into the hash-cache.
+ if (name != NULL)
+ {
+ hv_store_nomg(self, (char *)name, namelen,
+ newSViv((unsigned)FETCH), FALSE);
+ }
+ }
+
+ return FETCH;
+}
+
+int rpmdb_EXISTS(RPM__Database self, SV* key)
+{
+ SV* tmp;
+
+ tmp = (SV *)rpmdb_FETCH(self, key);
+ // There is probably a cleaner test for (SV *)tmp == sv_undef
+ return (SvANY(tmp) != NULL);
+}
+
+// This is quite a bit easier than the FIRSTKEY/NEXTKEY combo for headers.
+// In these cases, the transition is based on the last offset fetched, which
+// we store on the struct part of self. We don't have to worry about an
+// iterator struct.
+int rpmdb_FIRSTKEY(RPM__Database self, SV** key, RPM__Header* value)
+{
+ RPM_Database* dbstruct;
+ SV** svp;
+ AV* tmpav;
+
+ dbstruct_from_object_ret(svp, dbstruct, self, 0);
+ // This more or less resets our "iterator"
+ dbstruct->current_rec = 0;
+
+ if (! (dbstruct->current_rec = rpmdbFirstRecNum(dbstruct->dbp)))
+ return 0;
+
+ *value = rpmdb_FETCH(self, newSViv(dbstruct->current_rec));
+ tmpav = rpmhdr_FETCH(*value, newSVpv("name", 4), Nullch, 0, 0);
+ svp = av_fetch(tmpav, 0, FALSE);
+ *key = newSVsv(*svp);
+
+ return 1;
+}
+
+int rpmdb_NEXTKEY(RPM__Database self, SV* key,
+ SV** nextkey, RPM__Header* nextvalue)
+{
+ RPM_Database* dbstruct;
+ SV** svp;
+ AV* tmpav;
+
+ dbstruct_from_object_ret(svp, dbstruct, self, 0);
+
+ if (! (dbstruct->current_rec = rpmdbNextRecNum(dbstruct->dbp,
+ dbstruct->current_rec)))
+ return 0;
+
+ *nextvalue = rpmdb_FETCH(self, newSViv(dbstruct->current_rec));
+ tmpav = rpmhdr_FETCH(*nextvalue, newSVpv("name", 4), Nullch, 0, 0);
+ svp = av_fetch(tmpav, 0, FALSE);
+ *nextkey = newSVsv(*svp);
+
+ return 1;
+}
+
+void rpmdb_DESTROY(RPM__Database self)
+{
+ SV** svp;
+ RPM_Database* dbstruct; // This is the struct used to hold C-level data
+
+ dbstruct_from_object(svp, dbstruct, self);
+
+ rpmdbClose(dbstruct->dbp);
+ if (dbstruct->index_set)
+ dbiFreeIndexRecord(*dbstruct->index_set);
+}
+
+int rpmdb_init(const char* class, const char* root, int perms)
+{
+ return (1 - rpmdbInit(root, perms));
+}
+
+int rpmdb_rebuild(const char* class, const char* root)
+{
+ return (1 - rpmdbRebuild(root));
+}
+
+// This is a front-end to all the rpmdbFindBy*() set, including FindByPackage
+// which differs from FETCH above in that if there is actually more than one
+// match, all will be returned.
+AV* rpmdb_find_by_whatever(RPM__Database self, SV* string, int idx)
+{
+ const char* str = NULL; // For the actual string out of (SV *)string
+ STRLEN len; // Arg for SvPV(..., len)
+ SV** svp;
+ RPM_Database* dbstruct; // This is the struct used to hold C-level data
+ AV* return_val;
+ int result, loop;
+ RPM__Header tmp_hdr;
+
+ // Any successful operation will store items on this
+ return_val = newAV();
+
+ dbstruct_from_object_ret(svp, dbstruct, self, return_val);
+ // De-reference key, if it is a reference
+ if (SvROK(string))
+ string = SvRV(string);
+ // Get the string
+ str = SvPV(string, len);
+
+ // Create an index set if we don't already have one
+ if (! dbstruct->index_set)
+ {
+ dbstruct->index_set = (dbiIndexSet *)safemalloc(sizeof(dbiIndexSet));
+ Zero(dbstruct->index_set, 1, dbiIndexSet);
+ }
+ // Run the search
+ // This goes back to the comment below at the ALIAS: XS keyword, that the
+ // indexing here shouldn't be hard-coded.
+ if (idx == 0)
+ result = rpmdbFindByFile(dbstruct->dbp, str, dbstruct->index_set);
+ else if (idx == 1)
+ result = rpmdbFindByGroup(dbstruct->dbp, str, dbstruct->index_set);
+ else if (idx == 2)
+ result = rpmdbFindByProvides(dbstruct->dbp, str, dbstruct->index_set);
+ else if (idx == 3)
+ result = rpmdbFindByRequiredBy(dbstruct->dbp,str, dbstruct->index_set);
+ else if (idx == 4)
+ result = rpmdbFindByConflicts(dbstruct->dbp, str, dbstruct->index_set);
+ else if (idx == 5)
+ result = rpmdbFindPackage(dbstruct->dbp, str, dbstruct->index_set);
+
+ // The various rpmdbFind*() routines return 0 on success
+ if (! result)
+ {
+ av_extend(return_val, dbstruct->index_set->count);
+ for (loop = 0; loop < dbstruct->index_set->count; loop++)
+ {
+ idx = dbstruct->index_set->recs[loop].recOffset;
+ tmp_hdr = rpmdb_FETCH(self, sv_2mortal(newSViv(idx)));
+ av_store(return_val, loop, sv_2mortal(newSViv((I32)tmp_hdr)));
+ }
+ }
+
+ return return_val;
+}
+
+MODULE = RPM::Database PACKAGE = RPM::Database PREFIX = rpmdb_
+
+
+RPM::Database
+rpmdb_TIEHASH(class, opts=NULL)
+ char* class;
+ SV* opts;
+ PROTOTYPE: $;$
+
+RPM::Header
+rpmdb_FETCH(self, key)
+ RPM::Database self;
+ SV* key;
+ PROTOTYPE: $$
+
+int
+rpmdb_STORE(self, key, value)
+ RPM::Database self;
+ SV* key;
+ SV* value;
+ PROTOTYPE: $$$
+ CODE:
+ {
+ warn("STORE: operation not permitted");
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+int
+rpmdb_DELETE(self, key)
+ RPM::Database self;
+ SV* key;
+ PROTOTYPE: $$
+ CODE:
+ {
+ warn("DELETE: operation not permitted");
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+int
+rpmdb_CLEAR(self)
+ RPM::Database self;
+ PROTOTYPE: $
+ CODE:
+ {
+ warn("CLEAR: operation not permitted");
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+int
+rpmdb_EXISTS(self, key)
+ RPM::Database self;
+ SV* key;
+ PROTOTYPE: $$
+
+void
+rpmdb_FIRSTKEY(self)
+ RPM::Header self;
+ PROTOTYPE: $
+ PREINIT:
+ SV* key;
+ SV* value;
+ PPCODE:
+ {
+ RPM__Header hvalue;
+
+ if (! rpmdb_FIRSTKEY(self, &key, &hvalue))
+ {
+ key = newSVsv(&sv_undef);
+ value = newSVsv(&sv_undef);
+ }
+ else
+ value = newRV((SV *)hvalue);
+
+ EXTEND(SP, 2);
+ PUSHs(sv_2mortal(value));
+ PUSHs(sv_2mortal(newSVsv(key)));
+ }
+
+void
+rpmdb_NEXTKEY(self, key=NULL)
+ RPM::Database self;
+ SV* key;
+ PROTOTYPE: $;$
+ PREINIT:
+ SV* nextkey;
+ SV* nextvalue;
+ PPCODE:
+ {
+ RPM__Header hvalue;
+
+ if (! rpmdb_NEXTKEY(self, key, &nextkey, &hvalue))
+ {
+ nextkey = newSVsv(&sv_undef);
+ nextvalue = newRV(&sv_undef);
+ }
+ else
+ nextvalue = newRV((SV *)hvalue);
+
+ EXTEND(SP, 2);
+ PUSHs(sv_2mortal(nextvalue));
+ PUSHs(sv_2mortal(newSVsv(nextkey)));
+ }
+
+void
+rpmdb_DESTROY(self)
+ RPM::Database self;
+ PROTOTYPE: $
+
+int
+rpmdb_init(class, root=NULL, perms=O_RDWR)
+ const char* class;
+ const char* root;
+ int perms;
+ PROTOTYPE: $;$$
+ INIT:
+ if (strcmp(class, "RPM::Database"))
+ croak("RPM::Database::init must be called as a static method");
+
+int
+rpmdb_rebuild(class, root=NULL)
+ const char* class;
+ const char* root;
+ PROTOTYPE: $;$
+ INIT:
+ if (strcmp(class, "RPM::Database"))
+ croak("RPM::Database::rebuild must be called as a static method");
+
+void
+rpmdb_FindByFile(self, string)
+ RPM::Database self;
+ SV* string;
+ PROTOTYPE: $$
+ ALIAS:
+ # These should not be hard-coded, fix in later rev
+ FindByGroup = 1
+ FindByProvides = 2
+ FindByRequiredBy = 3
+ FindByConflicts = 4
+ FindByPackage = 5
+ PPCODE:
+ {
+ AV* matches;
+ int len, size;
+ SV** svp;
+ RPM__Header hdr;
+ SV* hdr_ptr;
+
+ matches = rpmdb_find_by_whatever(self, string, ix);
+ if ((len = av_len(matches)) != -1)
+ {
+ // We have (len+1) elements in the array to put onto the stack
+ size = len + 1;
+ EXTEND(SP, size);
+ while (len >= 0)
+ {
+ // This being a stack and all, we put them in backwards
+ svp = av_fetch(matches, len, FALSE);
+ if (svp && SvIOK(*svp))
+ {
+ hdr = (RPM__Header)SvIV(*svp);
+ hdr_ptr = sv_bless(newRV_noinc((SV*)hdr),
+ gv_stashpv("RPM::Header", TRUE));
+ hv_magic(hdr, (GV *)Nullhv, 'P');
+ }
+ else
+ hdr_ptr = newSVsv(&sv_undef);
+ PUSHs(hdr_ptr);
+ len--;
+ }
+ }
+ else
+ size = 0;
+
+ XSRETURN(size);
+ }
diff --git a/Perl-RPM/RPM/Header.pm b/Perl-RPM/RPM/Header.pm
new file mode 100644
index 000000000..fe4c833a1
--- /dev/null
+++ b/Perl-RPM/RPM/Header.pm
@@ -0,0 +1,196 @@
+###############################################################################
+#
+# (c) Copyright @ 2000, Red Hat Software, Inc.,
+# All Rights Reserved
+#
+###############################################################################
+#
+# $Id: Header.pm,v 1.1 2000/05/27 03:54:15 rjray Exp $
+#
+# Description: The RPM::Header class provides access to the RPM Header
+# structure as a tied hash, allowing direct access to the
+# tags in a header as keys, and the content of said tags
+# as the values.
+#
+# Functions: new
+#
+# Libraries: None.
+#
+# Global Consts: None.
+#
+# Environment: Just stuff from the RPM config.
+#
+###############################################################################
+
+package RPM::Header;
+
+require 5.005;
+
+use strict;
+use vars qw($VERSION $revision);
+use subs qw(new);
+
+require RPM;
+
+$VERSION = $RPM::VERSION;
+$revision = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
+
+1;
+
+sub new
+{
+ my $class = shift;
+ my %hash = ();
+
+ tie %hash, $class, @_;
+ return (tied %hash);
+}
+
+__END__
+
+=head1 NAME
+
+RPM::Header - Access to RPM package headers
+
+=head1 SYNOPSIS
+
+ use RPM::Header;
+
+ tie %hdr, "RPM::Header", "rpm-3.0.4-0.48.i386.rpm" or die "$RPM::err";
+
+ for (sort keys %hdr)
+ {
+ ...
+ }
+
+=head1 DESCRIPTION
+
+The B<RPM::Header> package permits access to the header of a package (external
+file or currently installed) as either a tied hash or a blessed hash reference.
+The tags that are present in the header are expressed as keys. Retrieving
+them via C<keys> or C<each> returns the tags in the order in which they
+appear in the header. Keys may be requested without regard for letter case,
+but they are always returned as all upper-case.
+
+The return value corresponding to each key is a list reference (or C<undef>
+if the key is not valid). This is due to the fact that any of the tags may
+have more than one piece of data associated, and the C<FETCH> interface to
+hashes presumes scalar calling context and return value. Thus, rather than
+require developers to frequently test the return value as a reference or
+not, the value is simple always returned as a list ref, even if there is only
+one element.
+
+B<RPM::Header> objects are also the native return value from keys retrieved
+in the B<RPM::Database> class (see L<RPM::Database>). In these cases, the
+header data is marked read-only, and attempts to alter any of the keys will
+generate an error.
+
+There are also a number of class methods implemented, which are described in
+the next section.
+
+=head1 USAGE
+
+=head2 Creating an Object
+
+An object may be created one of two ways:
+
+ tie %h, "RPM::Header", "filename";
+
+ $href = new RPM::Header "filename";
+
+The latter approach offers more direct access to the class methods, while
+also permitting the usual tied-hash operations such as fetching:
+
+ $href->{tag} # Such as "name" or "version"
+
+=head2 Class Methods
+
+The following methods are available to objects of this class, in addition to
+the tied-hash suite of operations. If the object is a hash instead of a
+hash reference, it can be used to call these methods via:
+
+ (tied %hash)->method_name(...)
+
+=over
+
+=item size
+
+Return the size of the header, in bytes, within the disk file containing the
+associated package. The value is also returned for those headers within the
+database.
+
+=item tagtype(TAG)
+
+Given a tag I<TAG>, return the type as a numerical value. The valid types
+can be imported from the B<RPM::Constants> package via the import-tag
+":rpmtype", and are:
+
+=over
+
+=item RPM_NULL_TYPE
+
+Used internally by B<rpm>.
+
+=item RPM_BIN_TYPE
+
+The data returned is a single chunk of binary data. It has been converted to
+a single "string" in Perl terms, but may contain nulls within it. The
+B<length()> keyword should return the correct size for the chunk.
+
+=item RPM_CHAR_TYPE
+
+All items are single-character in nature. Note that since Perl does not
+distinguish single characters versus strings in the way that C does, these
+are stored as single-character strings. It is a tradeoff of efficiency over
+memory.
+
+=item RPM_INT8_TYPE
+
+All items are integers no larger than 8 bits wide.
+
+=item RPM_INT16_TYPE
+
+All items are integers no larger than 16 bits wide.
+
+=item RPM_INT32_TYPE
+
+All items are integers no larger than 32 bits wide.
+
+=item RPM_STRING_TYPE
+
+=item RPM_I18NSTRING_TYPE
+
+=item RPM_STRING_ARRAY_TYPE
+
+These three are functionally similar from the Perl perspective. Currently,
+B<RPM> does not export data in an I18N format, it will have been converted to
+an ordinary string before being handed to the caller (in this case, before
+the internal Perl/XS code receives it). The distinction between STRING and
+STRING_ARRAY types is only relevant internally. All of these are sequences of
+one or more text strings, returned in the same internal order as they are
+stored within the header.
+
+=back
+
+=back
+
+=head1 DIAGNOSTICS
+
+Direct binding to the internal error-management of B<rpm> is still under
+development. At present, most operations generate their diagnostics to
+STDERR.
+
+=head1 CAVEATS
+
+This is currently regarded as alpha-quality software. The interface is
+subject to change in future releases.
+
+=head1 SEE ALSO
+
+L<RPM>, L<RPM::Database>, L<perl>, L<rpm>
+
+=head1 AUTHOR
+
+Randy J. Ray <rjray@blackperl.com>
+
+=cut
diff --git a/Perl-RPM/RPM/Header.xs b/Perl-RPM/RPM/Header.xs
new file mode 100644
index 000000000..b3b0fc6fe
--- /dev/null
+++ b/Perl-RPM/RPM/Header.xs
@@ -0,0 +1,1060 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <ctype.h>
+#include "RPM.h"
+
+static char * const rcsid = "$Id: Header.xs,v 1.1 2000/05/27 03:54:15 rjray Exp $";
+
+//
+// Use this define for deriving the saved Header struct, rather than coding
+// it a dozen places. Note that the hv_fetch call is the no-magic one defined
+// in RPM.h
+//
+#define header_from_object_ret(s_ptr, header, object, err_ret) \
+ hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
+ (header) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Header *)SvIV(*(s_ptr)) : NULL; \
+ if (! (header)) \
+ return (err_ret);
+// And a no-return-value version:
+#define header_from_object(s_ptr, header, object) \
+ hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
+ (header) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Header *)SvIV(*(s_ptr)) : NULL; \
+ if (! (header)) return;
+
+
+// Some simple functions to manage key-to-SV* transactions, since these
+// gets used frequently.
+const char* sv2key(SV* key)
+{
+ const char* new_key;
+ STRLEN na;
+
+ // De-reference key, if it is a reference
+ if (SvROK(key))
+ key = SvRV(key);
+ new_key = SvPV(key, na);
+
+ return new_key;
+}
+
+SV* key2sv(const char* key)
+{
+ STRLEN na;
+
+ return (sv_2mortal(newSVpv((char *)key, na)));
+}
+
+static SV* ikey2sv(int key)
+{
+ return (sv_2mortal(newSViv(key)));
+}
+
+// This creates a header data-field from the passed-in data
+static AV* rpmhdr_create(const char* data, int type, int size)
+{
+ char urk[2];
+ AV* new_list;
+ SV* new_item;
+ int idx;
+
+ new_list = newAV();
+
+ //
+ // Bad enough to have to duplicate the loop for all the case branches, I
+ // can at least bitch out on two of them:
+ //
+ if (type == RPM_NULL_TYPE)
+ {
+ return new_list;
+ }
+ else if (type == RPM_BIN_TYPE)
+ {
+ // This differs from other types in that here size is the length of
+ // the binary chunk itself
+ av_store(new_list, 0, newSVpv((char *)data, size));
+ }
+ else
+ {
+ // There will be at least this many items:
+ av_extend(new_list, size);
+
+ switch (type)
+ {
+ case RPM_CHAR_TYPE:
+ {
+ char* loop;
+
+ for (loop = (char *)data, idx = 0; idx < size; idx++, loop++)
+ {
+ urk[0] = *data;
+ urk[1] = '\0';
+ new_item = newSVpv((char *)urk, 1);
+ av_store(new_list, idx, sv_2mortal(new_item));
+ SvREFCNT_inc(new_item);
+ }
+
+ break;
+ }
+ case RPM_INT8_TYPE:
+ {
+ I8* loop;
+
+ for (loop = (I8 *)data, idx = 0; idx < size; idx++, loop++)
+ {
+ // Note that the rpm lib also uses masks for INT8
+ new_item = newSViv((I32)(*((I8 *)loop) & 0xff));
+ av_store(new_list, idx, sv_2mortal(new_item));
+ SvREFCNT_inc(new_item);
+ }
+
+ break;
+ }
+ case RPM_INT16_TYPE:
+ {
+ I16* loop;
+
+ for (loop = (I16 *)data, idx = 0; idx < size; idx++, loop++)
+ {
+ // Note that the rpm lib also uses masks for INT16
+ new_item = newSViv((I32)(*((I16 *)loop) & 0xffff));
+ av_store(new_list, idx, sv_2mortal(new_item));
+ SvREFCNT_inc(new_item);
+ }
+
+ break;
+ }
+ case RPM_INT32_TYPE:
+ {
+ I32* loop;
+
+ for (loop = (I32 *)data, idx = 0; idx < size; idx++, loop++)
+ {
+ new_item = newSViv((I32)*((I32 *)loop));
+ av_store(new_list, idx, sv_2mortal(new_item));
+ SvREFCNT_inc(new_item);
+ }
+
+ break;
+ }
+ case RPM_STRING_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ case RPM_STRING_ARRAY_TYPE:
+ {
+ char** loop;
+
+ // Special case for exactly one RPM_STRING_TYPE
+ if (type == RPM_STRING_TYPE && size == 1)
+ {
+ new_item = newSVsv(&sv_undef);
+ sv_setpvn(new_item, (char *)data, strlen((char *)data));
+ av_store(new_list, 0, sv_2mortal(new_item));
+ SvREFCNT_inc(new_item);
+ }
+ else
+ {
+ for (loop = (char **)data, idx = 0;
+ idx < size;
+ idx++, loop++)
+ {
+ new_item = newSVsv(&sv_undef);
+ sv_setpvn(new_item, *loop, strlen(*loop));
+ av_store(new_list, idx, sv_2mortal(new_item));
+ SvREFCNT_inc(new_item);
+ }
+ }
+
+ // Only for STRING_ARRAY_TYPE do we have to call free()
+ if (type == RPM_STRING_ARRAY_TYPE) Safefree(data);
+ break;
+ }
+ default:
+ warn("Unimplemented tag type");
+ break;
+ }
+ }
+
+ return new_list;
+}
+
+// These three are for reading the header data from external sources
+static int new_from_fd_t(FD_t fd, RPM_Header* new_hdr)
+{
+ int is_source;
+ int major;
+ int minor;
+
+ if (rpmReadPackageHeader(fd, &new_hdr->hdr, &is_source, &major, &minor))
+ return 0;
+
+ new_hdr->isSource = is_source;
+ new_hdr->major = major;
+ new_hdr->minor = minor;
+
+ return 1;
+}
+
+static int new_from_fd(int fd, RPM_Header* new_hdr)
+{
+ FD_t FD = fdDup(fd);
+
+ return(new_from_fd_t(FD, new_hdr));
+}
+
+static int new_from_fname(const char* source, RPM_Header* new_hdr)
+{
+ FD_t fd;
+
+ if (! (fd = Fopen(source, "r+")))
+ croak("Error opening the file %s", source);
+
+ return(new_from_fd_t(fd, new_hdr));
+}
+
+RPM__Header rpmhdr_TIEHASH(SV* class, SV* source, int flags)
+{
+ char* fname;
+ int fname_len;
+ SV* val;
+ RPM__Header TIEHASH;
+ RPM_Header* hdr_struct; // Use this to store the actual C-level data
+
+ hdr_struct = safemalloc(sizeof(RPM_Header));
+ Zero(hdr_struct, 1, RPM_Header);
+
+ if (! source)
+ hdr_struct->hdr = headerNew();
+ else if (! (flags & RPM_HEADER_FROM_REF))
+ {
+ // If we aren't starting out with a pointer to a Header
+ // struct, figure out how to get there from here
+
+ // If it is a string value, assume it to be a file name
+ if (SvPOK(source))
+ {
+ fname = SvPV(source, fname_len);
+ if (! new_from_fname(fname, hdr_struct))
+ {
+ return ((RPM__Header)newSVsv(&sv_undef));
+ }
+ }
+ else if (IoIFP(sv_2io(source)))
+ {
+ if (! new_from_fd(PerlIO_fileno(IoIFP(sv_2io(source))),
+ hdr_struct))
+ {
+ return ((RPM__Header)newSVsv(&sv_undef));
+ }
+ }
+ else
+ {
+ croak("Argument 2 must be filename or GLOB");
+ }
+ }
+ else
+ {
+ hdr_struct->hdr = (Header)SvRV(source);
+ // We simply don't know these three settings at this point
+ hdr_struct->isSource = -1;
+ hdr_struct->major = -1;
+ hdr_struct->minor = -1;
+ }
+
+ // These three are likely to be most of the data requests, anyway
+ headerNVR(hdr_struct->hdr,
+ &hdr_struct->name, &hdr_struct->version, &hdr_struct->release);
+ // This defaults to false, but RPM::Database will set it true
+ hdr_struct->read_only = flags & RPM_HEADER_READONLY;
+
+ hdr_struct->iterator = (HeaderIterator)NULL;
+
+ new_RPM__Header(TIEHASH);
+ // With the actual HV*, store the type-keys for the three cached values:
+ hv_store_nomg(TIEHASH, "NAME_t", 7, newSViv(RPM_STRING_TYPE), FALSE);
+ hv_store_nomg(TIEHASH, "VERSION_t", 10, newSViv(RPM_STRING_TYPE), FALSE);
+ hv_store_nomg(TIEHASH, "RELEASE_t", 10, newSViv(RPM_STRING_TYPE), FALSE);
+ hv_store_nomg(TIEHASH,
+ STRUCT_KEY, STRUCT_KEY_LEN,
+ newSViv((unsigned)hdr_struct), FALSE);
+ return TIEHASH;
+}
+
+AV* rpmhdr_FETCH(RPM__Header self, SV* key,
+ const char* data_in, int type_in, int size_in)
+{
+ const char* name; // For the actual name out of (SV *)key
+ int namelen; // Arg for SvPV(..., len)
+ char* uc_name; // UC'd version of name
+ RPM_Header* hdr; // Pointer to C-level struct
+ SV** svp;
+ SV* ret_undef;
+ AV* FETCH;
+ int i;
+
+ FETCH = newAV();
+ av_store(FETCH, 0, newSVsv(&sv_undef));
+
+ header_from_object_ret(svp, hdr, self, FETCH);
+
+ name = sv2key(key);
+ if (! (name && (namelen = strlen(name))))
+ return FETCH;
+
+ uc_name = safemalloc(namelen + 3);
+ for (i = 0; i < namelen; i++)
+ uc_name[i] = toUPPER(name[i]);
+ uc_name[i] = '\0';
+
+ // Check the three keys that are cached directly on the struct itself:
+ if (! strcmp(uc_name, "NAME"))
+ av_store(FETCH, 0, newSVpv((char *)hdr->name, 0));
+ else if (! strcmp(uc_name, "VERSION"))
+ av_store(FETCH, 0, newSVpv((char *)hdr->version, 0));
+ else if (! strcmp(uc_name, "RELEASE"))
+ av_store(FETCH, 0, newSVpv((char *)hdr->release, 0));
+ else
+ {
+ // If it wasn't one of those three, then we have to explicitly fetch
+ // it, either from the store in cache or via the headerGetEntry() call
+ hv_fetch_nomg(svp, self, uc_name, namelen, FALSE);
+ if (svp && SvOK(*svp))
+ {
+ av_undef(FETCH);
+ FETCH = (AV *)SvRV(*svp);
+ }
+ else if (data_in)
+ {
+ // In some cases (particarly the iterators) we could be called
+ // with the data already available, but not on the hash just yet.
+ AV* new_item = rpmhdr_create(data_in, type_in, size_in);
+
+ hv_store_nomg(self, uc_name, namelen, newRV_noinc((SV *)new_item),
+ FALSE);
+ hv_store_nomg(self, strcat(uc_name, "_t"), (namelen + 2),
+ newSViv(type_in), FALSE);
+ av_undef(FETCH);
+ FETCH = new_item;
+ }
+ else
+ {
+ AV* new_item;
+ char* new_item_p;
+ int new_item_type;
+ int tag_by_num;
+ int size;
+ char urk[2];
+
+ // Get the #define value for the tag from the hash made at boot-up
+ if (! (tag_by_num = tag2num(uc_name)))
+ {
+ // Later we need to set some sort of error message
+ Safefree(uc_name);
+ return FETCH;
+ }
+
+ // Pull the tag by the int value we now have
+ if (! headerGetEntry(hdr->hdr, tag_by_num,
+ &new_item_type, (void **)&new_item_p, &size))
+ {
+ Safefree(uc_name);
+ return FETCH;
+ }
+ new_item = rpmhdr_create(new_item_p, new_item_type, size);
+
+ hv_store_nomg(self, uc_name, namelen, newRV_noinc((SV *)new_item),
+ FALSE);
+ hv_store_nomg(self, strcat(uc_name, "_t"), (namelen + 2),
+ newSViv(new_item_type), FALSE);
+ av_undef(FETCH);
+ FETCH = new_item;
+ }
+ }
+
+ Safefree(uc_name);
+ return FETCH;
+}
+
+//
+// Store the data in "value" both in the header and in the hash associated
+// with "self".
+//
+int rpmhdr_STORE(RPM__Header self, SV* key, AV* value)
+{
+ SV** svp;
+ const char* name;
+ char* uc_name;
+ STRLEN namelen;
+ int size, i;
+ I32 num_ent, data_type, data_key;
+ void* data;
+ RPM_Header* hdr;
+
+ header_from_object_ret(svp, hdr, self, 0);
+ if (hdr->read_only)
+ return 0;
+
+ name = sv2key(key);
+ if (! (name && (namelen = strlen(name))))
+ return 0;
+
+ uc_name = safemalloc(namelen + 3);
+ for (i = 0; i < namelen; i++)
+ uc_name[i] = toUPPER(name[i]);
+ uc_name[i] = '\0';
+
+ // Get the numerical tag value for this name. If none exists, this means
+ // that there is no such tag, which is an error in this case
+ if (! (num_ent = tag2num(uc_name)))
+ return 0;
+
+ // Setting/STORE-ing means do the following:
+ //
+ // 1. Confirm that data adheres to type (mostly check against int types)
+ // 2. Create the blob in **data
+ // 3. Store to the header struct
+ // 4. Store the AV* on the hash
+
+ // How many elements being passed?
+ size = av_len(value) + 1;
+ // This will permanently concat "_t" to uc_name. But we'll craftily
+ // manipulate that later on with namelen.
+ hv_fetch_nomg(svp, self, strcat(uc_name, "_t"), (namelen + 2), FALSE);
+ // This should NOT happen, but I prefer caution:
+ if (! (svp && SvOK(*svp)))
+ return 0;
+ data_type = SvIV(*svp);
+ SvREFCNT_dec(*svp);
+
+ if (data_type == RPM_INT8_TYPE ||
+ data_type == RPM_INT16_TYPE ||
+ data_type == RPM_INT32_TYPE)
+ {
+ // Cycle over the array and quickly verify that all elements are valid
+ for (i = 0; i <= size; i++)
+ {
+ svp = av_fetch(value, i, FALSE);
+ if (! (SvOK(*svp) && SvIOK(*svp)))
+ {
+ warn("Non-integer value passed for integer-type tag");
+ return 0;
+ }
+ }
+ }
+
+ //
+ // This is more like the rpmhdr_create case block, where we have to
+ // discern based on data-type, so that the pointers are properly
+ // allocated and assigned.
+ //
+ switch (data_type)
+ {
+ case RPM_NULL_TYPE:
+ size = 1;
+ data = NULL;
+ break;
+ case RPM_BIN_TYPE:
+ {
+ char* data_p;
+
+ svp = av_fetch(value, 0, FALSE);
+ if (svp && SvPOK(*svp))
+ data_p = SvPV(*svp, size);
+ else
+ {
+ size = 0;
+ data_p = Nullch;
+ }
+
+ data = (void *)data_p;
+ break;
+ }
+ case RPM_CHAR_TYPE:
+ {
+ char* data_p;
+ char* str_sv;
+ STRLEN len;
+
+ Newz(TRUE, data_p, size, char);
+ for (i = 0; i < size; i++)
+ {
+ // Having stored the chars in separate SVs wasn't the most
+ // efficient way, but it made the rest of things a lot
+ // cleaner. To be safe, only take the initial character from
+ // each SV.
+ svp = av_fetch(value, i, FALSE);
+ if (svp && SvPOK(*svp))
+ {
+ str_sv = SvPV(*svp, len);
+ data_p[i] = str_sv[0];
+ }
+ else
+ data_p[i] = '\0';
+ }
+
+ data = (void *)data_p;
+ break;
+ }
+ case RPM_INT8_TYPE:
+ {
+ I8** data_p;
+
+ Newz(TRUE, data_p, size, I8*);
+
+ for (i = 0; i < size; i++)
+ {
+ svp = av_fetch(value, i, FALSE);
+ if (svp && SvIOK(*svp))
+ *(data_p[i]) = (I8)SvIV(*svp);
+ else
+ *(data_p[i]) = (I8)0;
+ }
+
+ data = (void *)data_p;
+ break;
+ }
+ case RPM_INT16_TYPE:
+ {
+ I16** data_p;
+
+ Newz(TRUE, data_p, size, I16*);
+
+ for (i = 0; i < size; i++)
+ {
+ svp = av_fetch(value, i, FALSE);
+ if (svp && SvIOK(*svp))
+ *(data_p[i]) = (I16)SvIV(*svp);
+ else
+ *(data_p[i]) = (I16)0;
+ }
+
+ data = (void *)data_p;
+ break;
+ }
+ case RPM_INT32_TYPE:
+ {
+ I32** data_p;
+
+ Newz(TRUE, data_p, size, I32*);
+
+ for (i = 0; i < size; i++)
+ {
+ svp = av_fetch(value, i, FALSE);
+ if (svp && SvIOK(*svp))
+ *(data_p[i]) = SvIV(*svp);
+ else
+ *(data_p[i]) = 0;
+ }
+
+ data = (void *)data_p;
+ break;
+ }
+ case RPM_STRING_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ case RPM_STRING_ARRAY_TYPE:
+ {
+ char** data_p;
+ char* str_sv;
+ char* str_new;
+ STRLEN len;
+
+ if (data_type == RPM_STRING_TYPE && size == 1)
+ {
+ // Special case for exactly one RPM_STRING_TYPE
+ svp = av_fetch(value, 0, FALSE);
+ if (svp && SvPOK(*svp))
+ {
+ str_sv = SvPV(*svp, len);
+ str_new = safemalloc(len + 1);
+ strncpy(str_new, str_sv, len + 1);
+ }
+ else
+ str_new = Nullch;
+
+ data = (void **)str_new;
+ }
+ else
+ {
+ Newz(TRUE, data_p, size, char*);
+
+ for (i = 0; i < size; i++)
+ {
+ svp = av_fetch(value, i, FALSE);
+ if (svp && SvPOK(*svp))
+ {
+ str_sv = SvPV(*svp, len);
+ str_new = safemalloc(len + 1);
+ strncpy(str_new, str_sv, len + 1);
+ data_p[i] = str_new;
+ }
+ else
+ data_p[i] = Nullch;
+ }
+
+ data = (void *)data_p;
+ }
+ break;
+ }
+ default:
+ warn("Unimplemented tag type");
+ break;
+ }
+ // That was fun. I always enjoy delving into the black magic of void *.
+
+ // Remove any pre-existing tag
+ headerRemoveEntry(hdr->hdr, num_ent); // Don't care if it fails?
+ // Store the new data
+ headerAddEntry(hdr->hdr, num_ent, data_type, data, size); // Always ret. 1
+ // Store on the hash
+ hv_store_nomg(self, uc_name, namelen, newRV_noinc((SV *)value), FALSE);
+
+ return 1;
+}
+
+int rpmhdr_DELETE(RPM__Header self, SV* key)
+{
+ const char* name; // For the actual name out of (SV *)key
+ int namelen; // Arg for SvPV(..., len)
+ char* uc_name; // UC'd version of name
+ RPM_Header* hdr; // Pointer to C-level struct
+ SV** svp;
+ int retval, num, i;
+
+ header_from_object_ret(svp, hdr, self, 0);
+ if (hdr->read_only)
+ return 0;
+
+ name = sv2key(key);
+ if (! (name && (namelen = strlen(name))))
+ return 0;
+
+ uc_name = safemalloc(namelen + 3);
+ for (i = 0; i < namelen; i++)
+ uc_name[i] = toUPPER(name[i]);
+ uc_name[i] = '\0';
+
+ // Get the numerical tag value for this name. If none exists, this means
+ // that there is no such tag, which isn't really an error (so return 1).
+ if (! (num = tag2num(uc_name)))
+ {
+ retval = 1;
+ }
+ // Deletion means three steps:
+ //
+ // 1. rpmlib-level deletion
+ // 2. Delete the key from self
+ // 3. Delete the KEY_t from self
+ //
+ // First off, if there were no entries of this tag, no need to do 2 or 3
+ else if (headerRemoveEntry(hdr->hdr, num))
+ {
+ retval = 1;
+ }
+ else
+ {
+ // Remove magic long enough to do two hv_delete() calls
+ SvMAGICAL_off((SV *)self);
+ hv_delete(self, uc_name, namelen, G_DISCARD);
+ hv_delete(self, strcat(uc_name, "_t"), namelen + 2, G_DISCARD);
+ SvMAGICAL_on((SV *)self);
+ retval = 1;
+ }
+
+ Safefree(uc_name);
+ return retval;
+}
+
+int rpmhdr_EXISTS(RPM__Header self, SV* key)
+{
+ const char* name;
+ char* uc_name;
+ int namelen, tag_by_num, i;
+ SV** svp;
+ RPM_Header* hdr;
+
+ header_from_object_ret(svp, hdr, self, 0);
+ name = sv2key(key);
+ if (! (name && (namelen = strlen(name))))
+ return 0;
+
+ // Unlike FETCH, there will be no need for the KEY_t string
+ uc_name = safemalloc(namelen + 1);
+ for (i = 0; i < namelen; i++)
+ uc_name[i] = toUPPER(name[i]);
+ uc_name[i] = '\0';
+
+ // Get the #define value for the tag from the hash made at boot-up
+ tag_by_num = tag2num(uc_name);
+ Safefree(uc_name);
+ if (! tag_by_num)
+ // Later we need to set some sort of error message
+ return 0;
+
+ return (headerIsEntry(hdr->hdr, tag_by_num));
+}
+
+int rpmhdr_FIRSTKEY(RPM__Header self, SV** key, AV** value)
+{
+ SV** svp;
+ RPM_Header* hdr;
+ int tag, type, size;
+ char* ptr;
+ const char* tagname;
+
+ header_from_object_ret(svp, hdr, self, 0);
+ // If there is an existing iterator attached to the struct, free it
+ if (hdr->iterator)
+ headerFreeIterator(hdr->iterator);
+
+ // The init function returns the iterator that will be used in later calls
+ if (! (hdr->iterator = headerInitIterator(hdr->hdr)))
+ // need some error message?
+ return 0;
+
+ // Run once to get started
+ headerNextIterator(hdr->iterator,
+ Null(int *), Null(int *), Null(void **), Null(int *));
+ // Now run it once, to get the first header entry
+ if (! headerNextIterator(hdr->iterator, &tag, &type, (void **)&ptr, &size))
+ return 0;
+
+ tagname = num2tag(tag);
+ *key = newSVpv((char *)tagname, strlen(tagname));
+ *value = rpmhdr_FETCH(self, *key, ptr, type, size);
+
+ return 1;
+}
+
+int rpmhdr_NEXTKEY(RPM__Header self, SV* key, SV** nextkey, AV** nextvalue)
+{
+ SV** svp;
+ RPM_Header* hdr;
+ int tag, type, size;
+ char* ptr;
+ const char* tagname;
+
+ header_from_object_ret(svp, hdr, self, 0);
+ // If there is not an existing iterator, we can't continue
+ if (! hdr->iterator)
+ return 0;
+
+ // Run it once, to get the next header entry
+ if (! headerNextIterator(hdr->iterator, &tag, &type, (void **)&ptr, &size))
+ return 0;
+
+ tagname = num2tag(tag);
+ *nextkey = newSVpv((char *)tagname, strlen(tagname));
+ *nextvalue = rpmhdr_FETCH(self, *nextkey, ptr, type, size);
+
+ return 1;
+}
+
+void rpmhdr_DESTROY(RPM__Header self)
+{
+ SV** svp;
+ RPM_Header* hdr;
+
+ header_from_object(svp, hdr, self);
+
+ if (hdr->iterator)
+ headerFreeIterator(hdr->iterator);
+ if (hdr->hdr)
+ headerFree(hdr->hdr);
+}
+
+unsigned int rpmhdr_size(RPM__Header self)
+{
+ SV** svp;
+ RPM_Header* hdr;
+
+ header_from_object_ret(svp, hdr, self, 0);
+
+ if (! hdr->hdr)
+ return 0;
+ else
+ return(headerSizeof(hdr->hdr, HEADER_MAGIC_YES));
+}
+
+int rpmhdr_tagtype(RPM__Header self, SV* key)
+{
+ STRLEN namelen;
+ const char* name;
+ char* uc_name;
+ SV** svp;
+ int i, retval;
+
+ name = sv2key(key);
+ if (! (name && (namelen = strlen(name))))
+ return RPM_NULL_TYPE;
+
+ uc_name = safemalloc(namelen + 3);
+ for (i = 0; i < namelen; i++)
+ uc_name[i] = toUPPER(name[i]);
+ uc_name[i] = '\0';
+ strcat(uc_name, "_t");
+
+ retval = RPM_NULL_TYPE;
+
+ hv_fetch_nomg(svp, self, uc_name, strlen(uc_name) + 1, FALSE);
+ if (svp && SvOK(*svp))
+ {
+ // The base tag has already been fetched and thus we have a type
+ retval = SvIV(*svp);
+ }
+ else
+ {
+ // We haven't had to fetch the tag itself yet. Until then, the special
+ // key that holds the type isn't available, either.
+ //
+ // Do a plain fetch (that is, leave magic on) to populate the other
+ AV* sub_fetch = rpmhdr_FETCH(self, key, Nullch, 0, 0);
+
+ if (sub_fetch)
+ {
+ hv_fetch_nomg(svp, self, uc_name, strlen(uc_name), FALSE);
+ if (svp && SvOK(*svp))
+ {
+ // The base tag has now been fetched
+ retval = SvIV(*svp);
+ }
+ }
+ }
+
+ Safefree(uc_name);
+ return retval;
+}
+
+int rpmhdr_write(RPM__Header self, SV* gv_in, int magicp)
+{
+ IO* io;
+ PerlIO* fp;
+ FD_t fd;
+ RPM_Header* hdr;
+ GV* gv;
+ SV** svp;
+ int written = 0;
+
+ gv = (SvPOK(gv_in) && (SvTYPE(gv_in) == SVt_PVGV)) ?
+ (GV *)SvRV(gv_in) : (GV *)gv_in;
+ header_from_object_ret(svp, hdr, self, 0);
+
+ if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io)))
+ return written;
+
+ fd = fdDup(PerlIO_fileno(fp));
+ headerWrite(fd, hdr->hdr, magicp);
+ Fclose(fd);
+ written = headerSizeof(hdr->hdr, magicp);
+
+ return written;
+}
+
+// Here starts the code for the RPM::Header::datum class
+RPM__Header__datum rpmdatum_TIESCALAR(SV* class, SV* datum, int size, int type)
+{
+}
+
+SV* rpmdatum_FETCH(RPM__Header__datum self)
+{
+}
+
+SV* rpmdatum_STORE(RPM__Header__datum self, RPM__Header__datum newval)
+{
+}
+
+void rpmdatum_DESTROY(RPM__Header__datum self)
+{
+}
+
+int rpmdatum_type(RPM__Header__datum self)
+{
+ return self->type;
+}
+
+int rpmdatum_size(RPM__Header__datum self)
+{
+ return self->size;
+}
+
+
+MODULE = RPM::Header PACKAGE = RPM::Header PREFIX = rpmhdr_
+
+
+RPM::Header
+rpmhdr_TIEHASH(class, source=NULL, flags=0)
+ SV* class;
+ SV* source;
+ int flags;
+ PROTOTYPE: $;$$
+
+AV*
+rpmhdr_FETCH(self, key)
+ RPM::Header self;
+ SV* key;
+ PROTOTYPE: $$
+ CODE:
+ RETVAL = rpmhdr_FETCH(self, key, Nullch, 0, 0);
+ OUTPUT:
+ RETVAL
+
+int
+rpmhdr_STORE(self, key, value)
+ RPM::Header self;
+ SV* key;
+ SV* value;
+ PROTOTYPE: $$$
+ PREINIT:
+ AV* avalue;
+ CODE:
+ {
+ if (sv_isa(value, "AVPtr"))
+ avalue = (AV *)SvRV(value);
+ else
+ {
+ avalue = newAV();
+ av_store(avalue, 0, value);
+ }
+
+ RETVAL = rpmhdr_STORE(self, key, avalue);
+ }
+ OUTPUT:
+ RETVAL
+
+int
+rpmhdr_DELETE(self, key)
+ RPM::Header self;
+ SV* key;
+ PROTOTYPE: $$
+
+int
+rpmhdr_CLEAR(self)
+ RPM::Header self;
+ PROTOTYPE: $
+ CODE:
+ {
+ warn("CLEAR: operation not permitted");
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+int
+rpmhdr_EXISTS(self, key)
+ RPM::Header self;
+ SV* key;
+ PROTOTYPE: $$
+
+void
+rpmhdr_FIRSTKEY(self)
+ RPM::Header self;
+ PROTOTYPE: $
+ PREINIT:
+ SV* key;
+ AV* value;
+ int i;
+ PPCODE:
+ {
+ if (! rpmhdr_FIRSTKEY(self, &key, &value))
+ {
+ key = newSVsv(&sv_undef);
+ value = newAV();
+ }
+
+ XPUSHs(sv_2mortal(newRV((SV *)value)));
+ XPUSHs(sv_2mortal(newSVsv(key)));
+ }
+
+void
+rpmhdr_NEXTKEY(self, key=NULL)
+ RPM::Header self;
+ SV* key;
+ PROTOTYPE: $;$
+ PREINIT:
+ SV* nextkey;
+ AV* nextvalue;
+ int i;
+ PPCODE:
+ {
+ if (! rpmhdr_NEXTKEY(self, key, &nextkey, &nextvalue))
+ {
+ nextkey = newSVsv(&sv_undef);
+ nextvalue = newAV();
+ }
+
+ XPUSHs(sv_2mortal(newRV((SV *)nextvalue)));
+ XPUSHs(sv_2mortal(newSVsv(nextkey)));
+ }
+
+void
+rpmhdr_DESTROY(self)
+ RPM::Header self;
+ PROTOTYPE: $
+
+unsigned int
+rpmhdr_size(self)
+ RPM::Header self;
+ PROTOTYPE: $
+
+int
+rpmhdr_tagtype(self, key)
+ RPM::Header self;
+ SV* key;
+ PROTOTYPE: $$
+
+int
+rpmhdr_write(self, gv, magicp=0)
+ RPM::Header self;
+ SV* gv;
+ SV* magicp;
+ PROTOTYPE: $$;$
+ CODE:
+ {
+ int flag;
+
+ if (magicp && SvIOK(magicp))
+ flag = SvIV(magicp);
+ else
+ flag = HEADER_MAGIC_YES;
+
+ RETVAL = rpmhdr_write(self, gv, flag);
+ }
+ OUTPUT:
+ RETVAL
+
+
+MODULE = RPM::Header PACKAGE = RPM::Header::datum PREFIX = rpmdatum_
+
+
+RPM::Header::datum
+rpmdatum_TIESCALAR(class, data, size, type)
+ SV* class;
+ SV* data;
+ int size;
+ int type;
+ PROTOTYPE: $$$$
+
+SV*
+rpmdatum_FETCH(self)
+ RPM::Header::datum self;
+ PROTOTYPE: $
+
+SV*
+rpmdatum_STORE(self, newval)
+ RPM::Header::datum self;
+ RPM::Header::datum newval;
+ PROTOTYPE: $$
+
+void
+rpmdatum_DESTROY(self)
+ RPM::Header::datum self;
+ PROTOTYPE: $
+
+int
+rpmdatum_size(self)
+ RPM::Header::datum self;
+ PROTOTYPE: $
+
+int
+rpmdatum_type(self)
+ RPM::Header::datum self;
+ PROTOTYPE: $