1# ex:ts=8 sw=4: 2# $OpenBSD: Handle.pm,v 1.39 2014/02/08 16:11:02 espie Exp $ 3# 4# Copyright (c) 2007-2009 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 18# fairly non-descriptive name. Used to store various package information 19# during installs and updates. 20 21use strict; 22use warnings; 23 24package OpenBSD::Handle; 25 26use OpenBSD::PackageInfo; 27use OpenBSD::Error; 28 29use constant { 30 BAD_PACKAGE => 1, 31 CANT_INSTALL => 2, 32 ALREADY_INSTALLED => 3, 33 NOT_FOUND => 4, 34 CANT_DELETE => 5, 35}; 36 37sub is_real { return 1; } 38 39sub cleanup 40{ 41 my ($self, $error, $errorinfo) = @_; 42 if (defined $error) { 43 $self->{error} //= $error; 44 $self->{errorinfo} //= $errorinfo; 45 } 46 if (defined $self->location) { 47 if (defined $self->{error} && $self->{error} == BAD_PACKAGE) { 48 $self->location->close_with_client_error; 49 } else { 50 $self->location->close_now; 51 } 52 $self->location->wipe_info; 53 } 54 delete $self->{plist}; 55 delete $self->{db}; 56 delete $self->{conflict_list}; 57} 58 59sub new 60{ 61 my $class = shift; 62 return bless {}, $class; 63} 64 65sub system 66{ 67 my $class = shift; 68 return OpenBSD::Handle::BaseSystem->new; 69} 70 71sub pkgname 72{ 73 my $self = shift; 74 if (!defined $self->{pkgname}) { 75 if (defined $self->{plist}) { 76 $self->{pkgname} = $self->{plist}->pkgname; 77 } elsif (defined $self->{location}) { 78 $self->{pkgname} = $self->{location}->name; 79 } elsif (defined $self->{name}) { 80 require OpenBSD::PackageName; 81 82 $self->{pkgname} = 83 OpenBSD::PackageName::url2pkgname($self->{name}); 84 } 85 } 86 87 return $self->{pkgname}; 88} 89 90sub location 91{ 92 return shift->{location}; 93} 94 95sub plist 96{ 97 return shift->{plist}; 98} 99 100sub dependency_info 101{ 102 my $self = shift; 103 if (defined $self->{plist}) { 104 return $self->{plist}; 105 } elsif (defined $self->{location} && 106 defined $self->{location}{update_info}) { 107 return $self->{location}{update_info}; 108 } else { 109 return undef; 110 } 111} 112 113OpenBSD::Auto::cache(conflict_list, 114 sub { 115 require OpenBSD::PkgCfl; 116 return OpenBSD::PkgCfl->make_conflict_list(shift->dependency_info); 117 }); 118 119sub set_error 120{ 121 my ($self, $error) = @_; 122 $self->{error} = $error; 123} 124 125sub has_error 126{ 127 my ($self, $error) = @_; 128 if (!defined $self->{error}) { 129 return undef; 130 } 131 if (defined $error) { 132 return $self->{error} eq $error; 133 } 134 return $self->{error}; 135} 136 137sub error_message 138{ 139 my $self = shift; 140 my $error = $self->{error}; 141 if ($error == BAD_PACKAGE) { 142 return "bad package"; 143 } elsif ($error == CANT_INSTALL) { 144 if ($self->{errorinfo}) { 145 return "$self->{errorinfo}"; 146 } else { 147 return "can't install"; 148 } 149 } elsif ($error == NOT_FOUND) { 150 return "not found"; 151 } elsif ($error == ALREADY_INSTALLED) { 152 return "already installed"; 153 } else { 154 return "no error"; 155 } 156} 157 158sub complete_old 159{ 160 my $self = shift; 161 my $location = $self->{location}; 162 163 if (!defined $location) { 164 $self->set_error(NOT_FOUND); 165 } else { 166 my $plist = $location->plist; 167 if (!defined $plist) { 168 $self->set_error(BAD_PACKAGE); 169 } else { 170 $self->{plist} = $plist; 171 delete $location->{contents}; 172 delete $location->{update_info}; 173 } 174 } 175} 176 177sub complete_dependency_info 178{ 179 my $self = shift; 180 my $location = $self->{location}; 181 182 if (!defined $location) { 183 $self->set_error(NOT_FOUND); 184 } else { 185 if (!defined $self->{plist}) { 186 # trigger build 187 $location->update_info; 188 } 189 } 190} 191 192sub create_old 193{ 194 195 my ($class, $pkgname, $state) = @_; 196 my $self= $class->new; 197 $self->{name} = $pkgname; 198 199 my $location = $state->repo->installed->find($pkgname); 200 if (defined $location) { 201 $self->{location} = $location; 202 } 203 $self->complete_dependency_info; 204 205 return $self; 206} 207 208sub create_new 209{ 210 my ($class, $pkg) = @_; 211 my $handle = $class->new; 212 $handle->{name} = $pkg; 213 $handle->{tweaked} = 0; 214 return $handle; 215} 216 217sub from_location 218{ 219 my ($class, $location) = @_; 220 my $handle = $class->new; 221 $handle->{location} = $location; 222 $handle->{tweaked} = 0; 223 return $handle; 224} 225 226sub get_plist 227{ 228 my ($handle, $state) = @_; 229 230 my $location = $handle->{location}; 231 my $pkg = $handle->pkgname; 232 233 if ($state->verbose >= 2) { 234 $state->say("#1parsing #2", $state->deptree_header($pkg), $pkg); 235 } 236 my $plist = $location->plist; 237 unless (defined $plist) { 238 $state->say("Can't find CONTENTS from #1", $location->url); 239 $location->close_with_client_error; 240 $location->wipe_info; 241 $handle->set_error(BAD_PACKAGE); 242 return; 243 } 244 delete $location->{update_info}; 245 unless ($plist->has('url')) { 246 OpenBSD::PackingElement::Url->add($plist, $location->url); 247 } 248 if ($plist->localbase ne $state->{localbase}) { 249 $state->say("Localbase mismatch: package has: #1, user wants: #2", 250 $plist->localbase, $state->{localbase}); 251 $location->close_with_client_error; 252 $location->wipe_info; 253 $handle->set_error(BAD_PACKAGE); 254 return; 255 } 256 my $pkgname = $handle->{pkgname} = $plist->pkgname; 257 258 if ($pkg ne '-') { 259 if (!defined $pkgname or $pkg ne $pkgname) { 260 $state->say("Package name is not consistent ???"); 261 $location->close_with_client_error; 262 $location->wipe_info; 263 $handle->set_error(BAD_PACKAGE); 264 return; 265 } 266 } 267 $handle->{plist} = $plist; 268} 269 270sub get_location 271{ 272 my ($handle, $state) = @_; 273 274 my $name = $handle->{name}; 275 276 my $location = $state->repo->find($name); 277 if (!$location) { 278 $state->print("#1", $state->deptree_header($name)); 279 $handle->set_error(NOT_FOUND); 280 $handle->{tweaked} = 281 OpenBSD::Add::tweak_package_status($handle->pkgname, 282 $state); 283 if (!$handle->{tweaked}) { 284 $state->say("Can't find #1", $name); 285 eval { 286 my $r = [$name]; 287 $state->quirks->filter_obsolete($r, $state); 288 } 289 } 290 return; 291 } 292 $handle->{location} = $location; 293 $handle->{pkgname} = $location->name; 294} 295 296sub complete 297{ 298 my ($handle, $state) = @_; 299 300 return if $handle->has_error; 301 302 if (!defined $handle->{location}) { 303 $handle->get_location($state); 304 } 305 return if $handle->has_error; 306 if (!defined $handle->{plist}) { 307 $handle->get_plist($state); 308 } 309} 310 311package OpenBSD::Handle::BaseSystem; 312our @ISA = qw(OpenBSD::Handle); 313sub pkgname { return "BaseSystem"; } 314 315sub is_real { return 0; } 316 3171; 318