xref: /openbsd/usr.sbin/pkg_add/OpenBSD/Handle.pm (revision 039cbdaa)
1e626734bSespie# ex:ts=8 sw=4:
2*039cbdaaSespie# $OpenBSD: Handle.pm,v 1.44 2023/06/13 09:07:17 espie Exp $
3e626734bSespie#
4e626734bSespie# Copyright (c) 2007-2009 Marc Espie <espie@openbsd.org>
5e626734bSespie#
6e626734bSespie# Permission to use, copy, modify, and distribute this software for any
7e626734bSespie# purpose with or without fee is hereby granted, provided that the above
8e626734bSespie# copyright notice and this permission notice appear in all copies.
9e626734bSespie#
10e626734bSespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11e626734bSespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12e626734bSespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13e626734bSespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14e626734bSespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15e626734bSespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16e626734bSespie# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17e626734bSespie
18e626734bSespie# fairly non-descriptive name. Used to store various package information
19e626734bSespie# during installs and updates.
200fbefeddSespie
21*039cbdaaSespieuse v5.36;
220fbefeddSespie
23e626734bSespiepackage OpenBSD::Handle;
24e626734bSespie
25e626734bSespieuse OpenBSD::PackageInfo;
26357f3812Sespieuse OpenBSD::Error;
27e626734bSespie
28e626734bSespieuse constant {
29e626734bSespie	BAD_PACKAGE => 1,
30e626734bSespie	CANT_INSTALL => 2,
31e626734bSespie	ALREADY_INSTALLED => 3,
32681090d4Sespie	NOT_FOUND => 4,
33681090d4Sespie	CANT_DELETE => 5,
34e626734bSespie};
35e626734bSespie
36*039cbdaaSespiesub is_real($) { return 1; }
3741d1a3fdSespie
38*039cbdaaSespiesub cleanup($self, $error = undef, $errorinfo = undef)
39063ed140Sespie{
404d9a1ca7Sespie	if (defined $error) {
41063ed140Sespie		$self->{error} //= $error;
42963c2b7fSespie		$self->{errorinfo} //= $errorinfo;
434d9a1ca7Sespie	}
44063ed140Sespie	if (defined $self->location) {
45a6202cf1Sespie		if (defined $self->{error} && $self->{error} == BAD_PACKAGE) {
46063ed140Sespie			$self->location->close_with_client_error;
473ecf5ca9Sespie		} else {
483ecf5ca9Sespie			$self->location->close_now;
493ecf5ca9Sespie		}
50063ed140Sespie		$self->location->wipe_info;
51063ed140Sespie	}
52063ed140Sespie	delete $self->{plist};
538a5a2985Sespie	delete $self->{db};
54357f3812Sespie	delete $self->{conflict_list};
55063ed140Sespie}
56063ed140Sespie
57*039cbdaaSespiesub new($class)
58e626734bSespie{
59e626734bSespie	return bless {}, $class;
60e626734bSespie}
61e626734bSespie
62*039cbdaaSespiesub system($class)
6341d1a3fdSespie{
6441d1a3fdSespie	return OpenBSD::Handle::BaseSystem->new;
6541d1a3fdSespie}
6641d1a3fdSespie
67*039cbdaaSespiesub pkgname($self)
689a4592f8Sespie{
699a4592f8Sespie	if (!defined $self->{pkgname}) {
709a4592f8Sespie		if (defined $self->{plist}) {
719a4592f8Sespie			$self->{pkgname} = $self->{plist}->pkgname;
729a4592f8Sespie		} elsif (defined $self->{location}) {
739a4592f8Sespie			$self->{pkgname} = $self->{location}->name;
749a4592f8Sespie		} elsif (defined $self->{name}) {
759a4592f8Sespie			require OpenBSD::PackageName;
769a4592f8Sespie
779a4592f8Sespie			$self->{pkgname} =
789a4592f8Sespie			    OpenBSD::PackageName::url2pkgname($self->{name});
799a4592f8Sespie		}
809a4592f8Sespie	}
819a4592f8Sespie
829a4592f8Sespie	return $self->{pkgname};
839a4592f8Sespie}
849a4592f8Sespie
85*039cbdaaSespiesub location($self)
86ae327c1dSespie{
87*039cbdaaSespie	return $self->{location};
88ae327c1dSespie}
89ae327c1dSespie
90*039cbdaaSespiesub plist($self)
91ae327c1dSespie{
92*039cbdaaSespie	return $self->{plist};
93ae327c1dSespie}
94ae327c1dSespie
95*039cbdaaSespiesub dependency_info($self)
96357f3812Sespie{
97357f3812Sespie	if (defined $self->{plist}) {
98357f3812Sespie		return $self->{plist};
99aa4a3272Sespie	} elsif (defined $self->{location} &&
100aa4a3272Sespie	    defined $self->{location}{update_info}) {
101357f3812Sespie		return $self->{location}{update_info};
102357f3812Sespie	} else {
103357f3812Sespie		return undef;
104357f3812Sespie	}
105357f3812Sespie}
106357f3812Sespie
107357f3812SespieOpenBSD::Auto::cache(conflict_list,
108*039cbdaaSespie    sub($self) {
109357f3812Sespie    	require OpenBSD::PkgCfl;
110*039cbdaaSespie	return OpenBSD::PkgCfl->make_conflict_list($self->dependency_info);
111357f3812Sespie    });
112357f3812Sespie
113*039cbdaaSespiesub set_error($self, $error)
114e626734bSespie{
115e626734bSespie	$self->{error} = $error;
116e626734bSespie}
117e626734bSespie
118*039cbdaaSespiesub has_error($self, $error = undef)
119e626734bSespie{
120e626734bSespie	if (!defined $self->{error}) {
121e626734bSespie		return undef;
122e626734bSespie	}
123e626734bSespie	if (defined $error) {
124e626734bSespie		return $self->{error} eq $error;
125e626734bSespie	}
126e626734bSespie	return $self->{error};
127e626734bSespie}
128e626734bSespie
129*039cbdaaSespiesub has_reported_error($self)
130a806879eSespie{
131a806879eSespie	return $self->{error_reported};
132a806879eSespie}
133a806879eSespie
134*039cbdaaSespiesub error_message($self)
13584e1a6ebSespie{
13684e1a6ebSespie	my $error = $self->{error};
13784e1a6ebSespie	if ($error == BAD_PACKAGE) {
13884e1a6ebSespie		return "bad package";
13984e1a6ebSespie	} elsif ($error == CANT_INSTALL) {
140963c2b7fSespie		if ($self->{errorinfo}) {
141501d5867Sespie			return "$self->{errorinfo}";
142963c2b7fSespie		} else {
14384e1a6ebSespie			return "can't install";
144963c2b7fSespie		}
14584e1a6ebSespie	} elsif ($error == NOT_FOUND) {
14684e1a6ebSespie		return "not found";
14784e1a6ebSespie	} elsif ($error == ALREADY_INSTALLED) {
14884e1a6ebSespie		return "already installed";
14984e1a6ebSespie	} else {
15084e1a6ebSespie		return "no error";
15184e1a6ebSespie	}
15284e1a6ebSespie}
15384e1a6ebSespie
154*039cbdaaSespiesub complete_old($self)
15525b4afaeSespie{
15625b4afaeSespie	my $location = $self->{location};
15725b4afaeSespie
15825b4afaeSespie	if (!defined $location) {
15925b4afaeSespie		$self->set_error(NOT_FOUND);
16025b4afaeSespie    	} else {
16125b4afaeSespie		my $plist = $location->plist;
16225b4afaeSespie		if (!defined $plist) {
16325b4afaeSespie			$self->set_error(BAD_PACKAGE);
16425b4afaeSespie		} else {
16525b4afaeSespie			$self->{plist} = $plist;
166101e1cdbSespie			delete $location->{contents};
167d29de6feSespie			delete $location->{update_info};
16825b4afaeSespie		}
16925b4afaeSespie	}
17025b4afaeSespie}
17125b4afaeSespie
172*039cbdaaSespiesub complete_dependency_info($self)
173bbe3831fSespie{
174bbe3831fSespie	my $location = $self->{location};
175bbe3831fSespie
176bbe3831fSespie	if (!defined $location) {
177bbe3831fSespie		$self->set_error(NOT_FOUND);
178bbe3831fSespie	} else {
179bbe3831fSespie		if (!defined $self->{plist}) {
180bbe3831fSespie			# trigger build
181bbe3831fSespie			$location->update_info;
182bbe3831fSespie		}
183bbe3831fSespie	}
184bbe3831fSespie}
185bbe3831fSespie
186*039cbdaaSespiesub create_old($class, $pkgname, $state)
187e626734bSespie{
188e626734bSespie	my $self= $class->new;
1899a4592f8Sespie	$self->{name} = $pkgname;
190e626734bSespie
191db099e94Sespie	my $location = $state->repo->installed->find($pkgname);
19225b4afaeSespie	if (defined $location) {
193e626734bSespie		$self->{location} = $location;
194e626734bSespie	}
195bbe3831fSespie	$self->complete_dependency_info;
1969a4592f8Sespie
197e626734bSespie	return $self;
198e626734bSespie}
199e626734bSespie
200*039cbdaaSespiesub create_new($class, $pkg)
201e626734bSespie{
202e626734bSespie	my $handle = $class->new;
2039a4592f8Sespie	$handle->{name} = $pkg;
204e626734bSespie	$handle->{tweaked} = 0;
205e626734bSespie	return $handle;
206e626734bSespie}
207e626734bSespie
208*039cbdaaSespiesub from_location($class, $location)
209e626734bSespie{
210e626734bSespie	my $handle = $class->new;
211e626734bSespie	$handle->{location} = $location;
212e626734bSespie	$handle->{tweaked} = 0;
213e626734bSespie	return $handle;
214e626734bSespie}
215e626734bSespie
216*039cbdaaSespiesub get_plist($handle, $state)
217e626734bSespie{
218e626734bSespie	my $location = $handle->{location};
2199a4592f8Sespie	my $pkg = $handle->pkgname;
220e626734bSespie
221e74b30b0Sespie	if ($state->verbose >= 2) {
2227e83eca3Sespie		$state->say("#1parsing #2", $state->deptree_header($pkg), $pkg);
223e626734bSespie	}
2243ecf5ca9Sespie	my $plist = $location->plist;
225e626734bSespie	unless (defined $plist) {
226b25de260Sespie		$state->say("Can't find CONTENTS from #1", $location->url)
227b25de260Sespie		    unless $location->{error_reported};
228e626734bSespie		$location->close_with_client_error;
229e626734bSespie		$location->wipe_info;
230e626734bSespie		$handle->set_error(BAD_PACKAGE);
231a806879eSespie		$handle->{error_reported} = 1;
232e626734bSespie		return;
233e626734bSespie	}
234d29de6feSespie	delete $location->{update_info};
23527828011Sespie	$location->decorate($plist);
236e626734bSespie	if ($plist->localbase ne $state->{localbase}) {
2377e83eca3Sespie		$state->say("Localbase mismatch: package has: #1, user wants: #2",
2387e83eca3Sespie		    $plist->localbase, $state->{localbase});
239e626734bSespie		$location->close_with_client_error;
240e626734bSespie		$location->wipe_info;
241e626734bSespie		$handle->set_error(BAD_PACKAGE);
242e626734bSespie		return;
243e626734bSespie	}
244e626734bSespie	my $pkgname = $handle->{pkgname} = $plist->pkgname;
245e626734bSespie
246e626734bSespie	if ($pkg ne '-') {
2479a4592f8Sespie		if (!defined $pkgname or $pkg ne $pkgname) {
248662ab648Sespie			$state->say("Package name is not consistent ???");
249e626734bSespie			$location->close_with_client_error;
250e626734bSespie			$location->wipe_info;
251e626734bSespie			$handle->set_error(BAD_PACKAGE);
252e626734bSespie			return;
253e626734bSespie		}
254e626734bSespie	}
255e626734bSespie	$handle->{plist} = $plist;
256e626734bSespie}
257e626734bSespie
258*039cbdaaSespiesub get_location($handle, $state)
259e626734bSespie{
2609a4592f8Sespie	my $name = $handle->{name};
2619a4592f8Sespie
262db099e94Sespie	my $location = $state->repo->find($name);
263e626734bSespie	if (!$location) {
2647e83eca3Sespie		$state->print("#1", $state->deptree_header($name));
265e626734bSespie		$handle->set_error(NOT_FOUND);
266e626734bSespie		$handle->{tweaked} =
2679a4592f8Sespie		    OpenBSD::Add::tweak_package_status($handle->pkgname,
268e626734bSespie			$state);
269e626734bSespie		if (!$handle->{tweaked}) {
2707e83eca3Sespie			$state->say("Can't find #1", $name);
271f2b1e24cSespie			$handle->{error_reported} = 1;
272c6ec65baSespie			eval {
273c6ec65baSespie				my $r = [$name];
274c6ec65baSespie				$state->quirks->filter_obsolete($r, $state);
275c6ec65baSespie			}
276e626734bSespie		}
277e626734bSespie		return;
278e626734bSespie	}
279e626734bSespie	$handle->{location} = $location;
2809a4592f8Sespie	$handle->{pkgname} = $location->name;
281e626734bSespie}
28250fc42e3Sespie
283*039cbdaaSespiesub complete($handle, $state)
28450fc42e3Sespie{
28550fc42e3Sespie	return if $handle->has_error;
28650fc42e3Sespie
28750fc42e3Sespie	if (!defined $handle->{location}) {
28850fc42e3Sespie		$handle->get_location($state);
28950fc42e3Sespie	}
2900d49d264Sespie	return if $handle->has_error;
291e626734bSespie	if (!defined $handle->{plist}) {
292e626734bSespie		$handle->get_plist($state);
293e626734bSespie	}
294e626734bSespie}
2959a4592f8Sespie
29641d1a3fdSespiepackage OpenBSD::Handle::BaseSystem;
29741d1a3fdSespieour @ISA = qw(OpenBSD::Handle);
298*039cbdaaSespiesub pkgname($) { return "BaseSystem"; }
29941d1a3fdSespie
300*039cbdaaSespiesub is_real($) { return 0; }
30141d1a3fdSespie
302e626734bSespie1;
303