diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-29 07:45:33 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-29 07:45:33 +0100 |
commit | f94c9bf288290c9f4e5a7c2745922abd600e88ca (patch) | |
tree | 57289568fb310466798ae6b297fe46d6e3d2bfcf /archival/libunarchive | |
parent | 2ce42e98d799de4c3389d9c4ce0a6b0d42dac7cc (diff) | |
download | busybox-w32-f94c9bf288290c9f4e5a7c2745922abd600e88ca.tar.gz busybox-w32-f94c9bf288290c9f4e5a7c2745922abd600e88ca.tar.bz2 busybox-w32-f94c9bf288290c9f4e5a7c2745922abd600e88ca.zip |
tar: fix bug 673 (misdetection of repeated dir as hardlink). +92 bytes
While at it, remove many superfluous ops on unpack:
mkdir("."), lots of umask() calls. Can remove more
by caching username->uid.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival/libunarchive')
-rw-r--r-- | archival/libunarchive/data_extract_all.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index 2fcddc404..1100410e6 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c | |||
@@ -13,9 +13,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
13 | int res; | 13 | int res; |
14 | 14 | ||
15 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { | 15 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { |
16 | char *name = xstrdup(file_header->name); | 16 | char *slash = strrchr(file_header->name, '/'); |
17 | bb_make_directory(dirname(name), -1, FILEUTILS_RECUR); | 17 | if (slash) { |
18 | free(name); | 18 | *slash = '\0'; |
19 | bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); | ||
20 | *slash = '/'; | ||
21 | } | ||
19 | } | 22 | } |
20 | 23 | ||
21 | if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { | 24 | if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { |
@@ -52,8 +55,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
52 | 55 | ||
53 | /* Handle hard links separately | 56 | /* Handle hard links separately |
54 | * We identified hard links as regular files of size 0 with a symlink */ | 57 | * We identified hard links as regular files of size 0 with a symlink */ |
55 | if (S_ISREG(file_header->mode) && (file_header->link_target) | 58 | if (S_ISREG(file_header->mode) |
56 | && (file_header->size == 0) | 59 | && file_header->link_target |
60 | && file_header->size == 0 | ||
57 | ) { | 61 | ) { |
58 | /* hard link */ | 62 | /* hard link */ |
59 | res = link(file_header->link_target, file_header->name); | 63 | res = link(file_header->link_target, file_header->name); |
@@ -121,6 +125,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
121 | gid_t gid = file_header->gid; | 125 | gid_t gid = file_header->gid; |
122 | 126 | ||
123 | if (file_header->uname) { | 127 | if (file_header->uname) { |
128 | //TODO: cache last name/id pair? | ||
124 | struct passwd *pwd = getpwnam(file_header->uname); | 129 | struct passwd *pwd = getpwnam(file_header->uname); |
125 | if (pwd) uid = pwd->pw_uid; | 130 | if (pwd) uid = pwd->pw_uid; |
126 | } | 131 | } |
@@ -128,7 +133,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
128 | struct group *grp = getgrnam(file_header->gname); | 133 | struct group *grp = getgrnam(file_header->gname); |
129 | if (grp) gid = grp->gr_gid; | 134 | if (grp) gid = grp->gr_gid; |
130 | } | 135 | } |
131 | /* GNU tar 1.15.1 use chown, not lchown */ | 136 | /* GNU tar 1.15.1 uses chown, not lchown */ |
132 | chown(file_header->name, uid, gid); | 137 | chown(file_header->name, uid, gid); |
133 | } else | 138 | } else |
134 | #endif | 139 | #endif |