#! /usr/bin/perl # Copyright (c) 2005-2010 Marc Espie # $OpenBSD: pkg_mklocatedb,v 1.28 2010/06/30 11:33:57 espie Exp $ # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. use strict; use warnings; use OpenBSD::PackageInfo; use OpenBSD::PackingList; use OpenBSD::Getopt; use OpenBSD::Error; use OpenBSD::Paths; use OpenBSD::AddCreateDelete; use File::Path; package OpenBSD::PackingElement; sub print_name {} package OpenBSD::PackingElement::FileObject; sub print_name { my ($self, $fh, $pkgname) = @_; print $fh $pkgname, ":", $self->fullname, "\n"; } package main; our ($opt_a, $opt_n, $opt_q, $opt_s, $opt_x, $opt_r, $opt_p, $opt_P, $opt_d); sub info { my $plist = shift; my $r; if ($opt_a) { $r = $plist->fullpkgpath.":".$plist->pkgname; } elsif ($opt_P) { $r = $plist->fullpkgpath; } else { $r = $plist->pkgname; } print STDERR "$r\n" unless $opt_q; return $r; } sub tag { my ($dir, $set, $rev) = @_; my $r; if ($opt_a) { $r = "$dir/$set:$set$rev"; } elsif ($opt_P) { $r = "$dir/$set"; } else { $r = "$set$rev"; } print STDERR "$r\n" unless $opt_q; return $r; } my $state = OpenBSD::AddCreateDelete::State->new("pkg_mklocatedb"); $state->handle_options('ad:nqs:x:r:p:P', '[-anPq] [-d repository] [-p portsdir] [-r release] [-s src] ', '[-x X11src] [pkg-name [...]]'); my $fh; my $MKLOCATEDB = OpenBSD::Paths->mklocatedb; if ($opt_n or -t STDOUT) { $fh = \*STDOUT; } else { open $fh, "|-", $MKLOCATEDB, $MKLOCATEDB or $state->fatal("couldn't open pipe: #1", $!); } if ($opt_s || $opt_x) { my $cmd = OpenBSD::Paths->uname." -mr"; my ($rev, $arch) = split(/\s+/o, `$cmd`); chomp $arch; $rev =~ s/\.//; if ($opt_s) { my $dir = "$opt_s/distrib/sets/lists"; for my $set (qw(base comp etc game man misc)) { my $tag = tag('src', $set, $rev); for my $f ("$dir/$set/mi", "$dir/$set/md.$arch") { open my $l, '<', $f or next; while (my $e = <$l>) { chomp $e; $e =~ s/^\.//; print $fh "$tag:$e\n"; } } } } if ($opt_x) { my $dir = "$opt_x/distrib/sets/lists"; for my $set (qw(xbase xetc xfont xserv xshare)) { my $tag = tag('XF4', $set, $rev); for my $f ("$dir/$set/mi", "$dir/$set/md.$arch") { open my $l, '<', $f or next; while (my $e = <$l>) { chomp $e; $e =~ s/^\.//; print $fh "$tag:$e\n"; } } } } } if ($opt_r) { require OpenBSD::Ustar; opendir(my $dir, $opt_r) or next; while (my $e = readdir $dir) { if ($e =~ m/^(\w+\d\d)\.tgz$/o) { my $set = $1; open my $arc, '-|', OpenBSD::Paths->gzip, '-c', '-d', "--", "$opt_r/$e"; my $u = OpenBSD::Ustar->new($arc, '/'); while (my $f = $u->next) { my $name = $f->{name}; $name =~ s/^\.//o; print $fh "$set:$name\n"; } close $arc; } } closedir($dir); } if ($opt_p) { my $make = $ENV{MAKE} || 'make'; open my $in, "cd $opt_p && $make print-plist-all |"; my $done = 0; while (!$done) { my $plist = OpenBSD::PackingList->read($in, sub { my ($fh, $cont) = @_; my $_; while (<$fh>) { return if m/^\=\=\=\> /o; next unless m/^\@(?:bin|cwd|name|info|man|file|lib|shell|comment\s+subdir\=)\b/o || !m/^\@/o; &$cont($_); } $done = 1; }); if (defined $plist && defined $plist->pkgname) { $plist->print_name($fh, info($plist)); } } close($in); } elsif ($opt_d) { require File::Find; no warnings qw(once); $state->fatal("Bad argument: #1 is not a directory", $opt_d) unless -d $opt_d; File::Find::find( sub { return unless -f $_; my $plist = $state->repo->grabPlist($File::Find::name); return unless defined $plist; $plist->print_name($fh, info($plist)); }, $opt_d); } elsif (@ARGV == 0) { $state->progress->for_list("Scanning installation", [installed_packages()], sub { my $pkgname = shift; my $plist = OpenBSD::PackingList->from_installation($pkgname); return unless defined $plist; $plist->print_name($fh, info($plist)); }); } else { $state->progress->for_list("Scanning packages", \@ARGV, sub { my $pkgname = shift; my $plist = $state->repo->grabPlist($pkgname); next unless $plist; $plist->print_name($fh, info($plist)); }); }