diff options
| author | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-03 14:05:15 +0000 |
|---|---|---|
| committer | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-03 14:05:15 +0000 |
| commit | 237ae42fc96ede945d28d9054f045b73e419d089 (patch) | |
| tree | 3fb6a9c10150303aca3c218b47aaf327a186382a | |
| parent | 2fc54a9258c3aa5dad2ce9807ba85cf29af2668e (diff) | |
| download | busybox-w32-237ae42fc96ede945d28d9054f045b73e419d089.tar.gz busybox-w32-237ae42fc96ede945d28d9054f045b73e419d089.tar.bz2 busybox-w32-237ae42fc96ede945d28d9054f045b73e419d089.zip | |
Abstract read and seek in unarchiving code, convert bunzip to file descriptors, support tar -j
28 files changed, 464 insertions, 330 deletions
diff --git a/archival/ar.c b/archival/ar.c index 997927346..71cde4ebe 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
| @@ -50,7 +50,7 @@ static void header_verbose_list_ar(const file_header_t *file_header) | |||
| 50 | printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid, (int) file_header->size, &mtime[4], file_header->name); | 50 | printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid, (int) file_header->size, &mtime[4], file_header->name); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO | 53 | #if !defined CONFIG_TAR && !defined CONFIG_DPKG_DEB && !defined CONFIG_CPIO |
| 54 | /* This is simpler than data_extract_all */ | 54 | /* This is simpler than data_extract_all */ |
| 55 | static void data_extract_regular_file(archive_handle_t *archive_handle) | 55 | static void data_extract_regular_file(archive_handle_t *archive_handle) |
| 56 | { | 56 | { |
| @@ -59,7 +59,7 @@ static void data_extract_regular_file(archive_handle_t *archive_handle) | |||
| 59 | 59 | ||
| 60 | file_header = archive_handle->file_header; | 60 | file_header = archive_handle->file_header; |
| 61 | dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); | 61 | dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); |
| 62 | copy_file_chunk_fd(archive_handle->src_fd, dst_fd, file_header->size); | 62 | archive_copy_file(archive_handle, dst_fd); |
| 63 | close(dst_fd); | 63 | close(dst_fd); |
| 64 | 64 | ||
| 65 | chmod(file_header->name, file_header->mode); | 65 | chmod(file_header->name, file_header->mode); |
| @@ -80,18 +80,10 @@ extern int ar_main(int argc, char **argv) | |||
| 80 | archive_handle_t *archive_handle; | 80 | archive_handle_t *archive_handle; |
| 81 | int opt; | 81 | int opt; |
| 82 | 82 | ||
| 83 | #ifndef CONFIG_DPKG_DEB | 83 | #if !defined CONFIG_DPKG_DEB && !defined CONFIG_DPKG |
| 84 | char magic[8]; | 84 | char magic[8]; |
| 85 | #endif | 85 | #endif |
| 86 | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO | ||
| 87 | archive_handle = init_handle(); | 86 | archive_handle = init_handle(); |
| 88 | #else | ||
| 89 | archive_handle = xcalloc(1, sizeof(archive_handle_t)); | ||
| 90 | archive_handle->filter = filter_accept_all; | ||
| 91 | archive_handle->action_data = data_skip; | ||
| 92 | archive_handle->action_header = header_skip; | ||
| 93 | archive_handle->file_header =xmalloc(sizeof(file_header_t)); | ||
| 94 | #endif | ||
| 95 | 87 | ||
| 96 | while ((opt = getopt(argc, argv, "covtpxX")) != -1) { | 88 | while ((opt = getopt(argc, argv, "covtpxX")) != -1) { |
| 97 | switch (opt) { | 89 | switch (opt) { |
| @@ -104,7 +96,7 @@ extern int ar_main(int argc, char **argv) | |||
| 104 | case 'X': | 96 | case 'X': |
| 105 | archive_handle->action_header = header_verbose_list_ar; | 97 | archive_handle->action_header = header_verbose_list_ar; |
| 106 | case 'x': /* extract */ | 98 | case 'x': /* extract */ |
| 107 | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO | 99 | #if defined CONFIG_TAR || defined CONFIG_DPKG_DEB || defined CONFIG_CPIO |
| 108 | archive_handle->action_data = data_extract_all; | 100 | archive_handle->action_data = data_extract_all; |
| 109 | #else | 101 | #else |
| 110 | archive_handle->action_data = data_extract_regular_file; | 102 | archive_handle->action_data = data_extract_regular_file; |
| @@ -136,10 +128,10 @@ extern int ar_main(int argc, char **argv) | |||
| 136 | optind++; | 128 | optind++; |
| 137 | } | 129 | } |
| 138 | 130 | ||
| 139 | #if defined CONFIG_DPKG_DEB | 131 | #if defined CONFIG_DPKG_DEB || defined CONFIG_DPKG |
| 140 | unpack_ar_archive(archive_handle); | 132 | unpack_ar_archive(archive_handle); |
| 141 | #else | 133 | #else |
| 142 | xread_all(archive_handle->src_fd, magic, 7); | 134 | archive_xread_all(archive_handle, magic, 7); |
| 143 | if (strncmp(magic, "!<arch>", 7) != 0) { | 135 | if (strncmp(magic, "!<arch>", 7) != 0) { |
| 144 | error_msg_and_die("Invalid ar magic"); | 136 | error_msg_and_die("Invalid ar magic"); |
| 145 | } | 137 | } |
diff --git a/archival/bunzip2.c b/archival/bunzip2.c index 9f346f266..d5c06f4fd 100644 --- a/archival/bunzip2.c +++ b/archival/bunzip2.c | |||
| @@ -17,9 +17,11 @@ | |||
| 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <fcntl.h> | ||
| 20 | #include <getopt.h> | 21 | #include <getopt.h> |
| 21 | #include <stdio.h> | 22 | #include <stdio.h> |
| 22 | #include <stdlib.h> | 23 | #include <stdlib.h> |
| 24 | #include <string.h> | ||
| 23 | #include <unistd.h> | 25 | #include <unistd.h> |
| 24 | 26 | ||
| 25 | #include "busybox.h" | 27 | #include "busybox.h" |
| @@ -33,8 +35,8 @@ int bunzip2_main(int argc, char **argv) | |||
| 33 | int opt = 0; | 35 | int opt = 0; |
| 34 | int status; | 36 | int status; |
| 35 | 37 | ||
| 36 | FILE *src_stream; | 38 | int src_fd; |
| 37 | FILE *dst_stream; | 39 | int dst_fd; |
| 38 | char *save_name = NULL; | 40 | char *save_name = NULL; |
| 39 | char *delete_name = NULL; | 41 | char *delete_name = NULL; |
| 40 | 42 | ||
| @@ -59,10 +61,10 @@ int bunzip2_main(int argc, char **argv) | |||
| 59 | /* Set input filename and number */ | 61 | /* Set input filename and number */ |
| 60 | if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) { | 62 | if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) { |
| 61 | flags |= bunzip_to_stdout; | 63 | flags |= bunzip_to_stdout; |
| 62 | src_stream = stdin; | 64 | src_fd = fileno(stdin); |
| 63 | } else { | 65 | } else { |
| 64 | /* Open input file */ | 66 | /* Open input file */ |
| 65 | src_stream = xfopen(argv[optind], "r"); | 67 | src_fd = xopen(argv[optind], O_RDONLY); |
| 66 | 68 | ||
| 67 | save_name = xstrdup(argv[optind]); | 69 | save_name = xstrdup(argv[optind]); |
| 68 | if (strcmp(save_name + strlen(save_name) - 4, ".bz2") != 0) | 70 | if (strcmp(save_name + strlen(save_name) - 4, ".bz2") != 0) |
| @@ -71,29 +73,30 @@ int bunzip2_main(int argc, char **argv) | |||
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | /* Check that the input is sane. */ | 75 | /* Check that the input is sane. */ |
| 74 | if (isatty(fileno(src_stream)) && (flags & bunzip_force) == 0) | 76 | if (isatty(src_fd) && (flags & bunzip_force) == 0) { |
| 75 | error_msg_and_die("compressed data not read from terminal. Use -f to force it."); | 77 | error_msg_and_die("compressed data not read from terminal. Use -f to force it."); |
| 78 | } | ||
| 76 | 79 | ||
| 77 | if (flags & bunzip_to_stdout) { | 80 | if (flags & bunzip_to_stdout) { |
| 78 | dst_stream = stdout; | 81 | dst_fd = fileno(stdout); |
| 79 | } else { | 82 | } else { |
| 80 | dst_stream = xfopen(save_name, "w"); | 83 | dst_fd = xopen(save_name, O_WRONLY | O_CREAT); |
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | if (uncompressStream(src_stream, dst_stream)) { | 86 | if (uncompressStream(src_fd, dst_fd)) { |
| 84 | if (!(flags & bunzip_to_stdout)) | 87 | if (!(flags & bunzip_to_stdout)) { |
| 85 | delete_name = argv[optind]; | 88 | delete_name = argv[optind]; |
| 89 | } | ||
| 86 | status = EXIT_SUCCESS; | 90 | status = EXIT_SUCCESS; |
| 87 | } else { | 91 | } else { |
| 88 | if (!(flags & bunzip_to_stdout)) | 92 | if (!(flags & bunzip_to_stdout)) { |
| 89 | delete_name = save_name; | 93 | delete_name = save_name; |
| 94 | } | ||
| 90 | status = EXIT_FAILURE; | 95 | status = EXIT_FAILURE; |
| 91 | } | 96 | } |
| 92 | 97 | ||
| 93 | if (delete_name) { | 98 | if ((delete_name) && (unlink(delete_name) < 0)) { |
| 94 | if (unlink(delete_name) < 0) { | 99 | error_msg_and_die("Couldn't remove %s", delete_name); |
| 95 | error_msg_and_die("Couldn't remove %s", delete_name); | ||
| 96 | } | ||
| 97 | } | 100 | } |
| 98 | 101 | ||
| 99 | return status; | 102 | return status; |
diff --git a/archival/config.in b/archival/config.in index 689561b8e..3ec03fd8c 100644 --- a/archival/config.in +++ b/archival/config.in | |||
| @@ -26,6 +26,7 @@ bool 'rpm2cpio' CONFIG_RPM2CPIO | |||
| 26 | bool 'tar' CONFIG_TAR | 26 | bool 'tar' CONFIG_TAR |
| 27 | if [ "$CONFIG_TAR" = "y" ] ; then | 27 | if [ "$CONFIG_TAR" = "y" ] ; then |
| 28 | bool ' Enable archive creation' CONFIG_FEATURE_TAR_CREATE | 28 | bool ' Enable archive creation' CONFIG_FEATURE_TAR_CREATE |
| 29 | bool ' Enable -j option to handle .tar.bz2 files' CONFIG_FEATURE_TAR_BZIP2 | ||
| 29 | bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE | 30 | bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE |
| 30 | bool ' Enable -z option' CONFIG_FEATURE_TAR_GZIP | 31 | bool ' Enable -z option' CONFIG_FEATURE_TAR_GZIP |
| 31 | bool ' Enable support for old tar header format' CONFIG_FEATURE_TAR_OLD_FORMAT | 32 | bool ' Enable support for old tar header format' CONFIG_FEATURE_TAR_OLD_FORMAT |
diff --git a/archival/cpio.c b/archival/cpio.c index 761517516..0d0614932 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
| @@ -45,6 +45,7 @@ extern int cpio_main(int argc, char **argv) | |||
| 45 | /* Initialise */ | 45 | /* Initialise */ |
| 46 | archive_handle = init_handle(); | 46 | archive_handle = init_handle(); |
| 47 | archive_handle->src_fd = fileno(stdin); | 47 | archive_handle->src_fd = fileno(stdin); |
| 48 | archive_handle->seek = seek_by_char; | ||
| 48 | archive_handle->action_header = header_list; | 49 | archive_handle->action_header = header_list; |
| 49 | 50 | ||
| 50 | while ((opt = getopt(argc, argv, "idmuvtF:")) != -1) { | 51 | while ((opt = getopt(argc, argv, "idmuvtF:")) != -1) { |
| @@ -69,6 +70,7 @@ extern int cpio_main(int argc, char **argv) | |||
| 69 | break; | 70 | break; |
| 70 | case 'F': | 71 | case 'F': |
| 71 | archive_handle->src_fd = xopen(optarg, O_RDONLY); | 72 | archive_handle->src_fd = xopen(optarg, O_RDONLY); |
| 73 | archive_handle->seek = seek_by_jump; | ||
| 72 | break; | 74 | break; |
| 73 | default: | 75 | default: |
| 74 | show_usage(); | 76 | show_usage(); |
| @@ -117,9 +119,9 @@ extern int cpio_main(int argc, char **argv) | |||
| 117 | } | 119 | } |
| 118 | 120 | ||
| 119 | /* There can be padding before archive header */ | 121 | /* There can be padding before archive header */ |
| 120 | archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 4); | 122 | data_align(archive_handle, 4); |
| 121 | 123 | ||
| 122 | if (xread_all_eof(archive_handle->src_fd, cpio_header, 110) == 0) { | 124 | if (archive_xread_all_eof(archive_handle, cpio_header, 110) == 0) { |
| 123 | return(EXIT_FAILURE); | 125 | return(EXIT_FAILURE); |
| 124 | } | 126 | } |
| 125 | archive_handle->offset += 110; | 127 | archive_handle->offset += 110; |
| @@ -145,12 +147,12 @@ extern int cpio_main(int argc, char **argv) | |||
| 145 | dummy, &major, &minor, &namesize, dummy); | 147 | dummy, &major, &minor, &namesize, dummy); |
| 146 | 148 | ||
| 147 | file_header->name = (char *) xmalloc(namesize + 1); | 149 | file_header->name = (char *) xmalloc(namesize + 1); |
| 148 | xread(archive_handle->src_fd, file_header->name, namesize); /* Read in filename */ | 150 | archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */ |
| 149 | file_header->name[namesize] = '\0'; | 151 | file_header->name[namesize] = '\0'; |
| 150 | archive_handle->offset += namesize; | 152 | archive_handle->offset += namesize; |
| 151 | 153 | ||
| 152 | /* Update offset amount and skip padding before file contents */ | 154 | /* Update offset amount and skip padding before file contents */ |
| 153 | archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 4); | 155 | data_align(archive_handle, 4); |
| 154 | 156 | ||
| 155 | if (strcmp(file_header->name, "TRAILER!!!") == 0) { | 157 | if (strcmp(file_header->name, "TRAILER!!!") == 0) { |
| 156 | printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */ | 158 | printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */ |
| @@ -173,7 +175,7 @@ extern int cpio_main(int argc, char **argv) | |||
| 173 | 175 | ||
| 174 | if (S_ISLNK(file_header->mode)) { | 176 | if (S_ISLNK(file_header->mode)) { |
| 175 | file_header->link_name = (char *) xmalloc(file_header->size + 1); | 177 | file_header->link_name = (char *) xmalloc(file_header->size + 1); |
| 176 | xread(archive_handle->src_fd, file_header->link_name, file_header->size); | 178 | archive_xread_all(archive_handle, file_header->link_name, file_header->size); |
| 177 | file_header->link_name[file_header->size] = '\0'; | 179 | file_header->link_name[file_header->size] = '\0'; |
| 178 | archive_handle->offset += file_header->size; | 180 | archive_handle->offset += file_header->size; |
| 179 | file_header->size = 0; /* Stop possible seeks in future */ | 181 | file_header->size = 0; /* Stop possible seeks in future */ |
diff --git a/archival/libunarchive/Makefile.in b/archival/libunarchive/Makefile.in index 432077721..e406f750e 100644 --- a/archival/libunarchive/Makefile.in +++ b/archival/libunarchive/Makefile.in | |||
| @@ -41,15 +41,23 @@ LIBUNARCHIVE-y:= \ | |||
| 41 | header_list.o \ | 41 | header_list.o \ |
| 42 | header_verbose_list.o \ | 42 | header_verbose_list.o \ |
| 43 | \ | 43 | \ |
| 44 | archive_xread.o \ | ||
| 45 | archive_xread_all.o \ | ||
| 46 | archive_xread_all_eof.o \ | ||
| 47 | archive_xread_char.o \ | ||
| 48 | \ | ||
| 49 | seek_by_char.o \ | ||
| 50 | seek_by_jump.o \ | ||
| 51 | \ | ||
| 52 | archive_copy_file.o \ | ||
| 53 | \ | ||
| 44 | add_to_list.o \ | 54 | add_to_list.o \ |
| 45 | check_header_gzip.o \ | 55 | check_header_gzip.o \ |
| 46 | check_trailer_gzip.o \ | 56 | check_trailer_gzip.o \ |
| 47 | copy_file_chunk_fd.o \ | ||
| 48 | data_align.o \ | 57 | data_align.o \ |
| 49 | decompress_bunzip2.o \ | 58 | decompress_bunzip2.o \ |
| 50 | find_list_entry.o \ | 59 | find_list_entry.o \ |
| 51 | init_handle.o \ | 60 | init_handle.o \ |
| 52 | seek_sub_file.o \ | ||
| 53 | uncompress.o \ | 61 | uncompress.o \ |
| 54 | unpack_ar_archive.o \ | 62 | unpack_ar_archive.o \ |
| 55 | unzip.o | 63 | unzip.o |
diff --git a/archival/libunarchive/archive_copy_file.c b/archival/libunarchive/archive_copy_file.c new file mode 100644 index 000000000..22355ccd5 --- /dev/null +++ b/archival/libunarchive/archive_copy_file.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <unistd.h> | ||
| 18 | |||
| 19 | #include "libbb.h" | ||
| 20 | #include "unarchive.h" | ||
| 21 | |||
| 22 | /* Copy CHUNKSIZE bytes (or untill EOF if chunksize == -1) | ||
| 23 | * from SRC_FILE to DST_FILE. */ | ||
| 24 | extern void archive_copy_file(const archive_handle_t *archive_handle, const int dst_fd) | ||
| 25 | { | ||
| 26 | size_t size; | ||
| 27 | char buffer[BUFSIZ]; | ||
| 28 | off_t chunksize = archive_handle->file_header->size; | ||
| 29 | |||
| 30 | while (chunksize != 0) { | ||
| 31 | if (chunksize > BUFSIZ) { | ||
| 32 | size = BUFSIZ; | ||
| 33 | } else { | ||
| 34 | size = chunksize; | ||
| 35 | } | ||
| 36 | archive_xread_all(archive_handle, buffer, size); | ||
| 37 | |||
| 38 | if (write(dst_fd, buffer, size) != size) { | ||
| 39 | error_msg_and_die ("Short write"); | ||
| 40 | } | ||
| 41 | |||
| 42 | if (chunksize != -1) { | ||
| 43 | chunksize -= size; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | return; | ||
| 48 | } | ||
diff --git a/archival/libunarchive/archive_xread.c b/archival/libunarchive/archive_xread.c new file mode 100644 index 000000000..7fde4c0b1 --- /dev/null +++ b/archival/libunarchive/archive_xread.c | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU Library General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <stdio.h> | ||
| 18 | #include <stdlib.h> | ||
| 19 | #include <string.h> | ||
| 20 | #include "unarchive.h" | ||
| 21 | #include "libbb.h" | ||
| 22 | |||
| 23 | extern ssize_t archive_xread(const archive_handle_t *archive_handle, unsigned char *buf, const size_t count) | ||
| 24 | { | ||
| 25 | ssize_t size; | ||
| 26 | |||
| 27 | size = archive_handle->read(archive_handle->src_fd, buf, count); | ||
| 28 | if (size == -1) { | ||
| 29 | perror_msg_and_die("Read error"); | ||
| 30 | } | ||
| 31 | |||
| 32 | return(size); | ||
| 33 | } | ||
diff --git a/archival/libunarchive/seek_sub_file.c b/archival/libunarchive/archive_xread_all.c index 733bb36a9..ef8cc0141 100644 --- a/archival/libunarchive/seek_sub_file.c +++ b/archival/libunarchive/archive_xread_all.c | |||
| @@ -14,19 +14,19 @@ | |||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <sys/types.h> | 17 | #include <stdio.h> |
| 18 | #include <errno.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <stdlib.h> | 18 | #include <stdlib.h> |
| 19 | #include <string.h> | ||
| 21 | #include "unarchive.h" | 20 | #include "unarchive.h" |
| 22 | #include "libbb.h" | 21 | #include "libbb.h" |
| 23 | 22 | ||
| 24 | extern void seek_sub_file(const int src_fd, const unsigned int amount) | 23 | extern void archive_xread_all(const archive_handle_t *archive_handle, void *buf, const size_t count) |
| 25 | { | 24 | { |
| 26 | if ((lseek(src_fd, amount, SEEK_CUR) == -1) && (errno == ESPIPE)) { | 25 | ssize_t size; |
| 27 | unsigned int i; | 26 | |
| 28 | for (i = 0; i < amount; i++) { | 27 | size = archive_xread(archive_handle, buf, count); |
| 29 | xread_char(src_fd); | 28 | if (size != count) { |
| 30 | } | 29 | error_msg_and_die("Short read"); |
| 31 | } | 30 | } |
| 31 | return; | ||
| 32 | } | 32 | } |
diff --git a/archival/libunarchive/archive_xread_all_eof.c b/archival/libunarchive/archive_xread_all_eof.c new file mode 100644 index 000000000..3cfbbd8d1 --- /dev/null +++ b/archival/libunarchive/archive_xread_all_eof.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU Library General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <stdio.h> | ||
| 18 | #include <stdlib.h> | ||
| 19 | #include <string.h> | ||
| 20 | #include "unarchive.h" | ||
| 21 | #include "libbb.h" | ||
| 22 | |||
| 23 | extern ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned char *buf, size_t count) | ||
| 24 | { | ||
| 25 | ssize_t size; | ||
| 26 | |||
| 27 | size = archive_xread(archive_handle, buf, count); | ||
| 28 | if ((size != 0) && (size != count)) { | ||
| 29 | perror_msg_and_die("Short read, read %d of %d", size, count); | ||
| 30 | } | ||
| 31 | return(size); | ||
| 32 | } | ||
diff --git a/archival/libunarchive/archive_xread_char.c b/archival/libunarchive/archive_xread_char.c new file mode 100644 index 000000000..4c665e159 --- /dev/null +++ b/archival/libunarchive/archive_xread_char.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU Library General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <stdio.h> | ||
| 18 | #include <stdlib.h> | ||
| 19 | #include <string.h> | ||
| 20 | #include "unarchive.h" | ||
| 21 | #include "libbb.h" | ||
| 22 | |||
| 23 | extern unsigned char archive_xread_char(const archive_handle_t *archive_handle) | ||
| 24 | { | ||
| 25 | unsigned char tmp; | ||
| 26 | |||
| 27 | archive_xread(archive_handle, &tmp, 1); | ||
| 28 | |||
| 29 | return(tmp); | ||
| 30 | } | ||
diff --git a/archival/libunarchive/copy_file_chunk_fd.c b/archival/libunarchive/copy_file_chunk_fd.c deleted file mode 100644 index fb513e6d5..000000000 --- a/archival/libunarchive/copy_file_chunk_fd.c +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | #include <unistd.h> | ||
| 2 | #include <sys/types.h> | ||
| 3 | #include "libbb.h" | ||
| 4 | |||
| 5 | /* Copy CHUNKSIZE bytes (or untill EOF if chunksize == -1) | ||
| 6 | * from SRC_FILE to DST_FILE. */ | ||
| 7 | extern int copy_file_chunk_fd(int src_fd, int dst_fd, off_t chunksize) | ||
| 8 | { | ||
| 9 | size_t nread, size; | ||
| 10 | char buffer[BUFSIZ]; | ||
| 11 | |||
| 12 | while (chunksize != 0) { | ||
| 13 | if (chunksize > BUFSIZ) { | ||
| 14 | size = BUFSIZ; | ||
| 15 | } else { | ||
| 16 | size = chunksize; | ||
| 17 | } | ||
| 18 | nread = xread(src_fd, buffer, size); | ||
| 19 | if (nread == 0) { | ||
| 20 | return 1; | ||
| 21 | } | ||
| 22 | |||
| 23 | if (write (dst_fd, buffer, nread) != nread) { | ||
| 24 | error_msg_and_die ("Short write"); | ||
| 25 | } | ||
| 26 | |||
| 27 | if (chunksize != -1) { | ||
| 28 | chunksize -= nread; | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | return 0; | ||
| 33 | } | ||
diff --git a/archival/libunarchive/data_align.c b/archival/libunarchive/data_align.c index d6243bc19..037242f25 100644 --- a/archival/libunarchive/data_align.c +++ b/archival/libunarchive/data_align.c | |||
| @@ -1,13 +1,34 @@ | |||
| 1 | #include <errno.h> | 1 | /* |
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 2 | #include <sys/types.h> | 17 | #include <sys/types.h> |
| 18 | |||
| 19 | #include <errno.h> | ||
| 3 | #include <unistd.h> | 20 | #include <unistd.h> |
| 4 | #include "unarchive.h" | 21 | |
| 5 | #include "libbb.h" | 22 | #include "libbb.h" |
| 23 | #include "unarchive.h" | ||
| 6 | 24 | ||
| 7 | extern const unsigned short data_align(const int src_fd, const unsigned int offset, const unsigned short align_to) | 25 | extern void data_align(archive_handle_t *archive_handle, const unsigned short boundary) |
| 8 | { | 26 | { |
| 9 | const unsigned short skip_amount = (align_to - (offset % align_to)) % align_to; | 27 | const unsigned short skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary; |
| 10 | seek_sub_file(src_fd, skip_amount); | 28 | |
| 29 | archive_handle->seek(archive_handle, skip_amount); | ||
| 30 | |||
| 31 | archive_handle->offset += skip_amount; | ||
| 11 | 32 | ||
| 12 | return(skip_amount); | 33 | return; |
| 13 | } | 34 | } |
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index f839be35e..dda514771 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c | |||
| @@ -1,4 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 1 | #include <sys/types.h> | 17 | #include <sys/types.h> |
| 18 | |||
| 2 | #include <errno.h> | 19 | #include <errno.h> |
| 3 | #include <fcntl.h> | 20 | #include <fcntl.h> |
| 4 | #include <stdlib.h> | 21 | #include <stdlib.h> |
| @@ -6,6 +23,7 @@ | |||
| 6 | #include <utime.h> | 23 | #include <utime.h> |
| 7 | #include <unistd.h> | 24 | #include <unistd.h> |
| 8 | #include <stdlib.h> | 25 | #include <stdlib.h> |
| 26 | |||
| 9 | #include "libbb.h" | 27 | #include "libbb.h" |
| 10 | #include "unarchive.h" | 28 | #include "unarchive.h" |
| 11 | 29 | ||
| @@ -21,7 +39,7 @@ extern void data_extract_all(archive_handle_t *archive_handle) | |||
| 21 | free(name); | 39 | free(name); |
| 22 | } | 40 | } |
| 23 | 41 | ||
| 24 | /* Create the file */ | 42 | /* Create the filesystem entry */ |
| 25 | switch(file_header->mode & S_IFMT) { | 43 | switch(file_header->mode & S_IFMT) { |
| 26 | case S_IFREG: { | 44 | case S_IFREG: { |
| 27 | #ifdef CONFIG_CPIO | 45 | #ifdef CONFIG_CPIO |
| @@ -36,7 +54,7 @@ extern void data_extract_all(archive_handle_t *archive_handle) | |||
| 36 | { | 54 | { |
| 37 | /* Regular file */ | 55 | /* Regular file */ |
| 38 | dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); | 56 | dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); |
| 39 | copy_file_chunk_fd(archive_handle->src_fd, dst_fd, file_header->size); | 57 | archive_copy_file(archive_handle, dst_fd); |
| 40 | close(dst_fd); | 58 | close(dst_fd); |
| 41 | } | 59 | } |
| 42 | break; | 60 | break; |
diff --git a/archival/libunarchive/data_extract_to_buffer.c b/archival/libunarchive/data_extract_to_buffer.c index 02ee4b362..3fcab6d02 100644 --- a/archival/libunarchive/data_extract_to_buffer.c +++ b/archival/libunarchive/data_extract_to_buffer.c | |||
| @@ -1,11 +1,26 @@ | |||
| 1 | #include <stdlib.h> | 1 | /* |
| 2 | #include <stdio.h> | 2 | * This program is free software; you can redistribute it and/or modify |
| 3 | #include "unarchive.h" | 3 | * it under the terms of the GNU General Public License as published by |
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 4 | #include "libbb.h" | 17 | #include "libbb.h" |
| 18 | #include "unarchive.h" | ||
| 5 | 19 | ||
| 6 | extern void data_extract_to_buffer(archive_handle_t *archive_handle) | 20 | extern void data_extract_to_buffer(archive_handle_t *archive_handle) |
| 7 | { | 21 | { |
| 8 | archive_handle->buffer = xmalloc(archive_handle->file_header->size + 1); | 22 | archive_handle->buffer = xmalloc(archive_handle->file_header->size + 1); |
| 9 | 23 | ||
| 10 | xread_all(archive_handle->src_fd, archive_handle->buffer, archive_handle->file_header->size); | 24 | archive_xread_all(archive_handle, archive_handle->buffer, archive_handle->file_header->size); |
| 25 | |||
| 11 | } | 26 | } |
diff --git a/archival/libunarchive/data_extract_to_stdout.c b/archival/libunarchive/data_extract_to_stdout.c index 00687b315..8be2fa2e9 100644 --- a/archival/libunarchive/data_extract_to_stdout.c +++ b/archival/libunarchive/data_extract_to_stdout.c | |||
| @@ -1,8 +1,22 @@ | |||
| 1 | #include <stdlib.h> | 1 | /* |
| 2 | #include <stdio.h> | 2 | * This program is free software; you can redistribute it and/or modify |
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 3 | #include "unarchive.h" | 17 | #include "unarchive.h" |
| 4 | 18 | ||
| 5 | extern void data_extract_to_stdout(archive_handle_t *archive_handle) | 19 | extern void data_extract_to_stdout(archive_handle_t *archive_handle) |
| 6 | { | 20 | { |
| 7 | copy_file_chunk_fd(archive_handle->src_fd, fileno(stdout), archive_handle->file_header->size); | 21 | archive_copy_file(archive_handle, fileno(stdout)); |
| 8 | } | 22 | } |
diff --git a/archival/libunarchive/data_skip.c b/archival/libunarchive/data_skip.c index 4e63d4304..b82c9065b 100644 --- a/archival/libunarchive/data_skip.c +++ b/archival/libunarchive/data_skip.c | |||
| @@ -23,5 +23,5 @@ | |||
| 23 | 23 | ||
| 24 | extern void data_skip(archive_handle_t *archive_handle) | 24 | extern void data_skip(archive_handle_t *archive_handle) |
| 25 | { | 25 | { |
| 26 | seek_sub_file(archive_handle->src_fd, archive_handle->file_header->size); | 26 | archive_handle->seek(archive_handle, archive_handle->file_header->size); |
| 27 | } | 27 | } |
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index dd15b819f..00ae5a494 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
| @@ -57,10 +57,8 @@ | |||
| 57 | #include <string.h> | 57 | #include <string.h> |
| 58 | #include <getopt.h> | 58 | #include <getopt.h> |
| 59 | #include <unistd.h> | 59 | #include <unistd.h> |
| 60 | #include <busybox.h> | ||
| 61 | 60 | ||
| 62 | //#define TRUE 1 | 61 | #include "busybox.h" |
| 63 | //#define FALSE 0 | ||
| 64 | 62 | ||
| 65 | #define MTFA_SIZE 4096 | 63 | #define MTFA_SIZE 4096 |
| 66 | #define MTFL_SIZE 16 | 64 | #define MTFL_SIZE 16 |
| @@ -142,9 +140,10 @@ typedef struct { | |||
| 142 | 140 | ||
| 143 | } bz_stream; | 141 | } bz_stream; |
| 144 | 142 | ||
| 143 | #define BZ_MAX_UNUSED 5000 | ||
| 145 | typedef struct { | 144 | typedef struct { |
| 146 | bz_stream strm; | 145 | bz_stream strm; |
| 147 | FILE *handle; | 146 | int fd; |
| 148 | unsigned char initialisedOk; | 147 | unsigned char initialisedOk; |
| 149 | char buf[BZ_MAX_UNUSED]; | 148 | char buf[BZ_MAX_UNUSED]; |
| 150 | int lastErr; | 149 | int lastErr; |
| @@ -237,18 +236,11 @@ typedef struct { | |||
| 237 | int *save_gPerm; | 236 | int *save_gPerm; |
| 238 | } DState; | 237 | } DState; |
| 239 | 238 | ||
| 240 | int BZ2_rNums[512]; | 239 | static int BZ2_rNums[512]; |
| 241 | char inName[FILE_NAME_LEN]; | 240 | static bzFile *bzf; |
| 242 | char outName[FILE_NAME_LEN]; | 241 | static int bzerr = BZ_OK; |
| 243 | int srcMode; | ||
| 244 | int opMode; | ||
| 245 | unsigned char deleteOutputOnInterrupt; | ||
| 246 | FILE *outputHandleJustInCase; | ||
| 247 | int numFileNames; | ||
| 248 | int numFilesProcessed; | ||
| 249 | int exitValue; | ||
| 250 | 242 | ||
| 251 | const unsigned int BZ2_crc32Table[256] = { | 243 | static const unsigned int BZ2_crc32Table[256] = { |
| 252 | 244 | ||
| 253 | /*-- Ugly, innit? --*/ | 245 | /*-- Ugly, innit? --*/ |
| 254 | 246 | ||
| @@ -330,16 +322,6 @@ static void bz_rand_udp_mask(DState *s) | |||
| 330 | s->rNToGo--; | 322 | s->rNToGo--; |
| 331 | } | 323 | } |
| 332 | 324 | ||
| 333 | static unsigned char myfeof(FILE *f) | ||
| 334 | { | ||
| 335 | int c = fgetc(f); | ||
| 336 | if (c == EOF) { | ||
| 337 | return(TRUE); | ||
| 338 | } | ||
| 339 | ungetc(c, f); | ||
| 340 | return(FALSE); | ||
| 341 | } | ||
| 342 | |||
| 343 | static void BZ2_hbCreateDecodeTables(int *limit, int *base, int *perm, unsigned char *length, int minLen, int maxLen, int alphaSize ) | 325 | static void BZ2_hbCreateDecodeTables(int *limit, int *base, int *perm, unsigned char *length, int minLen, int maxLen, int alphaSize ) |
| 344 | { | 326 | { |
| 345 | int pp, i, j, vec; | 327 | int pp, i, j, vec; |
| @@ -1292,43 +1274,8 @@ save_state_and_return: | |||
| 1292 | return retVal; | 1274 | return retVal; |
| 1293 | } | 1275 | } |
| 1294 | 1276 | ||
| 1295 | //int BZ2_bzDecompressInit(bz_stream* strm, int verbosity_level, int small) | 1277 | static void BZ2_bzReadClose(void) |
| 1296 | static inline int BZ2_bzDecompressInit(bz_stream* strm) | ||
| 1297 | { | ||
| 1298 | DState* s; | ||
| 1299 | |||
| 1300 | // if (verbosity_level < 0 || verbosity_level > 4) { | ||
| 1301 | // return BZ_PARAM_ERROR; | ||
| 1302 | // } | ||
| 1303 | s = xmalloc(sizeof(DState)); | ||
| 1304 | s->strm = strm; | ||
| 1305 | strm->state = s; | ||
| 1306 | s->state = BZ_X_MAGIC_1; | ||
| 1307 | s->bsLive = 0; | ||
| 1308 | s->bsBuff = 0; | ||
| 1309 | s->calculatedCombinedCRC = 0; | ||
| 1310 | s->tt = NULL; | ||
| 1311 | s->currBlockNo = 0; | ||
| 1312 | |||
| 1313 | return BZ_OK; | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | static void bz_seterr(int eee, int *bzerror, bzFile **bzf) | ||
| 1317 | { | 1278 | { |
| 1318 | if (bzerror != NULL) { | ||
| 1319 | *bzerror = eee; | ||
| 1320 | } | ||
| 1321 | if (*bzf != NULL) { | ||
| 1322 | (*bzf)->lastErr = eee; | ||
| 1323 | } | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | static void BZ2_bzReadClose(int *bzerror, void *b) | ||
| 1327 | { | ||
| 1328 | bzFile* bzf = (bzFile*)b; | ||
| 1329 | |||
| 1330 | bz_seterr(BZ_OK, bzerror, &bzf); | ||
| 1331 | |||
| 1332 | if (bzf->initialisedOk) { | 1279 | if (bzf->initialisedOk) { |
| 1333 | bz_stream *strm = &(bzf->strm); | 1280 | bz_stream *strm = &(bzf->strm); |
| 1334 | DState *s; | 1281 | DState *s; |
| @@ -1588,31 +1535,22 @@ int BZ2_bzDecompress(bz_stream *strm) | |||
| 1588 | return(0); /*NOTREACHED*/ | 1535 | return(0); /*NOTREACHED*/ |
| 1589 | } | 1536 | } |
| 1590 | 1537 | ||
| 1591 | static inline int BZ2_bzRead(int *bzerror, void *b, void *buf, int len) | 1538 | extern ssize_t read_bz2(int fd, void *buf, size_t count) |
| 1592 | { | 1539 | { |
| 1593 | int n, ret; | 1540 | int n, ret; |
| 1594 | bzFile *bzf = (bzFile*)b; | ||
| 1595 | |||
| 1596 | bz_seterr(BZ_OK, bzerror, &bzf); | ||
| 1597 | 1541 | ||
| 1598 | if (len == 0) { | 1542 | bzerr = BZ_OK; |
| 1599 | bz_seterr(BZ_OK, bzerror, &bzf); | 1543 | if (count == 0) { |
| 1600 | return 0; | 1544 | return(0); |
| 1601 | } | 1545 | } |
| 1602 | 1546 | bzf->strm.avail_out = count; | |
| 1603 | bzf->strm.avail_out = len; | ||
| 1604 | bzf->strm.next_out = buf; | 1547 | bzf->strm.next_out = buf; |
| 1605 | 1548 | ||
| 1606 | while (1) { | 1549 | while (1) { |
| 1607 | if (ferror(bzf->handle)) { | 1550 | if (bzf->strm.avail_in == 0) { |
| 1608 | bz_seterr(BZ_IO_ERROR, bzerror, &bzf); | 1551 | n = xread(bzf->fd, bzf->buf, BZ_MAX_UNUSED); |
| 1609 | return 0; | 1552 | if (n == 0) { |
| 1610 | } | 1553 | break; |
| 1611 | if ((bzf->strm.avail_in == 0) && !myfeof(bzf->handle)) { | ||
| 1612 | n = fread(bzf->buf, sizeof(unsigned char), BZ_MAX_UNUSED, bzf->handle); | ||
| 1613 | if (ferror(bzf->handle)) { | ||
| 1614 | bz_seterr(BZ_IO_ERROR, bzerror, &bzf); | ||
| 1615 | return 0; | ||
| 1616 | } | 1554 | } |
| 1617 | bzf->bufN = n; | 1555 | bzf->bufN = n; |
| 1618 | bzf->strm.avail_in = bzf->bufN; | 1556 | bzf->strm.avail_in = bzf->bufN; |
| @@ -1622,48 +1560,43 @@ static inline int BZ2_bzRead(int *bzerror, void *b, void *buf, int len) | |||
| 1622 | ret = BZ2_bzDecompress(&(bzf->strm)); | 1560 | ret = BZ2_bzDecompress(&(bzf->strm)); |
| 1623 | 1561 | ||
| 1624 | if ((ret != BZ_OK) && (ret != BZ_STREAM_END)) { | 1562 | if ((ret != BZ_OK) && (ret != BZ_STREAM_END)) { |
| 1625 | bz_seterr(ret, bzerror, &bzf); | 1563 | error_msg_and_die("Error decompressing"); |
| 1626 | return 0; | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | if ((ret == BZ_OK) && myfeof(bzf->handle) && | ||
| 1630 | (bzf->strm.avail_in == 0) && (bzf->strm.avail_out > 0)) { | ||
| 1631 | bz_seterr(BZ_UNEXPECTED_EOF, bzerror, &bzf); | ||
| 1632 | return(0); | ||
| 1633 | } | 1564 | } |
| 1634 | 1565 | ||
| 1635 | if (ret == BZ_STREAM_END) { | 1566 | if (ret == BZ_STREAM_END) { |
| 1636 | bz_seterr(BZ_STREAM_END, bzerror, &bzf); | 1567 | bzerr = BZ_STREAM_END; |
| 1637 | return(len - bzf->strm.avail_out); | 1568 | return(count - bzf->strm.avail_out); |
| 1638 | } | 1569 | } |
| 1639 | if (bzf->strm.avail_out == 0) { | 1570 | if (bzf->strm.avail_out == 0) { |
| 1640 | bz_seterr(BZ_OK, bzerror, &bzf); | 1571 | bzerr = BZ_OK; |
| 1641 | return(len); | 1572 | return(count); |
| 1642 | } | 1573 | } |
| 1643 | } | 1574 | } |
| 1644 | return(0); /*not reached*/ | 1575 | return(0); |
| 1645 | } | 1576 | } |
| 1646 | 1577 | ||
| 1647 | static inline void *BZ2_bzReadOpen(int *bzerror, FILE *f, void *unused, int nUnused) | 1578 | extern void BZ2_bzReadOpen(int fd, void *unused, int nUnused) |
| 1648 | { | 1579 | { |
| 1649 | bzFile *bzf = xmalloc(sizeof(bzFile)); | 1580 | DState *s; |
| 1650 | int ret; | ||
| 1651 | |||
| 1652 | bz_seterr(BZ_OK, bzerror, &bzf); | ||
| 1653 | 1581 | ||
| 1582 | bzf = xmalloc(sizeof(bzFile)); | ||
| 1654 | bzf->initialisedOk = FALSE; | 1583 | bzf->initialisedOk = FALSE; |
| 1655 | bzf->handle = f; | 1584 | bzf->fd = fd; |
| 1656 | bzf->bufN = 0; | 1585 | bzf->bufN = 0; |
| 1657 | 1586 | ||
| 1658 | ret = BZ2_bzDecompressInit(&(bzf->strm)); | 1587 | s = xmalloc(sizeof(DState)); |
| 1659 | if (ret != BZ_OK) { | 1588 | s->strm = &bzf->strm; |
| 1660 | bz_seterr(ret, bzerror, &bzf); | 1589 | s->state = BZ_X_MAGIC_1; |
| 1661 | free(bzf); | 1590 | s->bsLive = 0; |
| 1662 | return NULL; | 1591 | s->bsBuff = 0; |
| 1663 | } | 1592 | s->calculatedCombinedCRC = 0; |
| 1593 | s->tt = NULL; | ||
| 1594 | s->currBlockNo = 0; | ||
| 1595 | bzf->strm.state = s; | ||
| 1664 | 1596 | ||
| 1665 | while (nUnused > 0) { | 1597 | while (nUnused > 0) { |
| 1666 | bzf->buf[bzf->bufN] = *((unsigned char *)(unused)); bzf->bufN++; | 1598 | bzf->buf[bzf->bufN] = *((unsigned char *)(unused)); |
| 1599 | bzf->bufN++; | ||
| 1667 | unused = ((void *)( 1 + ((unsigned char *)(unused)) )); | 1600 | unused = ((void *)( 1 + ((unsigned char *)(unused)) )); |
| 1668 | nUnused--; | 1601 | nUnused--; |
| 1669 | } | 1602 | } |
| @@ -1671,119 +1604,55 @@ static inline void *BZ2_bzReadOpen(int *bzerror, FILE *f, void *unused, int nUnu | |||
| 1671 | bzf->strm.next_in = bzf->buf; | 1604 | bzf->strm.next_in = bzf->buf; |
| 1672 | 1605 | ||
| 1673 | bzf->initialisedOk = TRUE; | 1606 | bzf->initialisedOk = TRUE; |
| 1674 | return bzf; | 1607 | |
| 1608 | return; | ||
| 1675 | } | 1609 | } |
| 1676 | 1610 | ||
| 1677 | extern unsigned char uncompressStream(FILE *zStream, FILE *stream) | 1611 | extern unsigned char uncompressStream(int src_fd, int dst_fd) |
| 1678 | { | 1612 | { |
| 1679 | unsigned char unused[BZ_MAX_UNUSED]; | 1613 | unsigned char unused[BZ_MAX_UNUSED]; |
| 1680 | unsigned char *unusedTmp; | 1614 | unsigned char *unusedTmp; |
| 1681 | unsigned char obuf[5000]; | 1615 | unsigned char obuf[5000]; |
| 1682 | bzFile *bzf = NULL; | ||
| 1683 | int bzerr_dummy; | ||
| 1684 | int bzerr; | ||
| 1685 | int nread; | 1616 | int nread; |
| 1686 | int nUnused; | 1617 | int nUnused; |
| 1687 | int streamNo; | 1618 | int streamNo; |
| 1688 | int ret; | ||
| 1689 | int i; | 1619 | int i; |
| 1690 | 1620 | ||
| 1691 | nUnused = 0; | 1621 | nUnused = 0; |
| 1692 | streamNo = 0; | 1622 | streamNo = 0; |
| 1693 | 1623 | ||
| 1694 | if (ferror(stream)) { | ||
| 1695 | goto errhandler_io; | ||
| 1696 | } | ||
| 1697 | if (ferror(zStream)) { | ||
| 1698 | goto errhandler_io; | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | while(1) { | 1624 | while(1) { |
| 1702 | bzf = BZ2_bzReadOpen(&bzerr, zStream, unused, nUnused); | 1625 | BZ2_bzReadOpen(src_fd, unused, nUnused); |
| 1703 | if (bzf == NULL || bzerr != BZ_OK) { | ||
| 1704 | goto errhandler; | ||
| 1705 | } | ||
| 1706 | streamNo++; | 1626 | streamNo++; |
| 1707 | 1627 | ||
| 1708 | while (bzerr == BZ_OK) { | 1628 | while (bzerr == BZ_OK) { |
| 1709 | nread = BZ2_bzRead(&bzerr, bzf, obuf, 5000); | 1629 | nread = read_bz2(src_fd, obuf, 5000); |
| 1710 | if (bzerr == BZ_DATA_ERROR_MAGIC) { | 1630 | if (bzerr == BZ_DATA_ERROR_MAGIC) { |
| 1711 | goto errhandler; | 1631 | error_msg_and_die("invalid magic"); |
| 1712 | } | ||
| 1713 | if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0) { | ||
| 1714 | fwrite(obuf, sizeof(unsigned char), nread, stream); | ||
| 1715 | } | 1632 | } |
| 1716 | if (ferror(stream)) { | 1633 | if (((bzerr == BZ_OK) || (bzerr == BZ_STREAM_END)) && (nread > 0)) { |
| 1717 | goto errhandler_io; | 1634 | if (write(dst_fd, obuf, nread) != nread) { |
| 1635 | BZ2_bzReadClose(); | ||
| 1636 | perror_msg_and_die("Couldnt write to file"); | ||
| 1637 | } | ||
| 1718 | } | 1638 | } |
| 1719 | } | 1639 | } |
| 1720 | if (bzerr != BZ_STREAM_END) { | ||
| 1721 | goto errhandler; | ||
| 1722 | } | ||
| 1723 | nUnused = bzf->strm.avail_in; | 1640 | nUnused = bzf->strm.avail_in; |
| 1724 | unusedTmp = bzf->strm.next_in; | 1641 | unusedTmp = bzf->strm.next_in; |
| 1725 | bz_seterr(BZ_OK, &bzerr, &bzf); | 1642 | |
| 1726 | for (i = 0; i < nUnused; i++) { | 1643 | for (i = 0; i < nUnused; i++) { |
| 1727 | unused[i] = unusedTmp[i]; | 1644 | unused[i] = unusedTmp[i]; |
| 1728 | } | 1645 | } |
| 1729 | BZ2_bzReadClose(&bzerr, bzf); | 1646 | BZ2_bzReadClose(); |
| 1730 | if ((nUnused == 0) && myfeof(zStream)) { | 1647 | if (nUnused == 0) { |
| 1731 | break; | 1648 | break; |
| 1732 | } | 1649 | } |
| 1733 | } | 1650 | } |
| 1734 | 1651 | ||
| 1735 | if (ferror(zStream)) { | 1652 | close(src_fd); |
| 1736 | goto errhandler_io; | 1653 | if (dst_fd != fileno(stdout)) { |
| 1737 | } | 1654 | close(dst_fd); |
| 1738 | ret = fclose(zStream); | ||
| 1739 | if (ret == EOF) { | ||
| 1740 | goto errhandler_io; | ||
| 1741 | } | ||
| 1742 | if (ferror(stream)) { | ||
| 1743 | goto errhandler_io; | ||
| 1744 | } | ||
| 1745 | ret = fflush(stream); | ||
| 1746 | if (ret != 0) { | ||
| 1747 | goto errhandler_io; | ||
| 1748 | } | ||
| 1749 | if (stream != stdout) { | ||
| 1750 | ret = fclose(stream); | ||
| 1751 | if (ret == EOF) { | ||
| 1752 | goto errhandler_io; | ||
| 1753 | } | ||
| 1754 | } | 1655 | } |
| 1755 | return TRUE; | 1656 | return TRUE; |
| 1756 | |||
| 1757 | errhandler: | ||
| 1758 | BZ2_bzReadClose ( &bzerr_dummy, bzf ); | ||
| 1759 | switch (bzerr) { | ||
| 1760 | case BZ_IO_ERROR: | ||
| 1761 | errhandler_io: | ||
| 1762 | error_msg("\n%s: I/O or other error, bailing out. " | ||
| 1763 | "Possible reason follows.\n", applet_name); | ||
| 1764 | perror(applet_name); | ||
| 1765 | exit(1); | ||
| 1766 | case BZ_DATA_ERROR: | ||
| 1767 | error_msg("\n%s: Data integrity error when decompressing.\n", applet_name); | ||
| 1768 | exit(2); | ||
| 1769 | case BZ_UNEXPECTED_EOF: | ||
| 1770 | error_msg("\n%s: Compressed file ends unexpectedly;\n\t" | ||
| 1771 | "perhaps it is corrupted? *Possible* reason follows.\n", applet_name); | ||
| 1772 | perror(applet_name); | ||
| 1773 | exit(2); | ||
| 1774 | case BZ_DATA_ERROR_MAGIC: | ||
| 1775 | if (zStream != stdin) { | ||
| 1776 | fclose(zStream); | ||
| 1777 | } | ||
| 1778 | if (stream != stdout) { | ||
| 1779 | fclose(stream); | ||
| 1780 | } | ||
| 1781 | if (streamNo == 1) { | ||
| 1782 | return FALSE; | ||
| 1783 | } else { | ||
| 1784 | return TRUE; | ||
| 1785 | } | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | return(TRUE); /*notreached*/ | ||
| 1789 | } | 1657 | } |
| 1658 | |||
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index e87eb77b8..b2b9e0b03 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
| @@ -50,9 +50,9 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
| 50 | char *tmp; | 50 | char *tmp; |
| 51 | 51 | ||
| 52 | /* Align header */ | 52 | /* Align header */ |
| 53 | archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 512); | 53 | data_align(archive_handle, 512); |
| 54 | 54 | ||
| 55 | if (xread_all_eof(archive_handle->src_fd, tar.raw, 512) == 0) { | 55 | if (archive_xread_all_eof(archive_handle, tar.raw, 512) == 0) { |
| 56 | /* End of file */ | 56 | /* End of file */ |
| 57 | return(EXIT_FAILURE); | 57 | return(EXIT_FAILURE); |
| 58 | } | 58 | } |
| @@ -72,7 +72,6 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
| 72 | #endif | 72 | #endif |
| 73 | error_msg_and_die("Invalid tar magic"); | 73 | error_msg_and_die("Invalid tar magic"); |
| 74 | } | 74 | } |
| 75 | |||
| 76 | /* Do checksum on headers */ | 75 | /* Do checksum on headers */ |
| 77 | for (i = 0; i < 148 ; i++) { | 76 | for (i = 0; i < 148 ; i++) { |
| 78 | sum += tar.raw[i]; | 77 | sum += tar.raw[i]; |
| @@ -138,7 +137,7 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
| 138 | char *longname; | 137 | char *longname; |
| 139 | 138 | ||
| 140 | longname = xmalloc(file_header->size + 1); | 139 | longname = xmalloc(file_header->size + 1); |
| 141 | xread_all(archive_handle->src_fd, longname, file_header->size); | 140 | archive_xread_all(archive_handle, longname, file_header->size); |
| 142 | longname[file_header->size] = '\0'; | 141 | longname[file_header->size] = '\0'; |
| 143 | archive_handle->offset += file_header->size; | 142 | archive_handle->offset += file_header->size; |
| 144 | 143 | ||
| @@ -150,7 +149,7 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |||
| 150 | char *linkname; | 149 | char *linkname; |
| 151 | 150 | ||
| 152 | linkname = xmalloc(file_header->size + 1); | 151 | linkname = xmalloc(file_header->size + 1); |
| 153 | xread_all(archive_handle->src_fd, linkname, file_header->size); | 152 | archive_xread_all(archive_handle, linkname, file_header->size); |
| 154 | linkname[file_header->size] = '\0'; | 153 | linkname[file_header->size] = '\0'; |
| 155 | archive_handle->offset += file_header->size; | 154 | archive_handle->offset += file_header->size; |
| 156 | 155 | ||
diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c index 24d19fbfd..f0d4b1359 100644 --- a/archival/libunarchive/get_header_tar_gz.c +++ b/archival/libunarchive/get_header_tar_gz.c | |||
| @@ -29,7 +29,10 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) | |||
| 29 | int pid; | 29 | int pid; |
| 30 | unsigned char magic[2]; | 30 | unsigned char magic[2]; |
| 31 | 31 | ||
| 32 | xread_all(archive_handle->src_fd, &magic, 2); | 32 | /* Cant lseek over pipe's */ |
| 33 | archive_handle->seek = seek_by_char; | ||
| 34 | |||
| 35 | archive_xread_all(archive_handle, &magic, 2); | ||
| 33 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { | 36 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { |
| 34 | error_msg_and_die("Invalid gzip magic"); | 37 | error_msg_and_die("Invalid gzip magic"); |
| 35 | } | 38 | } |
diff --git a/archival/libunarchive/init_handle.c b/archival/libunarchive/init_handle.c index 12d9e7183..4b0103491 100644 --- a/archival/libunarchive/init_handle.c +++ b/archival/libunarchive/init_handle.c | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <unistd.h> | ||
| 1 | #include <string.h> | 18 | #include <string.h> |
| 2 | #include "libbb.h" | 19 | #include "libbb.h" |
| 3 | #include "unarchive.h" | 20 | #include "unarchive.h" |
| @@ -13,6 +30,8 @@ archive_handle_t *init_handle(void) | |||
| 13 | archive_handle->action_header = header_skip; | 30 | archive_handle->action_header = header_skip; |
| 14 | archive_handle->action_data = data_skip; | 31 | archive_handle->action_data = data_skip; |
| 15 | archive_handle->filter = filter_accept_all; | 32 | archive_handle->filter = filter_accept_all; |
| 33 | archive_handle->read = read; | ||
| 34 | archive_handle->seek = seek_by_jump; | ||
| 16 | 35 | ||
| 17 | return(archive_handle); | 36 | return(archive_handle); |
| 18 | } | 37 | } |
diff --git a/archival/libunarchive/seek_by_char.c b/archival/libunarchive/seek_by_char.c new file mode 100644 index 000000000..f33935cb5 --- /dev/null +++ b/archival/libunarchive/seek_by_char.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU Library General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "unarchive.h" | ||
| 18 | |||
| 19 | extern void seek_by_char(const archive_handle_t *archive_handle, const unsigned int amount) | ||
| 20 | { | ||
| 21 | unsigned int i; | ||
| 22 | for (i = 0; i < amount; i++) { | ||
| 23 | archive_xread_char(archive_handle); | ||
| 24 | } | ||
| 25 | } | ||
diff --git a/archival/libunarchive/seek_by_jump.c b/archival/libunarchive/seek_by_jump.c new file mode 100644 index 000000000..efad97fc4 --- /dev/null +++ b/archival/libunarchive/seek_by_jump.c | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU Library General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <sys/types.h> | ||
| 18 | #include <errno.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <stdlib.h> | ||
| 21 | |||
| 22 | #include "libbb.h" | ||
| 23 | #include "unarchive.h" | ||
| 24 | |||
| 25 | extern void seek_by_jump(const archive_handle_t *archive_handle, const unsigned int amount) | ||
| 26 | { | ||
| 27 | if (lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1) { | ||
| 28 | #if CONFIG_FEATURE_UNARCHIVE_TAPE | ||
| 29 | if (errno == ESPIPE) { | ||
| 30 | seek_by_char(archive_handle, amount); | ||
| 31 | } else | ||
| 32 | #endif | ||
| 33 | perror_msg_and_die("Seek failure"); | ||
| 34 | } | ||
| 35 | } | ||
diff --git a/archival/libunarchive/unpack_ar_archive.c b/archival/libunarchive/unpack_ar_archive.c index 923b8a068..afa3672ad 100644 --- a/archival/libunarchive/unpack_ar_archive.c +++ b/archival/libunarchive/unpack_ar_archive.c | |||
| @@ -24,7 +24,7 @@ extern void unpack_ar_archive(archive_handle_t *ar_archive) | |||
| 24 | { | 24 | { |
| 25 | char magic[7]; | 25 | char magic[7]; |
| 26 | 26 | ||
| 27 | xread_all(ar_archive->src_fd, magic, 7); | 27 | archive_xread_all(ar_archive, magic, 7); |
| 28 | if (strncmp(magic, "!<arch>", 7) != 0) { | 28 | if (strncmp(magic, "!<arch>", 7) != 0) { |
| 29 | error_msg_and_die("Invalid ar magic"); | 29 | error_msg_and_die("Invalid ar magic"); |
| 30 | } | 30 | } |
diff --git a/archival/tar.c b/archival/tar.c index 48d6ce22e..e1e121a09 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
| @@ -627,7 +627,7 @@ int tar_main(int argc, char **argv) | |||
| 627 | tar_handle = init_handle(); | 627 | tar_handle = init_handle(); |
| 628 | tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS; | 628 | tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS; |
| 629 | 629 | ||
| 630 | while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) { | 630 | while ((opt = getopt(argc, argv, "cjtxT:X:C:f:Opvz")) != -1) { |
| 631 | switch (opt) { | 631 | switch (opt) { |
| 632 | /* One and only one of these is required */ | 632 | /* One and only one of these is required */ |
| 633 | #ifdef CONFIG_FEATURE_TAR_CREATE | 633 | #ifdef CONFIG_FEATURE_TAR_CREATE |
| @@ -684,9 +684,8 @@ int tar_main(int argc, char **argv) | |||
| 684 | break; | 684 | break; |
| 685 | #endif | 685 | #endif |
| 686 | #ifdef CONFIG_FEATURE_TAR_BZIP2 | 686 | #ifdef CONFIG_FEATURE_TAR_BZIP2 |
| 687 | /* Not enabled yet */ | ||
| 688 | case 'j': | 687 | case 'j': |
| 689 | archive_handle->archive_action = bunzip2; | 688 | tar_handle->read = read_bz2; |
| 690 | break; | 689 | break; |
| 691 | #endif | 690 | #endif |
| 692 | default: | 691 | default: |
| @@ -703,14 +702,8 @@ int tar_main(int argc, char **argv) | |||
| 703 | /* Setup an array of filenames to work with */ | 702 | /* Setup an array of filenames to work with */ |
| 704 | /* TODO: This is the same as in ar, seperate function ? */ | 703 | /* TODO: This is the same as in ar, seperate function ? */ |
| 705 | while (optind < argc) { | 704 | while (optind < argc) { |
| 706 | #if 0 | ||
| 707 | char absolute_path[PATH_MAX]; | ||
| 708 | realpath(argv[optind], absolute_path); | ||
| 709 | tar_handle->accept = add_to_list(tar_handle->accept, absolute_path); | ||
| 710 | #endif | ||
| 711 | tar_handle->accept = add_to_list(tar_handle->accept, argv[optind]); | 705 | tar_handle->accept = add_to_list(tar_handle->accept, argv[optind]); |
| 712 | optind++; | 706 | optind++; |
| 713 | |||
| 714 | } | 707 | } |
| 715 | 708 | ||
| 716 | if ((tar_handle->accept) || (tar_handle->reject)) { | 709 | if ((tar_handle->accept) || (tar_handle->reject)) { |
| @@ -744,13 +737,21 @@ int tar_main(int argc, char **argv) | |||
| 744 | if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) { | 737 | if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) { |
| 745 | tar_handle->src_fd = fileno(stdin); | 738 | tar_handle->src_fd = fileno(stdin); |
| 746 | } else { | 739 | } else { |
| 740 | tar_handle->seek = seek_by_jump; | ||
| 747 | tar_handle->src_fd = xopen(tar_filename, O_RDONLY); | 741 | tar_handle->src_fd = xopen(tar_filename, O_RDONLY); |
| 748 | } | 742 | } |
| 749 | #ifdef CONFIG_FEATURE_TAR_GZIP | 743 | #ifdef CONFIG_FEATURE_TAR_GZIP |
| 750 | if (get_header_ptr == get_header_tar_gz) { | 744 | if (get_header_ptr == get_header_tar_gz) { |
| 745 | tar_handle->seek = seek_by_char; | ||
| 751 | get_header_tar_gz(tar_handle); | 746 | get_header_tar_gz(tar_handle); |
| 752 | } else | 747 | } else |
| 753 | #endif /* CONFIG_FEATURE_TAR_CREATE */ | 748 | #endif /* CONFIG_FEATURE_TAR_GZIP */ |
| 749 | #ifdef CONFIG_FEATURE_TAR_BZIP2 | ||
| 750 | if (tar_handle->read == read_bz2) { | ||
| 751 | BZ2_bzReadOpen(tar_handle->src_fd, NULL, 0); | ||
| 752 | while (get_header_tar(tar_handle) == EXIT_SUCCESS); | ||
| 753 | } else | ||
| 754 | #endif /* CONFIG_FEATURE_TAR_BZIP2 */ | ||
| 754 | 755 | ||
| 755 | while (get_header_tar(tar_handle) == EXIT_SUCCESS); | 756 | while (get_header_tar(tar_handle) == EXIT_SUCCESS); |
| 756 | 757 | ||
diff --git a/archival/unzip.c b/archival/unzip.c index 5a22d242a..4c1e5ce40 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
| @@ -136,13 +136,14 @@ extern int unzip_main(int argc, char **argv) | |||
| 136 | 136 | ||
| 137 | if (*argv[optind] == '-') { | 137 | if (*argv[optind] == '-') { |
| 138 | archive_handle->src_fd = fileno(stdin); | 138 | archive_handle->src_fd = fileno(stdin); |
| 139 | } else { | 139 | archive_handle->seek = seek_by_char; |
| 140 | } else { | ||
| 140 | archive_handle->src_fd = xopen(argv[optind++], O_RDONLY); | 141 | archive_handle->src_fd = xopen(argv[optind++], O_RDONLY); |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | if ((base_dir) && (chdir(base_dir))) { | 144 | if ((base_dir) && (chdir(base_dir))) { |
| 144 | perror_msg_and_die("Couldnt chdir"); | 145 | perror_msg_and_die("Couldnt chdir"); |
| 145 | } | 146 | } |
| 146 | 147 | ||
| 147 | while (optind < argc) { | 148 | while (optind < argc) { |
| 148 | archive_handle->filter = filter_accept_list; | 149 | archive_handle->filter = filter_accept_list; |
| @@ -155,7 +156,7 @@ extern int unzip_main(int argc, char **argv) | |||
| 155 | int dst_fd; | 156 | int dst_fd; |
| 156 | 157 | ||
| 157 | /* TODO Endian issues */ | 158 | /* TODO Endian issues */ |
| 158 | xread_all(archive_handle->src_fd, &magic, 4); | 159 | archive_xread_all(archive_handle, &magic, 4); |
| 159 | archive_handle->offset += 4; | 160 | archive_handle->offset += 4; |
| 160 | 161 | ||
| 161 | if (magic == ZIP_CDS_MAGIC) { | 162 | if (magic == ZIP_CDS_MAGIC) { |
| @@ -166,7 +167,7 @@ extern int unzip_main(int argc, char **argv) | |||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | /* Read the file header */ | 169 | /* Read the file header */ |
| 169 | xread_all(archive_handle->src_fd, zip_header.raw, 26); | 170 | archive_xread_all(archive_handle, zip_header.raw, 26); |
| 170 | archive_handle->offset += 26; | 171 | archive_handle->offset += 26; |
| 171 | archive_handle->file_header->mode = S_IFREG | 0777; | 172 | archive_handle->file_header->mode = S_IFREG | 0777; |
| 172 | 173 | ||
| @@ -176,7 +177,7 @@ extern int unzip_main(int argc, char **argv) | |||
| 176 | 177 | ||
| 177 | /* Read filename */ | 178 | /* Read filename */ |
| 178 | archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); | 179 | archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); |
| 179 | xread_all(archive_handle->src_fd, archive_handle->file_header->name, zip_header.formated.filename_len); | 180 | archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len); |
| 180 | archive_handle->offset += zip_header.formated.filename_len; | 181 | archive_handle->offset += zip_header.formated.filename_len; |
| 181 | archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; | 182 | archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; |
| 182 | 183 | ||
| @@ -228,7 +229,7 @@ extern int unzip_main(int argc, char **argv) | |||
| 228 | /* skip over duplicate crc, compressed size and uncompressed size */ | 229 | /* skip over duplicate crc, compressed size and uncompressed size */ |
| 229 | unsigned short i; | 230 | unsigned short i; |
| 230 | for (i = 0; i != 12; i++) { | 231 | for (i = 0; i != 12; i++) { |
| 231 | xread_char(archive_handle->src_fd); | 232 | archive_xread_char(archive_handle); |
| 232 | } | 233 | } |
| 233 | archive_handle->offset += 12; | 234 | archive_handle->offset += 12; |
| 234 | } | 235 | } |
diff --git a/include/libbb.h b/include/libbb.h index bc8112310..ec4ff3a20 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -333,7 +333,6 @@ extern int obscure(const char *old, const char *newval, const struct passwd *pwd | |||
| 333 | 333 | ||
| 334 | extern int xopen(const char *pathname, int flags); | 334 | extern int xopen(const char *pathname, int flags); |
| 335 | extern ssize_t xread(int fd, void *buf, size_t count); | 335 | extern ssize_t xread(int fd, void *buf, size_t count); |
| 336 | extern ssize_t xread_all_eof(int fd, void *buf, size_t count); | ||
| 337 | extern void xread_all(int fd, void *buf, size_t count); | 336 | extern void xread_all(int fd, void *buf, size_t count); |
| 338 | extern unsigned char xread_char(int fd); | 337 | extern unsigned char xread_char(int fd); |
| 339 | 338 | ||
diff --git a/include/unarchive.h b/include/unarchive.h index 7926dccf5..b13388b54 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
| @@ -7,14 +7,8 @@ | |||
| 7 | #define ARCHIVE_EXTRACT_QUIET 8 | 7 | #define ARCHIVE_EXTRACT_QUIET 8 |
| 8 | 8 | ||
| 9 | #include <sys/types.h> | 9 | #include <sys/types.h> |
| 10 | #include <stdio.h> | ||
| 11 | 10 | ||
| 12 | typedef struct gunzip_s { | 11 | #include <stdio.h> |
| 13 | unsigned short buffer_count; | ||
| 14 | unsigned char *buffer; | ||
| 15 | unsigned int crc; | ||
| 16 | unsigned int count; | ||
| 17 | } gunzip_t; | ||
| 18 | 12 | ||
| 19 | typedef struct file_headers_s { | 13 | typedef struct file_headers_s { |
| 20 | char *name; | 14 | char *name; |
| @@ -58,6 +52,12 @@ typedef struct archive_handle_s { | |||
| 58 | /* Count the number of bytes processed */ | 52 | /* Count the number of bytes processed */ |
| 59 | off_t offset; | 53 | off_t offset; |
| 60 | 54 | ||
| 55 | /* Function that reads data: read or read_bz */ | ||
| 56 | ssize_t (*read)(int fd, void *buf, size_t count); | ||
| 57 | |||
| 58 | /* Function that skips data: read_by_char or read_by_skip */ | ||
| 59 | void (*seek)(const struct archive_handle_s *archive_handle, const unsigned int amount); | ||
| 60 | |||
| 61 | /* Temperary storage */ | 61 | /* Temperary storage */ |
| 62 | char *buffer; | 62 | char *buffer; |
| 63 | 63 | ||
| @@ -90,11 +90,21 @@ extern char get_header_ar(archive_handle_t *archive_handle); | |||
| 90 | extern char get_header_tar(archive_handle_t *archive_handle); | 90 | extern char get_header_tar(archive_handle_t *archive_handle); |
| 91 | extern char get_header_tar_gz(archive_handle_t *archive_handle); | 91 | extern char get_header_tar_gz(archive_handle_t *archive_handle); |
| 92 | 92 | ||
| 93 | extern unsigned char uncompressStream(FILE *zStream, FILE *stream); | 93 | extern void seek_by_jump(const archive_handle_t *archive_handle, const unsigned int amount); |
| 94 | extern void seek_by_char(const archive_handle_t *archive_handle, const unsigned int amount); | ||
| 94 | 95 | ||
| 95 | extern void seek_sub_file(int src_fd, unsigned int amount); | 96 | extern unsigned char archive_xread_char(const archive_handle_t *archive_handle); |
| 96 | extern const unsigned short data_align(const int src_fd, const unsigned int offset, const unsigned short align_to); | 97 | extern ssize_t archive_xread(const archive_handle_t *archive_handle, unsigned char *buf, const size_t count); |
| 98 | extern void archive_xread_all(const archive_handle_t *archive_handle, void *buf, const size_t count); | ||
| 99 | extern ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned char *buf, size_t count); | ||
| 100 | |||
| 101 | extern void data_align(archive_handle_t *archive_handle, const unsigned short boundary); | ||
| 97 | extern const llist_t *add_to_list(const llist_t *old_head, const char *new_item); | 102 | extern const llist_t *add_to_list(const llist_t *old_head, const char *new_item); |
| 98 | extern int copy_file_chunk_fd(int src_fd, int dst_fd, unsigned long long chunksize); | 103 | extern void archive_copy_file(const archive_handle_t *archive_handle, const int dst_fd); |
| 99 | extern const llist_t *find_list_entry(const llist_t *list, const char *filename); | 104 | extern const llist_t *find_list_entry(const llist_t *list, const char *filename); |
| 105 | |||
| 106 | extern ssize_t read_bz2(int fd, void *buf, size_t count); | ||
| 107 | extern void BZ2_bzReadOpen(int fd, void *unused, int nUnused); | ||
| 108 | extern unsigned char uncompressStream(int src_fd, int dst_fd); | ||
| 109 | |||
| 100 | #endif | 110 | #endif |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 2249e263a..820a0d7cc 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
| @@ -92,7 +92,7 @@ extern int xopen(const char *pathname, int flags) | |||
| 92 | { | 92 | { |
| 93 | int ret; | 93 | int ret; |
| 94 | 94 | ||
| 95 | ret = open(pathname, flags); | 95 | ret = open(pathname, flags, 0777); |
| 96 | if (ret == -1) { | 96 | if (ret == -1) { |
| 97 | perror_msg_and_die("%s", pathname); | 97 | perror_msg_and_die("%s", pathname); |
| 98 | } | 98 | } |
| @@ -121,17 +121,6 @@ extern void xread_all(int fd, void *buf, size_t count) | |||
| 121 | return; | 121 | return; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | extern ssize_t xread_all_eof(int fd, void *buf, size_t count) | ||
| 125 | { | ||
| 126 | ssize_t size; | ||
| 127 | |||
| 128 | size = xread(fd, buf, count); | ||
| 129 | if ((size != 0) && (size != count)) { | ||
| 130 | error_msg_and_die("Short read"); | ||
| 131 | } | ||
| 132 | return(size); | ||
| 133 | } | ||
| 134 | |||
| 135 | extern unsigned char xread_char(int fd) | 124 | extern unsigned char xread_char(int fd) |
| 136 | { | 125 | { |
| 137 | char tmp; | 126 | char tmp; |
