aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-11-29 07:45:33 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-11-29 07:45:33 +0100
commitf94c9bf288290c9f4e5a7c2745922abd600e88ca (patch)
tree57289568fb310466798ae6b297fe46d6e3d2bfcf /archival/libunarchive
parent2ce42e98d799de4c3389d9c4ce0a6b0d42dac7cc (diff)
downloadbusybox-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.c17
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