# ex:ts=8 sw=4: # $OpenBSD: SharedItems.pm,v 1.6 2006/07/31 17:09:19 espie Exp $ # # Copyright (c) 2004 Marc Espie # # 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; package OpenBSD::SharedItems; use OpenBSD::ProgressMeter; use OpenBSD::Error; use OpenBSD::PackageInfo; use OpenBSD::PackingList; sub find_items_in_installed_packages { my $db = {dirs=>{}, users=>{}, groups=>{}}; my @list = installed_packages(); my $total = @list; OpenBSD::ProgressMeter::set_header("Read shared items"); my $done = 0; for my $e (@list) { OpenBSD::ProgressMeter::show($done, $total); my $plist = OpenBSD::PackingList->from_installation($e, \&OpenBSD::PackingList::SharedItemsOnly) or next; $plist->visit('record_shared_item', $e, $db); $done++; } return $db; } sub cleanup { my $state = shift; my $h = $state->{dirs_to_rm}; my $u = $state->{users_to_rm}; my $g = $state->{groups_to_rm}; return unless defined $h or defined $u or defined $g; my $remaining = find_items_in_installed_packages(); OpenBSD::ProgressMeter::clear(); OpenBSD::ProgressMeter::set_header("Clean shared items"); my $total = 0; $total += keys %$h if defined $h; $total += keys %$u if defined $u; $total += keys %$g if defined $g; my $done = 0; if (defined $h) { for my $d (sort {$b cmp $a} keys %$h) { OpenBSD::ProgressMeter::show($done, $total); my $realname = $state->{destdir}.$d; if ($remaining->{dirs}->{$realname}) { for my $i (@{$h->{$d}}) { $state->set_pkgname($i->{pkgname}); $i->reload($state); } } else { for my $i (@{$h->{$d}}) { $state->set_pkgname($i->{pkgname}); $i->cleanup($state); } if (!rmdir $realname) { $state->print("Error deleting directory $realname: $!\n") unless $state->{dirs_okay}->{$d}; } } $done++; } } if (defined $u) { while (my ($user, $pkgname) = each %$u) { OpenBSD::ProgressMeter::show($done, $total); next if $remaining->{users}->{$user}; if ($state->{extra}) { System("/usr/sbin/userdel", $user); } else { $state->set_pkgname($pkgname); $state->print("You should also run /usr/sbin/userdel $user\n"); } $done++; } } if (defined $g) { while (my ($group, $pkgname) = each %$g) { OpenBSD::ProgressMeter::show($done, $total); next if $remaining->{groups}->{$group}; if ($state->{extra}) { System("/usr/sbin/groupdel", $group); } else { $state->set_pkgname($pkgname); $state->print("You should also run /usr/sbin/groupdel $group\n"); } $done++; } } OpenBSD::ProgressMeter::next(); } package OpenBSD::PackingElement; sub record_shared_item { } sub cleanup { } sub reload { } package OpenBSD::PackingElement::NewUser; sub record_shared_item { my ($self, $pkgname, $db) = @_; my $k = $self->{name}; $db->{users}->{$k} = $pkgname; } package OpenBSD::PackingElement::NewGroup; sub record_shared_item { my ($self, $pkgname, $db) = @_; my $k = $self->{name}; $db->{groups}->{$k} = $pkgname; } package OpenBSD::PackingElement::DirBase; sub record_shared_item { my ($self, $pkgname, $db) = @_; my $k = $self->fullname(); $db->{dirs}->{$k} = 1; } package OpenBSD::PackingElement::DirRm; sub record_shared_item { &OpenBSD::PackingElement::DirBase::record_shared_item; } package OpenBSD::PackingElement::Mandir; sub cleanup { my ($self, $state) = @_; my $fullname = $state->{destdir}.$self->fullname(); $state->print("You may wish to remove ", $fullname, " from man.conf\n"); unlink("$fullname/whatis.db"); } package OpenBSD::PackingElement::Fontdir; sub cleanup { my ($self, $state) = @_; my $fullname = $state->{destdir}.$self->fullname(); $state->print("You may wish to remove ", $fullname, " from your font path\n"); unlink("$fullname/fonts.alias"); unlink("$fullname/fonts.dir"); unlink("$fullname/fonts.cache-1"); } package OpenBSD::PackingElement::Infodir; sub cleanup { my ($self, $state) = @_; my $fullname = $state->{destdir}.$self->fullname(); unlink("$fullname/dir"); } 1;