aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-28 05:04:09 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-28 05:04:09 +0000
commita60936da062fc569328cd643c460dcf215ed9966 (patch)
treef67e12d028c68c40d6ece445420cd5ab4046ff61
parent9579d87be4ab9b02195749c15a2112e2a4466ab4 (diff)
downloadbusybox-w32-a60936da062fc569328cd643c460dcf215ed9966.tar.gz
busybox-w32-a60936da062fc569328cd643c460dcf215ed9966.tar.bz2
busybox-w32-a60936da062fc569328cd643c460dcf215ed9966.zip
libunarchive: stop using static data in archivers - archive_handle_t
can trivially provide space for that. rpm: code shrink tar: simplify autodetection of bz2/.gz function old new delta static.not_first 1 - -1 static.end 1 - -1 bb_makedev 51 49 -2 static.saved_hardlinks_created 4 - -4 static.saved_hardlinks 4 - -4 longname 4 - -4 linkname 4 - -4 hash_file 251 247 -4 get_header_tar 1528 1521 -7 rpm_main 1711 1697 -14 get_header_cpio 965 944 -21 ------------------------------------------------------------------------------ (add/remove: 0/6 grow/shrink: 0/5 up/down: 0/-66) Total: -66 bytes text data bss dec hex filename 804926 611 6868 812405 c6575 busybox_old 804878 611 6852 812341 c6535 busybox_unstripped
-rw-r--r--archival/ar.c2
-rw-r--r--archival/cpio.c10
-rw-r--r--archival/dpkg.c4
-rw-r--r--archival/libunarchive/data_extract_all.c22
-rw-r--r--archival/libunarchive/get_header_ar.c2
-rw-r--r--archival/libunarchive/get_header_cpio.c11
-rw-r--r--archival/libunarchive/get_header_tar.c93
-rw-r--r--archival/libunarchive/get_header_tar_lzma.c2
-rw-r--r--archival/rpm.c5
-rw-r--r--archival/tar.c12
-rw-r--r--include/unarchive.h12
11 files changed, 89 insertions, 86 deletions
diff --git a/archival/ar.c b/archival/ar.c
index ddc12095c..d49329ce9 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -63,7 +63,7 @@ int ar_main(int argc, char **argv)
63 archive_handle->action_data = data_extract_all; 63 archive_handle->action_data = data_extract_all;
64 } 64 }
65 if (opt & AR_OPT_PRESERVE_DATE) { 65 if (opt & AR_OPT_PRESERVE_DATE) {
66 archive_handle->flags |= ARCHIVE_PRESERVE_DATE; 66 archive_handle->ah_flags |= ARCHIVE_PRESERVE_DATE;
67 } 67 }
68 if (opt & AR_OPT_VERBOSE) { 68 if (opt & AR_OPT_VERBOSE) {
69 archive_handle->action_header = header_verbose_list_ar; 69 archive_handle->action_header = header_verbose_list_ar;
diff --git a/archival/cpio.c b/archival/cpio.c
index 0147d0e96..a10bfa85f 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -204,7 +204,7 @@ int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv)
204 archive_handle = init_handle(); 204 archive_handle = init_handle();
205 archive_handle->src_fd = STDIN_FILENO; 205 archive_handle->src_fd = STDIN_FILENO;
206 archive_handle->seek = seek_by_read; 206 archive_handle->seek = seek_by_read;
207 archive_handle->flags = ARCHIVE_EXTRACT_NEWER; 207 archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER;
208 208
209#if ENABLE_FEATURE_CPIO_O 209#if ENABLE_FEATURE_CPIO_O
210 opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt); 210 opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt);
@@ -241,8 +241,8 @@ int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv)
241 archive_handle->action_data = data_extract_all; 241 archive_handle->action_data = data_extract_all;
242 } 242 }
243 if (opt & CPIO_OPT_UNCONDITIONAL) { 243 if (opt & CPIO_OPT_UNCONDITIONAL) {
244 archive_handle->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; 244 archive_handle->ah_flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
245 archive_handle->flags &= ~ARCHIVE_EXTRACT_NEWER; 245 archive_handle->ah_flags &= ~ARCHIVE_EXTRACT_NEWER;
246 } 246 }
247 if (opt & CPIO_OPT_VERBOSE) { 247 if (opt & CPIO_OPT_VERBOSE) {
248 if (archive_handle->action_header == header_list) { 248 if (archive_handle->action_header == header_list) {
@@ -256,10 +256,10 @@ int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv)
256 archive_handle->seek = seek_by_jump; 256 archive_handle->seek = seek_by_jump;
257 } 257 }
258 if (opt & CPIO_OPT_CREATE_LEADING_DIR) { 258 if (opt & CPIO_OPT_CREATE_LEADING_DIR) {
259 archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; 259 archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS;
260 } 260 }
261 if (opt & CPIO_OPT_PRESERVE_MTIME) { 261 if (opt & CPIO_OPT_PRESERVE_MTIME) {
262 archive_handle->flags |= ARCHIVE_PRESERVE_DATE; 262 archive_handle->ah_flags |= ARCHIVE_PRESERVE_DATE;
263 } 263 }
264 264
265 while (*argv) { 265 while (*argv) {
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 34e5f80e4..22e26f566 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -1532,7 +1532,7 @@ static void unpack_package(deb_file_t *deb_file)
1532 archive_handle->sub_archive->filter = filter_accept_list; 1532 archive_handle->sub_archive->filter = filter_accept_list;
1533 archive_handle->sub_archive->action_data = data_extract_all_prefix; 1533 archive_handle->sub_archive->action_data = data_extract_all_prefix;
1534 archive_handle->sub_archive->buffer = info_prefix; 1534 archive_handle->sub_archive->buffer = info_prefix;
1535 archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; 1535 archive_handle->sub_archive->ah_flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
1536 unpack_ar_archive(archive_handle); 1536 unpack_ar_archive(archive_handle);
1537 1537
1538 /* Run the preinst prior to extracting */ 1538 /* Run the preinst prior to extracting */
@@ -1543,7 +1543,7 @@ static void unpack_package(deb_file_t *deb_file)
1543 init_archive_deb_data(archive_handle); 1543 init_archive_deb_data(archive_handle);
1544 archive_handle->sub_archive->action_data = data_extract_all_prefix; 1544 archive_handle->sub_archive->action_data = data_extract_all_prefix;
1545 archive_handle->sub_archive->buffer = (char*)"/"; /* huh? */ 1545 archive_handle->sub_archive->buffer = (char*)"/"; /* huh? */
1546 archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; 1546 archive_handle->sub_archive->ah_flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
1547 unpack_ar_archive(archive_handle); 1547 unpack_ar_archive(archive_handle);
1548 1548
1549 /* Create the list file */ 1549 /* Create the list file */
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c
index 1b4876799..a67587d72 100644
--- a/archival/libunarchive/data_extract_all.c
+++ b/archival/libunarchive/data_extract_all.c
@@ -12,14 +12,14 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
12 int dst_fd; 12 int dst_fd;
13 int res; 13 int res;
14 14
15 if (archive_handle->flags & ARCHIVE_CREATE_LEADING_DIRS) { 15 if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
16 char *name = xstrdup(file_header->name); 16 char *name = xstrdup(file_header->name);
17 bb_make_directory(dirname(name), -1, FILEUTILS_RECUR); 17 bb_make_directory(dirname(name), -1, FILEUTILS_RECUR);
18 free(name); 18 free(name);
19 } 19 }
20 20
21 /* Check if the file already exists */ 21 /* Check if the file already exists */
22 if (archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) { 22 if (archive_handle->ah_flags & ARCHIVE_EXTRACT_UNCONDITIONAL) {
23 /* Remove the entry if it exists */ 23 /* Remove the entry if it exists */
24 if (((file_header->mode & S_IFMT) != S_IFDIR) 24 if (((file_header->mode & S_IFMT) != S_IFDIR)
25 && (unlink(file_header->name) == -1) 25 && (unlink(file_header->name) == -1)
@@ -29,7 +29,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
29 file_header->name); 29 file_header->name);
30 } 30 }
31 } 31 }
32 else if (archive_handle->flags & ARCHIVE_EXTRACT_NEWER) { 32 else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
33 /* Remove the existing entry if its older than the extracted entry */ 33 /* Remove the existing entry if its older than the extracted entry */
34 struct stat statbuf; 34 struct stat statbuf;
35 if (lstat(file_header->name, &statbuf) == -1) { 35 if (lstat(file_header->name, &statbuf) == -1) {
@@ -38,7 +38,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
38 } 38 }
39 } 39 }
40 else if (statbuf.st_mtime <= file_header->mtime) { 40 else if (statbuf.st_mtime <= file_header->mtime) {
41 if (!(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 41 if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
42 bb_error_msg("%s not created: newer or " 42 bb_error_msg("%s not created: newer or "
43 "same age file exists", file_header->name); 43 "same age file exists", file_header->name);
44 } 44 }
@@ -58,7 +58,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
58 ) { 58 ) {
59 /* hard link */ 59 /* hard link */
60 res = link(file_header->link_target, file_header->name); 60 res = link(file_header->link_target, file_header->name);
61 if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { 61 if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
62 bb_perror_msg("cannot create %slink " 62 bb_perror_msg("cannot create %slink "
63 "from %s to %s", "hard", 63 "from %s to %s", "hard",
64 file_header->name, 64 file_header->name,
@@ -78,7 +78,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
78 case S_IFDIR: 78 case S_IFDIR:
79 res = mkdir(file_header->name, file_header->mode); 79 res = mkdir(file_header->name, file_header->mode);
80 if ((res == -1) && (errno != EISDIR) 80 if ((res == -1) && (errno != EISDIR)
81 && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) 81 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
82 ) { 82 ) {
83 bb_perror_msg("cannot make dir %s", file_header->name); 83 bb_perror_msg("cannot make dir %s", file_header->name);
84 } 84 }
@@ -87,7 +87,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
87 /* Symlink */ 87 /* Symlink */
88 res = symlink(file_header->link_target, file_header->name); 88 res = symlink(file_header->link_target, file_header->name);
89 if ((res == -1) 89 if ((res == -1)
90 && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) 90 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
91 ) { 91 ) {
92 bb_perror_msg("cannot create %slink " 92 bb_perror_msg("cannot create %slink "
93 "from %s to %s", "sym", 93 "from %s to %s", "sym",
@@ -101,7 +101,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
101 case S_IFIFO: 101 case S_IFIFO:
102 res = mknod(file_header->name, file_header->mode, file_header->device); 102 res = mknod(file_header->name, file_header->mode, file_header->device);
103 if ((res == -1) 103 if ((res == -1)
104 && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) 104 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
105 ) { 105 ) {
106 bb_perror_msg("cannot create node %s", file_header->name); 106 bb_perror_msg("cannot create node %s", file_header->name);
107 } 107 }
@@ -111,7 +111,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
111 } 111 }
112 } 112 }
113 113
114 if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_OWN)) { 114 if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_OWN)) {
115#if ENABLE_FEATURE_TAR_UNAME_GNAME 115#if ENABLE_FEATURE_TAR_UNAME_GNAME
116 uid_t uid = file_header->uid; 116 uid_t uid = file_header->uid;
117 gid_t gid = file_header->gid; 117 gid_t gid = file_header->gid;
@@ -133,11 +133,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
133 /* uclibc has no lchmod, glibc is even stranger - 133 /* uclibc has no lchmod, glibc is even stranger -
134 * it has lchmod which seems to do nothing! 134 * it has lchmod which seems to do nothing!
135 * so we use chmod... */ 135 * so we use chmod... */
136 if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_PERM)) { 136 if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_PERM)) {
137 chmod(file_header->name, file_header->mode); 137 chmod(file_header->name, file_header->mode);
138 } 138 }
139 /* same for utime */ 139 /* same for utime */
140 if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) { 140 if (archive_handle->ah_flags & ARCHIVE_PRESERVE_DATE) {
141 struct utimbuf t; 141 struct utimbuf t;
142 t.actime = t.modtime = file_header->mtime; 142 t.actime = t.modtime = file_header->mtime;
143 utime(file_header->name, &t); 143 utime(file_header->name, &t);
diff --git a/archival/libunarchive/get_header_ar.c b/archival/libunarchive/get_header_ar.c
index 05222992d..59fd34c73 100644
--- a/archival/libunarchive/get_header_ar.c
+++ b/archival/libunarchive/get_header_ar.c
@@ -110,7 +110,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
110 archive_handle->action_header(typed); 110 archive_handle->action_header(typed);
111 if (archive_handle->sub_archive) { 111 if (archive_handle->sub_archive) {
112 while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) 112 while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS)
113 /* repeat */; 113 continue;
114 } else { 114 } else {
115 archive_handle->action_data(archive_handle); 115 archive_handle->action_data(archive_handle);
116 } 116 }
diff --git a/archival/libunarchive/get_header_cpio.c b/archival/libunarchive/get_header_cpio.c
index 4ed18c68f..96be4b5ac 100644
--- a/archival/libunarchive/get_header_cpio.c
+++ b/archival/libunarchive/get_header_cpio.c
@@ -19,9 +19,6 @@ typedef struct hardlinks_s {
19 19
20char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) 20char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
21{ 21{
22 static hardlinks_t *saved_hardlinks = NULL;
23 static hardlinks_t *saved_hardlinks_created = NULL;
24
25 file_header_t *file_header = archive_handle->file_header; 22 file_header_t *file_header = archive_handle->file_header;
26 char cpio_header[110]; 23 char cpio_header[110];
27 char dummy[16]; 24 char dummy[16];
@@ -29,6 +26,14 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
29 int major, minor, nlink, mode, inode; 26 int major, minor, nlink, mode, inode;
30 unsigned size, uid, gid, mtime; 27 unsigned size, uid, gid, mtime;
31 28
29#define saved_hardlinks (*(hardlinks_t **)(&archive_handle->ah_priv[0]))
30#define saved_hardlinks_created (*(hardlinks_t **)(&archive_handle->ah_priv[1]))
31// if (!archive_handle->ah_priv_inited) {
32// archive_handle->ah_priv_inited = 1;
33// saved_hardlinks = NULL;
34// saved_hardlinks_created = NULL;
35// }
36
32 /* There can be padding before archive header */ 37 /* There can be padding before archive header */
33 data_align(archive_handle, 4); 38 data_align(archive_handle, 4);
34 39
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c
index a0a53c908..69362f1cc 100644
--- a/archival/libunarchive/get_header_tar.c
+++ b/archival/libunarchive/get_header_tar.c
@@ -14,26 +14,13 @@
14#include "libbb.h" 14#include "libbb.h"
15#include "unarchive.h" 15#include "unarchive.h"
16 16
17#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
18static char *longname;
19static char *linkname;
20#else
21enum {
22 longname = 0,
23 linkname = 0,
24};
25#endif
26
27/* NB: _DESTROYS_ str[len] character! */ 17/* NB: _DESTROYS_ str[len] character! */
28static unsigned long long getOctal(char *str, int len) 18static unsigned long long getOctal(char *str, int len)
29{ 19{
30 unsigned long long v; 20 unsigned long long v;
31 /* Actually, tar header allows leading spaces also. 21 /* NB: leading spaces are allowed. Using strtoull to handle that.
32 * Oh well, we will be liberal and skip this... 22 * The downside is that we accept e.g. "-123" too :)
33 * The only downside probably is that we allow "-123" too :) 23 */
34 if (*str < '0' || *str > '7')
35 bb_error_msg_and_die("corrupted octal value in tar header");
36 */
37 str[len] = '\0'; 24 str[len] = '\0';
38 v = strtoull(str, &str, 8); 25 v = strtoull(str, &str, 8);
39 if (*str && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || *str != ' ')) 26 if (*str && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || *str != ' '))
@@ -45,11 +32,6 @@ static unsigned long long getOctal(char *str, int len)
45void BUG_tar_header_size(void); 32void BUG_tar_header_size(void);
46char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) 33char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
47{ 34{
48 static smallint end;
49#if ENABLE_FEATURE_TAR_AUTODETECT
50 static smallint not_first;
51#endif
52
53 file_header_t *file_header = archive_handle->file_header; 35 file_header_t *file_header = archive_handle->file_header;
54 struct { 36 struct {
55 /* ustar header, Posix 1003.1 */ 37 /* ustar header, Posix 1003.1 */
@@ -65,7 +47,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
65 /* POSIX: "ustar" NUL "00" */ 47 /* POSIX: "ustar" NUL "00" */
66 /* GNU tar: "ustar " NUL */ 48 /* GNU tar: "ustar " NUL */
67 /* Normally it's defined as magic[6] followed by 49 /* Normally it's defined as magic[6] followed by
68 * version[2], but we put them together to save code. 50 * version[2], but we put them together to simplify code
69 */ 51 */
70 char magic[8]; /* 257-264 */ 52 char magic[8]; /* 257-264 */
71 char uname[32]; /* 265-296 */ 53 char uname[32]; /* 265-296 */
@@ -82,6 +64,22 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
82#endif 64#endif
83 int parse_names; 65 int parse_names;
84 66
67 /* Our "private data" */
68#define p_end (*(smallint *)(&archive_handle->ah_priv[0]))
69#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
70#define p_longname (*(char* *)(&archive_handle->ah_priv[1]))
71#define p_linkname (*(char* *)(&archive_handle->ah_priv[2]))
72#else
73#define p_longname 0
74#define p_linkname 0
75#endif
76// if (!archive_handle->ah_priv_inited) {
77// archive_handle->ah_priv_inited = 1;
78// p_end = 0;
79// USE_FEATURE_TAR_GNU_EXTENSIONS(p_longname = NULL;)
80// USE_FEATURE_TAR_GNU_EXTENSIONS(p_linkname = NULL;)
81// }
82
85 if (sizeof(tar) != 512) 83 if (sizeof(tar) != 512)
86 BUG_tar_header_size(); 84 BUG_tar_header_size();
87 85
@@ -95,7 +93,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
95 93
96#if ENABLE_DESKTOP 94#if ENABLE_DESKTOP
97 i = full_read(archive_handle->src_fd, &tar, 512); 95 i = full_read(archive_handle->src_fd, &tar, 512);
98 /* if GNU tar sees EOF in above read, it says: 96 /* If GNU tar sees EOF in above read, it says:
99 * "tar: A lone zero block at N", where N = kilobyte 97 * "tar: A lone zero block at N", where N = kilobyte
100 * where EOF was met (not EOF block, actual EOF!), 98 * where EOF was met (not EOF block, actual EOF!),
101 * and tar will exit with error code 0. 99 * and tar will exit with error code 0.
@@ -113,18 +111,18 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
113 111
114 /* If there is no filename its an empty header */ 112 /* If there is no filename its an empty header */
115 if (tar.name[0] == 0 && tar.prefix[0] == 0) { 113 if (tar.name[0] == 0 && tar.prefix[0] == 0) {
116 if (end) { 114 if (p_end) {
117 /* This is the second consecutive empty header! End of archive! 115 /* Second consecutive empty header - end of archive.
118 * Read until the end to empty the pipe from gz or bz2 116 * Read until the end to empty the pipe from gz or bz2
119 */ 117 */
120 while (full_read(archive_handle->src_fd, &tar, 512) == 512) 118 while (full_read(archive_handle->src_fd, &tar, 512) == 512)
121 continue; 119 continue;
122 return EXIT_FAILURE; 120 return EXIT_FAILURE;
123 } 121 }
124 end = 1; 122 p_end = 1;
125 return EXIT_SUCCESS; 123 return EXIT_SUCCESS;
126 } 124 }
127 end = 0; 125 p_end = 0;
128 126
129 /* Check header has valid magic, "ustar" is for the proper tar, 127 /* Check header has valid magic, "ustar" is for the proper tar,
130 * five NULs are for the old tar format */ 128 * five NULs are for the old tar format */
@@ -136,12 +134,10 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
136 char FAST_FUNC (*get_header_ptr)(archive_handle_t *); 134 char FAST_FUNC (*get_header_ptr)(archive_handle_t *);
137 135
138 /* tar gz/bz autodetect: check for gz/bz2 magic. 136 /* tar gz/bz autodetect: check for gz/bz2 magic.
139 * If it is the very first block, and we see the magic, 137 * If we see the magic, and it is the very first block,
140 * we can switch to get_header_tar_gz/bz2/lzma(). 138 * we can switch to get_header_tar_gz/bz2/lzma().
141 * Needs seekable fd. I wish recv(MSG_PEEK) works 139 * Needs seekable fd. I wish recv(MSG_PEEK) works
142 * on any fd... */ 140 * on any fd... */
143 if (not_first)
144 goto err;
145#if ENABLE_FEATURE_TAR_GZIP 141#if ENABLE_FEATURE_TAR_GZIP
146 if (tar.name[0] == 0x1f && tar.name[1] == (char)0x8b) { /* gzip */ 142 if (tar.name[0] == 0x1f && tar.name[1] == (char)0x8b) { /* gzip */
147 get_header_ptr = get_header_tar_gz; 143 get_header_ptr = get_header_tar_gz;
@@ -155,6 +151,9 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
155 } else 151 } else
156#endif 152#endif
157 goto err; 153 goto err;
154 /* Two different causes for lseek() != 0:
155 * unseekable fd (would like to support that too, but...),
156 * or not first block (false positive, it's not .gz/.bz2!) */
158 if (lseek(archive_handle->src_fd, -512, SEEK_CUR) != 0) 157 if (lseek(archive_handle->src_fd, -512, SEEK_CUR) != 0)
159 goto err; 158 goto err;
160 while (get_header_ptr(archive_handle) == EXIT_SUCCESS) 159 while (get_header_ptr(archive_handle) == EXIT_SUCCESS)
@@ -165,10 +164,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
165 bb_error_msg_and_die("invalid tar magic"); 164 bb_error_msg_and_die("invalid tar magic");
166 } 165 }
167 166
168#if ENABLE_FEATURE_TAR_AUTODETECT
169 not_first = 1;
170#endif
171
172 /* Do checksum on headers. 167 /* Do checksum on headers.
173 * POSIX says that checksum is done on unsigned bytes, but 168 * POSIX says that checksum is done on unsigned bytes, but
174 * Sun and HP-UX gets it wrong... more details in 169 * Sun and HP-UX gets it wrong... more details in
@@ -219,7 +214,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
219 tar.prefix[0] = t; 214 tar.prefix[0] = t;
220 } 215 }
221 file_header->link_target = NULL; 216 file_header->link_target = NULL;
222 if (!linkname && parse_names && tar.linkname[0]) { 217 if (!p_linkname && parse_names && tar.linkname[0]) {
223 file_header->link_target = xstrndup(tar.linkname, sizeof(tar.linkname)); 218 file_header->link_target = xstrndup(tar.linkname, sizeof(tar.linkname));
224 /* FIXME: what if we have non-link object with link_target? */ 219 /* FIXME: what if we have non-link object with link_target? */
225 /* Will link_target be free()ed? */ 220 /* Will link_target be free()ed? */
@@ -236,7 +231,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
236 file_header->mode = 07777 & GET_OCTAL(tar.mode); 231 file_header->mode = 07777 & GET_OCTAL(tar.mode);
237 232
238 file_header->name = NULL; 233 file_header->name = NULL;
239 if (!longname && parse_names) { 234 if (!p_longname && parse_names) {
240 /* we trash mode[0] here, it's ok */ 235 /* we trash mode[0] here, it's ok */
241 //tar.name[sizeof(tar.name)] = '\0'; - gcc 4.3.0 would complain 236 //tar.name[sizeof(tar.name)] = '\0'; - gcc 4.3.0 would complain
242 tar.mode[0] = '\0'; 237 tar.mode[0] = '\0';
@@ -284,20 +279,20 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
284#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 279#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
285 case 'L': 280 case 'L':
286 /* free: paranoia: tar with several consecutive longnames */ 281 /* free: paranoia: tar with several consecutive longnames */
287 free(longname); 282 free(p_longname);
288 /* For paranoia reasons we allocate extra NUL char */ 283 /* For paranoia reasons we allocate extra NUL char */
289 longname = xzalloc(file_header->size + 1); 284 p_longname = xzalloc(file_header->size + 1);
290 /* We read ASCIZ string, including NUL */ 285 /* We read ASCIZ string, including NUL */
291 xread(archive_handle->src_fd, longname, file_header->size); 286 xread(archive_handle->src_fd, p_longname, file_header->size);
292 archive_handle->offset += file_header->size; 287 archive_handle->offset += file_header->size;
293 /* return get_header_tar(archive_handle); */ 288 /* return get_header_tar(archive_handle); */
294 /* gcc 4.1.1 didn't optimize it into jump */ 289 /* gcc 4.1.1 didn't optimize it into jump */
295 /* so we will do it ourself, this also saves stack */ 290 /* so we will do it ourself, this also saves stack */
296 goto again; 291 goto again;
297 case 'K': 292 case 'K':
298 free(linkname); 293 free(p_linkname);
299 linkname = xzalloc(file_header->size + 1); 294 p_linkname = xzalloc(file_header->size + 1);
300 xread(archive_handle->src_fd, linkname, file_header->size); 295 xread(archive_handle->src_fd, p_linkname, file_header->size);
301 archive_handle->offset += file_header->size; 296 archive_handle->offset += file_header->size;
302 /* return get_header_tar(archive_handle); */ 297 /* return get_header_tar(archive_handle); */
303 goto again; 298 goto again;
@@ -324,13 +319,13 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
324 } 319 }
325 320
326#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 321#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
327 if (longname) { 322 if (p_longname) {
328 file_header->name = longname; 323 file_header->name = p_longname;
329 longname = NULL; 324 p_longname = NULL;
330 } 325 }
331 if (linkname) { 326 if (p_linkname) {
332 file_header->link_target = linkname; 327 file_header->link_target = p_linkname;
333 linkname = NULL; 328 p_linkname = NULL;
334 } 329 }
335#endif 330#endif
336 if (!strncmp(file_header->name, "/../"+1, 3) 331 if (!strncmp(file_header->name, "/../"+1, 3)
@@ -349,7 +344,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
349 /* Note that we kill the '/' only after action_header() */ 344 /* Note that we kill the '/' only after action_header() */
350 /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ 345 /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */
351 if (cp) *cp = '\0'; 346 if (cp) *cp = '\0';
352 archive_handle->flags |= ARCHIVE_EXTRACT_QUIET; 347 archive_handle->ah_flags |= ARCHIVE_EXTRACT_QUIET;
353 archive_handle->action_data(archive_handle); 348 archive_handle->action_data(archive_handle);
354 llist_add_to(&(archive_handle->passed), file_header->name); 349 llist_add_to(&(archive_handle->passed), file_header->name);
355 } else { 350 } else {
diff --git a/archival/libunarchive/get_header_tar_lzma.c b/archival/libunarchive/get_header_tar_lzma.c
index 4ae125f4a..730c1b1bb 100644
--- a/archival/libunarchive/get_header_tar_lzma.c
+++ b/archival/libunarchive/get_header_tar_lzma.c
@@ -9,7 +9,7 @@
9#include "libbb.h" 9#include "libbb.h"
10#include "unarchive.h" 10#include "unarchive.h"
11 11
12char FAST_FUNC get_header_tar_lzma(archive_handle_t * archive_handle) 12char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle)
13{ 13{
14 /* Can't lseek over pipes */ 14 /* Can't lseek over pipes */
15 archive_handle->seek = seek_by_read; 15 archive_handle->seek = seek_by_read;
diff --git a/archival/rpm.c b/archival/rpm.c
index 3d03dbcce..c4bcd605d 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -202,10 +202,9 @@ static void extract_cpio_gz(int fd)
202 archive_handle->seek = seek_by_read; 202 archive_handle->seek = seek_by_read;
203 //archive_handle->action_header = header_list; 203 //archive_handle->action_header = header_list;
204 archive_handle->action_data = data_extract_all; 204 archive_handle->action_data = data_extract_all;
205 archive_handle->flags |= ARCHIVE_PRESERVE_DATE; 205 archive_handle->ah_flags = ARCHIVE_PRESERVE_DATE | ARCHIVE_CREATE_LEADING_DIRS;
206 archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS;
207 archive_handle->src_fd = fd; 206 archive_handle->src_fd = fd;
208 archive_handle->offset = 0; 207 /*archive_handle->offset = 0; - init_handle() did it */
209 208
210 xread(archive_handle->src_fd, &magic, 2); 209 xread(archive_handle->src_fd, &magic, 2);
211#if BB_MMU 210#if BB_MMU
diff --git a/archival/tar.c b/archival/tar.c
index 2a140184c..526edb69d 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -814,9 +814,9 @@ int tar_main(int argc ATTRIBUTE_UNUSED, char **argv)
814 814
815 /* Initialise default values */ 815 /* Initialise default values */
816 tar_handle = init_handle(); 816 tar_handle = init_handle();
817 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS 817 tar_handle->ah_flags = ARCHIVE_CREATE_LEADING_DIRS
818 | ARCHIVE_PRESERVE_DATE 818 | ARCHIVE_PRESERVE_DATE
819 | ARCHIVE_EXTRACT_UNCONDITIONAL; 819 | ARCHIVE_EXTRACT_UNCONDITIONAL;
820 820
821 /* Prepend '-' to the first argument if required */ 821 /* Prepend '-' to the first argument if required */
822 opt_complementary = "--:" // first arg is options 822 opt_complementary = "--:" // first arg is options
@@ -862,13 +862,13 @@ int tar_main(int argc ATTRIBUTE_UNUSED, char **argv)
862 tar_handle->action_data = data_extract_to_stdout; 862 tar_handle->action_data = data_extract_to_stdout;
863 863
864 if (opt & OPT_KEEP_OLD) 864 if (opt & OPT_KEEP_OLD)
865 tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; 865 tar_handle->ah_flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL;
866 866
867 if (opt & OPT_NOPRESERVE_OWN) 867 if (opt & OPT_NOPRESERVE_OWN)
868 tar_handle->flags |= ARCHIVE_NOPRESERVE_OWN; 868 tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_OWN;
869 869
870 if (opt & OPT_NOPRESERVE_PERM) 870 if (opt & OPT_NOPRESERVE_PERM)
871 tar_handle->flags |= ARCHIVE_NOPRESERVE_PERM; 871 tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_PERM;
872 872
873 if (opt & OPT_GZIP) 873 if (opt & OPT_GZIP)
874 get_header_ptr = get_header_tar_gz; 874 get_header_ptr = get_header_tar_gz;
diff --git a/include/unarchive.h b/include/unarchive.h
index 721f879a4..1fab570c3 100644
--- a/include/unarchive.h
+++ b/include/unarchive.h
@@ -30,7 +30,7 @@ typedef struct file_header_t {
30} file_header_t; 30} file_header_t;
31 31
32typedef struct archive_handle_t { 32typedef struct archive_handle_t {
33 /* define if the header and data component should be processed */ 33 /* Define if the header and data component should be processed */
34 char FAST_FUNC (*filter)(struct archive_handle_t *); 34 char FAST_FUNC (*filter)(struct archive_handle_t *);
35 llist_t *accept; 35 llist_t *accept;
36 /* List of files that have been rejected */ 36 /* List of files that have been rejected */
@@ -41,10 +41,10 @@ typedef struct archive_handle_t {
41 /* Contains the processed header entry */ 41 /* Contains the processed header entry */
42 file_header_t *file_header; 42 file_header_t *file_header;
43 43
44 /* process the header component, e.g. tar -t */ 44 /* Process the header component, e.g. tar -t */
45 void FAST_FUNC (*action_header)(const file_header_t *); 45 void FAST_FUNC (*action_header)(const file_header_t *);
46 46
47 /* process the data component, e.g. extract to filesystem */ 47 /* Process the data component, e.g. extract to filesystem */
48 void FAST_FUNC (*action_data)(struct archive_handle_t *); 48 void FAST_FUNC (*action_data)(struct archive_handle_t *);
49 49
50 /* How to process any sub archive, e.g. get_header_tar_gz */ 50 /* How to process any sub archive, e.g. get_header_tar_gz */
@@ -66,7 +66,11 @@ typedef struct archive_handle_t {
66 char *buffer; 66 char *buffer;
67 67
68 /* Flags and misc. stuff */ 68 /* Flags and misc. stuff */
69 unsigned char flags; 69 unsigned char ah_flags;
70
71 /* "Private" storage for archivers */
72// unsigned char ah_priv_inited;
73 void *ah_priv[8];
70 74
71} archive_handle_t; 75} archive_handle_t;
72 76