310 lines
9.2 KiB
Perl
310 lines
9.2 KiB
Perl
###############################################################################
|
|
#
|
|
# (c) Copyright @ 2000, Randy J. Ray <rjray@blackperl.com>
|
|
# All Rights Reserved
|
|
#
|
|
###############################################################################
|
|
#
|
|
# $Id: Header.pm,v 1.20 2001/04/27 09:05:21 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
|
|
# AUTOLOAD
|
|
# filenames
|
|
#
|
|
# Libraries: None.
|
|
#
|
|
# Global Consts: None.
|
|
#
|
|
# Environment: Just stuff from the RPM config.
|
|
#
|
|
###############################################################################
|
|
|
|
package RPM::Header;
|
|
|
|
require 5.005;
|
|
|
|
use strict;
|
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD);
|
|
use subs qw(new AUTOLOAD filenames);
|
|
|
|
require Exporter;
|
|
|
|
use RPM;
|
|
use RPM::Error;
|
|
use RPM::Constants ':rpmerr';
|
|
|
|
$VERSION = do { my @r=(q$Revision: 1.20 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
|
|
|
|
@ISA = qw(Exporter);
|
|
@EXPORT = ();
|
|
@EXPORT_OK = qw(RPM_HEADER_MASK RPM_HEADER_READONLY);
|
|
%EXPORT_TAGS = (all => \@EXPORT_OK);
|
|
|
|
1;
|
|
|
|
sub AUTOLOAD
|
|
{
|
|
my $constname;
|
|
($constname = $AUTOLOAD) =~ s/.*:://;
|
|
die "& not defined" if $constname eq 'constant';
|
|
my $val = constant($constname);
|
|
if ($! != 0)
|
|
{
|
|
die "Your vendor has not defined RPM macro $constname";
|
|
}
|
|
no strict 'refs';
|
|
*$AUTOLOAD = sub { $val };
|
|
goto &$AUTOLOAD;
|
|
}
|
|
|
|
sub new
|
|
{
|
|
my $class = shift;
|
|
my %hash = ();
|
|
|
|
tie %hash, $class, @_;
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# Sub Name: filenames
|
|
#
|
|
# Description: Glue together the contents of BASENAMES, DIRNAMES and
|
|
# DIRINDEXES to create a single list of fully-qualified
|
|
# filenames
|
|
#
|
|
# Arguments: NAME IN/OUT TYPE DESCRIPTION
|
|
# $self in ref Object of this class
|
|
#
|
|
# Globals: None.
|
|
#
|
|
# Environment: None.
|
|
#
|
|
# Returns: Success: listref
|
|
# Failure: undef
|
|
#
|
|
###############################################################################
|
|
sub filenames
|
|
{
|
|
my $self = shift;
|
|
|
|
# Each of these three fetches will have already triggered rpm_error, were
|
|
# there any problems.
|
|
my $base = $self->{BASENAMES} || return undef;
|
|
my $dirs = $self->{DIRNAMES} || return undef;
|
|
my $idxs = $self->{DIRINDEXES} || return undef;
|
|
|
|
unless (@$base == @$idxs)
|
|
{
|
|
rpm_error(RPMERR_INTERNAL,
|
|
"Mis-matched elements lists for BASENAMES and DIRINDEXES");
|
|
return undef;
|
|
}
|
|
|
|
# The value from DIRNAMES already has the trailing separator
|
|
[ map { "$dirs->[$idxs->[$_]]$base->[$_]" } (0 .. $#$base) ];
|
|
}
|
|
|
|
|
|
__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 scalar
|
|
(or C<undef> if the key is not valid), depending on the data-type of the
|
|
key. Each of the header tags are noted with one of C<$> or C<@> in the
|
|
B<RPM::Constants> documentation. The C<defined> keyword should be used
|
|
for testing success versus failure, as empty tags are possible. See the
|
|
C<scalar_tag> test, below.
|
|
|
|
This is a significant change from versions prior to 0.27, in which the
|
|
return value was always a list reference. This new approach brings
|
|
B<RPM::Header> more in line with other interfaces to B<rpm> header information.
|
|
|
|
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 filenames
|
|
|
|
The B<RPM> system attempts to save space by splitting up the file paths into
|
|
the leafs (stored by the tag C<BASENAMES>), the directories (stored under
|
|
C<DIRNAMES>) and indexes into the list of directories (stored under
|
|
C<DIRINDEXES>). As a convenience, this method re-assembles the list of
|
|
filenames and returns it as a list reference. If an error occurs, C<undef>
|
|
will be returned after C<rpm_error> has been called.
|
|
|
|
=item is_source
|
|
|
|
Returns true (1) or false (0), depending on whether the package the header
|
|
object is derived from is a source RPM.
|
|
|
|
=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 scalar_tag(TAG)
|
|
|
|
Returns a true/false value (1 or 0) based on whether the value returned by
|
|
the specified tag is a scalar or an array reference. Useful in place of
|
|
using C<ref> to test the fetched values. B<TAG> may be either a string (name)
|
|
or a number (imported from the B<RPM::Constants> tag C<:rpmtag>). This
|
|
method may be called as a class (static) method.
|
|
|
|
=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
|
|
|
|
=item NVR
|
|
|
|
The commonly-needed data triple of (B<name>, B<version>, B<release>) may be
|
|
accessed more directly by means of this method. It returns the three values
|
|
on the stack, saving the need for three separate fetches.
|
|
|
|
=item cmpver(OTHER)
|
|
|
|
Compare the version of the current header against that in the header
|
|
referenced by C<$other>. The argument should be an object reference, not
|
|
a tied-hash representation of a header. Returns -1, 0 or 1, based on the
|
|
established behavior of other comparison operators (C<cmp> and C<E<lt>=E<gt>>);
|
|
-1 indicates that the calling object is considered less, or older, than the
|
|
passed argument. A value of 1 indicates that the calling object is greater,
|
|
or newer, than the argument. A value of 0 indicates that they are equal.
|
|
|
|
=item source_name
|
|
|
|
If the B<RPM::Header> object is created directly from a file, FTP source
|
|
or HTTP source, then that source is kept for future reference and may be
|
|
retrieved using this accessor. This will be an empty string if the header
|
|
was retrieved from the RPM database, or was built in-memory from data.
|
|
|
|
=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<RPM::Constants>, L<perl>, L<rpm>
|
|
|
|
=head1 AUTHOR
|
|
|
|
Randy J. Ray <rjray@blackperl.com>
|
|
|
|
=cut
|