167d43fbcSespie# ex:ts=8 sw=4:
2*a4f5498fSespie# $OpenBSD: PackingList.pm,v 1.98 2010/01/01 16:09:35 espie Exp $
36f05d20cSespie#
425a529f6Sespie# Copyright (c) 2003-2010 Marc Espie <espie@openbsd.org>
56f05d20cSespie#
667d43fbcSespie# Permission to use, copy, modify, and distribute this software for any
767d43fbcSespie# purpose with or without fee is hereby granted, provided that the above
867d43fbcSespie# copyright notice and this permission notice appear in all copies.
96f05d20cSespie#
1067d43fbcSespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1167d43fbcSespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1267d43fbcSespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1367d43fbcSespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1467d43fbcSespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1567d43fbcSespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1667d43fbcSespie# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
176f05d20cSespie
186f05d20cSespieuse strict;
196f05d20cSespieuse warnings;
20d76faf42Sespie
21d76faf42Sespiepackage OpenBSD::PackingList::State;
22d76faf42Sespiemy $dot = '.';
23d76faf42Sespie
24d76faf42Sespiesub new
25d76faf42Sespie{
26d76faf42Sespie	my $class = shift;
27d76faf42Sespie	bless { default_owner=>'root',
28d76faf42Sespie	     default_group=>'bin',
29d76faf42Sespie	     default_mode=> 0444,
30d76faf42Sespie	     cwd=>\$dot}, $class;
31d76faf42Sespie}
32d76faf42Sespie
33d76faf42Sespiesub cwd
34d76faf42Sespie{
35d76faf42Sespie	return ${$_[0]->{cwd}};
36d76faf42Sespie}
37d76faf42Sespie
38d76faf42Sespiesub set_cwd
39d76faf42Sespie{
40d76faf42Sespie	my ($self, $p) = @_;
41d76faf42Sespie
42d76faf42Sespie	require File::Spec;
43d76faf42Sespie
44d76faf42Sespie	$p = File::Spec->canonpath($p);
45d76faf42Sespie	$self->{cwd} = \$p;
46d76faf42Sespie}
47d76faf42Sespie
48e451b54dSespiepackage OpenBSD::PackingList::hashpath;
49e451b54dSespiesub match
50e451b54dSespie{
5131e751cfSespie	my ($h, $plist) = @_;
5285fd506aSespie	return
53*a4f5498fSespie	    defined $plist->fullpkgpath &&
54*a4f5498fSespie	    $h->{$plist->fullpkgpath};
55e451b54dSespie}
56e451b54dSespie
576f05d20cSespiepackage OpenBSD::PackingList;
586f05d20cSespie
596f05d20cSespieuse OpenBSD::PackingElement;
606f05d20cSespieuse OpenBSD::PackageInfo;
616f05d20cSespie
626f05d20cSespiesub new
636f05d20cSespie{
646f05d20cSespie	my $class = shift;
65e39fac1bSespie	my $plist = bless {state => OpenBSD::PackingList::State->new,
66e39fac1bSespie		infodir => \(my $d)}, $class;
67435cc565Sespie	OpenBSD::PackingElement::File->add($plist, CONTENTS);
68435cc565Sespie	return $plist;
696f05d20cSespie}
706f05d20cSespie
71e39fac1bSespiesub set_infodir
72e39fac1bSespie{
73c0956bedSespie	my ($self, $dir) = @_;
74cc24e6f2Sespie	$dir .= '/' unless $dir =~ m/\/$/o;
75e39fac1bSespie	${$self->{infodir}} = $dir;
76e39fac1bSespie}
77e39fac1bSespie
786a5fab34Sespiesub make_shallow_copy
7926205b33Sespie{
8026205b33Sespie	my ($plist, $h) = @_;
8126205b33Sespie
8226205b33Sespie	my $copy = bless {state => OpenBSD::PackingList::State->new,
8326205b33Sespie		infodir => \(my $d = ${$plist->{infodir}})}, ref($plist);
846a5fab34Sespie	$plist->copy_shallow_if($copy, $h);
8526205b33Sespie	return $copy;
8626205b33Sespie}
8726205b33Sespie
886a5fab34Sespiesub make_deep_copy
896a5fab34Sespie{
906a5fab34Sespie	my ($plist, $h) = @_;
916a5fab34Sespie
926a5fab34Sespie	my $copy = bless {state => OpenBSD::PackingList::State->new,
936a5fab34Sespie		infodir => \(my $d = ${$plist->{infodir}})}, ref($plist);
946a5fab34Sespie	$plist->copy_deep_if($copy, $h);
956a5fab34Sespie	return $copy;
966a5fab34Sespie}
9726205b33Sespie
98c0956bedSespiesub infodir
99c0956bedSespie{
100c0956bedSespie	my $self = shift;
1013f2ef483Sespie	return ${$self->{infodir}};
102c0956bedSespie}
103c0956bedSespie
104ec33acfdSespiesub conflict_list
105ec33acfdSespie{
106ec33acfdSespie	require OpenBSD::PkgCfl;
107ec33acfdSespie
108ec33acfdSespie	my $self = shift;
109ec33acfdSespie
110ec33acfdSespie	$self->{conflict_list} //= OpenBSD::PkgCfl->make_conflict_list($self);
111ec33acfdSespie	return $self->{conflict_list};
112ec33acfdSespie}
113ec33acfdSespie
1146f05d20cSespiesub read
1156f05d20cSespie{
11609568254Sespie	my ($a, $u, $code) = @_;
1176f05d20cSespie	my $plist;
11818f2b7ffSespie	$code = \&defaultCode if !defined $code;
1196f05d20cSespie	if (ref $a) {
1206f05d20cSespie		$plist = $a;
1216f05d20cSespie	} else {
1226f05d20cSespie		$plist = new $a;
1236f05d20cSespie	}
12409568254Sespie	&$code($u,
125f7e1ce99Sespie		sub {
1262c486618Sespie			my $line = shift;
1272c486618Sespie			return if $line =~ m/^\s*$/o;
1282c486618Sespie			OpenBSD::PackingElement->create($line, $plist);
129f7e1ce99Sespie		});
1306f05d20cSespie	return $plist;
1316f05d20cSespie}
1326f05d20cSespie
133f7e1ce99Sespiesub defaultCode
1346f05d20cSespie{
135f7e1ce99Sespie	my ($fh, $cont) = @_;
136294e3aadSespie	my $_;
137f7e1ce99Sespie	while (<$fh>) {
138f7e1ce99Sespie		&$cont($_);
139f7e1ce99Sespie	}
1406f05d20cSespie}
1416f05d20cSespie
14258be51c0Sespiesub SharedItemsOnly
1436f05d20cSespie{
144f7e1ce99Sespie	my ($fh, $cont) = @_;
145294e3aadSespie	my $_;
146f7e1ce99Sespie	while (<$fh>) {
14761e70cf3Sespie		next unless m/^\@(?:cwd|dir|fontdir|mandir|newuser|newgroup|name)\b/o || m/^\@(?:sample|extra)\b.*\/$/o || m/^[^\@].*\/$/o;
148f7e1ce99Sespie		&$cont($_);
149f7e1ce99Sespie	}
1506f05d20cSespie}
1516f05d20cSespie
15258be51c0Sespiesub DirrmOnly
15358be51c0Sespie{
15458be51c0Sespie	&OpenBSD::PackingList::SharedItemsOnly;
15558be51c0Sespie}
15658be51c0Sespie
1572d9bc31aSespiesub LibraryOnly
1582d9bc31aSespie{
1592d9bc31aSespie	my ($fh, $cont) = @_;
160294e3aadSespie	my $_;
1612d9bc31aSespie	while (<$fh>) {
162f5e8aff1Sespie		next unless m/^\@(?:cwd|lib|name)\b/o ||
163f5e8aff1Sespie			m/^\@comment\s+subdir\=/o;
1642d9bc31aSespie		&$cont($_);
1652d9bc31aSespie	}
1662d9bc31aSespie}
1672d9bc31aSespie
168f7e1ce99Sespiesub FilesOnly
1696f05d20cSespie{
170f7e1ce99Sespie	my ($fh, $cont) = @_;
171294e3aadSespie	my $_;
172f7e1ce99Sespie	while (<$fh>) {
17346c323b9Sespie	    	next unless m/^\@(?:cwd|name|info|man|file|lib|shell|sample|bin)\b/o || !m/^\@/o;
174f7e1ce99Sespie		&$cont($_);
175f7e1ce99Sespie	}
176f7e1ce99Sespie}
177f7e1ce99Sespie
1786a8d296fSespiesub PrelinkStuffOnly
1796a8d296fSespie{
1806a8d296fSespie	my ($fh, $cont) = @_;
181294e3aadSespie	my $_;
1826a8d296fSespie	while (<$fh>) {
1836a8d296fSespie		next unless m/^\@(?:cwd|bin|lib|name|depend|wantlib)\b/o ||
1846a8d296fSespie			m/^\@comment\s+subdir\=/o;
1856a8d296fSespie		&$cont($_);
1866a8d296fSespie	}
1876a8d296fSespie}
1886a8d296fSespie
18938727c08Sespiesub DependOnly
19038727c08Sespie{
19138727c08Sespie	my ($fh, $cont) = @_;
192294e3aadSespie	my $_;
19338727c08Sespie	while (<$fh>) {
19428790261Sespie		# XXX optimization
195f5e8aff1Sespie		if (m/^\@arch\b/o) {
19628790261Sespie			while (<$fh>) {
197b82ff443Sespie			    if (m/^\@(?:depend|wantlib|define-tag)\b/o) {
19828790261Sespie				    &$cont($_);
199f5e8aff1Sespie			    } elsif (m/^\@(?:groups|users|cwd)\b/o) {
20028790261Sespie				    last;
20128790261Sespie			    }
20228790261Sespie			}
20328790261Sespie			return;
20428790261Sespie		}
205b82ff443Sespie		next unless m/^\@(?:depend|wantlib|define-tag)\b/o;
20638727c08Sespie		&$cont($_);
20738727c08Sespie	}
20838727c08Sespie}
20938727c08Sespie
210737fdd9bSespiesub ExtraInfoOnly
211737fdd9bSespie{
212737fdd9bSespie	my ($fh, $cont) = @_;
213294e3aadSespie	my $_;
214737fdd9bSespie	while (<$fh>) {
215737fdd9bSespie		# XXX optimization
216f5e8aff1Sespie		if (m/^\@arch\b/o) {
2177522c6eaSespie			while (<$fh>) {
2187522c6eaSespie			    if (m/^\@(?:pkgpath)\b/o) {
219987c5975Sespie				    &$cont($_);
2207522c6eaSespie			    } elsif (m/^\@(?:groups|users|cwd)\b/o) {
2217522c6eaSespie				    last;
2227522c6eaSespie			    }
2237522c6eaSespie			}
224737fdd9bSespie			return;
225737fdd9bSespie		}
226f5e8aff1Sespie		next unless m/^\@(?:name\b|comment\s+subdir\=)/o;
227737fdd9bSespie		&$cont($_);
228737fdd9bSespie	}
229737fdd9bSespie}
230737fdd9bSespie
2319b5ce663Sespiesub UpdateInfoOnly
2329b5ce663Sespie{
2339b5ce663Sespie	my ($fh, $cont) = @_;
234294e3aadSespie	my $_;
2359b5ce663Sespie	while (<$fh>) {
2369b5ce663Sespie		# XXX optimization
2379b5ce663Sespie		if (m/^\@arch\b/o) {
2389b5ce663Sespie			while (<$fh>) {
239ec56d8ffSespie			    if (m/^\@(?:depend|wantlib|conflict|option|pkgpath|url)\b/o) {
2409b5ce663Sespie				    &$cont($_);
2419b5ce663Sespie			    } elsif (m/^\@(?:groups|users|cwd)\b/o) {
2429b5ce663Sespie				    last;
2439b5ce663Sespie			    }
2449b5ce663Sespie			}
2459b5ce663Sespie			return;
2469b5ce663Sespie		}
2479131f929Sespie		# if alwaysupdate, all info is sig
2489131f929Sespie		if (m/^\@option\s+always-update\b/o) {
2499131f929Sespie		    &$cont($_);
2509131f929Sespie		    while (<$fh>) {
2519131f929Sespie			    &$cont($_);
2529131f929Sespie		    }
2533b9b0d1bSespie		    return;
2549131f929Sespie		}
255ec56d8ffSespie		next unless m/^\@(?:name\b|depend\b|wantlib\b|conflict|\b|option\b|pkgpath\b|comment\s+subdir\=|arch\b|url\b)/o;
2569b5ce663Sespie		&$cont($_);
2579b5ce663Sespie	}
2589b5ce663Sespie}
2599b5ce663Sespie
2602092b510Sespiesub FatOnly
2612092b510Sespie{
2622092b510Sespie	my ($fh, $cont) = @_;
263294e3aadSespie	my $_;
2642092b510Sespie	while (<$fh>) {
265c055770eSespie		# XXX optimization
266c055770eSespie		if (m/^\@arch\b/o) {
267c055770eSespie			&$cont($_);
268c055770eSespie			return;
269c055770eSespie		}
270c055770eSespie		next unless m/^\@(?:name\b)/o;
2712092b510Sespie		&$cont($_);
2722092b510Sespie	}
2732092b510Sespie}
2742092b510Sespie
275f7e1ce99Sespiesub ConflictOnly
276f7e1ce99Sespie{
277f7e1ce99Sespie	my ($fh, $cont) = @_;
278294e3aadSespie	my $_;
279f7e1ce99Sespie	while (<$fh>) {
28028790261Sespie		# XXX optimization
281f5e8aff1Sespie		if (m/^\@arch\b/o) {
28228790261Sespie			while (<$fh>) {
28361e70cf3Sespie			    if (m/^\@(?:conflict|option|name)\b/o) {
28428790261Sespie				    &$cont($_);
28561e70cf3Sespie			    } elsif (m/^\@(?:depend|wantlib|groups|users|cwd)\b/o) {
28628790261Sespie				    last;
28728790261Sespie			    }
28828790261Sespie			}
28928790261Sespie			return;
29028790261Sespie		}
29161e70cf3Sespie	    	next unless m/^\@(?:conflict|option|name)\b/o;
292f7e1ce99Sespie		&$cont($_);
293f7e1ce99Sespie	}
294f7e1ce99Sespie}
295f7e1ce99Sespie
296f7e1ce99Sespiesub SharedStuffOnly
297f7e1ce99Sespie{
298f7e1ce99Sespie	my ($fh, $cont) = @_;
299294e3aadSespie	my $_;
300f7e1ce99SespieMAINLOOP:
301f7e1ce99Sespie	while (<$fh>) {
302cc24e6f2Sespie		if (m/^\@shared\b/o) {
303f7e1ce99Sespie			&$cont($_);
304f7e1ce99Sespie			while(<$fh>) {
305700d29cbSespie				redo MAINLOOP unless m/^\@(?:sha|md5|size|symlink|link)\b/o;
306cc24e6f2Sespie				    m/^\@size\b/o || m/^\@symlink\b/o ||
307cc24e6f2Sespie				    m/^\@link\b/o;
308f7e1ce99Sespie				&$cont($_);
309f7e1ce99Sespie			}
310f7e1ce99Sespie		} else {
311cc24e6f2Sespie			next unless m/^\@(?:cwd|name)\b/o;
312f7e1ce99Sespie		}
313f7e1ce99Sespie		&$cont($_);
314f7e1ce99Sespie	}
3156f05d20cSespie}
3166f05d20cSespie
3176f05d20cSespiesub fromfile
3186f05d20cSespie{
3196f05d20cSespie	my ($a, $fname, $code) = @_;
320b9b2024bSespie	open(my $fh, '<', $fname) or return;
3218433647eSespie	my $plist;
3228433647eSespie	eval {
3238433647eSespie		$plist = $a->read($fh, $code);
3248433647eSespie	};
3258433647eSespie	if ($@) {
3268433647eSespie		chomp $@;
327cc24e6f2Sespie		$@ =~ s/\.$/,/o;
3288433647eSespie		die "$@ in $fname, ";
3298433647eSespie	}
3306f05d20cSespie	close($fh);
3316f05d20cSespie	return $plist;
3326f05d20cSespie}
3336f05d20cSespie
3346f05d20cSespiesub tofile
3356f05d20cSespie{
3366f05d20cSespie	my ($self, $fname) = @_;
337b9b2024bSespie	open(my $fh, '>', $fname) or return;
3386f05d20cSespie	$self->write($fh);
339b9b2024bSespie	close($fh) or return;
3406f05d20cSespie	return 1;
3416f05d20cSespie}
3426f05d20cSespie
343c0956bedSespiesub save
344c0956bedSespie{
345c0956bedSespie	my $self = shift;
346c0956bedSespie	$self->tofile($self->infodir.CONTENTS);
347c0956bedSespie}
348c0956bedSespie
3496f05d20cSespiesub add2list
3506f05d20cSespie{
3516f05d20cSespie	my ($plist, $object) = @_;
352f04afe28Sespie	my $category = $object->category;
3536f05d20cSespie	push @{$plist->{$category}}, $object;
3546f05d20cSespie}
3556f05d20cSespie
3566f05d20cSespiesub addunique
3576f05d20cSespie{
3586f05d20cSespie	my ($plist, $object) = @_;
359f04afe28Sespie	my $category = $object->category;
3606f05d20cSespie	if (defined $plist->{$category}) {
3618e2dcc0dSespie		die "Duplicate $category in plist";
3626f05d20cSespie	}
3636f05d20cSespie	$plist->{$category} = $object;
3646f05d20cSespie}
3656f05d20cSespie
36610d7f8b4Sespiesub has
36710d7f8b4Sespie{
36810d7f8b4Sespie	my ($plist, $name) = @_;
36910d7f8b4Sespie	return defined $plist->{$name};
37010d7f8b4Sespie}
37110d7f8b4Sespie
37210d7f8b4Sespiesub get
37310d7f8b4Sespie{
37410d7f8b4Sespie	my ($plist, $name) = @_;
37510d7f8b4Sespie	return $plist->{$name};
37610d7f8b4Sespie}
37710d7f8b4Sespie
37826205b33Sespiesub set_pkgname
37926205b33Sespie{
38026205b33Sespie	my ($self, $name) = @_;
38126205b33Sespie	if (defined $self->{name}) {
382e451b54dSespie		$self->{name}->set_name($name);
38326205b33Sespie	} else {
38426205b33Sespie		OpenBSD::PackingElement::Name->add($self, $name);
38526205b33Sespie	}
38626205b33Sespie}
38726205b33Sespie
38836a7fe47Sespiesub pkgname
3896f05d20cSespie{
3906f05d20cSespie	my $self = shift;
391c9089320Snaddy	if (defined $self->{name}) {
392e451b54dSespie		return $self->{name}->name;
393c9089320Snaddy	} else {
394c9089320Snaddy		return undef;
395c9089320Snaddy	}
3966f05d20cSespie}
3976f05d20cSespie
39836a7fe47Sespiesub localbase
399dccc2276Sespie{
400dccc2276Sespie	my $self = shift;
401e95d9ee4Sespie
402e95d9ee4Sespie	if (defined $self->{localbase}) {
403e451b54dSespie		return $self->{localbase}->name;
404e95d9ee4Sespie	} else {
405e95d9ee4Sespie		return '/usr/local';
406e95d9ee4Sespie	}
407dccc2276Sespie}
408dccc2276Sespie
40911ccabebSespiesub is_signed
41011ccabebSespie{
41187317f7eSespie	my $self = shift;
41287317f7eSespie	return defined $self->{'digital-signature'};
41311ccabebSespie}
4142063c02eSespie
415*a4f5498fSespiesub fullpkgpath
416*a4f5498fSespie{
417*a4f5498fSespie	my $self = shift;
418*a4f5498fSespie	if (defined $self->{extrainfo} && $self->{extrainfo}->{subdir} ne '') {
419*a4f5498fSespie		return $self->{extrainfo}->{subdir};
420*a4f5498fSespie	} else {
421*a4f5498fSespie		return undef;
422*a4f5498fSespie	}
423*a4f5498fSespie}
424e451b54dSespiesub pkgpath
425e451b54dSespie{
426e451b54dSespie	my $self = shift;
427e451b54dSespie	if (!defined $self->{_hashpath}) {
428e451b54dSespie		my $h = $self->{_hashpath} =
429e451b54dSespie		    bless {}, "OpenBSD::PackingList::hashpath";
430*a4f5498fSespie		if (defined $self->fullpkgpath) {
431*a4f5498fSespie			$h->{$self->fullpkgpath} = 1;
432e451b54dSespie		}
433e451b54dSespie		if (defined $self->{pkgpath}) {
434e451b54dSespie			for my $i (@{$self->{pkgpath}}) {
435e451b54dSespie				$h->{$i->name} = 1;
436e451b54dSespie			}
437e451b54dSespie		}
438e451b54dSespie	}
439e451b54dSespie	return $self->{_hashpath};
440e451b54dSespie}
441e451b54dSespie
442e451b54dSespiesub match_pkgpath
443e451b54dSespie{
444e451b54dSespie	my ($self, $plist2) = @_;
44531e751cfSespie	return $self->pkgpath->match($plist2) ||
44631e751cfSespie	    $plist2->pkgpath->match($self);
447e451b54dSespie}
448e451b54dSespie
4499b5ce663Sespieour @unique_categories =
45025a529f6Sespie    (qw(name url digital-signature no-default-conflict manual-installation always-update explicit-update extrainfo localbase arch));
4519b5ce663Sespie
4529b5ce663Sespieour @list_categories =
45361e70cf3Sespie    (qw(conflict pkgpath incompatibility updateset depend
454b82ff443Sespie    	wantlib define-tag groups users items));
4559b5ce663Sespie
4569b5ce663Sespieour @cache_categories =
45761e70cf3Sespie    (qw(depend wantlib));
4589b5ce663Sespie
4592063c02eSespiesub visit
4602063c02eSespie{
4612063c02eSespie	my ($self, $method, @l) = @_;
4622063c02eSespie
4632063c02eSespie	if (defined $self->{cvstags}) {
4642063c02eSespie		for my $item (@{$self->{cvstags}}) {
4652063c02eSespie			$item->$method(@l);
4662063c02eSespie		}
4672063c02eSespie	}
4682063c02eSespie
4699b5ce663Sespie	for my $unique_item (@unique_categories) {
4702063c02eSespie		$self->{$unique_item}->$method(@l) if defined $self->{$unique_item};
4712063c02eSespie	}
4722063c02eSespie
4732063c02eSespie	for my $special (OpenBSD::PackageInfo::info_names()) {
4742063c02eSespie		$self->{$special}->$method(@l) if defined $self->{$special};
4752063c02eSespie	}
4762063c02eSespie
4779b5ce663Sespie	for my $listname (@list_categories) {
4782063c02eSespie		if (defined $self->{$listname}) {
4792063c02eSespie			for my $item (@{$self->{$listname}}) {
4802063c02eSespie				$item->$method(@l);
4812063c02eSespie			}
4822063c02eSespie		}
4832063c02eSespie	}
4842063c02eSespie}
4852063c02eSespie
48651f6b09fSespiemy $plist_cache = {};
48751f6b09fSespie
48818f9a590Sespiesub from_installation
48918f9a590Sespie{
49051f6b09fSespie	my ($o, $pkgname, $code) = @_;
49118f9a590Sespie
49218f9a590Sespie	require OpenBSD::PackageInfo;
49318f9a590Sespie
49451f6b09fSespie	$code = \&defaultCode if !defined $code;
49551f6b09fSespie
4963571b10fSespie	if ($code == \&DependOnly && defined $plist_cache->{$pkgname}) {
4973571b10fSespie	    return $plist_cache->{$pkgname};
4983571b10fSespie	}
4998ee98284Sespie	my $filename = OpenBSD::PackageInfo::installed_contents($pkgname);
5008ee98284Sespie	my $plist = $o->fromfile($filename, $code);
5013571b10fSespie	if (defined $plist && $code == \&DependOnly) {
5023571b10fSespie		$plist_cache->{$pkgname} = $plist;
5033571b10fSespie	}
5043fdb0aa4Sespie	if (defined $plist) {
505e39fac1bSespie		$plist->set_infodir(OpenBSD::PackageInfo::installed_info($pkgname));
5063fdb0aa4Sespie	}
5078ee98284Sespie	if (!defined $plist) {
5088ee98284Sespie		print STDERR "Warning: couldn't read packing-list from installed package $pkgname\n";
5098ee98284Sespie		unless (-e $filename) {
5108ee98284Sespie			print STDERR "File $filename does not exist\n";
5118ee98284Sespie		}
5128ee98284Sespie	}
51351f6b09fSespie	return $plist;
51418f9a590Sespie}
51518f9a590Sespie
516f0b76557Sespiesub to_cache
517f0b76557Sespie{
518bd99e8b0Sespie	my ($self) = @_;
519b1674f53Sespie	return if defined $plist_cache->{$self->pkgname};
520bd99e8b0Sespie	my $plist = new OpenBSD::PackingList;
5219b5ce663Sespie	for my $c (@cache_categories) {
522bd99e8b0Sespie		if (defined $self->{$c}) {
523bd99e8b0Sespie			$plist->{$c} = $self->{$c};
524bd99e8b0Sespie		}
525bd99e8b0Sespie	}
526e39fac1bSespie	$plist_cache->{$self->pkgname} = $plist;
527f0b76557Sespie}
528f0b76557Sespie
52918f9a590Sespiesub to_installation
53018f9a590Sespie{
53118f9a590Sespie	my ($self) = @_;
53218f9a590Sespie
53318f9a590Sespie	require OpenBSD::PackageInfo;
53418f9a590Sespie
53538599eebSespie	return if $main::not;
53638599eebSespie
537f04afe28Sespie	$self->tofile(OpenBSD::PackageInfo::installed_contents($self->pkgname));
53851f6b09fSespie}
53951f6b09fSespie
54051f6b09fSespie
5419b5ce663Sespiesub signature
5429b5ce663Sespie{
5439b5ce663Sespie	my $self = shift;
5449131f929Sespie	if ($self->has('always-update')) {
5459131f929Sespie		my $s;
5469131f929Sespie		open my $fh, '>', \$s;
5479131f929Sespie		$self->write_no_sig($fh);
5489131f929Sespie		close $fh;
5499131f929Sespie		return $s;
5509131f929Sespie	} else {
5519b5ce663Sespie		my $k = {};
5529b5ce663Sespie		$self->visit('signature', $k);
553f04afe28Sespie		return join(',', $self->pkgname, sort keys %$k);
5549b5ce663Sespie	}
5559131f929Sespie}
5569b5ce663Sespie
55751f6b09fSespiesub forget
55851f6b09fSespie{
55918f2b7ffSespie}
56018f9a590Sespie
561d62e3fc0Sespie# convert call to $self->sub(@args) into $self->visit(sub, @args)
562d62e3fc0Sespie
563d62e3fc0Sespiesub AUTOLOAD
564d62e3fc0Sespie{
565d62e3fc0Sespie	our $AUTOLOAD;
566d62e3fc0Sespie	my $fullsub = $AUTOLOAD;
567cc24e6f2Sespie	(my $sub = $fullsub) =~ s/.*:://o;
568d62e3fc0Sespie	return if $sub eq 'DESTROY'; # special case
569d62e3fc0Sespie	# verify it makes sense
570d62e3fc0Sespie	if (OpenBSD::PackingElement->can($sub)) {
571d62e3fc0Sespie		no strict "refs";
572d62e3fc0Sespie		# create the sub to avoid regenerating further calls
573d62e3fc0Sespie		*$fullsub = sub {
574d62e3fc0Sespie			my $self = shift;
575d62e3fc0Sespie			$self->visit($sub, @_);
576d62e3fc0Sespie		};
577d62e3fc0Sespie		# and jump to it
578d62e3fc0Sespie		goto &$fullsub;
579d62e3fc0Sespie	} else {
580d62e3fc0Sespie		die "Can't call $sub on ", __PACKAGE__;
581d62e3fc0Sespie	}
582d62e3fc0Sespie}
583d62e3fc0Sespie
5846f05d20cSespie1;
585