1eef84043Sespie#! /usr/bin/perl 2eef84043Sespie 3eef84043Sespie# ex:ts=8 sw=4: 4*7068cea4Sespie# $OpenBSD: PkgCheck.pm,v 1.81 2023/06/16 10:38:29 espie Exp $ 5eef84043Sespie# 645019a4aSespie# Copyright (c) 2003-2014 Marc Espie <espie@openbsd.org> 7eef84043Sespie# 8eef84043Sespie# Permission to use, copy, modify, and distribute this software for any 9eef84043Sespie# purpose with or without fee is hereby granted, provided that the above 10eef84043Sespie# copyright notice and this permission notice appear in all copies. 11eef84043Sespie# 12eef84043Sespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13eef84043Sespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14eef84043Sespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15eef84043Sespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16eef84043Sespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17eef84043Sespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18eef84043Sespie# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19eef84043Sespie 20039cbdaaSespieuse v5.36; 21eef84043Sespie 22eef84043Sespieuse OpenBSD::AddCreateDelete; 23eef84043Sespie 24556a8905Sespiepackage Installer::State; 25556a8905Sespieour @ISA = qw(OpenBSD::PkgAdd::State); 26039cbdaaSespiesub new($class, $cmd) 27556a8905Sespie{ 28556a8905Sespie my $state = $class->SUPER::new($cmd); 29556a8905Sespie $state->{localbase} = OpenBSD::Paths->localbase; 30556a8905Sespie return $state; 31556a8905Sespie} 32556a8905Sespie 33556a8905Sespiepackage Installer; 34556a8905Sespieour @ISA = qw(OpenBSD::PkgAdd); 35556a8905Sespie 36039cbdaaSespiesub new($class, $mystate) 37556a8905Sespie{ 38556a8905Sespie my $state = Installer::State->new("pkg_check"); 39556a8905Sespie $state->{v} = $mystate->{v}; 407279417dSespie $state->{subst} = $mystate->{subst}; 41556a8905Sespie $state->{interactive} = $mystate->{interactive}; 42556a8905Sespie $state->{destdir} = $mystate->{destdir}; 4356f6d8b7Sespie $state->{signature_style} = $mystate->{signature_style}; 44e05b4ceeSespie $state->progress->setup($state->opt('x'), $state->opt('m'), $state); 45556a8905Sespie bless { state => $state}, $class; 46556a8905Sespie} 47556a8905Sespie 48039cbdaaSespiesub install($self, $pkg) 49556a8905Sespie{ 50556a8905Sespie my $state = $self->{state}; 51556a8905Sespie push(@{$state->{setlist}}, 52556a8905Sespie $state->updateset->add_hints2($pkg)); 53fddcf565Sespie $self->try_and_run_command($state); 54556a8905Sespie return $state->{bad} != 0; 55556a8905Sespie} 56556a8905Sespie 57eef84043Sespiepackage OpenBSD::PackingElement; 58039cbdaaSespiesub thorough_check($self, $state) 59eef84043Sespie{ 60eef84043Sespie $self->basic_check($state); 61eef84043Sespie} 62eef84043Sespie 63039cbdaaSespiesub basic_check($, $) 64eef84043Sespie{ 659a24c98bSespie 1 66eef84043Sespie} 67eef84043Sespie 68039cbdaaSespie# $self->find_dpendencies($state, $l, $checker, $pkgname) 69039cbdaaSespiesub find_dependencies($, $, $, $, $) 70eef84043Sespie{ 71eef84043Sespie} 72eef84043Sespie 73039cbdaaSespie# XXX this is a snag for ShareLibs OO-ness 74039cbdaaSespie# $self->mark_indirect_depends($pkgname, $state) 75039cbdaaSespiesub mark_indirect_depends($self, $pkgname, $state) 7602ee83faSespie{ 7708eb747cSespie $self->mark_available_lib($pkgname, $state->shlibs); 7802ee83faSespie} 7902ee83faSespie 80039cbdaaSespie# $self->cache_depends($copy) 81039cbdaaSespiesub cache_depends($, $) 824be5dd99Sespie{ 834be5dd99Sespie} 844be5dd99Sespie 8502ee83faSespiepackage OpenBSD::PackingElement::DefineTag; 8602ee83faSespie 87039cbdaaSespiesub mark_indirect_depends($self, $pkgname, $state) 8802ee83faSespie{ 8902ee83faSespie $state->{tagdefinition}{$self->name} = $pkgname; 9002ee83faSespie} 9102ee83faSespie 92eef84043Sespiepackage OpenBSD::PackingElement::FileBase; 93eef84043Sespieuse File::Basename; 94eef84043Sespie 95039cbdaaSespiesub basic_check($self, $state) 96eef84043Sespie{ 970f19ffacSespie my $name = $state->destdir($self->fullname); 98eef84043Sespie $state->{known}{dirname($name)}{basename($name)} = 1; 99eef84043Sespie if ($self->{symlink}) { 100eef84043Sespie if (!-l $name) { 1010dc934edSespie if (!-e $name) { 1027e83eca3Sespie $state->log("#1 should be a symlink but does not exist", $name); 1030dc934edSespie } else { 1047e83eca3Sespie $state->log("#1 is not a symlink", $name); 1050dc934edSespie } 1069a24c98bSespie return 0; 107eb01027bSespie } else { 108eb01027bSespie if (readlink($name) ne $self->{symlink}) { 1097e83eca3Sespie $state->log("#1 should point to #2 but points to #3 instead", 1107e83eca3Sespie $name, $self->{symlink}, readlink($name)); 1119a24c98bSespie return 0; 112eb01027bSespie } 113eef84043Sespie } 1149a24c98bSespie return 1; 115eef84043Sespie } 1160dc934edSespie if (!-e $name) { 1170dc934edSespie if (-l $name) { 1187e83eca3Sespie $state->log("#1 points to non-existent #2", 1197e83eca3Sespie $name, readlink($name)); 1200dc934edSespie } else { 1217e83eca3Sespie $state->log("#1 should exist", $name); 1220dc934edSespie } 1239a24c98bSespie return 0; 1249a24c98bSespie } elsif (!-f _) { 1257e83eca3Sespie $state->log("#1 is not a file", $name); 1269a24c98bSespie return 0; 127eef84043Sespie } 128eb01027bSespie if ($self->{link}) { 129eb01027bSespie my ($a, $b) = (stat _)[0, 1]; 1300f19ffacSespie if (!-f $state->destdir($self->{link})) { 1317e83eca3Sespie $state->log("#1 should link to non-existent #2", 1327e83eca3Sespie $name, $self->{link}); 1339a24c98bSespie return 0; 134eb01027bSespie } else { 135eb01027bSespie my ($c, $d) = (stat _)[0, 1]; 136eb01027bSespie if (defined $a && defined $c) { 137eb01027bSespie if ($a != $c || $b != $d) { 1387e83eca3Sespie $state->log("#1 doesn't link to #2", 1397e83eca3Sespie $name, $self->{link}); 1409a24c98bSespie return 0; 141eb01027bSespie } 142eb01027bSespie } 1439a24c98bSespie 144eb01027bSespie } 145eb01027bSespie } 1469a24c98bSespie return 1; 147eef84043Sespie} 148eef84043Sespie 149039cbdaaSespiesub thorough_check($self, $state) 150eef84043Sespie{ 1510f19ffacSespie my $name = $state->destdir($self->fullname); 1529a24c98bSespie if (!$self->basic_check($state)) { 1539a24c98bSespie return; 1549a24c98bSespie } 155eef84043Sespie return if $self->{link} or $self->{symlink} or $self->{nochecksum}; 156eef84043Sespie if (!-r $name) { 1577e83eca3Sespie $state->log("can't read #1", $name); 158eef84043Sespie return; 159eef84043Sespie } 16000231fa2Sespie if (!defined $self->{d}) { 16100231fa2Sespie $state->log("no checksum for #1", $name); 16200231fa2Sespie return; 16300231fa2Sespie } 164a5de4416Sespie my $d = $self->compute_digest($name, $self->{d}); 165eef84043Sespie if (!$d->equals($self->{d})) { 1667e83eca3Sespie $state->log("checksum for #1 does not match", $name); 167eef84043Sespie } 168eef84043Sespie} 169eef84043Sespie 170eef84043Sespiepackage OpenBSD::PackingElement::SpecialFile; 171039cbdaaSespiesub basic_check # forwarder 172eef84043Sespie{ 173eef84043Sespie &OpenBSD::PackingElement::FileBase::basic_check; 174eef84043Sespie} 175eef84043Sespie 176039cbdaaSespiesub thorough_check # forwarder 177eef84043Sespie{ 178eef84043Sespie &OpenBSD::PackingElement::FileBase::basic_check; 179eef84043Sespie} 180eef84043Sespie 181eef84043Sespiepackage OpenBSD::PackingElement::DirlikeObject; 182039cbdaaSespiesub basic_check($self, $state) 183eef84043Sespie{ 1840f19ffacSespie my $name = $state->destdir($self->fullname); 185eef84043Sespie $state->{known}{$name} //= {}; 186eef84043Sespie if (!-e $name) { 1877e83eca3Sespie $state->log("#1 should exist", $name); 188eef84043Sespie } 189eef84043Sespie if (!-d _) { 1907e83eca3Sespie $state->log("#1 is not a directory", $name); 191eef84043Sespie } 192eef84043Sespie} 193eef84043Sespie 194a991246fSespiepackage OpenBSD::PackingElement::Sample; 195a991246fSespieuse File::Basename; 196039cbdaaSespiesub basic_check($self, $state) 197a991246fSespie{ 1980f19ffacSespie my $name = $state->destdir($self->fullname); 199a991246fSespie $state->{known}{dirname($name)}{basename($name)} = 1; 2009a24c98bSespie return 1; 201a991246fSespie} 202a991246fSespie 203a991246fSespiepackage OpenBSD::PackingElement::Sampledir; 204039cbdaaSespiesub basic_check($self, $state) 205a991246fSespie{ 2060f19ffacSespie my $name = $state->destdir($self->fullname); 207a991246fSespie $state->{known}{$name} //= {}; 2089a24c98bSespie return 1; 209a991246fSespie} 210a991246fSespie 211eef84043Sespiepackage OpenBSD::PackingElement::Mandir; 212039cbdaaSespiesub basic_check($self, $state) 213eef84043Sespie{ 214eef84043Sespie $self->SUPER::basic_check($state); 2150f19ffacSespie my $name = $state->destdir($self->fullname); 216f723c71dSespie for my $file (OpenBSD::Paths->man_cruft) { 217752d47c3Sespie $state->{known}{$name}{$file} = 1; 218752d47c3Sespie } 2199a24c98bSespie return 1; 220eef84043Sespie} 221eef84043Sespie 222eef84043Sespiepackage OpenBSD::PackingElement::Fontdir; 223039cbdaaSespiesub basic_check($self, $state) 224eef84043Sespie{ 225eef84043Sespie $self->SUPER::basic_check($state); 2260f19ffacSespie my $name = $state->destdir($self->fullname); 227eef84043Sespie for my $i (qw(fonts.alias fonts.scale fonts.dir)) { 228eef84043Sespie $state->{known}{$name}{$i} = 1; 229eef84043Sespie } 2309a24c98bSespie return 1; 231eef84043Sespie} 232eef84043Sespie 233eef84043Sespiepackage OpenBSD::PackingElement::Infodir; 234039cbdaaSespiesub basic_check($self, $state) 235eef84043Sespie{ 236eef84043Sespie $self->SUPER::basic_check($state); 2370f19ffacSespie my $name = $state->destdir($self->fullname); 238eef84043Sespie $state->{known}{$name}{'dir'} = 1; 2399a24c98bSespie return 1; 240eef84043Sespie} 241eef84043Sespie 2424be5dd99Sespiepackage OpenBSD::PackingElement::Depend; 243039cbdaaSespiesub cache_depends($self, $copy) 2444be5dd99Sespie{ 2454be5dd99Sespie $self->add_object($copy); 2464be5dd99Sespie} 2474be5dd99Sespie 248eef84043Sespiepackage OpenBSD::PackingElement::Dependency; 249039cbdaaSespiesub find_dependencies($self, $state, $l, $checker, $pkgname) 250eef84043Sespie{ 251eef84043Sespie # several ways to failure 252eef84043Sespie if (!$self->spec->is_valid) { 253eef84043Sespie $state->log("invalid \@", $self->keyword, " ", 254eef84043Sespie $self->stringize); 255eef84043Sespie return; 256eef84043Sespie } 257eef84043Sespie my @deps = $self->spec->filter(@$l); 258eef84043Sespie if (@deps == 0) { 25902ee83faSespie $state->log("dependency #1 in #2 does not match any installed package", 26002ee83faSespie $self->stringize, $pkgname); 261eef84043Sespie return; 262eef84043Sespie } 263eef84043Sespie my $okay = 0; 264eef84043Sespie for my $i (@deps) { 265bf3472c5Sespie if ($checker->find($i)) { 266eef84043Sespie $okay = 1; 267eef84043Sespie } 268eef84043Sespie } 269eef84043Sespie if (!$okay) { 270bf3472c5Sespie $checker->not_found($deps[0]); 271eef84043Sespie } 272eef84043Sespie} 273eef84043Sespie 27410f87983Sespiepackage OpenBSD::PackingElement::Wantlib; 275039cbdaaSespiesub find_dependencies($self, $state, $l, $checker, $pkgname) 27610f87983Sespie{ 27708eb747cSespie my $r = $state->shlibs->lookup_libspec($state->{localbase}, 27810f87983Sespie $self->spec); 2797e83eca3Sespie if (defined $r && @$r != 0) { 28010f87983Sespie my $okay = 0; 28110f87983Sespie for my $lib (@$r) { 28210f87983Sespie my $i = $lib->origin; 28310f87983Sespie if ($i eq 'system') { 28410f87983Sespie $okay = 1; 2852779f69aSespie $state->{needed_libs}{$lib->to_string} = 1; 28610f87983Sespie next; 28710f87983Sespie } 288bf3472c5Sespie if ($checker->find($i)) { 28910f87983Sespie $okay = 1; 29010f87983Sespie } 29110f87983Sespie } 29210f87983Sespie if (!$okay) { 293bf3472c5Sespie $checker->not_found($r->[0]->origin); 29410f87983Sespie } 29510f87983Sespie } else { 29602ee83faSespie $state->log("#1 in #2 not found", $self->stringize, $pkgname); 29702ee83faSespie } 29802ee83faSespie} 29902ee83faSespie 30002ee83faSespiepackage OpenBSD::PackingElement::Tag; 301039cbdaaSespiesub find_dependencies($self, $state, $l, $checker, $pkgname) 30202ee83faSespie{ 30302ee83faSespie my $location = $state->{tagdefinition}{$self->name}; 30402ee83faSespie if (defined $location) { 30502ee83faSespie if ($location eq $pkgname) { 30602ee83faSespie return; 30702ee83faSespie } 30802ee83faSespie if (!$checker->find($location)) { 30902ee83faSespie $checker->not_found($location); 31002ee83faSespie } 31102ee83faSespie } else { 31202ee83faSespie $state->log("definition for #1 not found", $self->stringize); 31310f87983Sespie } 31410f87983Sespie} 31510f87983Sespie 316039cbdaaSespiesub cache_depends # forwarder 3174be5dd99Sespie{ 3184be5dd99Sespie &OpenBSD::PackingElement::Depend::cache_depends; 3194be5dd99Sespie} 3204be5dd99Sespie 321eef84043Sespiepackage OpenBSD::PkgCheck::State; 322eef84043Sespieour @ISA = qw(OpenBSD::AddCreateDelete::State); 323eef84043Sespie 3240f19ffacSespieuse File::Spec; 3255f05097cSespieuse OpenBSD::Log; 3260f19ffacSespieuse File::Basename; 3275f05097cSespie 328039cbdaaSespiesub init($self) 329eef84043Sespie{ 330f4f6c15cSespie $self->{l} = OpenBSD::Log->new($self); 331eef84043Sespie $self->SUPER::init; 332eef84043Sespie} 333eef84043Sespie 334039cbdaaSespiesub log($self, @p) 335eef84043Sespie{ 336039cbdaaSespie if (@p == 0) { 337eef84043Sespie return $self->{l}; 338eef84043Sespie } else { 339039cbdaaSespie $self->{l}->say(@p); 340eef84043Sespie } 341eef84043Sespie} 342eef84043Sespie 343039cbdaaSespiesub handle_options($self) 34483ad63f0Sespie{ 34583ad63f0Sespie $self->{no_exports} = 1; 34683ad63f0Sespie 3473f0a1a28Sespie $self->add_interactive_options; 3488cd3e493Sespie $self->SUPER::handle_options('fFB:q', 34983181d8dSjmc '[-FfIimnqvx] [-B pkg-destdir] [-D value]'); 35083ad63f0Sespie $self->{force} = $self->opt('f'); 351c3f1c9b4Sespie $self->{quick} = $self->opt('q') // 0; 3528cd3e493Sespie $self->{filesystem} = $self->opt('F'); 35383ad63f0Sespie if (defined $self->opt('B')) { 35483ad63f0Sespie $self->{destdir} = $self->opt('B'); 35583ad63f0Sespie } 35683ad63f0Sespie if (defined $self->{destdir}) { 35783ad63f0Sespie $self->{destdir} .= '/'; 35883ad63f0Sespie } else { 35983ad63f0Sespie $self->{destdir} = ''; 36083ad63f0Sespie } 3610f19ffacSespie} 3620f19ffacSespie 363039cbdaaSespiesub destdir($self, $path) 3640f19ffacSespie{ 3650f19ffacSespie return File::Spec->canonpath($self->{destdir}.$path); 3660f19ffacSespie} 3670f19ffacSespie 368039cbdaaSespiesub process_entry($self, $entry) 3690f19ffacSespie{ 3700f19ffacSespie my $name = $self->destdir($entry); 3710f19ffacSespie $self->{known}{dirname($name)}{basename($name)} = 1; 37283ad63f0Sespie} 37383ad63f0Sespie 374bf3472c5Sespiepackage OpenBSD::DependencyCheck; 375bf3472c5Sespie 376039cbdaaSespiesub new($class, $state, $name, $req) 377bf3472c5Sespie{ 378bf3472c5Sespie my $o = bless { 379bf3472c5Sespie not_yet => {}, 380bf3472c5Sespie possible => {}, 381bf3472c5Sespie others => {}, 382bf3472c5Sespie name => $name, 383bf3472c5Sespie req => $req 384bf3472c5Sespie }, $class; 385bf3472c5Sespie for my $pkg ($req->list) { 386bf3472c5Sespie $o->{not_yet}{$pkg} = 1; 387bf3472c5Sespie if ($state->{exists}{$pkg}) { 388bf3472c5Sespie $o->{possible}{$pkg} = 1; 389bf3472c5Sespie } else { 390549f66e1Sespie $state->errsay("#1: bogus #2", $name, $o->string($pkg)); 391bf3472c5Sespie } 392bf3472c5Sespie } 393bf3472c5Sespie return $o; 394bf3472c5Sespie} 395bf3472c5Sespie 396039cbdaaSespiesub find($self, $name) 397bf3472c5Sespie{ 398bf3472c5Sespie if ($self->{possible}{$name}) { 399bf3472c5Sespie delete $self->{not_yet}{$name}; 400bf3472c5Sespie return 1; 401bf3472c5Sespie } else { 402bf3472c5Sespie return 0; 403bf3472c5Sespie } 404bf3472c5Sespie} 405bf3472c5Sespie 406039cbdaaSespiesub not_found($self, $name) 407bf3472c5Sespie{ 408bf3472c5Sespie $self->{others}{$name} = 1; 409bf3472c5Sespie} 410bf3472c5Sespie 411039cbdaaSespiesub ask_delete_deps($self, $state, $l) 412bf3472c5Sespie{ 413bf3472c5Sespie if ($state->{force}) { 414bf3472c5Sespie $self->{req}->delete(@$l); 415fb75580aSespie } elsif ($state->confirm_defaults_to_no( 416949b3cdfSespie "Remove extra #1", $self->string(@$l))) { 417bf3472c5Sespie $self->{req}->delete(@$l); 418bf3472c5Sespie } 419bf3472c5Sespie} 420bf3472c5Sespie 421039cbdaaSespiesub ask_add_deps($self, $state, $l) 422bf3472c5Sespie{ 423bf3472c5Sespie if ($state->{force}) { 424bf3472c5Sespie $self->{req}->add(@$l); 425fb75580aSespie } elsif ($state->confirm_defaults_to_no( 426fb75580aSespie "Add missing #1", $self->string(@$l))) { 427bf3472c5Sespie $self->{req}->add(@$l); 428bf3472c5Sespie } 429bf3472c5Sespie} 430bf3472c5Sespie 431039cbdaaSespiesub adjust($self, $state) 432bf3472c5Sespie{ 433bf3472c5Sespie if (keys %{$self->{not_yet}} > 0) { 434bf3472c5Sespie my @todo = sort keys %{$self->{not_yet}}; 4357e83eca3Sespie unless ($state->{subst}->value("weed_libs")) { 4367e83eca3Sespie @todo = grep {!/^\.libs/} @todo; 4377e83eca3Sespie } 4387e83eca3Sespie if (@todo != 0) { 4395f4221d5Ssthen $state->errsay("#1 has too many #2", 440549f66e1Sespie $self->{name}, $self->string(@todo)); 441bf3472c5Sespie $self->ask_delete_deps($state, \@todo); 442bf3472c5Sespie } 4437e83eca3Sespie } 444bf3472c5Sespie if (keys %{$self->{others}} > 0) { 445bf3472c5Sespie my @todo = sort keys %{$self->{others}}; 4467e83eca3Sespie $state->errsay("#1 is missing #2", 4477e83eca3Sespie $self->{name}, $self->string(@todo)); 44834134382Sespie if ($self->{name} =~ m/^partial/) { 44934134382Sespie $state->errsay("not a problem, since this is a partial- package"); 45034134382Sespie } else { 451bf3472c5Sespie $self->ask_add_deps($state, \@todo); 452bf3472c5Sespie } 453bf3472c5Sespie } 45434134382Sespie} 455bf3472c5Sespie 456bf3472c5Sespiepackage OpenBSD::DirectDependencyCheck; 457bf3472c5Sespieour @ISA = qw(OpenBSD::DependencyCheck); 458bf3472c5Sespieuse OpenBSD::RequiredBy; 459039cbdaaSespiesub string($self, @p) 460bf3472c5Sespie{ 461039cbdaaSespie return "dependencies: ". join(' ', @p); 462bf3472c5Sespie} 463bf3472c5Sespie 464039cbdaaSespiesub new($class, $state, $name) 465bf3472c5Sespie{ 466bf3472c5Sespie return $class->SUPER::new($state, $name, 467bf3472c5Sespie OpenBSD::Requiring->new($name)); 468bf3472c5Sespie} 469bf3472c5Sespie 470bf3472c5Sespiepackage OpenBSD::ReverseDependencyCheck; 471bf3472c5Sespieour @ISA = qw(OpenBSD::DependencyCheck); 472bf3472c5Sespieuse OpenBSD::RequiredBy; 473039cbdaaSespiesub string($self, @p) 474bf3472c5Sespie{ 475039cbdaaSespie return "reverse dependencies: ". join(' ', @p); 476bf3472c5Sespie} 477bf3472c5Sespie 478039cbdaaSespiesub new($class, $state, $name) 479bf3472c5Sespie{ 480bf3472c5Sespie return $class->SUPER::new($state, $name, 481bf3472c5Sespie OpenBSD::RequiredBy->new($name)); 482bf3472c5Sespie} 483bf3472c5Sespie 484bd2f84f9Sespiepackage OpenBSD::Pkglocate; 485039cbdaaSespiesub new($class, $state) 486556a8905Sespie{ 487e0cbfadbSespie bless {state => $state, result => {unknown => []}, 488e0cbfadbSespie params => []}, $class; 489556a8905Sespie} 490556a8905Sespie 491039cbdaaSespiesub add_param($self, @p) 492556a8905Sespie{ 493556a8905Sespie push(@{$self->{params}}, @p); 494bd2f84f9Sespie while (@{$self->{params}} > 200) { 495556a8905Sespie $self->run_command; 496556a8905Sespie } 497556a8905Sespie} 498556a8905Sespie 499039cbdaaSespiesub run_command($self) 500556a8905Sespie{ 501556a8905Sespie if (@{$self->{params}} == 0) { 502556a8905Sespie return; 503556a8905Sespie } 504556a8905Sespie my %h = map {($_, 1)} @{$self->{params}}; 505bd2f84f9Sespie open(my $cmd, '-|', 'pkg_locate', map {"*:$_"} @{$self->{params}}); 506556a8905Sespie while (<$cmd>) { 507556a8905Sespie chomp; 508bd2f84f9Sespie my ($pkgname, $pkgpath, $path) = split(':', $_, 3); 509e0cbfadbSespie 510556a8905Sespie # pkglocate will return false positives, so trim them 511556a8905Sespie if ($h{$path}) { 512bd2f84f9Sespie push(@{$self->{result}{"$pkgname:$pkgpath"} }, $path); 513556a8905Sespie delete $h{$path}; 514556a8905Sespie } 515556a8905Sespie } 516556a8905Sespie close($cmd); 517556a8905Sespie for my $k (keys %h) { 518556a8905Sespie push(@{$self->{result}{unknown}}, $k); 519556a8905Sespie } 520556a8905Sespie 521556a8905Sespie $self->{params} = []; 522556a8905Sespie} 523556a8905Sespie 524*7068cea4Sespiesub show_results($self) 525556a8905Sespie{ 526556a8905Sespie while (@{$self->{params}} > 0) { 527556a8905Sespie $self->run_command; 528556a8905Sespie } 529556a8905Sespie my $state = $self->{state}; 530556a8905Sespie my $r = $self->{result}; 531556a8905Sespie my $u = $r->{unknown}; 532556a8905Sespie delete $r->{unknown}; 53347e4d683Sespie 53447e4d683Sespie $state->say("Not found:"); 53547e4d683Sespie for my $e (sort @$u) { 53647e4d683Sespie $state->say("\t#1", $e); 53747e4d683Sespie } 53847e4d683Sespie 539556a8905Sespie for my $k (sort keys %{$r}) { 540556a8905Sespie $state->say("In #1:", $k); 541556a8905Sespie for my $e (sort @{$r->{$k}}) { 542556a8905Sespie $state->say("\t#1", $e); 543556a8905Sespie } 544556a8905Sespie } 545556a8905Sespie} 546556a8905Sespie 547eef84043Sespiepackage OpenBSD::PkgCheck; 548eef84043Sespieour @ISA = qw(OpenBSD::AddCreateDelete); 549eef84043Sespie 550eef84043Sespieuse OpenBSD::PackageInfo; 551eef84043Sespieuse OpenBSD::PackingList; 552eef84043Sespieuse File::Find; 553eef84043Sespieuse OpenBSD::Paths; 554eef84043Sespieuse OpenBSD::Mtree; 555eef84043Sespie 556039cbdaaSespiesub fill_base_system($self, $state) 557bd2f84f9Sespie{ 558bd2f84f9Sespie open(my $cmd, '-|', 'locate', 55961d49fb8Sespie '-d', OpenBSD::Paths->srclocatedb, 56061d49fb8Sespie '-d', OpenBSD::Paths->xlocatedb, ':'); 561bd2f84f9Sespie while (<$cmd>) { 562bd2f84f9Sespie chomp; 563bd2f84f9Sespie my ($set, $path) = split(':', $_, 2); 564bd2f84f9Sespie $state->{basesystem}{$path} = 1; 565bd2f84f9Sespie } 566bd2f84f9Sespie close($cmd); 567bd2f84f9Sespie} 568bd2f84f9Sespie 569039cbdaaSespiesub remove($self, $state, $name) 570eef84043Sespie{ 571eef84043Sespie $state->{removed}{$name} = 1; 572eef84043Sespie my $dir = installed_info($name); 573eef84043Sespie for my $i (@OpenBSD::PackageInfo::info) { 574eef84043Sespie if (-e $dir.$i) { 575eef84043Sespie if ($state->verbose) { 576549f66e1Sespie $state->say("unlink(#1)", $dir.$i); 577eef84043Sespie } 578eef84043Sespie unless ($state->{not}) { 579eef84043Sespie unlink($dir.$i) or 5807e83eca3Sespie $state->errsay("#1: Couldn't delete #2: #3", 581549f66e1Sespie $name, $dir.$i, $!); 582eef84043Sespie } 583eef84043Sespie } 584eef84043Sespie } 585eef84043Sespie if (-f $dir) { 586eef84043Sespie if ($state->verbose) { 587549f66e1Sespie $state->say("unlink(#1)", $dir); 588eef84043Sespie } 589eef84043Sespie unless ($state->{not}) { 590eef84043Sespie unlink($dir) or 5917e83eca3Sespie $state->errsay("#1: Couldn't delete #2: #3", 592549f66e1Sespie $name, $dir, $!); 593eef84043Sespie } 594eef84043Sespie } elsif (-d $dir) { 595eef84043Sespie if ($state->verbose) { 596549f66e1Sespie $state->say("rmdir(#1)", $dir); 597eef84043Sespie } 598eef84043Sespie unless ($state->{not}) { 599eef84043Sespie rmdir($dir) or 6007e83eca3Sespie $state->errsay("#1: Couldn't delete #2: #3", 601549f66e1Sespie $name, $dir, $!); 602eef84043Sespie } 603eef84043Sespie } 604eef84043Sespie} 605eef84043Sespie 606039cbdaaSespiesub may_remove($self, $state, $name) 607eef84043Sespie{ 608eef84043Sespie if ($state->{force}) { 609eef84043Sespie $self->remove($state, $name); 610fb75580aSespie } elsif ($state->confirm_defaults_to_no( 611fb75580aSespie "Remove wrong package #1", $name)) { 612eef84043Sespie $self->remove($state, $name); 613eef84043Sespie } 61457231a67Sespie $state->{bogus}{$name} = 1; 615eef84043Sespie} 616eef84043Sespie 617039cbdaaSespiesub may_unlink($self, $state, $path) 6188734ed95Sespie{ 6198734ed95Sespie if (!$state->{force} && 620fb75580aSespie !$state->confirm_defaults_to_no("Remove #1", $path)) { 6218734ed95Sespie return; 6228734ed95Sespie } 6238734ed95Sespie if ($state->verbose) { 624549f66e1Sespie $state->say("remove #1", $path); 6258734ed95Sespie } 6268734ed95Sespie return if $state->{not}; 627549f66e1Sespie unlink($path) or rmdir($path) or 628549f66e1Sespie $state->errsay("Couldn't delete #1: #2", $path, $!); 6298734ed95Sespie} 6308734ed95Sespie 631039cbdaaSespiesub may_fix_ownership($self, $state, $path) 632ebe8b9f1Sespie{ 633ebe8b9f1Sespie if (!$state->{force} && 634fb75580aSespie !$state->confirm_defaults_to_no("Give #1 to root:wheel", $path)) { 635ebe8b9f1Sespie return; 636ebe8b9f1Sespie } 637ebe8b9f1Sespie if ($state->verbose) { 638549f66e1Sespie $state->say("chown root:wheel #1", $path); 639ebe8b9f1Sespie } 640ebe8b9f1Sespie return if $state->{not}; 641ebe8b9f1Sespie chown 0, 0, $path or 642549f66e1Sespie $state->errsay("Couldn't fix ownership for #1: #2", $path, $!); 643ebe8b9f1Sespie} 644ebe8b9f1Sespie 645039cbdaaSespiesub may_fix_perms($self, $state, $path, $perm, $readable) 6468734ed95Sespie{ 6478734ed95Sespie if (!$state->{force} && 648fb75580aSespie !$state->confirm_defaults_to_no("Make #1 #2", $path, 649ebe8b9f1Sespie ($readable ? "not world/group-writable" : "world readable"))) { 6508734ed95Sespie return; 6518734ed95Sespie } 6528734ed95Sespie if ($state->verbose) { 653549f66e1Sespie $state->say("chmod #1 #2", sprintf("%04o", $perm), $path); 6548734ed95Sespie } 6558734ed95Sespie return if $state->{not}; 6568734ed95Sespie chmod $perm, $path or 657549f66e1Sespie $state->errsay("Couldn't fix perms for #1: #2", $path, $!); 6588734ed95Sespie} 6598734ed95Sespie 660039cbdaaSespiesub for_all_packages($self, $state, $l, $msg, $code) 6610dc934edSespie{ 662f4f6c15cSespie $state->progress->for_list($msg, $l, 663039cbdaaSespie sub($name) { 664039cbdaaSespie return if $state->{removed}{$name}; 665039cbdaaSespie if ($state->{bogus}{$name}) { 666039cbdaaSespie $state->errsay("skipping #1", $name); 66757231a67Sespie return; 66857231a67Sespie } 669039cbdaaSespie &$code($name); 670f4f6c15cSespie }); 6710dc934edSespie} 6720dc934edSespie 673039cbdaaSespiesub check_dir_permissions($self, $state, $dir) 6748734ed95Sespie{ 675ebe8b9f1Sespie my ($perm, $uid, $gid) = (stat $dir)[2, 4, 5]; 676ebe8b9f1Sespie $perm &= 0777; 6778734ed95Sespie 6788734ed95Sespie if (($perm & 0555) != 0555) { 679549f66e1Sespie $state->errsay("Directory #1 is not world-readable", $dir); 680ebe8b9f1Sespie $perm |= 0555; 681ebe8b9f1Sespie $self->may_fix_perms($state, $dir, $perm, 0); 6828734ed95Sespie } 683ebe8b9f1Sespie if ($uid != 0 || $gid != 0) { 684ebe8b9f1Sespie $state->errsay("Directory #1 does not belong to root:wheel", 685549f66e1Sespie $dir); 686ebe8b9f1Sespie $self->may_fix_ownership($state, $dir); 687ebe8b9f1Sespie } 688ebe8b9f1Sespie if (($perm & 0022) != 0) { 689549f66e1Sespie $state->errsay("Directory #1 is world/group writable", $dir); 690ebe8b9f1Sespie $perm &= 0755; 691ebe8b9f1Sespie $self->may_fix_perms($state, $dir, $perm, 1); 692ebe8b9f1Sespie } 693ebe8b9f1Sespie} 694ebe8b9f1Sespie 695039cbdaaSespiesub check_permissions($self, $state, $dir) 696ebe8b9f1Sespie{ 697ebe8b9f1Sespie $self->check_dir_permissions($state, $dir); 698549f66e1Sespie opendir(my $d, $dir) or return; 699549f66e1Sespie for my $name (readdir $d) { 700549f66e1Sespie next if $name eq '.' or $name eq '..'; 701ebe8b9f1Sespie my $file = $dir.$name; 702549f66e1Sespie if (!grep {$_ eq $name} (@OpenBSD::PackageInfo::info)) { 703549f66e1Sespie $state->errsay("Weird filename in pkg db: #1", 704549f66e1Sespie $file); 705549f66e1Sespie $self->may_unlink($state, $file); 706549f66e1Sespie next; 707549f66e1Sespie } 708ebe8b9f1Sespie my ($perm, $uid, $gid) = (stat $file)[2, 4, 5]; 7098734ed95Sespie if (!-f $file) { 710549f66e1Sespie $state->errsay("#1 should be a file", $file); 7118734ed95Sespie $self->may_unlink($state, $file); 712ebe8b9f1Sespie next; 713ebe8b9f1Sespie } 714ebe8b9f1Sespie $perm &= 0777; 715ebe8b9f1Sespie if (($perm & 0444) != 0444) { 716549f66e1Sespie $state->errsay("File #1 is not world-readable", $file); 717ebe8b9f1Sespie $perm |= 0444; 718ebe8b9f1Sespie $self->may_fix_perms($state, $file, $perm, 0); 7198734ed95Sespie } 720ebe8b9f1Sespie if ($uid != 0 || $gid != 0) { 721ebe8b9f1Sespie $state->errsay("File #1 does not belong to root:wheel", 722549f66e1Sespie $file); 723ebe8b9f1Sespie $self->may_fix_ownership($state, $file); 724ebe8b9f1Sespie } 725ebe8b9f1Sespie if (($perm & 0022) != 0) { 726ebe8b9f1Sespie $state->errsay("File #1 is world/group writable", 727549f66e1Sespie $file); 728ebe8b9f1Sespie $perm &= 0755; 729ebe8b9f1Sespie $self->may_fix_perms($state, $file, $perm, 1); 730ebe8b9f1Sespie } 7318734ed95Sespie } 732549f66e1Sespie closedir($d); 7338734ed95Sespie} 7348734ed95Sespie 7358734ed95Sespie 736039cbdaaSespiesub sanity_check($self, $state, $l) 737eef84043Sespie{ 7388734ed95Sespie # let's find /var/db/pkg or its equivalent 7398734ed95Sespie my $base = installed_info(""); 7408734ed95Sespie $base =~ s,/*$,,; 741ebe8b9f1Sespie $self->check_dir_permissions($state, $base); 7428734ed95Sespie 743039cbdaaSespie $self->for_all_packages($state, $l, "Packing-list sanity", sub($name) { 744549f66e1Sespie if ($name ne $state->safe($name)) { 745549f66e1Sespie $state->errsay("#1: bogus pkgname", $name); 746549f66e1Sespie $self->may_remove($state, $name); 747549f66e1Sespie return; 748549f66e1Sespie } 749eef84043Sespie my $info = installed_info($name); 750eef84043Sespie if (-f $info) { 75123bb920cSespie $state->errsay("#1: #2 should be a directory", 752549f66e1Sespie $name, $info); 753eef84043Sespie if ($info =~ m/\.core$/) { 7547e83eca3Sespie $state->errsay("looks like a core dump, ". 755eef84043Sespie "removing"); 756eef84043Sespie $self->remove($state, $name); 757eef84043Sespie } else { 758eef84043Sespie $self->may_remove($state, $name); 759eef84043Sespie } 760a1f569a1Sespie return; 761eef84043Sespie } 7628734ed95Sespie $self->check_permissions($state, $info); 763eef84043Sespie my $contents = $info.OpenBSD::PackageInfo::CONTENTS; 764eef84043Sespie unless (-f $contents) { 765549f66e1Sespie $state->errsay("#1: missing #2", $name, $contents); 766eef84043Sespie $self->may_remove($state, $name); 767a1f569a1Sespie return; 768eef84043Sespie } 769eef84043Sespie my $plist; 770eef84043Sespie eval { 771eef84043Sespie $plist = OpenBSD::PackingList->fromfile($contents); 772eef84043Sespie }; 773ff2f6eceSespie if ($@ || !defined $plist) { 774549f66e1Sespie $state->errsay("#1: bad packing-list", $name); 7759873b3f8Sespie if ($@) { 776549f66e1Sespie $state->errsay("#1", $@); 7779873b3f8Sespie } 778eef84043Sespie $self->may_remove($state, $name); 779a1f569a1Sespie return; 780eef84043Sespie } 78178bb2478Sespie if (!defined $plist->pkgname) { 782549f66e1Sespie $state->errsay("#1: no pkgname in plist", $name); 78378bb2478Sespie $self->may_remove($state, $name); 78478bb2478Sespie return; 78578bb2478Sespie } 786eef84043Sespie if ($plist->pkgname ne $name) { 787549f66e1Sespie $state->errsay("#1: pkgname does not match", $name); 788eef84043Sespie $self->may_remove($state, $name); 789eef84043Sespie } 79002ee83faSespie $plist->mark_indirect_depends($plist->pkgname, $state); 7914be5dd99Sespie my $p = OpenBSD::PackingList->new; 7924be5dd99Sespie $plist->cache_depends($p); 7934be5dd99Sespie $state->{plist_cache}{$plist->pkgname} = $p; 7940dc934edSespie $state->{exists}{$plist->pkgname} = 1; 7950dc934edSespie }); 796eef84043Sespie} 797eef84043Sespie 798039cbdaaSespiesub dependencies_check($self, $state, $l) 799eef84043Sespie{ 80008eb747cSespie $state->shlibs->add_libs_from_system($state->{destdir}); 801039cbdaaSespie $self->for_all_packages($state, $l, "Direct dependencies", sub($name) { 8022779f69aSespie $state->log->set_context($name); 8034be5dd99Sespie my $plist = $state->{plist_cache}{$name}; 804bf3472c5Sespie my $checker = OpenBSD::DirectDependencyCheck->new($state, 805bf3472c5Sespie $name); 80610f87983Sespie $state->{localbase} = $plist->localbase; 80702ee83faSespie $plist->find_dependencies($state, $l, $checker, $name); 808bf3472c5Sespie $checker->adjust($state); 809bf3472c5Sespie for my $dep ($checker->{req}->list) { 81079cf49beSespie push(@{$state->{reverse}{$dep}}, $name); 81179cf49beSespie } 81279cf49beSespie }); 8134be5dd99Sespie delete $state->{plist_cache}; 81479cf49beSespie} 81579cf49beSespie 816039cbdaaSespiesub reverse_dependencies_check($self, $state, $l) 81779cf49beSespie{ 818039cbdaaSespie $self->for_all_packages($state, $l, "Reverse dependencies", sub($name) { 819bf3472c5Sespie my $checker = OpenBSD::ReverseDependencyCheck->new($state, 820bf3472c5Sespie $name); 82179cf49beSespie for my $i (@{$state->{reverse}{$name}}) { 822bf3472c5Sespie $checker->find($i) or $checker->not_found($i); 82379cf49beSespie } 824bf3472c5Sespie $checker->adjust($state); 8250dc934edSespie }); 826eef84043Sespie} 827eef84043Sespie 828039cbdaaSespiesub package_files_check($self, $state, $l) 829eef84043Sespie{ 830039cbdaaSespie $self->for_all_packages($state, $l, "Files from packages", sub($name) { 831eef84043Sespie my $plist = OpenBSD::PackingList->from_installation($name); 832eef84043Sespie $state->log->set_context($name); 833eef84043Sespie if ($state->{quick}) { 834eef84043Sespie $plist->basic_check($state); 835eef84043Sespie } else { 836eef84043Sespie $plist->thorough_check($state); 837eef84043Sespie } 83808eb747cSespie $plist->mark_available_lib($plist->pkgname, $state->shlibs); 8390dc934edSespie }); 840eef84043Sespie} 841eef84043Sespie 842039cbdaaSespiesub install_pkglocate($self, $state) 843556a8905Sespie{ 844bd2f84f9Sespie my $spec = 'pkglocatedb->=1.1'; 845c5ec2d87Sespie 846c5ec2d87Sespie my @l = installed_stems()->find('pkglocatedb'); 8476a9c80c4Sespie require OpenBSD::PkgSpec; 848c5ec2d87Sespie if (OpenBSD::PkgSpec->new($spec)->match_ref(\@l)) { 849556a8905Sespie return 1; 850556a8905Sespie } 851fb75580aSespie unless ($state->confirm_defaults_to_no("Unknown file system entries.\n". 852c5ec2d87Sespie "Do you want to install $spec to look them up")) { 853556a8905Sespie return 0; 854556a8905Sespie } 855556a8905Sespie 856556a8905Sespie require OpenBSD::PkgAdd; 857556a8905Sespie 858556a8905Sespie $state->{installer} //= Installer->new($state); 859c5ec2d87Sespie if ($state->{installer}->install('pkglocatedb--')) { 860556a8905Sespie return 1; 861556a8905Sespie } else { 862c5ec2d87Sespie $state->errsay("Couldn't install #1", $spec); 863556a8905Sespie return 0; 864556a8905Sespie } 865556a8905Sespie} 866556a8905Sespie 867556a8905Sespie# non fancy display of unknown objects 868039cbdaaSespiesub display_unknown($self, $state) 869556a8905Sespie{ 870556a8905Sespie if (defined $state->{unknown}{file}) { 871556a8905Sespie $state->say("Unknown files:"); 872556a8905Sespie for my $e (sort @{$state->{unknown}{file}}) { 873556a8905Sespie $state->say("\t#1", $e); 874556a8905Sespie } 875556a8905Sespie } 876556a8905Sespie if (defined $state->{unknown}{dir}) { 877556a8905Sespie $state->say("Unknown directories:"); 878556a8905Sespie for my $e (sort {$b cmp $a } @{$state->{unknown}{dir}}) { 879556a8905Sespie $state->say("\t#1", $e); 880556a8905Sespie } 881556a8905Sespie } 882556a8905Sespie} 883556a8905Sespie 884039cbdaaSespiesub display_tmps($self, $state) 885ebff90d8Sespie{ 886ebff90d8Sespie $state->say("Unregistered temporary files:"); 887ebff90d8Sespie for my $e (sort @{$state->{tmps}}) { 888ebff90d8Sespie $state->say("\t#1", $e); 889ebff90d8Sespie } 890ebff90d8Sespie if ($state->{force}) { 891ebff90d8Sespie unlink(@{$state->{tmps}}); 892fb75580aSespie } elsif ($state->confirm_defaults_to_no("Remove")) { 893ebff90d8Sespie unlink(@{$state->{tmps}}); 894ebff90d8Sespie } 895ebff90d8Sespie} 896ebff90d8Sespie 897039cbdaaSespiesub display_unregs($self, $state) 8982779f69aSespie{ 8992779f69aSespie $state->say("System libs NOT in locate dbs:"); 9002779f69aSespie for my $e (sort @{$state->{unreg_libs}}) { 9012779f69aSespie $state->say("\t#1", $e); 9022779f69aSespie } 9032779f69aSespie} 9042779f69aSespie 905039cbdaaSespiesub locate_unknown($self, $state) 906556a8905Sespie{ 907bd2f84f9Sespie my $locator = OpenBSD::Pkglocate->new($state); 908556a8905Sespie if (defined $state->{unknown}{file}) { 909556a8905Sespie $state->progress->for_list("Locating unknown files", 910556a8905Sespie $state->{unknown}{file}, 911039cbdaaSespie sub($p) { 912039cbdaaSespie $locator->add_param($p); 913556a8905Sespie }); 914556a8905Sespie } 915556a8905Sespie if (defined $state->{unknown}{dir}) { 916556a8905Sespie $state->progress->for_list("Locating unknown directories", 917556a8905Sespie $state->{unknown}{dir}, 918039cbdaaSespie sub($p) { 919039cbdaaSespie $locator->add_param($p); 920556a8905Sespie }); 921556a8905Sespie } 922*7068cea4Sespie $locator->show_results; 923556a8905Sespie} 924556a8905Sespie 925039cbdaaSespiesub fill_localbase($self, $state, $base) 926eef84043Sespie{ 927f723c71dSespie for my $file (OpenBSD::Paths->man_cruft) { 928752d47c3Sespie $state->{known}{$base."/man"}{$file} = 1; 929752d47c3Sespie } 930eb01027bSespie $state->{known}{$base."/info"}{'dir'} = 1; 931eb01027bSespie $state->{known}{$base."/lib/X11"}{'app-defaults'} = 1; 932eb01027bSespie $state->{known}{$base."/libdata"} = {}; 933eb01027bSespie $state->{known}{$base."/libdata/perl5"} = {}; 9340f19ffacSespie} 9350f19ffacSespie 936039cbdaaSespiesub fill_root($self, $state, $root) 9370f19ffacSespie{ 9380f19ffacSespie OpenBSD::Mtree::parse($state->{known}, $root, 9390f19ffacSespie '/etc/mtree/4.4BSD.dist', 1); 9400f19ffacSespie OpenBSD::Mtree::parse($state->{known}, $root, 9410f19ffacSespie '/etc/mtree/BSD.x11.dist', 1); 9420f19ffacSespie} 9430f19ffacSespie 944039cbdaaSespiesub filesystem_check($self, $state) 9450f19ffacSespie{ 9460f19ffacSespie $state->{known} //= {}; 947e0cbfadbSespie $self->fill_localbase($state, 948e0cbfadbSespie $state->destdir(OpenBSD::Paths->localbase)); 949e0cbfadbSespie my $root = $state->{destdir} || '/'; 9500f19ffacSespie $self->fill_root($state, $root); 951bd2f84f9Sespie $self->fill_base_system($state); 9520f19ffacSespie 953556a8905Sespie $state->progress->set_header("Checking file system"); 954039cbdaaSespie find(sub() { 955eef84043Sespie $state->progress->working(1024); 95661d49fb8Sespie if (-d $_) { 95761d49fb8Sespie for my $i ('/dev', '/home', OpenBSD::Paths->pkgdb, '/var/log', '/var/backups', '/var/cron', '/var/run', '/tmp', '/var/tmp') { 95861d49fb8Sespie if ($File::Find::name eq $state->destdir($i)) { 95961d49fb8Sespie $File::Find::prune = 1; 96061d49fb8Sespie } 96161d49fb8Sespie } 96261d49fb8Sespie } 963bd2f84f9Sespie if (defined $state->{basesystem}{$File::Find::name}) { 964bd2f84f9Sespie delete $state->{basesystem}{$File::Find::name}; 965bd2f84f9Sespie return; 966bd2f84f9Sespie } 9672779f69aSespie if (defined $state->{needed_libs}{$File::Find::name}) { 9682779f69aSespie push(@{$state->{unreg_libs}}, $File::Find::name); 9692779f69aSespie return; 9702779f69aSespie } 971eef84043Sespie if (-d $_) { 9720f19ffacSespie if ($_ eq "lost+found") { 973087e0674Sespie $state->say("fsck(8) info found: #1", 974087e0674Sespie $File::Find::name); 975087e0674Sespie $File::Find::prune = 1; 976087e0674Sespie return; 977087e0674Sespie } 9780f19ffacSespie # some directories we've got to ignore 9796af91da1Sespie if (! -r -x _) { 9806af91da1Sespie $File::Find::prune = 1; 9816af91da1Sespie $state->errsay("can't enter #1", 9826af91da1Sespie $File::Find::name); 9836af91da1Sespie } 984eef84043Sespie return if defined $state->{known}{$File::Find::name}; 985eb01027bSespie if (-l $_) { 986eef84043Sespie return if $state->{known}{$File::Find::dir}{$_}; 987eef84043Sespie } 988556a8905Sespie push(@{$state->{unknown}{dir}}, $File::Find::name); 9890f19ffacSespie $File::Find::prune = 1; 990eb01027bSespie } else { 991eb01027bSespie return if $state->{known}{$File::Find::dir}{$_}; 992ebff90d8Sespie if (m/^pkg\..{10}$/) { 993ebff90d8Sespie push(@{$state->{tmps}}, $File::Find::name); 994ebff90d8Sespie } else { 995ebff90d8Sespie push(@{$state->{unknown}{file}}, 996ebff90d8Sespie $File::Find::name); 997ebff90d8Sespie } 998eb01027bSespie } 9990f19ffacSespie }, $root); 1000ebff90d8Sespie if (defined $state->{tmps}) { 1001ebff90d8Sespie $self->display_tmps($state); 1002ebff90d8Sespie } 10032779f69aSespie if (defined $state->{unreg_libs}) { 10042779f69aSespie $self->display_unregs($state); 10052779f69aSespie } 1006556a8905Sespie if (defined $state->{unknown}) { 1007556a8905Sespie if ($self->install_pkglocate($state)) { 1008bd2f84f9Sespie $self->locate_unknown($state); 1009556a8905Sespie } else { 1010bd2f84f9Sespie $self->display_unknown($state); 1011556a8905Sespie } 1012556a8905Sespie } 1013eef84043Sespie} 1014eef84043Sespie 1015039cbdaaSespiesub run($self, $state) 1016eef84043Sespie{ 10176e815952Sespie my $list = [installed_packages()]; 10186e815952Sespie 10196e815952Sespie my $list2; 10206e815952Sespie if (@ARGV != 0) { 10216e815952Sespie $list2 = \@ARGV; 10226e815952Sespie } else { 10236e815952Sespie $list2 = $list; 10246e815952Sespie } 10256e815952Sespie $self->sanity_check($state, $list); 10266e815952Sespie $self->dependencies_check($state, $list); 102710f87983Sespie $state->log->dump; 10286e815952Sespie $self->reverse_dependencies_check($state, $list); 102979cf49beSespie $state->log->dump; 10308cd3e493Sespie if ($state->{quick} < 2) { 10316e815952Sespie $self->package_files_check($state, $list2); 1032eef84043Sespie $state->log->dump; 10338cd3e493Sespie } 10348cd3e493Sespie if ($state->{filesystem}) { 103561d49fb8Sespie $self->filesystem_check($state); 1036eb01027bSespie $state->progress->next; 1037eef84043Sespie } 10388cd3e493Sespie} 1039eef84043Sespie 1040039cbdaaSespiesub parse_and_run($self, $cmd) 1041eef84043Sespie{ 10427e83eca3Sespie my $state = OpenBSD::PkgCheck::State->new($cmd); 104383ad63f0Sespie $state->handle_options; 10448d5333baSespie lock_db(0, $state) unless $state->{subst}->value('nolock'); 1045eef84043Sespie $self->run($state); 1046138429bfSespie return 0; 1047eef84043Sespie} 1048eef84043Sespie 1049eef84043Sespie1; 1050