summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2005-10-24 09:50:52 +0000
committerMarc Espie <espie@cvs.openbsd.org>2005-10-24 09:50:52 +0000
commit90afe515722225cb9815e5eec728dc2b7bdd4423 (patch)
treed940385b9e2522d145284c456d52c3d27011c832 /usr.sbin
parentb8df9af404f92a9956187c3c802d8648b984ceb9 (diff)
factor out a bit of code, and be more aware of symlinks.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Delete.pm128
1 files changed, 86 insertions, 42 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Delete.pm b/usr.sbin/pkg_add/OpenBSD/Delete.pm
index a9214499f4f..003ef9e7a44 100644
--- a/usr.sbin/pkg_add/OpenBSD/Delete.pm
+++ b/usr.sbin/pkg_add/OpenBSD/Delete.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Delete.pm,v 1.28 2005/10/22 13:11:07 espie Exp $
+# $OpenBSD: Delete.pm,v 1.29 2005/10/24 09:50:51 espie Exp $
#
# Copyright (c) 2003-2004 Marc Espie <espie@openbsd.org>
#
@@ -244,17 +244,42 @@ sub delete
package OpenBSD::PackingElement::FileObject;
use File::Basename;
-sub mark_dir
+sub mark_directory
{
my ($self, $state, $dir) = @_;
$state->{dirs_okay}->{$dir} = 1;
my $d2 = dirname($dir);
if ($d2 ne $dir) {
- $self->mark_dir($state, $d2);
+ $self->mark_directory($state, $d2);
}
}
+sub mark_dir
+{
+ my ($self, $state) = @_;
+
+ $self->mark_directory($state, dirname($self->fullname()));
+}
+
+sub realname
+{
+ my ($self, $state) = @_;
+
+ my $name = $self->fullname();
+ if (defined $self->{tempname}) {
+ $name = $self->{tempname};
+ }
+ return $state->{destdir}.$name;
+}
+
+package OpenBSD::PackingElement::DirlikeObject;
+sub mark_dir
+{
+ my ($self, $state) = @_;
+ $self->mark_directory($state, $self->fullname());
+}
+
package OpenBSD::PackingElement::NewUser;
sub delete
{
@@ -326,41 +351,62 @@ use OpenBSD::md5;
sub delete
{
my ($self, $state) = @_;
- my $name = $self->fullname();
- if (defined $self->{tempname}) {
- $name = $self->{tempname};
- }
- my $realname = $state->{destdir}.$name;
- if (-l $realname) {
- if ($state->{very_verbose}) {
- print "deleting symlink: $realname\n";
- }
- } else {
- if (! -f $realname) {
- print "File $realname does not exist\n";
- return;
- }
- unless (defined($self->{link}) or $self->{nochecksum} or $state->{quick}) {
- if (!defined $self->{md5}) {
- print "Problem: $name does not have an md5 checksum\n";
- print "NOT deleting: $realname\n";
- $state->print("Couldn't delete $realname (no md5)\n");
+ my $realname = $self->realname($state);
+
+ if (defined $self->{symlink}) {
+ if (-l $realname) {
+ my $contents = readlink $realname;
+ if ($contents ne $self->{symlink}) {
+ print "Symlink does not match: $realname ($contents vs. ", $self->{symlink},")\n";
+ $self->{stillaround} = 1;
+ $self->{symlink} = $contents;
+ $state->{baddelete} = 1;
return;
}
- my $md5 = OpenBSD::md5::fromfile($realname);
- if ($md5 ne $self->{md5}) {
- print "Problem: md5 doesn't match for $name\n";
- print "NOT deleting: $realname\n";
- $state->print("Couldn't delete $realname (bad md5)\n");
+ } else {
+ print "Bogus symlink: $realname\n";
+ if (-f $realname) {
+ delete $self->{symlink};
+ $self->{md5} = OpenBSD::md5::fromfile($realname);
+ $self->{stillaround} = 1;
+ }
+ $state->{baddelete} = 1;
+ return;
+ }
+ } else {
+ if (-l $realname) {
+ print "Unexpected symlink: $realname\n";
$self->{stillaround} = 1;
- $self->{md5} = $md5;
$state->{baddelete} = 1;
+ } else {
+ if (! -f $realname) {
+ print "File $realname does not exist\n";
return;
}
+ unless (defined($self->{link}) or $self->{nochecksum} or $state->{quick}) {
+ if (!defined $self->{md5}) {
+ print "Problem: ", $self->fullname(),
+ " does not have an md5 checksum\n";
+ print "NOT deleting: $realname\n";
+ $state->print("Couldn't delete $realname (no md5)\n");
+ return;
+ }
+ my $md5 = OpenBSD::md5::fromfile($realname);
+ if ($md5 ne $self->{md5}) {
+ print "Problem: md5 doesn't match for ",
+ $self->fullname(), "\n";
+ print "NOT deleting: $realname\n";
+ $state->print("Couldn't delete $realname (bad md5)\n");
+ $self->{stillaround} = 1;
+ $self->{md5} = $md5;
+ $state->{baddelete} = 1;
+ return;
+ }
+ }
}
- if ($state->{very_verbose}) {
- print "deleting: $realname\n";
- }
+ }
+ if ($state->{very_verbose}) {
+ print "deleting: $realname\n";
}
return if $state->{not};
if (!unlink $realname) {
@@ -377,14 +423,13 @@ use File::Basename;
sub delete
{
my ($self, $state) = @_;
- my $name = $self->fullname();
- my $realname = $state->{destdir}.$name;
+ my $realname = $self->realname($state);
my $orig = $self->{copyfrom};
if (!defined $orig) {
Fatal "\@sample element does not reference a valid file\n";
}
- my $origname = $state->{destdir}.$orig->fullname();
+ my $origname = $orig->realname($state);
if (! -e $realname) {
$state->print("File $realname does not exist\n");
return;
@@ -401,7 +446,7 @@ sub delete
if ($state->{quick}) {
unless ($state->{extra}) {
- $self->mark_dir($state, dirname($name));
+ $self->mark_dir($state);
$state->print("You should also remove $realname\n");
return;
}
@@ -411,7 +456,7 @@ sub delete
print "File $realname identical to sample\n" if $state->{not} or $state->{verbose};
} else {
unless ($state->{extra}) {
- $self->mark_dir($state, dirname($name));
+ $self->mark_dir($state);
$state->print("You should also remove $realname (which was modified)\n");
return;
}
@@ -473,8 +518,7 @@ use File::Basename;
sub delete
{
my ($self, $state) = @_;
- my $name = $self->fullname();
- my $realname = $state->{destdir}.$name;
+ my $realname = $self->realname($state);
if ($state->{beverbose} && $state->{extra}) {
print "deleting extra file: $realname\n";
}
@@ -482,13 +526,13 @@ sub delete
return unless -e $realname;
if ($state->{replacing}) {
$state->print("Remember to update $realname\n");
- $self->mark_dir($state, dirname($name));
+ $self->mark_dir($state);
} elsif ($state->{extra}) {
unlink($realname) or
print "problem deleting extra file $realname\n";
} else {
$state->print("You should also remove $realname\n");
- $self->mark_dir($state, dirname($name));
+ $self->mark_dir($state);
}
}
@@ -498,13 +542,13 @@ sub delete
{
my ($self, $state) = @_;
return unless $state->{extra};
- my $realname = $state->{destdir}.$self->fullname();
+ my $realname = $self->realname($state);
return if $state->{replacing};
if ($state->{extra}) {
$self->SUPER::delete($state);
} else {
$state->print("You should also remove the directory $realname\n");
- $self->mark_dir($state, $self->fullname());
+ $self->mark_dir($state);
}
}