diff options
author | kientzle <kientzle@FreeBSD.org> | 2007-03-13 06:04:24 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2007-03-13 06:04:24 +0000 |
commit | 847bf0fdc9b7822157bcc1b36b6570e2ad05bb14 (patch) | |
tree | 81849ae05e3816b7b29a5544620173a3f1cb7d99 /lib/libarchive/archive_write_disk.c | |
parent | c2c65e0dd6f06d53bf32829de24c93b1ab6453d6 (diff) | |
download | FreeBSD-src-847bf0fdc9b7822157bcc1b36b6570e2ad05bb14.zip FreeBSD-src-847bf0fdc9b7822157bcc1b36b6570e2ad05bb14.tar.gz |
When ARCHIVE_EXTRACT_UNLINK is requested:
* Only try to remove the existing item if we're not restoring a directory.
* If unlink fails, try rmdir next.
This should fix the broken --unlink option in bsdtar.
Thanks again to: Kris Kennaway, for beating up bsdtar on pointyhat.
Diffstat (limited to 'lib/libarchive/archive_write_disk.c')
-rw-r--r-- | lib/libarchive/archive_write_disk.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c index 1f8f0ce..02fabd6 100644 --- a/lib/libarchive/archive_write_disk.c +++ b/lib/libarchive/archive_write_disk.c @@ -659,14 +659,20 @@ restore_entry(struct archive_write_disk *a) { int ret = ARCHIVE_OK, en; - if (a->flags & ARCHIVE_EXTRACT_UNLINK) - if (unlink(a->name) != 0 && errno != ENOENT) { - /* If the file doesn't exist, that's okay. */ - /* Anything else is a problem. */ + if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) { + if (unlink(a->name) == 0) { + /* We removed it, we're done. */ + } else if (errno == ENOENT) { + /* File didn't exist, that's just as good. */ + } else if (rmdir(a->name) == 0) { + /* It was a dir, but now it's gone. */ + } else { + /* We tried, but couldn't get rid of it. */ archive_set_error(&a->archive, errno, "Could not unlink"); return(ARCHIVE_WARN); } + } /* Try creating it first; if this fails, we'll try to recover. */ en = create_filesystem_object(a); |