summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_read_extract.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2004-04-30 01:31:20 +0000
committerkientzle <kientzle@FreeBSD.org>2004-04-30 01:31:20 +0000
commiteb83ce39b488c2182b387f90a47fb09bf47c9883 (patch)
treebe7b2e4d0fd449c8ff79f24db3dd7ce7baf6e9fd /lib/libarchive/archive_read_extract.c
parent1c5fa3c156e6f2c28b3577fcbd6a7c8fce933772 (diff)
downloadFreeBSD-src-eb83ce39b488c2182b387f90a47fb09bf47c9883.zip
FreeBSD-src-eb83ce39b488c2182b387f90a47fb09bf47c9883.tar.gz
Create missing directories when extracting hardlinks and symlinks.
Diffstat (limited to 'lib/libarchive/archive_read_extract.c')
-rw-r--r--lib/libarchive/archive_read_extract.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c
index 0ba3595..fa3974f 100644
--- a/lib/libarchive/archive_read_extract.c
+++ b/lib/libarchive/archive_read_extract.c
@@ -487,6 +487,13 @@ static int
archive_read_extract_hard_link(struct archive *a, struct archive_entry *entry,
int flags)
{
+ int r;
+ const char *pathname;
+ const char *linkname;
+
+ pathname = archive_entry_pathname(entry);
+ linkname = archive_entry_hardlink(entry);
+
/*
* XXX Should we suppress the unlink here unless
* ARCHIVE_EXTRACT_UNLINK? That would make the
@@ -497,11 +504,20 @@ archive_read_extract_hard_link(struct archive *a, struct archive_entry *entry,
/* Just remove any pre-existing file with this name. */
if (!(flags & ARCHIVE_EXTRACT_NO_OVERWRITE))
- unlink(archive_entry_pathname(entry));
+ unlink(pathname);
+
+ r = link(linkname, pathname);
- if (link(archive_entry_hardlink(entry),
- archive_entry_pathname(entry))) {
- archive_set_error(a, errno, "Can't restore hardlink");
+ if (r != 0) {
+ /* Might be a non-existent parent dir; try fixing that. */
+ mkdirpath(a, pathname);
+ r = link(linkname, pathname);
+ }
+
+ if (r != 0) {
+ /* XXX Better error message here XXX */
+ archive_set_error(a, errno,
+ "Can't restore hardlink to '%s'", linkname);
return (ARCHIVE_WARN);
}
@@ -518,6 +534,13 @@ static int
archive_read_extract_symbolic_link(struct archive *a,
struct archive_entry *entry, int flags)
{
+ int r;
+ const char *pathname;
+ const char *linkname;
+
+ pathname = archive_entry_pathname(entry);
+ linkname = archive_entry_symlink(entry);
+
/*
* XXX Should we suppress the unlink here unless
* ARCHIVE_EXTRACT_UNLINK? That would make the
@@ -528,13 +551,20 @@ archive_read_extract_symbolic_link(struct archive *a,
/* Just remove any pre-existing file with this name. */
if (!(flags & ARCHIVE_EXTRACT_NO_OVERWRITE))
- unlink(archive_entry_pathname(entry));
+ unlink(pathname);
+
+ r = symlink(linkname, pathname);
- if (symlink(archive_entry_symlink(entry),
- archive_entry_pathname(entry))) {
+ if (r != 0) {
+ /* Might be a non-existent parent dir; try fixing that. */
+ mkdirpath(a, pathname);
+ r = symlink(linkname, pathname);
+ }
+
+ if (r != 0) {
/* XXX Better error message here XXX */
- archive_set_error(a, errno, "Can't restore symlink to '%s'",
- archive_entry_symlink(entry));
+ archive_set_error(a, errno,
+ "Can't restore symlink to '%s'", linkname);
return (ARCHIVE_WARN);
}
OpenPOWER on IntegriCloud