<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package URPM;

use strict;
use DynaLoader;

# different files, but same package
# require them here to avoid dependencies
use URPM::Build;
use URPM::Resolve;
use URPM::Signature;

our @ISA = qw(DynaLoader);
our $VERSION = '1.11';

URPM-&gt;bootstrap($VERSION);

sub new {
    my ($class, %options) = @_;
    my $self = bless {
	depslist =&gt; [],
	provides =&gt; {},
    }, $class;
    $self-&gt;{nofatal} = 1 if $options{nofatal};
    $self;
}

sub set_nofatal { $_[0]-&gt;{nofatal} = $_[1] }

sub search {
    my ($urpm, $name, %options) = @_;
    my $best;

    #- tries other alternative if no strict searching.
    unless ($options{strict_name}) {
	if ($name =~ /^(.*)-([^\-]*)-([^\-]*)\.([^\.\-]*)$/) {
	    foreach (keys %{$urpm-&gt;{provides}{$1} || {}}) {
		my $pkg = $urpm-&gt;{depslist}[$_];
		$pkg-&gt;fullname eq $name and return $pkg;
	    }
	}
	unless ($options{strict_fullname}) {
	    if ($name =~ /^(.*)-([^\-]*)-([^\-]*)$/) {
		foreach (keys %{$urpm-&gt;{provides}{$1} || {}}) {
		    my $pkg = $urpm-&gt;{depslist}[$_];
		    my ($n, $v, $r, $a) = $pkg-&gt;fullname;
		    $options{src} &amp;&amp; $a eq 'src' || $pkg-&gt;is_arch_compat or next;
		    "$n-$v-$r" eq $name or next;
		    !$best || $pkg-&gt;compare_pkg($best) &gt; 0 and $best = $pkg;
		}
		$best and return $best;
	    }
	    if ($name =~ /^(.*)-([^\-]*)$/) {
		foreach (keys %{$urpm-&gt;{provides}{$1} || {}}) {
		    my $pkg = $urpm-&gt;{depslist}[$_];
		    my ($n, $v, undef, $a) = $pkg-&gt;fullname;
		    $options{src} &amp;&amp; $a eq 'src' || $pkg-&gt;is_arch_compat or next;
		    "$n-$v" eq $name or next;
		    !$best || $pkg-&gt;compare_pkg($best) &gt; 0 and $best = $pkg;
		}
		$best and return $best;
	    }
	}
    }

    unless ($options{strict_fullname}) {
	foreach (keys %{$urpm-&gt;{provides}{$name} || {}}) {
	    my $pkg = $urpm-&gt;{depslist}[$_];
	    my ($n, undef, undef, $a) = $pkg-&gt;fullname;
	    $options{src} &amp;&amp; $a eq 'src' || $pkg-&gt;is_arch_compat or next;
	    $n eq $name or next;
	    !$best || $pkg-&gt;compare_pkg($best) &gt; 0 and $best = $pkg;
	}
    }

    return $best;
}

#- Olivier Thauvin:
#- Returns @$listid, $start .. $end or the whole deplist id
#- according to the given args
sub build_listid {
    my ($urpm, $start, $end, $listid) = @_;

    @{$listid || []} &gt; 0 ? @{$listid} :
        (($start || 0) .. (defined($end) ? $end : $#{$urpm-&gt;{depslist}}));
}

sub traverse {
    my ($urpm, $callback) = @_;

    if ($callback) {
	foreach (@{$urpm-&gt;{depslist} || []}) {
	    $callback-&gt;($_);
	}
    }

    scalar @{$urpm-&gt;{depslist} || []};
}

sub traverse_tag {
    my ($urpm, $tag, $names, $callback) = @_;
    my $count = 0; 
    my %names;

    if (@{$names || []}) {
	if ($tag eq 'name') {
	    foreach my $n (@$names) {
		foreach (keys %{$urpm-&gt;{provides}{$n} || {}}) {
		    my $p = $urpm-&gt;{depslist}[$_];
		    $p-&gt;name eq $n or next;
		    $callback and $callback-&gt;($p);
		    ++$count;
		}
	    }
	} elsif ($tag eq 'whatprovides') {
	    foreach (@$names) {
		foreach (keys %{$urpm-&gt;{provides}{$_} || {}}) {
		    $callback and $callback-&gt;($urpm-&gt;{depslist}[$_]);
		    ++$count;
		}
	    }
	} else {
	    @names{@$names} = ();
	    if ($tag eq 'whatrequires') {
		foreach (@{$urpm-&gt;{depslist} || []}) {
		    if (grep { exists $names{$_} } $_-&gt;requires_nosense) {
			$callback and $callback-&gt;($_);
			++$count;
		    }
		}
	    } elsif ($tag eq 'whatconflicts') {
		foreach (@{$urpm-&gt;{depslist} || []}) {
		    if (grep { exists $names{$_} } $_-&gt;conflicts_nosense) {
			$callback and $callback-&gt;($_);
			++$count;
		    }
		}
	    } elsif ($tag eq 'group') {
		foreach (@{$urpm-&gt;{depslist} || []}) {
		    if (exists $names{$_-&gt;group}) {
			$callback and $callback-&gt;($_);
			++$count;
		    }
		}
	    } elsif ($tag eq 'triggeredby' || $tag eq 'path') {
		foreach (@{$urpm-&gt;{depslist} || []}) {
		    if (grep { exists $names{$_} } $_-&gt;files, grep { m!^/! } $_-&gt;provides_nosense) {
			$callback and $callback-&gt;($_);
			++$count;
		    }
		}
	    } else {
		die "unknown tag";
	    }
	}
    }

    $count;
}

package URPM::Package;
our @ISA = qw(); # help perl_checker

package URPM::Transaction;
our @ISA = qw(); # help perl_checker

package URPM::DB;
our @ISA = qw(); # help perl_checker

1;

__END__

=head1 NAME

URPM - Perl module to manipulate RPM files

=head1 SYNOPSIS

    use URPM;

    # using the local RPM database
    my $db = URPM::DB::open();
    $db-&gt;traverse(sub {
	my ($package) = @_; # this is a URPM::Package object
	print $package-&gt;filename, "\n";
	# ...
    });

    # loading and parsing a synthesis file
    my $urpm = new URPM;
    $urpm-&gt;parse_synthesis("synthesis.sample.cz");
    $urpm-&gt;traverse(sub {
	# retrieve all packages from the dependency list
	# ...
    });

=head1 DESCRIPTION

The URPM module allows you to manipulate RPM files, RPM header files and
hdlist files and manage them in memory. It is notably used by the B&lt;urpmi&gt;
utility. It provides four classes : C&lt;URPM&gt;, C&lt;URPM::DB&gt;, C&lt;URPM::Package&gt;,
and C&lt;URPM::Transaction&gt;.

=head2 The URPM class

=over 4

=item new()

The constructor creates a new, empty URPM object. It's a blessed hash that
contains two fields:

B&lt;depslist&gt; is an arrayref containing the list of depending packages (which are
C&lt;URPM::Package&gt; objects).

B&lt;provides&gt; is an hashref containing as keys the list of items provided by the
URPM object.

If the constructor is called with the arguments C&lt;&lt; nofatal =&gt; 1 &gt;&gt;, various
fatal error messages are suppressed (file not found in parse_hdlist() and
parse_synthesis()).

=item read_config_files()

Force the re-reading of the RPM configuration files.

=item list_rpm_tag()

Return a hash containing the key/id values of known rpm tags

=item ranges_overlap($range1, $range2 [, $nopromoteepoch])

This utility function compares two version ranges, in order to calculate
dependencies properly. The ranges have roughly the form

    [&lt;|&lt;=|==|=&gt;|&gt;] [epoch:]version[-release]

where epoch, version and release are RPM-style version numbers.

If the optional parameter $nopromoteepoch is true, and if the 2nd range has no
epoch while the first one has one, then the 2nd range is assumed to have an
epoch == 0.

=item $urpm-&gt;parse_synthesis($file, [ callback =&gt; sub {...} ])

This method gets the B&lt;depslist&gt; and the B&lt;provides&gt; from a synthesis file
and adds them to the URPM object.

=item $urpm-&gt;parse_hdlist($file, %options)

This method loads rpm informations from rpm B&lt;headers&gt; contained in an hdlist
file and adds them to the URPM object. Allowed options are 

    packing =&gt; 0 / 1
    callback =&gt; sub { ... }
    keep_all_tags =&gt; 0 / 1

Return value is an array of first and last id parsed.
    
=item $urpm-&gt;parse_rpms($files, %options)

This method loads rpm informations from rpm B&lt;headers&gt; and adds them to
the URPM object.

Return value is an array of first and last id parsed.

=item $urpm-&gt;parse_rpm($file, %options)

This method gets the B&lt;depslist&gt; and the B&lt;provides&gt; from an RPM file
and adds them to the URPM object. Allowed options are

    packing =&gt; 0 / 1
    keep_all_tags =&gt; 0 / 1
    callback =&gt; sub { ... }

=item $urpm-&gt;search($name, %options)

Search an RPM by name or by part of name in the list of RPMs represented by
this $urpm. The behaviour of the search is influenced by several options:

    strict_name =&gt; 0 / 1
    strict_fullname =&gt; 0 / 1
    src =&gt; 0 / 1

=item $urpm-&gt;traverse($callback)

Executes the callback for each package in the depslist, passing a
C&lt;URPM::Package&gt; object as argument the callback.

=item $urpm-&gt;traverse_tag($tag, $names, $callback)

$tag may be one of C&lt;name&gt;, C&lt;whatprovides&gt;, C&lt;whatrequires&gt;, C&lt;whatconflicts&gt;,
C&lt;group&gt;, C&lt;triggeredby&gt;, or C&lt;path&gt;.
$names is a reference to an array, holding the acceptable values of the said
tag for the searched variables.
Then, $callback is called for each matching package in the depslist.

=item $urpm-&gt;verify_rpm($file, %options)

Verifies an RPM file.
Recognized options are:

    db =&gt; $urpm_db
    nopgp =&gt; 0 / 1
    nogpg =&gt; 0 / 1
    nomd5 =&gt; 0 / 1
    norsa =&gt; 0 / 1
    nodsa =&gt; 0 / 1
    nodigests =&gt; 0 / 1
    tmp_filename =&gt; '...'
    nosignatures =&gt; 0 / 1 (equivalent to nopgp = nogpg = norsa = nodsa = 1)

=item $urpm-&gt;import_pubkey(%options)

    db =&gt; $urpm_db
    root =&gt; '...'
    block =&gt; '...'
    filename =&gt; '...'

=back

=head2 The URPM::DB class

=over 4

=item open($prefix, $write_perm)

Returns a new C&lt;URPM::DB&gt; object pointing on the local RPM database.

$prefix defaults to C&lt;""&gt; and indicates the RPM DB root directory prefix if
any. (See the B&lt;--root&gt; option to rpm(1)).

$write_perm is a boolean that defaults to false, and that indicates whether
the RPM DB should be open in read/write mode.

=item rebuild($prefix)

Rebuilds the RPM database (like C&lt;rpm --rebuilddb&gt;). $prefix defaults to C&lt;""&gt;.

=item $db-&gt;traverse($callback)

Executes the specified callback (a code reference) for each package
in the DB, passing a C&lt;URPM::Package&gt; object as argument the callback.

=item $db-&gt;traverse_tag($tag,$names,$callback)

$tag may be one of C&lt;name&gt;, C&lt;whatprovides&gt;, C&lt;whatrequires&gt;, C&lt;whatconflicts&gt;,
C&lt;group&gt;, C&lt;triggeredby&gt;, or C&lt;path&gt;.
$names is a reference to an array, holding the acceptable values of the said
tag for the searched variables.
Then, $callback is called for each matching package in the DB.

=item $db-&gt;create_transaction($prefix)

Creates and returns a new transaction (an C&lt;URPM::Transaction&gt; object) on the
specified DB. For $prefix, cf L&lt;open&gt;.

=back

=head2 The URPM::Package class

Most methods of C&lt;URPM::Package&gt; are accessors for the various properties
of an RPM package.

=over 4

=item $package-&gt;arch()

=item $package-&gt;build_header($fileno)

=item $package-&gt;build_info($fileno, [$provides_files])

=item $package-&gt;buildarchs()

=item $package-&gt;buildhost()

=item $package-&gt;buildtime()

=item $package-&gt;changelog_name()

=item $package-&gt;changelog_text()

=item $package-&gt;changelog_time()

=item $package-&gt;compare($evr)

=item $package-&gt;compare_pkg($other_pkg)

=item $package-&gt;conf_files()

=item $package-&gt;conflicts()

=item $package-&gt;conflicts_nosense()

=item $package-&gt;description()

=item $package-&gt;distribution()

=item $package-&gt;epoch()

=item $package-&gt;excludearchs()

=item $package-&gt;exclusivearchs()

=item $package-&gt;filename()

=item $package-&gt;files()

=item $package-&gt;files_flags()

=item $package-&gt;files_gid()

=item $package-&gt;files_group()

=item $package-&gt;files_md5sum()

=item $package-&gt;files_mode()

=item $package-&gt;files_mtime()

=item $package-&gt;files_owner()

=item $package-&gt;files_size()

=item $package-&gt;files_uid()

=item $package-&gt;flag($name)

=item $package-&gt;flag_available()

=item $package-&gt;flag_base()

=item $package-&gt;flag_disable_obsolete()

=item $package-&gt;flag_installed()

=item $package-&gt;flag_requested()

=item $package-&gt;flag_required()

=item $package-&gt;flag_selected()

=item $package-&gt;flag_skip()

=item $package-&gt;flag_upgrade()

=item $package-&gt;free_header()

=item $package-&gt;fullname()

Returns a 4 element list: name, version, release and architecture in an array context.
Returns a string NAME-VERSION-RELEASE.ARCH in scalar context.

=item $package-&gt;get_tag($tagid)

Returns an array containing values of $tagid. $tagid is the numerical value of
rpm tags. See rpmlib.h. 

=item $package-&gt;queryformat($format)

Querying the package like rpm --queryformat do. 

The function calls directly the rpmlib, then use header informations, so it 
silently failed if you use synthesis instead of hdlist/rpm/header files or rpmdb.

=item $package-&gt;get_tag_modifiers($tagid)

Return an array of human readable view of tag values. $tagid is the numerical value of rpm tags.

=item $package-&gt;group()

=item $package-&gt;header_filename()

=item $package-&gt;id()

=item $package-&gt;is_arch_compat()

=item $package-&gt;license()

=item $package-&gt;name()

=item $package-&gt;obsoletes()

=item $package-&gt;obsoletes_nosense()

=item $package-&gt;obsoletes_overlap($s, [$nopromoteepoch,] [$direction])

=item $package-&gt;os()

=item $package-&gt;pack_header()

=item $package-&gt;packager()

=item $package-&gt;provides()

=item $package-&gt;provides_nosense()

=item $package-&gt;provides_overlap($s, [$nopromoteepoch,] [$direction])

=item $package-&gt;rate()

=item $package-&gt;release()

=item $package-&gt;requires()

=item $package-&gt;requires_nosense()

=item $package-&gt;rflags()

=item $package-&gt;set_flag($name, $value)

=item $package-&gt;set_flag_base($value)

=item $package-&gt;set_flag_disable_obsolete($value)

=item $package-&gt;set_flag_installed($value)

=item $package-&gt;set_flag_requested($value)

=item $package-&gt;set_flag_required($value)

=item $package-&gt;set_flag_skip($value)

=item $package-&gt;set_flag_upgrade($value)

=item $package-&gt;set_id($id)

=item $package-&gt;set_rate($rate)

=item $package-&gt;set_rflags(...)

=item $package-&gt;size()

=item $package-&gt;sourcerpm()

=item $package-&gt;summary()

=item $package-&gt;update_header($filename, ...)

=item $package-&gt;upgrade_files()

=item $package-&gt;url()

=item $package-&gt;vendor()

=item $package-&gt;version()

=back

=head2 The URPM::Transaction class

=over 4

=item $trans-&gt;set_script_fd($fileno)

Sets the transaction output filehandle.

=item $trans-&gt;add($pkg, %options)

Adds a package to be installed to the transaction represented by $trans.
$pkg is an C&lt;URPM::Package&gt; object.

Options are:

    update =&gt; 0 / 1 : indicates whether this is an upgrade
    excludepath =&gt; [ ... ]

=item $trans-&gt;remove($name)

Adds a package to be erased to the transaction represented by $trans.
$name is the name of the package.

=item $trans-&gt;check(%options)

Checks that all dependencies can be resolved in this transaction.

Options are:

    translate_message =&gt; 0 / 1 (currently ignored.)

=item $trans-&gt;order()

Determines package order in a transaction set according to dependencies.
Returns a boolean indicating success.

=item $trans-&gt;run($data, %options)

Runs the transaction.

$data is an arbitrary user-provided piece of data to be passed to callbacks.

Recognized options are:

    callback_close  =&gt; sub { ... }
    callback_inst   =&gt; sub { ... }
    callback_open   =&gt; sub { ... }
    callback_trans  =&gt; sub { ... }
    callback_uninst =&gt; sub { ... }
    delta =&gt; used for progress callbacks (trans, uninst, inst)
    excludedocs =&gt; 0 / 1
    force =&gt; 0 / 1
    nosize =&gt; 0 / 1
    oldpackage =&gt; 0 / 1
    test =&gt; 0 / 1
    translate_message

They roughly correspond to command-line options to rpm(1).

=back

=head2 Macro handling functions

=over

=item loadmacrosfile($filename)

Load the specified macro file. Sets $! if the file can't be read.

=item expand($name)

Expands the specified macro.

=item add_macro($macro_definition)

Define a macro. For example,

    URPM::add_macro("vendor Mandrakesoft");
    my $vendor = URPM::expand("%vendor");

=item del_macro($name)

Delete a macro.

=item resetmacros()

Destroys macros.

=back

=head1 COPYRIGHT

Copyright 2002-2005 Mandrakesoft

Original author: François Pons

This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.

=cut
</pre></body></html>