From 334f72c87ce8a048074cb0664e1997a62663825c Mon Sep 17 00:00:00 2001 From: Marcin Deranek Date: Thu, 20 Feb 2020 20:49:44 +0100 Subject: Provide local copy as package is not maintained anymore --- app-portage/epm/Manifest | 7 +- app-portage/epm/epm-1.40.ebuild | 8 +- app-portage/epm/files/epm | 984 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 995 insertions(+), 4 deletions(-) create mode 100644 app-portage/epm/files/epm (limited to 'app-portage') diff --git a/app-portage/epm/Manifest b/app-portage/epm/Manifest index 99526a3..6a55b7d 100644 --- a/app-portage/epm/Manifest +++ b/app-portage/epm/Manifest @@ -1,3 +1,4 @@ -AUX epm-1.40-prefix.patch 1293 SHA256 11a6411c14ac807f75191d5281795aa61fdbdc0e91207afde55f84a62d487f7e SHA512 877204c75356b36df74ace94fe26a09f598448cbf502b7d65fec9d4b142368c4734e16807e5e4706671d8a59bc7db09811166f422d43d74a40fae5ff65e8c256 WHIRLPOOL 009f33ba08c34ba709ddf08f57209b4d707c5652dd8f46a9abe77e0984eda7b2ec3d4a5c3c698aae603a1d5cfcbf9e8f597586a0280790075b040d19e7dba4c4 -DIST epm-1.40.tar.gz 10980 BLAKE2B 3d05968038157b650bcb553c7cadba467604ae8e8318c20d3a1973146925c4daad796ec61aea2ed541e7ec1b2dc59da690c1cd073b2f63f20bd4976ebb152cf6 SHA512 745c7f902fb35672058b05763a308322fb891b5dcc4f37a0444fdc22f1802ec5e8479445537c299e23dcf3882259751a163e356a633e270a2386a1456b541103 -EBUILD epm-1.40.ebuild 722 SHA256 5684efa3e5606f4f8337c7c498927b10bdf1782567155c8ba1a8f7eec2c9700d SHA512 8b417529834667b2d86a3ac92818211b2110c83e77268b5d2ce387af662cea627f5a3f31124970937bcb524c07e627e52c683278c8b137b2cf61a5c839a55678 WHIRLPOOL 9310a6bf8822ae053bb985e7ff8bb0a49fb624669fc733ff4206ab7b46a3ed04b4a0fb9a1c10f26e6595d283bce0a7028f673a710133ef838bf1497337792e5e +AUX epm 30664 BLAKE2B 72988b0b08616761367b98dc3c698e0d352e2c442d0bcc1c77b2bfcd0009cb06bd27572e93d727babeca5bc353a3e7db43a8d7997e316a9e3b41b434e1d93a11 SHA512 75ae3fb03be9508f357f020310fba1e2d89513782ea57cb39f5a524b8cf5ded95c45bc4fbe0bfd195902c25f286119cf54501de64a2f082a69ea0ca55968175a +AUX epm-1.40-prefix.patch 1293 BLAKE2B 6d835610fce455f6089867b2fd7e959b5dffff07f72a96a9a8a2be3fb4033822967098e32f859b836c25cc8d463b9ae950a7337f65c261ceb538a0dac14a842c SHA512 877204c75356b36df74ace94fe26a09f598448cbf502b7d65fec9d4b142368c4734e16807e5e4706671d8a59bc7db09811166f422d43d74a40fae5ff65e8c256 +DIST epm 30664 BLAKE2B 72988b0b08616761367b98dc3c698e0d352e2c442d0bcc1c77b2bfcd0009cb06bd27572e93d727babeca5bc353a3e7db43a8d7997e316a9e3b41b434e1d93a11 SHA512 75ae3fb03be9508f357f020310fba1e2d89513782ea57cb39f5a524b8cf5ded95c45bc4fbe0bfd195902c25f286119cf54501de64a2f082a69ea0ca55968175a +EBUILD epm-1.40.ebuild 740 BLAKE2B 79ef448a32b5d8484b3a33475304e47a297671b046c4542e91fd8a2a0caa3018d088b6189ad00779c3036002e1ab0bc1be8ed6418fa14be5e51493993517d50c SHA512 3acd58f62b9b191d4a8021d180125ac551396857e86ddbce368f37af11af5a1d613f0be2766acadf5b6fbfb77f1a69071dc98bdc904e4bd67563d8998ab098c4 diff --git a/app-portage/epm/epm-1.40.ebuild b/app-portage/epm/epm-1.40.ebuild index 853bf26..7009253 100644 --- a/app-portage/epm/epm-1.40.ebuild +++ b/app-portage/epm/epm-1.40.ebuild @@ -8,7 +8,8 @@ inherit eutils prefix DESCRIPTION="rpm workalike for Gentoo Linux" HOMEPAGE="https://github.com/fuzzyray/epm" -SRC_URI="http://dev.gentoo.org/~fuzzyray/distfiles/${P}.tar.gz" +SRC_URI="epm" +S="${WORKDIR}/" LICENSE="GPL-2" SLOT="0" @@ -18,7 +19,12 @@ IUSE="" DEPEND=">=dev-lang/perl-5" RDEPEND="${DEPEND}" +src_unpack() { + : +} + src_prepare() { + cp "${FILESDIR}"/epm ${S}/epm epatch "${FILESDIR}"/${P}-prefix.patch eprefixify epm } diff --git a/app-portage/epm/files/epm b/app-portage/epm/files/epm new file mode 100644 index 0000000..29d3d2f --- /dev/null +++ b/app-portage/epm/files/epm @@ -0,0 +1,984 @@ +#!/usr/bin/perl -wI. + +use Getopt::Long; +use Cwd qw(abs_path); + +# Global vars +my $version = "EPM version 1.40"; +my $verbose = 0; +my $dbpath = '/var/db/pkg'; +my $pkgregex = + '^.+?\/'. # group (ignored) + '(.+?)'. # name + '-(\d+(?:\.\d+)*\w*)'. # version, eg 1.23.4a + '((?:(?:_alpha|_beta|_pre|_rc)\d*)?)'. # special suffix + '((?:-r\d+)?)$'; # revision, eg r12 +my $root = '/'; +my %opt = ( + 'dbpath' => \$dbpath, + 'root' => \$root, + 'v' => \$verbose, +); +my $exitcode = 0; + +############################################## +# +# UTILITY FUNCTIONS +# +############################################## +sub verb +{ + print STDERR map "-- $_\n", @_ if $verbose; +} + +sub vverb +{ + print STDERR map "-- $_\n", @_ if $verbose > 1; +} + +############################################## +# +# DATABASE FUNCTIONS +# +# @dgrps contains a list of all the groups at dbpath +# @dpkgs contains a list of all the packages at dbpath/@dgrps +# %dnampkg contains a mapping of nam=>@pkg (libxml=>[libxml-1.8.13]) +# %dfilepkg is a mapping of filename=>@pkg +# +############################################## + +my (@dgrps, @dpkgs, %dnampkg); + +sub load_database() +{ + # Check if the database is already loaded + return if @dgrps; + + # Read all groups in the db (except for virtual) + opendir D, $dbpath or + die "epm: Database not found at $dbpath\n"; + @dgrps = grep {-d "$dbpath/$_" && !/^\./ && $_ ne 'virtual'} readdir D; + closedir D; + verb "read ".@dgrps." groups from $dbpath"; vverb @dgrps; + + # Read all pkgs in the db (except for virtual) + for my $g (@dgrps) { + opendir D, "$dbpath/$g" or + die "epm: Error reading directory $dbpath/$g\n"; + my @dp = grep { !/^\./ && + -d "$dbpath/$g/$_" && + !-f "$dbpath/$g/$_/VIRTUAL" } readdir D; + @dp = map $g."/".$_, @dp; + verb "read ".@dp." pkgs in group $g"; vverb @dp; + push @dpkgs, @dp; + } + + # Create association of names => pkgs + for my $p (@dpkgs) { + $p =~ /$pkgregex/o || $p =~ /^virtual/ || + die "epm: Could't parse name/version/suffix/rev from $p"; + # $2, $3, $4 aren't used right now, but they're in the regex + # for the sake of completeness. + push @{$dnampkg{$1}}, $p; + } +} + +sub cmppkg($$) +{ + my ($p1, $p2) = (shift, shift); + # Remove the group from the beginning + $p1 =~ s#.*/##; + $p2 =~ s#.*/##; + # Apply the regex + # [0] = name, [1] = version, [2] = special suffix, [3] = revision + my (@p1) = ($p1 =~ /$pkgregex/o); + die "epm: Couldn't parse name/version/suffix/rev from $p1" unless @p1; + my (@p2) = ($p2 =~ /$pkgregex/o); + die "epm: Couldn't parse name/version/suffix/rev from $p2" unless @p2; + + # + # Compare VERSION (element 1) + # + + # Split on . + my (@v1) = split /\./, $p1[1]; + my (@v2) = split /\./, $p2[1]; + # Make trailing letters their own element in the array + if ($v1[-1] =~ s/[a-z]+$//) { push @v1, $& } + if ($v2[-1] =~ s/[a-z]+$//) { push @v1, $& } + # Compare each element in turn + for (my $i = 0; $i < @v1 && $i < @v2; $i++) { + if ($v1[$i] =~ /^\d+$/) { + if ($v2[$i] =~ /^\d+$/) { + if ($v1[$i] != $v2[$i]) { + # 2 <=> 3 + return $v1[$i] <=> $v2[$i]; + } else { + # 2 == 2 + next; # 2 == 2 + } + } else { + # 1.2.1 is newer than 1.2a + return -1; + } + } elsif ($v2[$i] =~ /^\d+$/) { + # 1.2a is older than 1.2.1 + return 1; + } elsif ($i != $#v1 || $i != $#v2) { + # 1.2a.3 is not a legal version + die "Error in comparing versions: $p1 vs. $p2"; + } elsif ($v1[$i] ne $v2[$i]) { + # 1.2a <=> 1.2c + return $v1[$i] cmp $v2[$i]; + } + # These elements are equal, just continue + } + + # + # Compare SPECIAL SUFFIX (element 2) + # + # + if ($p1[2] eq '' && $p2[2] ne '') { + # 1.2 is newer than 1.2_pre1 + return 1; + } elsif ($p1[2] ne '' && $p2[2] eq '') { + # 1.2_pre1 is older than 1.2 + return -1; + } elsif ($p1[2] ne '' && $p2[2] ne '') { + my (%sufs) = qw/p 0 alpha 1 beta 2 pre 3 rc 4/; + die "Illegal suffix in $p1" unless defined $sufs{$p1[2]}; + die "Illegal suffix in $p2" unless defined $sufs{$p2[2]}; + } + + # This isn't finished. What was I doing here? +} + +############################################## +# +# QUERY MODE +# +############################################## + +# Utility function to sum the size of a package on the filesystem +# in bytes +sub pkg_bytes($) +{ + my ($p) = @_; + my $total = 0; + my $CONTENTS; + + $CONTENTS = "$dbpath/$p/CONTENTS"; + + open F, "<$CONTENTS" or die "epm: Can't open $CONTENTS\n" + or die "epm: Can't open $CONTENTS: $!\n"; + for my $f (grep /^obj/, ) { + $f =~ s/^obj (.+) \w+ \d+\s*$/$1/; + my ($size) = (stat($f))[7]; + next unless $size; + verb "Adding $f ($size bytes)"; + $total += $size; + } + close F; + return $total; +} + +# Utility function to do -qi +sub query_info($) +{ + my ($p) = @_; + my ($group, $ename) = $p =~ /^(.+?)\/(.+)$/; + my ($key, $value); + my %vals = map {$_, '(n/a)'} qw/CATEGORY HOSTNAME DESCRIPTION URL LICENSE NAME RELEASE VERSION SLOT PACKAGER/; + my $ldbpath = "$dbpath/$p"; + my $fmt = <) { + next unless (/^(?:declare\s+(?:-[x-]\s+)*)?(CATEGORY|HOSTNAME|DESCRIPTION|HOMEPAGE|LICENSE|PN|PR|PV|SLOT)=(.*)/); + ($key, $value) = ($1, $2); + if ($key eq 'PN') { + $key = 'NAME'; + } elsif ($key eq 'PR') { + $key = 'RELEASE'; + $value =~ s/^r0?//o; + } elsif ($key eq 'PV') { + $key = 'VERSION'; + } elsif ($key eq 'HOMEPAGE') { + $key = 'URL'; + $value = '(none)' unless $value; + } + # Clean up the double and single quotes + $value =~ s/^'(.*)'$/$1/o; + $value =~ s/^"(.*)"$/$1/o; + $value =~ s/'\\''/'/go; + $value =~ s/\\"/"/go; + + $vals{$key} = $value; + } + close(F); + + # When was this last built/installed? + $vals{'DATE'} = localtime((stat "$ldbpath/USE")[9]); + + # Calculate the SIZE for the files it uses on the filesystem + $vals{'SIZE'} = $opt{'nosize'} ? '' : pkg_bytes($p); + + # Extract the packager and description from the ebuild itself + open(F, "$ldbpath/$ename.ebuild") + or die "epm: Can't open $ldbpath/$p.ebuild: $!\n"; + while () { + if (/Header:.*:\d\d (\w+)/o) { + $vals{'PACKAGER'} = $1; + last; + } + } + close(F); + + printf $fmt, $vals{'NAME'}, $vals{'VERSION'}, $vals{'RELEASE'}, + $vals{'SLOT'}, $vals{'DATE'}, $vals{'HOSTNAME'}, $group, + $vals{'LICENSE'}, $vals{'SIZE'}, $vals{'PACKAGER'}, $vals{'URL'}, + $vals{'DESCRIPTION'}; +} + +# Utility function to do -ql +sub query_list($) +{ + my ($p) = @_; + my ($CONTENTS) = "$dbpath/$p/CONTENTS"; + my (@files); + + open F, "<$CONTENTS" || die "epm: Can't open $CONTENTS\n"; + @files = ; + close F; + + # Look up CONFIG_PROTECT if -c + if ($opt{'c'}) { + # Read in CONFIG_PROTECT from /etc/make.{global,conf} + my (@CONFIG_PROTECT) = split ' ', + `. /etc/make.globals; . /etc/make.conf; echo \$CONFIG_PROTECT`; + die "CONFIG_PROTECT is empty" unless @CONFIG_PROTECT; + my ($confprotre) = join '|', @CONFIG_PROTECT; + @files = grep { + (split ' ', $_, 2)[1] =~ /^($confprotre)/o } @files; + } + + # Trim @files if doc files requested + if ($opt{'d'}) { + # We don't have a variable like CONFIG_PROTECT to work + # with, so just fake it... :-) + @files = grep { + (split ' ', $_, 2)[1] =~ m/\/(?:doc|man|info)\//o } @files; + } + + # If this is a dump query, then print the entire array + if ($opt{'dump'}) { + print @files; + } else { + print grep { + s{^obj (.+?)(?:/\.keep[^\s/]*)? \w+ \d+\s*?}{$1} || + s{^sym (\S.*?) -> .*$}{$1} } @files; + } +} + +# Utility function to do -qf +sub query_file(@) +{ + my (@pkgs) = @_; + # Search through CONTENTS for elements in ARGV. Building an + # index would be bad because it would be HUGE. + for my $a (@ARGV) { + my $found = 0; + my $origa = $a; + + # Try to get the absolute path before searching + $a = abs_path($a) || $a; + + # TODO: stat the file here so that we can determine later + # what package the file currently belongs to + for my $p (@dpkgs) { + my $CONTENTS = "$dbpath/$p/CONTENTS"; + + unless (-s $CONTENTS) { + verb "skipping empty/nonexistent $CONTENTS"; + next; + } + open F, "<$CONTENTS" or die "epm: Can't open $CONTENTS\n"; + # Check this list of files for the current query + while (my $f = ) { + chomp($f); + $f =~ s/^dir // or + $f =~ s/^obj (.+) \w+ \d+\s*$/$1/ or + $f =~ s/^sym (\S.*?) -> .*$/$1/ or next; + next unless $f eq $a; + $found = 1; + push @pkgs, $p; + } + close F; + } + unless ($found) { + if (-e $a) { print "file $origa is not owned by any package\n"; } + else { print "file $origa: No such file or directory\n"; } + $exitcode = 1; + } + } + return @pkgs; +} + +# Utility function to do -V +sub verify($) +{ + my ($p) = @_; + my ($CONTENTS) = "$dbpath/$p/CONTENTS"; + verb "verifying $p"; + + # CONTENTS consists of lines such as + # dir /usr/bin + # obj /usr/bin/qpkg e4a2da62aabb399c537ea9fa92b5af29 1034786384 + open F, "<$CONTENTS" || die "epm: Can't open $CONTENTS\n"; + + # Verify directories and files + # XXX should label config files with 'c' + while ($f = ) { + chomp($f); + if ($f =~ /^obj (.+) (\w+) (\d+)\s*$/o) { + my ($Cname, $Cmd5, $Cmtime) = ($1, $2, $3); + my ($md5, $mtime); + vverb "$Cname: $Cmd5 $Cmtime"; + if (! -f $Cname) { + print "missing $Cname\n" unless ($opt{'nofiles'}); + next; + } + unless ($opt{'nomd5'}) { + if (-r _) { + ($md5 = `md5sum "$Cname"`) =~ s/\s.*//s; + } else { + $md5 = 'UNKNOWN'; + } + # only report this if it's calculated. + vverb "Md5 is $md5 for $Cname"; + } + $mtime = (stat _)[9]; + vverb "Mtime is $mtime for $Cname"; + # XXX size, device, user, group, and mode are not checked... :-( + next if (($opt{'nomd5'} or $md5 eq $Cmd5) and $mtime eq $Cmtime); + printf "..%s....%s %s\n", + ($md5 ne $Cmd5) ? ($md5 eq 'UNKNOWN') ? '?' : '5' : '.', + ($mtime ne $Cmtime) ? 'T' : '.', $Cname; + if ($md5 ne $Cmd5) { $exitcode = 1; } + next; + } + if ($f =~ /^dir (.+)/o) { + print "missing $1\n" unless (-d $1 or $opt{'nofiles'}); + next; + } + if ($f =~/^sym (.+) -> (.+) (\d+)$/o) { + my ($Cname, $Clink, $Cmtime) = ($1, $2, $3); + my ($link, $mtime); + my ($modeok); + + if (! -e $Cname) { + print "missing $Cname\n" unless ($opt{'nofiles'}); + next; + } + vverb "$Cname -> $Clink $Cmtime"; + $mtime = (stat $Cname)[9]; + if (-l $Cname) { + $modeok = 1; + $link = readlink($Cname); + } else { + $modeok = 0; + $link = ''; + } + next if ($modeok + and defined ($link) + and $Clink eq $link + and defined ($mtime) + and $Cmtime eq $mtime); + printf ".%s..%s..%s %s\n", + $modeok ? '.' : 'M', + defined($link) ? ($Clink ne $link) ? 'L' : '.' : '?', + defined($mtime) ? ($Cmtime ne $mtime) ? 'T' : '.' : '?', + $Cname; + next; + } + # XXX presently ignoring devices + } + close F; +} + +sub query() +{ + verb "query mode"; + verb "actually Verify mode" if $opt{'V'}; + + # Load the database which is needed for query mode + load_database(); + my (@pkgs); # list of packages being queried + + # Package-based query (how does this work with emerge?) + if ($opt{'p'}) { + die "epm: Sorry, package-based query not yet supported\n"; + } + + # Implied -l similar to rpm + $opt{'dump'} and $opt{'l'} = 1; + $opt{'d'} and $opt{'l'} = 1; + $opt{'c'} and $opt{'l'} = 1; + + # File-based query + if ($opt{'f'}) { + @pkgs = query_file(@pkgs); + @ARGV = (); # Clear out ARGV so queries below don't get confused + } + + # Group-based query + # Note that if -qfg specified, then rpm prioritizes -qf over -qg, + # so we do too. + elsif ($opt{'g'}) { + for my $a (@ARGV) { + verb "checking for packages in group $a"; + my @l = grep /^$a\//, @dpkgs; + vverb "packages in group $a:"; + vverb " ", join "\n ", @l; + unless (@l) { + print "group $a does not contain any packages\n"; + $exitcode = 1; + } + push @pkgs, @l; + } + @ARGV = (); # Clear out ARGV so queries below don't get confused + } + + # Query on all packages + if ($opt{'a'}) { + die "epm: extra arguments given for query of all packages\n" if @ARGV; + @pkgs = @dpkgs; + } + elsif (@pkgs) { + # must have been populated by, for instance, -qf + } + else { + USERARG: for my $a (@ARGV) { + if ($a =~ /$pkgregex/o) { + verb "$a matches pkgregex"; + vverb "name=$1, version=$2, suffix=$3, revision=$4"; + # user has asked for specific version, check if any + # installed version matches + for my $pver (@{$dnampkg{$1}}) { + vverb "found version: $pver"; + if ($pver eq $a) { + push @pkgs, $a; + next USERARG; + } + } + } + if (defined $dnampkg{$a}) { + verb "$a found in dnampkg"; + vverb @{$dnampkg{$a}}; + push @pkgs, @{$dnampkg{$a}}; + next; + } + print "package $a is not installed\n"; + next; + } + } + + # Sort package order, by reverse mtime + if ($opt{'last'}) { + my %mtimes; + @pkgs = sort { + # When was this last built/installed? + unless (exists $mtimes{$a}) { + $mtimes{$a} = (stat "$dbpath/$a")[9]; + vverb "$a = $mtimes{$a}"; + } + unless (exists $mtimes{$b}) { + $mtimes{$b} = (stat "$dbpath/$b")[9]; + vverb "$b = $mtimes{$b}"; + } + $mtimes{$b} <=> $mtimes{$a} or $a cmp $b; + } @pkgs; + } + + for my $p (@pkgs) { + # Verify package + if ($opt{'V'}) { verify($p); next; } + + # Information query + query_info($p) if $opt{'i'}; + + # File listing... + # We allow this to chain after query_info because rpm allows it. + query_list($p) if $opt{'l'}; + + # If not another type of listing, then simply list the packages + if (!$opt{'l'} && !$opt{'i'}) { + # If doing -qS, then include the size in kb, like ls -s + printf "%6d ", int(pkg_bytes($p)/1000) if $opt{'S'}; + # If doing -qG, then include the group name + if ($opt{'G'}) { + print "$p\n"; + } else { + ($nogrp) = $p =~ /^.+?\/(.+)$/; + print "$nogrp\n"; + } + } + } +} + +############################################## +# +# ERASE MODE +# +############################################## +sub erase() +{ + my (@cmd); + verb "erase mode"; + verb "(testing)" if $opt{'test'}; + + # Catch empty command-line + die "epm: no packages given for uninstall\n" unless @ARGV; + + # Must be root to erase; rpm just lets permissions slide but I don't + if ($> != 0) { + print STDERR "Must be root to remove packages from the system\n"; + $exitcode = 1; + return; + } + + # There's no point implementing erase here. Might as well just + # use existing portage features. This means that we do + # --allmatches by default. + @cmd = qw(emerge --unmerge); + push @cmd, '--pretend' if $opt{'test'}; + push @cmd, '--quiet' unless $opt{'verbose'}; + push @cmd, @ARGV; + system(@cmd); + die "epm: Fatal error running emerge\n" if $?; +} + +############################################## +# +# MAIN +# +############################################## + +# Syntax string for errors +my $syntax = < - use as the directory for the database + --root - use as the top level directory + --last - list package(s) by install time, most + recent first + Package specification options: + -a, --all - query all packages + -f + - query package owning + *-p + - query (uninstalled) package + *--triggeredby - query packages triggered by + *--whatprovides - query packages which provide capability + *--whatrequires - query packages which require capability + -g + --group + - query packages in group + Information selection options: + -i, --info - display package information + --nosize - don't display size in info output (not in rpm) + -l - display package file list + -G, --showgroup - display group name in output (not in rpm) + -S, --size - display package size in output (not in rpm) + -d - list only documentation files (implies -l) + -c - list only configuration files (implies -l) + --dump - show all verifiable information for each file + (must be used with -l, -c, or -d) + *--provides - list capabilities package provides + *-R, --requires - list package dependencies + *--scripts - print the various [un]install scripts + + --erase + -e - erase (uninstall) package + --allmatches - remove all packages which match + (unlike rpm, this is the default) + --dbpath - use as the directory for the database + *--justdb - update the database, but do not modify the + filesystem + *--nodeps - do not verify package dependencies + *--noorder - do not reorder package installation to satisfy + dependencies + *--noscripts - do not execute any package specific scripts + *--notriggers - don't execute any scripts triggered by this + package + --root - use as the top level directory + --test - don't uninstall, but tell what would happen + + -V, -y, --verify - verify a package installation using the same + package specification options as -q + --dbpath - use as the directory for the database + *--root - use as the top level directory + *--nodeps - do not verify package dependencies + *--nomd5 - do not verify file md5 checksums + *--nofiles - do not verify file attributes +EOT + +# Allow bundling of options since rpm does +Getopt::Long::Configure ("bundling"); + +# Parse the options on the cmdline. Put the short versions first in +# each optionstring so that the hash keys are created using the short +# versions. For example, use 'q|query', not 'query|q'. +my $result = GetOptions( + \%opt, + 'help', # help message + 'version', # version message + 'v+', # verbose, more v's for more verbosity + + 'q|query', # query mode + 'dbpath=s', # use as the directory for the database + 'root=s', # use as the top level directory + 'last', # order package listing by most recent install first + # Package specification options: + 'a|all', # query all packages + 'f', # query package owning file(s) + 'p', # query (uninstalled) package + 'g|group', # query packages in group(s) + 'whatprovides', # query packages which provide capability + 'whatrequires', # query packages which require capability + # Information selection options: + 'i|info', # display package information + 'nosize', # don't display size in info output + 'l', # display package file list + 'd', # list documentation files (implies -l) + 'c', # list configuration files (implies -l) + 'dump', # show all verifiable information for each file + # (must be used with -l, -c, or -d) + 'R|requires', # list package dependencies + 'scripts', # print the various [un]install scripts + 'G|showgroup', # include group name in output + 'S|size', # display package size + + 'e|erase', # erase mode + 'allmatches', # remove all packages which match + 'test', # don't uninstall, but tell what would happen + + 'V|y|verify', # verify a package installation using the same + # package specification options as -q + 'nodeps', # do not verify package dependencies + 'nomd5', # do not verify file md5 checksums + 'nofiles', # do not verify file attributes +); + +# Handle help message +if ($opt{'help'}) { print $syntax; exit 0 } +if ($opt{'version'}) { print "$version\n"; exit 0 } + +# Determine which mode we're running in; make sure it's valid. +# (q)uery +# (V)erify +# (U)pgrade +# (e)rase +# (b)uild +# other +if ((defined $opt{'q'} || 0) + + (defined $opt{'V'} || 0) + + (defined $opt{'U'} || 0) + + (defined $opt{'e'} || 0) + + (defined $opt{'b'} || 0) != 1) { + die "$syntax\nOne mode required, and only one mode allowed\n"; +} + +# Query mode +if ($opt{'q'} || $opt{'V'}) { query(); exit $exitcode } +if ($opt{'e'}) { erase(); exit $exitcode } + +# Other modes not implemented yet +die "epm: Sorry, this mode isn't implemented yet. Check back later! :-)\n"; + +# Revision 1.4.0 2013-01-23 p2w +# Fix -qi (bug 310475). +# New maintainer. +# Revert the change of v1.33, fix others problems with -qf (Gentoo bugs 93843 and 153921) +# +# Revision 1.33 2006/09/13 15:09:19 agriffis +# Treat dirs the same in -qf as in -ql +# +# Revision 1.32 2006/09/13 15:04:49 agriffis +# Revert 1.30. Listing all intermediate dirs up to a file isn't useful, and doesn't match rpm. Only list dirs that contain .keep files +# +# Revision 1.31 2006/09/08 19:35:22 agriffis +# Switch to cvs-based versioning. Add --version option. Add --last option, based on patch submitted by Tim Stotts #138679 +# +# Revision 1.30 2006/04/04 21:07:07 mr_bones_ +# display directories as well as files and symlinks when doing query list (-ql) +# This matches what rpm does. Reported by Steven Elling via Gentoo bugzilla: +# http://bugs.gentoo.org/show_bug.cgi?id=128186 +# +# Revision 1.29 2006/03/15 21:49:48 agriffis +# Leave Size blank instead of n/a when --nosize given +# +# Revision 1.28 2006/03/15 21:43:23 agriffis +# Add --nosize option +# +# Revision 1.27 2005/08/29 13:32:35 kanaka +# Update version to 0.9.0 +# +# Revision 1.26 2005/08/25 22:03:59 mr_bones_ +# -i is implemented so remove the * from the usage message. (reported by agriffis) +# +# Revision 1.25 2005/08/16 20:39:16 kanaka +# Fix broken regex during file list query +# +# Revision 1.24 2005/08/15 20:37:14 kanaka +# Fix situation where package group is different, but name and version are the same (i.e. crossdev) +# +# Revision 1.23 2005/07/05 20:01:36 mr_bones_ +# pass --quiet to emerge when performing -e (erase) to be more like rpm +# +# Revision 1.22 2005/06/22 05:28:24 mr_bones_ +# Print out usage if user didn't get the mode specified correctly. +# Suggested by Tristan Cebulla in +# http://bugs.gentoo.org/show_bug.cgi?id=96726 +# +# Revision 1.21 2005/05/18 05:30:14 mr_bones_ +# fix silly check for empty HOMEPAGE +# +# Revision 1.20 2005/05/16 03:15:26 mr_bones_ +# Make all the regexs that match the obj lines from CONTENTS be the same. +# +# Revision 1.19 2005/05/14 23:50:33 mr_bones_ +# remove "use epm". guessing that was an idea that never materialized +# +# Revision 1.18 2005/05/14 23:48:48 mr_bones_ +# Added support for --nofiles in verify() - rpm man page claims it only +# suppresses reports of missing files. epm suppresses all "missing" reporting +# if --nofiles is given. +# +# Added support for --nomd5 in verify(); fixed up bare word in output. +# +# Added initial support for symlinks in verify(). +# +# Revision 1.17 2005/05/14 22:24:12 mr_bones_ +# no reason to read CONTENTS into memory in query_file(). Modified to read +# line at a time. +# +# Revision 1.16 2005/05/14 22:21:46 mr_bones_ +# Make output more similar to rpm by changing "Description" to "Summary" +# in output. Maybe at some point the extended description from metadata.xml +# will be stored in portage and can be extracted then by epm for Description. +# Also changed "Build Host" from CHOST to HOSTNAME. +# +# Modified to read environment.bz2 instead of the ebuild for some values. +# This is more reliable because environment.bz2 is the state after ebuild +# and eclass processing. Epm was confused by ebuilds that have the HOMEPAGE +# and DESCRIPTION in an eclass. (eg. xmms-mpg123) +# +# Fixed up display of values that contain double and single quotes +# (eg. libmad) +# +# Added error checking for open() +# +# Revision 1.15 2005/05/14 21:55:25 mr_bones_ +# Pass long option (--unmerge) to emerge instead of short option (-C) +# for better readability. +# +# Revision 1.14 2005/05/14 21:47:51 mr_bones_ +# fix bug in pkg_bytes() where files with whitespace in their name would +# cause incorrect behavior. +# +# Revision 1.13 2005/05/14 21:38:10 mr_bones_ +# prototype functions +# +# Revision 1.12 2005/05/14 21:30:44 mr_bones_ +# Use correct variable in error message ($p -> $p1/$p2) +# +# Revision 1.11 2005/05/14 20:54:19 mr_bones_ +# Trim trailing whitespace +# +# Revision 1.10 2005/05/13 20:47:44 agriffis +# epm-0.8.8 +# +# Revision 1.20 2004/04/28 13:22:41 agriffis +# - Fix printing of symlinks in -ql to exclude link target +# +# Revision 1.19 2004/04/05 04:37:46 agriffis +# - Add patch from Michael Sterret in bug 45927 to handle whitespace +# in filenames +# +# Revision 1.18 2004/03/29 16:47:34 agriffis +# Fix bug 45927: Handle filenames with spaces correctly +# Update version to 0.8.6 +# +# Revision 1.17 2004/03/08 23:23:39 agriffis +# - Update to 0.8.5 +# +# Revision 1.16 2004/03/08 23:21:46 agriffis +# - Added size option to -qi and -qS +# - Thanks to Bram Dumolin (http://lanka-expats.net/) for the idea and +# an initial effort at the code +# +# Revision 1.15 2003/05/27 01:36:01 agriffis +# - Update to 0.8.4 +# +# Revision 1.14 2003/05/27 01:33:41 agriffis +# - Include patch from Michael Sterrett to display URL +# in -qi output +# +# Revision 1.13 2003/05/02 02:00:22 agriffis +# - Update to 0.8.3 +# - Check if file exists to choose error message for -qf +# +# Revision 1.12 2003/05/01 02:42:39 agriffis +# - Add man-page in pod format inside epm +# +# Revision 1.11 2003/05/01 01:53:09 agriffis +# - Update version to 0.8.2; forgot to checkin 0.8.1 +# - Fix bug 8832: Add code to determine full path for epm -qf. +# Reported by Bill Gjestvang, patch provided by Wayne Davison. +# - Fix bug 12798: Fix -V output for unreadable files +# Reported and patched by Wayne Davison. +# - Fix bug 19806: Need double-quotes to interpret \n on die message +# Reported and patched by Scott Hunt +# - Fix bug 19681: Check for requested version on epm -q. +# Reported by Neil McCalden, patch provided by Wayne Davison. +# +# Revision 1.10 2002/10/22 13:55:00 agriffis +# - Fix version reporting in help message +# - Fix unmerging to use -C instead of non-existent --unmerge +# +# Revision 1.9 2002/10/22 13:48:47 agriffis +# - Fixed erase -e to do something when not --test +# +# Revision 1.8 2002/10/22 13:44:08 agriffis +# - Fix bug in -qa which listed too many packages +# +# Revision 1.7 2002/10/22 13:31:47 agriffis +# - Split out query types into separate functions +# - Add sub cmppkg which was for --update but might be abandoned +# - Add information query -qi +# - Add first-pass verification -V +# - Change erase -e to use emerge (which maintains world) +# + +=head1 NAME + +epm - rpm workalike for Gentoo + +=head1 SYNOPSIS + +epm { -eqVy | --erase | --help | --query | --verify } options... + +=head1 DESCRIPTION + +This tool provides a Gentoo query tool for users familiar with Red +Hat's "rpm" package manager. In particular, it can query, verify, and +erase packages from the system. I've tried to make it act as much +like rpm as possible, but there are some differences made necessary by +the differences in the distributions. + +Querying and verifying are the most powerful features of epm. Erase +mode is really just a gate to "emerge -C", but force of habit makes it +easier for me to type "epm -e". + +=head1 MODES + +=over + +=item B<-q --query> + +Query mode, for querying either the list of installed packages or the +files owned by a package. + +=item B<-V -y --verify> + +Verify mode, for determining the integrity of an installed package +using timestamps and md5 sums. Size, device, user, group, and mode +are not presently checked. + +=item B<-e --erase> + +Erase mode, for removing packages from the system. Specify a package +by version to remove a specific package. Specify a package by name to +remove all versions (i.e. --allmatches is the default for epm, this is +a difference from rpm). + +=item B<--help> + +This isn't really a mode, but it's the only thing you can do without +otherwise specifying a mode. Run "epm --help" to see the +comprehensive list of options available for each mode. + +=back + +=head1 EXAMPLES + +To find out if vim is installed: + + $ epm -q vim + vim-6.2_pre2 + +To include the group in the output: + + $ epm -qG vim + app-editors/vim-6.2_pre2 + +To see what binaries vim installs: + + $ epm -ql vim | grep bin + /usr/bin/ex + /usr/bin/vim + /usr/bin/rvim + /usr/bin/view + /usr/bin/rview + /usr/bin/vimdiff + +To find what package owns /usr/bin/vim + + $ epm -qf /usr/bin/vim + vim-6.2_pre2 + +To verify your installation of vim: + + $ epm -V vim + +No output indicates the installation is fine. If you get some other +output when you verify a package installation, try the following link +for an explanation. http://www.rpm.org/max-rpm/s1-rpm-verify-output.html + +To show all vim related packages on the system: + + $ epm -qa | grep vim + vim-core-6.2_pre2 + vim-6.2_pre2 + gvim-6.2_pre2 + +=head1 NOTES + +This tool was written by Aron Griffis. Currently, Peter Weilbacher + tries to maintain it. +It will probably blow up your computer, but it works well enough for +me. If you report bugs at http://bugs.gentoo.org/, assigned to Peter, +they might get fixed. Your chances increase a lot if you include a +good patch. + +=cut -- cgit v1.2.3