summaryrefslogtreecommitdiff
path: root/archival/libunarchive/data_extract_all.c
diff options
context:
space:
mode:
authorDenys Vlasenko2009-11-29 07:45:33 +0100
committerDenys Vlasenko2009-11-29 07:45:33 +0100
commitf94c9bf288290c9f4e5a7c2745922abd600e88ca (patch)
tree57289568fb310466798ae6b297fe46d6e3d2bfcf /archival/libunarchive/data_extract_all.c
parent2ce42e98d799de4c3389d9c4ce0a6b0d42dac7cc (diff)
downloadbusybox-f94c9bf288290c9f4e5a7c2745922abd600e88ca.zip
busybox-f94c9bf288290c9f4e5a7c2745922abd600e88ca.tar.gz
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/data_extract_all.c')
-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 2fcddc4..1100410 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)
int res;
if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
- char *name = xstrdup(file_header->name);
- bb_make_directory(dirname(name), -1, FILEUTILS_RECUR);
- free(name);
+ char *slash = strrchr(file_header->name, '/');
+ if (slash) {
+ *slash = '\0';
+ bb_make_directory(file_header->name, -1, FILEUTILS_RECUR);
+ *slash = '/';
+ }
}
if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
@@ -52,8 +55,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
/* Handle hard links separately
* We identified hard links as regular files of size 0 with a symlink */
- if (S_ISREG(file_header->mode) && (file_header->link_target)
- && (file_header->size == 0)
+ if (S_ISREG(file_header->mode)
+ && file_header->link_target
+ && file_header->size == 0
) {
/* hard link */
res = link(file_header->link_target, file_header->name);
@@ -121,6 +125,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
gid_t gid = file_header->gid;
if (file_header->uname) {
+//TODO: cache last name/id pair?
struct passwd *pwd = getpwnam(file_header->uname);
if (pwd) uid = pwd->pw_uid;
}
@@ -128,7 +133,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
struct group *grp = getgrnam(file_header->gname);
if (grp) gid = grp->gr_gid;
}
- /* GNU tar 1.15.1 use chown, not lchown */
+ /* GNU tar 1.15.1 uses chown, not lchown */
chown(file_header->name, uid, gid);
} else
#endif