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