1d15f7ce5Sespie# ex:ts=8 sw=4: 2*d17dc12fSespie# $OpenBSD: CollisionReport.pm,v 1.25 2009/11/14 21:04:02 espie Exp $ 3d15f7ce5Sespie# 41144937fSespie# Copyright (c) 2003-2006 Marc Espie <espie@openbsd.org> 5d15f7ce5Sespie# 6d15f7ce5Sespie# Permission to use, copy, modify, and distribute this software for any 7d15f7ce5Sespie# purpose with or without fee is hereby granted, provided that the above 8d15f7ce5Sespie# copyright notice and this permission notice appear in all copies. 9d15f7ce5Sespie# 10d15f7ce5Sespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11d15f7ce5Sespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12d15f7ce5Sespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13d15f7ce5Sespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14d15f7ce5Sespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15d15f7ce5Sespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16d15f7ce5Sespie# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 170fbefeddSespie 18d15f7ce5Sespieuse strict; 19d15f7ce5Sespieuse warnings; 20d15f7ce5Sespie 21d15f7ce5Sespiepackage OpenBSD::CollisionReport; 22d15f7ce5Sespieuse OpenBSD::PackingList; 23d15f7ce5Sespieuse OpenBSD::PackageInfo; 248eeac59fSespieuse OpenBSD::Vstat; 25d15f7ce5Sespie 262818ea65Sespiesub find_collisions 27d15f7ce5Sespie{ 280f0116c3Sespie my ($todo, $state) = @_; 290f0116c3Sespie my $verbose = $state->{verbose}; 30d15f7ce5Sespie my $bypkg = {}; 312818ea65Sespie for my $name (keys %$todo) { 328eeac59fSespie my $p = OpenBSD::Vstat::vexists $name; 338eeac59fSespie if (ref $p) { 348eeac59fSespie my $pkg = $$p; 358eeac59fSespie push(@{$bypkg->{$pkg}}, $name); 362818ea65Sespie delete $todo->{$name}; 378eeac59fSespie } 388eeac59fSespie } 39d15f7ce5Sespie 402818ea65Sespie 412818ea65Sespie if (!%$todo) { 422818ea65Sespie return $bypkg; 432818ea65Sespie } 44d15f7ce5Sespie for my $pkg (installed_packages()) { 45662ab648Sespie $state->say("Looking for collisions in $pkg") if $verbose; 46d15f7ce5Sespie my $plist = OpenBSD::PackingList->from_installation($pkg, 47d15f7ce5Sespie \&OpenBSD::PackingList::FilesOnly); 488ee98284Sespie next if !defined $plist; 49d15f7ce5Sespie for my $item (@{$plist->{items}}) { 50f04afe28Sespie next unless $item->IsFile; 51f04afe28Sespie my $name = $item->fullname; 522818ea65Sespie if (defined $todo->{$name}) { 53d15f7ce5Sespie push(@{$bypkg->{$pkg}}, $name); 542818ea65Sespie delete $todo->{$name}; 55d15f7ce5Sespie } 56d15f7ce5Sespie } 57d15f7ce5Sespie } 582818ea65Sespie return $bypkg; 59d15f7ce5Sespie} 602818ea65Sespie 612818ea65Sespiesub collision_report($$) 622818ea65Sespie{ 632818ea65Sespie my ($list, $state) = @_; 642818ea65Sespie 65*d17dc12fSespie my $destdir = $state->{destdir}; 66*d17dc12fSespie 672818ea65Sespie if ($state->{defines}->{removecollisions}) { 682818ea65Sespie require OpenBSD::Error; 692818ea65Sespie for my $f (@$list) { 70*d17dc12fSespie $state->unlink(1, $destdir.$f->fullname); 718eeac59fSespie } 722818ea65Sespie return; 732818ea65Sespie } 74700d29cbSespie my %todo = map {($_->fullname, $_->{d})} @$list; 752818ea65Sespie my $clueless_bat; 762818ea65Sespie my $clueless_bat2; 772818ea65Sespie my $found = 0; 782818ea65Sespie 79662ab648Sespie $state->say("Collision: the following files already exist"); 802818ea65Sespie if (!$state->{defines}->{dontfindcollisions}) { 810f0116c3Sespie my $bypkg = find_collisions(\%todo, $state); 82d15f7ce5Sespie for my $pkg (sort keys %$bypkg) { 83d15f7ce5Sespie for my $item (sort @{$bypkg->{$pkg}}) { 842818ea65Sespie $found++; 85662ab648Sespie $state->say("\t$item ($pkg)"); 86d15f7ce5Sespie } 87cc24e6f2Sespie if ($pkg =~ m/^(?:partial\-|borked\.\d+$)/o) { 88eefd3b46Sespie $clueless_bat = $pkg; 89eefd3b46Sespie } 90eb9d5597Sespie if ($pkg =~ m/^\.libs\d*-*$/o) { 911c9bf27fSespie $clueless_bat2 = $pkg; 921c9bf27fSespie } 93d15f7ce5Sespie } 942818ea65Sespie } 950b2ea41eSespie if (%todo) { 960b2ea41eSespie 97d15f7ce5Sespie for my $item (sort keys %todo) { 98eefd3b46Sespie if (defined $todo{$item}) { 99700d29cbSespie my $old = $todo{$item}; 100700d29cbSespie my $d = $old->new($destdir.$item); 101700d29cbSespie if ($d->equals($old)) { 102662ab648Sespie $state->say("\t$item (same checksum)"); 1030b2ea41eSespie } else { 104662ab648Sespie $state->say("\t$item (different checksum)"); 1050b2ea41eSespie } 106eefd3b46Sespie } else { 107662ab648Sespie $state->say("\t$item"); 1080b2ea41eSespie } 109d15f7ce5Sespie } 110d15f7ce5Sespie } 111a96a2504Sespie if (defined $clueless_bat) { 112662ab648Sespie $state->print("The package name $clueless_bat suggests that a former installation\n", 113662ab648Sespie "of a similar package got interrupted. It is likely that\n", 114662ab648Sespie "\tpkg_delete $clueless_bat\n", 115662ab648Sespie "will solve the problem\n"); 116eefd3b46Sespie } 117a96a2504Sespie if (defined $clueless_bat2) { 118662ab648Sespie $state->print("The package name $clueless_bat2 suggests remaining libraries\n", 119662ab648Sespie "from a former package update. It is likely that\n", 120662ab648Sespie "\tpkg_delete $clueless_bat2\n". 121662ab648Sespie "will solve the problem\n"); 1221c9bf27fSespie } 1232818ea65Sespie my $dorepair = 0; 1242818ea65Sespie if ($found == 0) { 1252818ea65Sespie if ($state->{defines}->{repair}) { 1262818ea65Sespie $dorepair = 1; 1272818ea65Sespie } elsif ($state->{interactive}) { 1282818ea65Sespie require OpenBSD::Interactive; 1292818ea65Sespie if (OpenBSD::Interactive::confirm( 1302818ea65Sespie "It seems to be a missing package registration\nRepair", 1, 0)) { 1312818ea65Sespie $dorepair = 1; 1322818ea65Sespie } 1332818ea65Sespie } 1342818ea65Sespie } 1352818ea65Sespie if ($dorepair == 1) { 1362818ea65Sespie for my $f (@$list) { 1372818ea65Sespie 138b5458979Sespie if ($state->unlink($state->{verbose}, 139*d17dc12fSespie $destdir.$f->fullname)) { 1402818ea65Sespie $state->{problems}--; 1412818ea65Sespie } else { 1422818ea65Sespie return; 1432818ea65Sespie } 1442818ea65Sespie } 1452818ea65Sespie $state->{repairdependencies} = 1; 1462818ea65Sespie } 147eefd3b46Sespie} 148d15f7ce5Sespie 149d15f7ce5Sespie1; 150