1# ex:ts=8 sw=4: 2# $OpenBSD: SharedLibs.pm,v 1.62 2023/06/13 09:07:17 espie Exp $ 3# 4# Copyright (c) 2003-2010 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 20use OpenBSD::Paths; 21use OpenBSD::LibSpec; 22 23package OpenBSD::PackingElement; 24 25sub mark_available_lib($, $, $) 26{ 27} 28 29package OpenBSD::PackingElement::Lib; 30 31sub mark_available_lib($self, $pkgname, $object) 32{ 33 $object->register_libname($self->fullname, $pkgname); 34} 35 36package OpenBSD::SharedLibs; 37use File::Basename; 38use OpenBSD::Error; 39 40sub _basestate($) 41{ 42 require OpenBSD::Basestate; 43 return 'OpenBSD::BaseState'; 44} 45 46sub new($class, $state = $class->_basestate) 47{ 48 bless { 49 state => $state, 50 repo => OpenBSD::LibRepo->new, 51 printed => {}, 52 done_plist => {}, 53 done_system => 0 54 }, $class; 55} 56 57sub register_library($self, $lib, $pkgname) 58{ 59 $self->{repo}->register($lib, $pkgname); 60} 61 62sub register_libname($self, $name, $pkgname) 63{ 64 my $lib = OpenBSD::Library->from_string($name); 65 if ($lib->is_valid) { 66 $self->register_library($lib, $pkgname); 67 } else { 68 $self->{state}->errsay("Bogus library in #1: #2", $pkgname, 69 $name) unless $pkgname eq 'system'; 70 } 71 72} 73 74sub find_best($self, $stem) 75{ 76 return $self->{repo}->find_best($stem); 77} 78 79sub system_dirs($) 80{ 81 return OpenBSD::Paths->library_dirs; 82} 83 84sub add_libs_from_system($self, $destdir) 85{ 86 return if $self->{done_system}; 87 $self->{done_system} = 1; 88 for my $dirname ($self->system_dirs) { 89 opendir(my $dir, $destdir.$dirname."/lib") or next; 90 while (my $d = readdir($dir)) { 91 next unless $d =~ m/\.so/; 92 $self->register_libname("$dirname/lib/$d", 'system'); 93 } 94 closedir($dir); 95 } 96} 97 98sub add_libs_from_installed_package($self, $pkgname) 99{ 100 return if $self->{done_plist}{$pkgname}; 101 $self->{done_plist}{$pkgname} = 1; 102 my $plist = OpenBSD::PackingList->from_installation($pkgname, 103 \&OpenBSD::PackingList::LibraryOnly); 104 return if !defined $plist; 105 106 $plist->mark_available_lib($pkgname, $self); 107} 108 109sub add_libs_from_plist($self, $plist) 110{ 111 my $pkgname = $plist->pkgname; 112 return if $self->{done_plist}{$pkgname}; 113 $self->{done_plist}{$pkgname} = 1; 114 $plist->mark_available_lib($pkgname, $self); 115} 116 117sub lookup_libspec($self, $base, $spec) 118{ 119 return $spec->lookup($self->{repo}, $base); 120} 121 122 123sub report_problem($self, $spec) 124{ 125 my $name = $spec->to_string; 126 my $state = $self->{state}; 127 my $base = $state->{localbase}; 128 my $approx = $spec->lookup_stem($self->{repo}); 129 my $printed = $self->{printed}; 130 131 my $r = ""; 132 if (!$spec->is_valid) { 133 $r = "| bad library specification\n"; 134 } elsif (!defined $approx) { 135 $r = "| not found anywhere\n"; 136 } else { 137 for my $bad (sort {$a->compare($b)} @$approx) { 138 my $ouch = $spec->no_match($bad, $base); 139 $ouch //= "not reachable"; 140 $r .= "| ".$bad->to_string." (".$bad->origin."): ". 141 $ouch."\n"; 142 } 143 } 144 if (!defined $printed->{$name} || $printed->{$name} ne $r) { 145 $printed->{$name} = $r; 146 $state->errsay("|library #1 not found", $name); 147 $state->print("#1", $r); 148 } 149} 150 1511; 152