diff options
-rw-r--r-- | archival/Config.in | 10 | ||||
-rw-r--r-- | archival/libunarchive/data_extract_all.c | 15 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 9 | ||||
-rw-r--r-- | archival/libunarchive/header_verbose_list.c | 28 | ||||
-rw-r--r-- | include/unarchive.h | 4 |
5 files changed, 64 insertions, 2 deletions
diff --git a/archival/Config.in b/archival/Config.in index 8d31ec771..160c54d64 100644 --- a/archival/Config.in +++ b/archival/Config.in | |||
@@ -237,7 +237,15 @@ config FEATURE_TAR_LONG_OPTIONS | |||
237 | default n | 237 | default n |
238 | depends on TAR && GETOPT_LONG | 238 | depends on TAR && GETOPT_LONG |
239 | help | 239 | help |
240 | Enable use of long options, increases size by about 400 Bytes | 240 | Enable use of long options, increases size by about 400 Bytes |
241 | |||
242 | config FEATURE_TAR_UNAME_GNAME | ||
243 | bool "Enable use of user and group names" | ||
244 | default n | ||
245 | help | ||
246 | Enables use of user and group names in tar. This affects contents | ||
247 | listings (-t) and preserving permissions when unpacking (-p). | ||
248 | +200 bytes. | ||
241 | 249 | ||
242 | config UNCOMPRESS | 250 | config UNCOMPRESS |
243 | bool "uncompress" | 251 | bool "uncompress" |
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index 76e7edf24..4df9c09a7 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c | |||
@@ -112,7 +112,22 @@ void data_extract_all(archive_handle_t *archive_handle) | |||
112 | } | 112 | } |
113 | 113 | ||
114 | if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_OWN)) { | 114 | if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_OWN)) { |
115 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
116 | uid_t uid = file_header->uid; | ||
117 | gid_t gid = file_header->gid; | ||
118 | |||
119 | if (file_header->uname) { | ||
120 | struct passwd *pwd = getpwnam(file_header->uname); | ||
121 | if (pwd) uid = pwd->pw_uid; | ||
122 | } | ||
123 | if (file_header->gname) { | ||
124 | struct group *grp = getgrnam(file_header->gname); | ||
125 | if (grp) gid = grp->gr_gid; | ||
126 | } | ||
127 | lchown(file_header->name, uid, gid); | ||
128 | #else | ||
115 | lchown(file_header->name, file_header->uid, file_header->gid); | 129 | lchown(file_header->name, file_header->uid, file_header->gid); |
130 | #endif | ||
116 | } | 131 | } |
117 | if ((file_header->mode & S_IFMT) != S_IFLNK) { | 132 | if ((file_header->mode & S_IFMT) != S_IFLNK) { |
118 | /* uclibc has no lchmod, glibc is even stranger - | 133 | /* uclibc has no lchmod, glibc is even stranger - |
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 5a1f5948f..893cd5b79 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
@@ -187,6 +187,10 @@ char get_header_tar(archive_handle_t *archive_handle) | |||
187 | /* FIXME: what if we have non-link object with link_target? */ | 187 | /* FIXME: what if we have non-link object with link_target? */ |
188 | /* Will link_target be free()ed? */ | 188 | /* Will link_target be free()ed? */ |
189 | } | 189 | } |
190 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
191 | file_header->uname = tar.uname[0] ? xstrndup(tar.uname, sizeof(tar.uname)) : NULL; | ||
192 | file_header->gname = tar.gname[0] ? xstrndup(tar.gname, sizeof(tar.gname)) : NULL; | ||
193 | #endif | ||
190 | file_header->mtime = GET_OCTAL(tar.mtime); | 194 | file_header->mtime = GET_OCTAL(tar.mtime); |
191 | file_header->size = GET_OCTAL(tar.size); | 195 | file_header->size = GET_OCTAL(tar.size); |
192 | file_header->gid = GET_OCTAL(tar.gid); | 196 | file_header->gid = GET_OCTAL(tar.gid); |
@@ -317,6 +321,9 @@ char get_header_tar(archive_handle_t *archive_handle) | |||
317 | 321 | ||
318 | free(file_header->link_target); | 322 | free(file_header->link_target); |
319 | /* Do not free(file_header->name)! */ | 323 | /* Do not free(file_header->name)! */ |
320 | 324 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | |
325 | free(file_header->uname); | ||
326 | free(file_header->gname); | ||
327 | #endif | ||
321 | return EXIT_SUCCESS; | 328 | return EXIT_SUCCESS; |
322 | } | 329 | } |
diff --git a/archival/libunarchive/header_verbose_list.c b/archival/libunarchive/header_verbose_list.c index b9ac3c499..ea623ed85 100644 --- a/archival/libunarchive/header_verbose_list.c +++ b/archival/libunarchive/header_verbose_list.c | |||
@@ -10,6 +10,33 @@ void header_verbose_list(const file_header_t *file_header) | |||
10 | { | 10 | { |
11 | struct tm *mtime = localtime(&(file_header->mtime)); | 11 | struct tm *mtime = localtime(&(file_header->mtime)); |
12 | 12 | ||
13 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
14 | char uid[8]; | ||
15 | char gid[8]; | ||
16 | char *user = file_header->uname; | ||
17 | char *group = file_header->gname; | ||
18 | |||
19 | if (user == NULL) { | ||
20 | snprintf(uid, sizeof(uid), "%u", (unsigned)file_header->uid); | ||
21 | user = uid; | ||
22 | } | ||
23 | if (group == NULL) { | ||
24 | snprintf(gid, sizeof(gid), "%u", (unsigned)file_header->gid); | ||
25 | group = gid; | ||
26 | } | ||
27 | printf("%s %s/%s %9u %4u-%02u-%02u %02u:%02u:%02u %s", | ||
28 | bb_mode_string(file_header->mode), | ||
29 | user, | ||
30 | group, | ||
31 | (unsigned int) file_header->size, | ||
32 | 1900 + mtime->tm_year, | ||
33 | 1 + mtime->tm_mon, | ||
34 | mtime->tm_mday, | ||
35 | mtime->tm_hour, | ||
36 | mtime->tm_min, | ||
37 | mtime->tm_sec, | ||
38 | file_header->name); | ||
39 | #else /* !FEATURE_TAR_UNAME_GNAME */ | ||
13 | printf("%s %d/%d %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", | 40 | printf("%s %d/%d %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", |
14 | bb_mode_string(file_header->mode), | 41 | bb_mode_string(file_header->mode), |
15 | file_header->uid, | 42 | file_header->uid, |
@@ -22,6 +49,7 @@ void header_verbose_list(const file_header_t *file_header) | |||
22 | mtime->tm_min, | 49 | mtime->tm_min, |
23 | mtime->tm_sec, | 50 | mtime->tm_sec, |
24 | file_header->name); | 51 | file_header->name); |
52 | #endif /* FEATURE_TAR_UNAME_GNAME */ | ||
25 | 53 | ||
26 | if (file_header->link_target) { | 54 | if (file_header->link_target) { |
27 | printf(" -> %s", file_header->link_target); | 55 | printf(" -> %s", file_header->link_target); |
diff --git a/include/unarchive.h b/include/unarchive.h index e8beebbe1..4ed2ccd0c 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -13,6 +13,10 @@ | |||
13 | typedef struct file_header_t { | 13 | typedef struct file_header_t { |
14 | char *name; | 14 | char *name; |
15 | char *link_target; | 15 | char *link_target; |
16 | #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||
17 | char *uname; | ||
18 | char *gname; | ||
19 | #endif | ||
16 | off_t size; | 20 | off_t size; |
17 | uid_t uid; | 21 | uid_t uid; |
18 | gid_t gid; | 22 | gid_t gid; |