xref: /openbsd-src/usr.sbin/pkg_add/OpenBSD/SharedItems.pm (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1# ex:ts=8 sw=4:
2# $OpenBSD: SharedItems.pm,v 1.32 2014/11/20 14:10:18 espie Exp $
3#
4# Copyright (c) 2004-2006 Marc Espie <espie@openbsd.org>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18use strict;
19use warnings;
20
21package OpenBSD::SharedItems;
22
23use OpenBSD::Error;
24use OpenBSD::PackageInfo;
25use OpenBSD::PackingList;
26use OpenBSD::Paths;
27
28sub find_items_in_installed_packages
29{
30	my $state = shift;
31	my $db = OpenBSD::SharedItemsRecorder->new;
32	$state->status->what("Read")->object("shared items");
33	$state->progress->for_list("Read shared items", [installed_packages()],
34	    sub {
35		my $e = shift;
36		my $plist = OpenBSD::PackingList->from_installation($e,
37		    \&OpenBSD::PackingList::SharedItemsOnly) or return;
38		return if !defined $plist;
39		$plist->record_shared($db, $e);
40	    });
41	return $db;
42}
43
44sub check_shared
45{
46	my ($set, $o) = @_;
47	if (!defined $set->{db}) {
48		$set->{db} = OpenBSD::SharedItemsRecorder->new;
49		for my $pkg (installed_packages()) {
50			next if $set->{older}{$pkg};
51			my $plist = OpenBSD::PackingList->from_installation($pkg,
52			    \&OpenBSD::PackingList::SharedItemsOnly) or next;
53			next if !defined $plist;
54			$plist->record_shared($set->{db}, $pkg);
55		}
56	}
57	if (defined $set->{db}{dirs}{$o->fullname}) {
58		return 1;
59	} else {
60		push(@{$set->{old_shared}{$o->fullname}}, $o);
61		return 0;
62	}
63}
64
65sub wipe_directory
66{
67	my ($state, $h, $d) = @_;
68
69	my $realname = $state->{destdir}.$d;
70
71	for my $i (@{$h->{$d}}) {
72		$i->cleanup($state);
73	}
74	if (!rmdir $realname) {
75		$state->log("Error deleting directory #1: #2",
76		    $realname, $!)
77			unless $state->{dirs_okay}{$d};
78		return 0;
79	}
80	return 1;
81}
82
83sub cleanup
84{
85	my ($recorder, $state) = @_;
86
87	my $remaining = find_items_in_installed_packages($state);
88
89	$state->progress->clear;
90	$state->status->what("Clean");
91	$state->progress->set_header("Clean shared items");
92	my $h = $recorder->{dirs};
93	my $u = $recorder->{users};
94	my $g = $recorder->{groups};
95	my $total = 0;
96	$total += keys %$h if defined $h;
97	$total += keys %$u if defined $u;
98	$total += keys %$g if defined $g;
99	my $done = 0;
100
101	for my $d (sort {$b cmp $a} keys %$h) {
102		$state->progress->show($done, $total);
103		my $realname = $state->{destdir}.$d;
104		if (defined $remaining->{dirs}{$realname}) {
105			for my $i (@{$h->{$d}}) {
106				$state->log->set_context('-'.$i->{pkgname});
107				$i->reload($state);
108			}
109		} else {
110			wipe_directory($state, $h, $d);
111		}
112		$done++;
113	}
114	while (my ($user, $pkgname) = each %$u) {
115		$state->progress->show($done, $total);
116		next if $remaining->{users}{$user};
117		if ($state->{extra}) {
118			$state->system(OpenBSD::Paths->userdel, '--',
119			    $user);
120		} else {
121			$state->log->set_context('-'.$pkgname);
122			$state->log("You should also run /usr/sbin/userdel #1", $user);
123		}
124		$done++;
125	}
126	while (my ($group, $pkgname) = each %$g) {
127		$state->progress->show($done, $total);
128		next if $remaining->{groups}{$group};
129		if ($state->{extra}) {
130			$state->system(OpenBSD::Paths->groupdel, '--',
131			    $group);
132		} else {
133			$state->log->set_context('-'.$pkgname);
134			$state->log("You should also run /usr/sbin/groupdel #1", $group);
135		}
136		$done++;
137	}
138	if ($state->verbose >= 2) {
139		$state->progress->next;
140	} else {
141		$state->progress->clear;
142	}
143}
144
145package OpenBSD::PackingElement;
146sub cleanup
147{
148}
149
150sub reload
151{
152}
153
154package OpenBSD::PackingElement::Mandir;
155sub cleanup
156{
157	my ($self, $state) = @_;
158	my $fullname = $state->{destdir}.$self->fullname;
159	$state->log->set_context('-'.$self->{pkgname});
160	$state->log("You may wish to remove #1 from man.conf", $fullname);
161	for my $f (OpenBSD::Paths->man_cruft) {
162		unlink("$fullname/$f");
163	}
164}
165
166package OpenBSD::PackingElement::Fontdir;
167sub cleanup
168{
169	my ($self, $state) = @_;
170	my $fullname = $state->{destdir}.$self->fullname;
171	$state->log->set_context('-'.$self->{pkgname});
172	$state->log("You may wish to remove #1 from your font path", $fullname);
173	for my $f (OpenBSD::Paths->font_cruft) {
174		unlink("$fullname/$f");
175	}
176}
177
178package OpenBSD::PackingElement::Infodir;
179sub cleanup
180{
181	my ($self, $state) = @_;
182	my $fullname = $state->{destdir}.$self->fullname;
183	for my $f (OpenBSD::Paths->info_cruft) {
184		unlink("$fullname/$f");
185	}
186}
187
1881;
189