diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-28 05:04:09 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-28 05:04:09 +0000 |
commit | a60936da062fc569328cd643c460dcf215ed9966 (patch) | |
tree | f67e12d028c68c40d6ece445420cd5ab4046ff61 | |
parent | 9579d87be4ab9b02195749c15a2112e2a4466ab4 (diff) | |
download | busybox-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.c | 2 | ||||
-rw-r--r-- | archival/cpio.c | 10 | ||||
-rw-r--r-- | archival/dpkg.c | 4 | ||||
-rw-r--r-- | archival/libunarchive/data_extract_all.c | 22 | ||||
-rw-r--r-- | archival/libunarchive/get_header_ar.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/get_header_cpio.c | 11 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 93 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar_lzma.c | 2 | ||||
-rw-r--r-- | archival/rpm.c | 5 | ||||
-rw-r--r-- | archival/tar.c | 12 | ||||
-rw-r--r-- | include/unarchive.h | 12 |
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 | ||
20 | char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) | 20 | char 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 | ||
18 | static char *longname; | ||
19 | static char *linkname; | ||
20 | #else | ||
21 | enum { | ||
22 | longname = 0, | ||
23 | linkname = 0, | ||
24 | }; | ||
25 | #endif | ||
26 | |||
27 | /* NB: _DESTROYS_ str[len] character! */ | 17 | /* NB: _DESTROYS_ str[len] character! */ |
28 | static unsigned long long getOctal(char *str, int len) | 18 | static 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) | |||
45 | void BUG_tar_header_size(void); | 32 | void BUG_tar_header_size(void); |
46 | char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | 33 | char 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 | ||
12 | char FAST_FUNC get_header_tar_lzma(archive_handle_t * archive_handle) | 12 | char 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 | ||
32 | typedef struct archive_handle_t { | 32 | typedef 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 | ||