1# ex:ts=8 sw=4: 2# $OpenBSD: SharedItems.pm,v 1.34 2023/06/13 09:07:17 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 v5.36; 19 20package OpenBSD::SharedItems; 21 22use OpenBSD::Error; 23use OpenBSD::PackageInfo; 24use OpenBSD::PackingList; 25use OpenBSD::Paths; 26 27sub find_items_in_installed_packages($state) 28{ 29 my $db = OpenBSD::SharedItemsRecorder->new; 30 $state->status->what("Read")->object("shared items"); 31 $state->progress->for_list("Read shared items", [installed_packages()], 32 sub($e) { 33 my $plist = OpenBSD::PackingList->from_installation($e, 34 \&OpenBSD::PackingList::SharedItemsOnly) or return; 35 return if !defined $plist; 36 $plist->record_shared($db, $e); 37 }); 38 return $db; 39} 40 41sub check_shared($set, $o) 42{ 43 if (!defined $set->{db}) { 44 $set->{db} = OpenBSD::SharedItemsRecorder->new; 45 for my $pkg (installed_packages()) { 46 next if $set->{older}{$pkg}; 47 my $plist = OpenBSD::PackingList->from_installation($pkg, 48 \&OpenBSD::PackingList::SharedItemsOnly) or next; 49 next if !defined $plist; 50 $plist->record_shared($set->{db}, $pkg); 51 } 52 } 53 if (defined $set->{db}{dirs}{$o->fullname}) { 54 return 1; 55 } else { 56 push(@{$set->{old_shared}{$o->fullname}}, $o); 57 return 0; 58 } 59} 60 61sub wipe_directory($state, $h, $d) 62{ 63 my $realname = $state->{destdir}.$d; 64 65 for my $i (@{$h->{$d}}) { 66 $i->cleanup($state); 67 } 68 if (!rmdir $realname) { 69 $state->log("Error deleting directory #1: #2", 70 $realname, $!) 71 unless $state->{dirs_okay}{$d}; 72 return 0; 73 } 74 return 1; 75} 76 77sub cleanup($recorder, $state) 78{ 79 my $remaining = find_items_in_installed_packages($state); 80 81 $state->progress->clear; 82 $state->status->what("Clean"); 83 $state->progress->set_header("Clean shared items"); 84 my $h = $recorder->{dirs}; 85 my $u = $recorder->{users}; 86 my $g = $recorder->{groups}; 87 my $total = 0; 88 $total += keys %$h if defined $h; 89 $total += keys %$u if defined $u; 90 $total += keys %$g if defined $g; 91 my $done = 0; 92 93 for my $d (sort {$b cmp $a} keys %$h) { 94 $state->progress->show($done, $total); 95 if (defined $remaining->{dirs}{$d}) { 96 for my $i (@{$h->{$d}}) { 97 $state->log->set_context('-'.$i->{pkgname}); 98 $i->reload($state); 99 } 100 } else { 101 wipe_directory($state, $h, $d); 102 } 103 $done++; 104 } 105 while (my ($user, $pkgname) = each %$u) { 106 $state->progress->show($done, $total); 107 next if $remaining->{users}{$user}; 108 if ($state->{extra}) { 109 $state->system(OpenBSD::Paths->userdel, '--', 110 $user); 111 } else { 112 $state->log->set_context('-'.$pkgname); 113 $state->log("You should also run /usr/sbin/userdel #1", $user); 114 } 115 $done++; 116 } 117 while (my ($group, $pkgname) = each %$g) { 118 $state->progress->show($done, $total); 119 next if $remaining->{groups}{$group}; 120 if ($state->{extra}) { 121 $state->system(OpenBSD::Paths->groupdel, '--', 122 $group); 123 } else { 124 $state->log->set_context('-'.$pkgname); 125 $state->log("You should also run /usr/sbin/groupdel #1", $group); 126 } 127 $done++; 128 } 129 if ($state->verbose >= 2) { 130 $state->progress->next; 131 } else { 132 $state->progress->clear; 133 } 134} 135 136package OpenBSD::PackingElement; 137sub cleanup($, $) 138{ 139} 140 141sub reload($, $) 142{ 143} 144 145package OpenBSD::PackingElement::Mandir; 146sub cleanup($self, $state) 147{ 148 my $fullname = $state->{destdir}.$self->fullname; 149 $state->log->set_context('-'.$self->{pkgname}); 150 $state->log("You may wish to remove #1 from man.conf", $fullname); 151 for my $f (OpenBSD::Paths->man_cruft) { 152 unlink("$fullname/$f"); 153 } 154} 155 156package OpenBSD::PackingElement::Fontdir; 157sub cleanup($self, $state) 158{ 159 my $fullname = $state->{destdir}.$self->fullname; 160 $state->log->set_context('-'.$self->{pkgname}); 161 $state->log("You may wish to remove #1 from your font path", $fullname); 162 for my $f (OpenBSD::Paths->font_cruft) { 163 unlink("$fullname/$f"); 164 } 165} 166 167package OpenBSD::PackingElement::Infodir; 168sub cleanup($self, $state) 169{ 170 my $fullname = $state->{destdir}.$self->fullname; 171 for my $f (OpenBSD::Paths->info_cruft) { 172 unlink("$fullname/$f"); 173 } 174} 175 1761; 177