Abstract read and seek in unarchiving code, convert bunzip to file descriptors, support tar -j
No binary (build failed)
—
(log yok)
| @@ -50,7 +50,7 @@ static void header_verbose_list_ar(const file_header_t *file_header) | |
| 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); | |
| } | |
| - | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO |
| + | #if !defined CONFIG_TAR && !defined CONFIG_DPKG_DEB && !defined CONFIG_CPIO |
| /* This is simpler than data_extract_all */ | |
| static void data_extract_regular_file(archive_handle_t *archive_handle) | |
| { | |
| @@ -59,7 +59,7 @@ static void data_extract_regular_file(archive_handle_t *archive_handle) | |
| file_header = archive_handle->file_header; | |
| dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); | |
| - | copy_file_chunk_fd(archive_handle->src_fd, dst_fd, file_header->size); |
| + | archive_copy_file(archive_handle, dst_fd); |
| close(dst_fd); | |
| chmod(file_header->name, file_header->mode); | |
| @@ -80,18 +80,10 @@ extern int ar_main(int argc, char **argv) | |
| archive_handle_t *archive_handle; | |
| int opt; | |
| - | #ifndef CONFIG_DPKG_DEB |
| + | #if !defined CONFIG_DPKG_DEB && !defined CONFIG_DPKG |
| char magic[8]; | |
| #endif | |
| - | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO |
| archive_handle = init_handle(); | |
| - | #else |
| - | archive_handle = xcalloc(1, sizeof(archive_handle_t)); |
| - | archive_handle->filter = filter_accept_all; |
| - | archive_handle->action_data = data_skip; |
| - | archive_handle->action_header = header_skip; |
| - | archive_handle->file_header =xmalloc(sizeof(file_header_t)); |
| - | #endif |
| while ((opt = getopt(argc, argv, "covtpxX")) != -1) { | |
| switch (opt) { | |
| @@ -104,7 +96,7 @@ extern int ar_main(int argc, char **argv) | |
| case 'X': | |
| archive_handle->action_header = header_verbose_list_ar; | |
| case 'x': /* extract */ | |
| - | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO |
| + | #if defined CONFIG_TAR || defined CONFIG_DPKG_DEB || defined CONFIG_CPIO |
| archive_handle->action_data = data_extract_all; | |
| #else | |
| archive_handle->action_data = data_extract_regular_file; | |
| @@ -136,10 +128,10 @@ extern int ar_main(int argc, char **argv) | |
| optind++; | |
| } | |
| - | #if defined CONFIG_DPKG_DEB |
| + | #if defined CONFIG_DPKG_DEB || defined CONFIG_DPKG |
| unpack_ar_archive(archive_handle); | |
| #else | |
| - | xread_all(archive_handle->src_fd, magic, 7); |
| + | archive_xread_all(archive_handle, magic, 7); |
| if (strncmp(magic, "!<arch>", 7) != 0) { | |
| error_msg_and_die("Invalid ar magic"); | |
| } | |
| @@ -17,9 +17,11 @@ | |
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
| */ | |
| + | #include <fcntl.h> |
| #include <getopt.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| + | #include <string.h> |
| #include <unistd.h> | |
| #include "busybox.h" | |
| @@ -33,8 +35,8 @@ int bunzip2_main(int argc, char **argv) | |
| int opt = 0; | |
| int status; | |
| - | FILE *src_stream; |
| - | FILE *dst_stream; |
| + | int src_fd; |
| + | int dst_fd; |
| char *save_name = NULL; | |
| char *delete_name = NULL; | |
| @@ -59,10 +61,10 @@ int bunzip2_main(int argc, char **argv) | |
| /* Set input filename and number */ | |
| if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) { | |
| flags |= bunzip_to_stdout; | |
| - | src_stream = stdin; |
| + | src_fd = fileno(stdin); |
| } else { | |
| /* Open input file */ | |
| - | src_stream = xfopen(argv[optind], "r"); |
| + | src_fd = xopen(argv[optind], O_RDONLY); |
| save_name = xstrdup(argv[optind]); | |
| if (strcmp(save_name + strlen(save_name) - 4, ".bz2") != 0) | |
| @@ -71,29 +73,30 @@ int bunzip2_main(int argc, char **argv) | |
| } | |
| /* Check that the input is sane. */ | |
| - | if (isatty(fileno(src_stream)) && (flags & bunzip_force) == 0) |
| + | if (isatty(src_fd) && (flags & bunzip_force) == 0) { |
| error_msg_and_die("compressed data not read from terminal. Use -f to force it."); | |
| + | } |
| if (flags & bunzip_to_stdout) { | |
| - | dst_stream = stdout; |
| + | dst_fd = fileno(stdout); |
| } else { | |
| - | dst_stream = xfopen(save_name, "w"); |
| + | dst_fd = xopen(save_name, O_WRONLY | O_CREAT); |
| } | |
| - | if (uncompressStream(src_stream, dst_stream)) { |
| - | if (!(flags & bunzip_to_stdout)) |
| + | if (uncompressStream(src_fd, dst_fd)) { |
| + | if (!(flags & bunzip_to_stdout)) { |
| delete_name = argv[optind]; | |
| + | } |
| status = EXIT_SUCCESS; | |
| } else { | |
| - | if (!(flags & bunzip_to_stdout)) |
| + | if (!(flags & bunzip_to_stdout)) { |
| delete_name = save_name; | |
| + | } |
| status = EXIT_FAILURE; | |
| } | |
| - | if (delete_name) { |
| - | if (unlink(delete_name) < 0) { |
| - | error_msg_and_die("Couldn't remove %s", delete_name); |
| - | } |
| + | if ((delete_name) && (unlink(delete_name) < 0)) { |
| + | error_msg_and_die("Couldn't remove %s", delete_name); |
| } | |
| return status; | |
| @@ -26,6 +26,7 @@ bool 'rpm2cpio' CONFIG_RPM2CPIO | |
| bool 'tar' CONFIG_TAR | |
| if [ "$CONFIG_TAR" = "y" ] ; then | |
| bool ' Enable archive creation' CONFIG_FEATURE_TAR_CREATE | |
| + | bool ' Enable -j option to handle .tar.bz2 files' CONFIG_FEATURE_TAR_BZIP2 |
| bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE | |
| bool ' Enable -z option' CONFIG_FEATURE_TAR_GZIP | |
| bool ' Enable support for old tar header format' CONFIG_FEATURE_TAR_OLD_FORMAT | |
| @@ -45,6 +45,7 @@ extern int cpio_main(int argc, char **argv) | |
| /* Initialise */ | |
| archive_handle = init_handle(); | |
| archive_handle->src_fd = fileno(stdin); | |
| + | archive_handle->seek = seek_by_char; |
| archive_handle->action_header = header_list; | |
| while ((opt = getopt(argc, argv, "idmuvtF:")) != -1) { | |
| @@ -69,6 +70,7 @@ extern int cpio_main(int argc, char **argv) | |
| break; | |
| case 'F': | |
| archive_handle->src_fd = xopen(optarg, O_RDONLY); | |
| + | archive_handle->seek = seek_by_jump; |
| break; | |
| default: | |
| show_usage(); | |
| @@ -117,9 +119,9 @@ extern int cpio_main(int argc, char **argv) | |
| } | |
| /* There can be padding before archive header */ | |
| - | archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 4); |
| + | data_align(archive_handle, 4); |
| - | if (xread_all_eof(archive_handle->src_fd, cpio_header, 110) == 0) { |
| + | if (archive_xread_all_eof(archive_handle, cpio_header, 110) == 0) { |
| return(EXIT_FAILURE); | |
| } | |
| archive_handle->offset += 110; | |
| @@ -145,12 +147,12 @@ extern int cpio_main(int argc, char **argv) | |
| dummy, &major, &minor, &namesize, dummy); | |
| file_header->name = (char *) xmalloc(namesize + 1); | |
| - | xread(archive_handle->src_fd, file_header->name, namesize); /* Read in filename */ |
| + | archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */ |
| file_header->name[namesize] = '\0'; | |
| archive_handle->offset += namesize; | |
| /* Update offset amount and skip padding before file contents */ | |
| - | archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 4); |
| + | data_align(archive_handle, 4); |
| if (strcmp(file_header->name, "TRAILER!!!") == 0) { | |
| 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) | |
| if (S_ISLNK(file_header->mode)) { | |
| file_header->link_name = (char *) xmalloc(file_header->size + 1); | |
| - | xread(archive_handle->src_fd, file_header->link_name, file_header->size); |
| + | archive_xread_all(archive_handle, file_header->link_name, file_header->size); |
| file_header->link_name[file_header->size] = '\0'; | |
| archive_handle->offset += file_header->size; | |
| file_header->size = 0; /* Stop possible seeks in future */ | |
| @@ -40,16 +40,24 @@ LIBUNARCHIVE-y:= \ | |
| header_skip.o \ | |
| header_list.o \ | |
| header_verbose_list.o \ | |
| + | \ |
| + | archive_xread.o \ |
| + | archive_xread_all.o \ |
| + | archive_xread_all_eof.o \ |
| + | archive_xread_char.o \ |
| + | \ |
| + | seek_by_char.o \ |
| + | seek_by_jump.o \ |
| + | \ |
| + | archive_copy_file.o \ |
| \ | |
| add_to_list.o \ | |
| check_header_gzip.o \ | |
| check_trailer_gzip.o \ | |
| - | copy_file_chunk_fd.o \ |
| data_align.o \ | |
| decompress_bunzip2.o \ | |
| find_list_entry.o \ | |
| init_handle.o \ | |
| - | seek_sub_file.o \ |
| uncompress.o \ | |
| unpack_ar_archive.o \ | |
| unzip.o | |
| @@ -0,0 +1,48 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include <unistd.h> |
| + | |
| + | #include "libbb.h" |
| + | #include "unarchive.h" |
| + | |
| + | /* Copy CHUNKSIZE bytes (or untill EOF if chunksize == -1) |
| + | * from SRC_FILE to DST_FILE. */ |
| + | extern void archive_copy_file(const archive_handle_t *archive_handle, const int dst_fd) |
| + | { |
| + | size_t size; |
| + | char buffer[BUFSIZ]; |
| + | off_t chunksize = archive_handle->file_header->size; |
| + | |
| + | while (chunksize != 0) { |
| + | if (chunksize > BUFSIZ) { |
| + | size = BUFSIZ; |
| + | } else { |
| + | size = chunksize; |
| + | } |
| + | archive_xread_all(archive_handle, buffer, size); |
| + | |
| + | if (write(dst_fd, buffer, size) != size) { |
| + | error_msg_and_die ("Short write"); |
| + | } |
| + | |
| + | if (chunksize != -1) { |
| + | chunksize -= size; |
| + | } |
| + | } |
| + | |
| + | return; |
| + | } |
| @@ -0,0 +1,33 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include <stdio.h> |
| + | #include <stdlib.h> |
| + | #include <string.h> |
| + | #include "unarchive.h" |
| + | #include "libbb.h" |
| + | |
| + | extern ssize_t archive_xread(const archive_handle_t *archive_handle, unsigned char *buf, const size_t count) |
| + | { |
| + | ssize_t size; |
| + | |
| + | size = archive_handle->read(archive_handle->src_fd, buf, count); |
| + | if (size == -1) { |
| + | perror_msg_and_die("Read error"); |
| + | } |
| + | |
| + | return(size); |
| + | } |
| @@ -14,19 +14,19 @@ | |
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
| */ | |
| - | #include <sys/types.h> |
| - | #include <errno.h> |
| - | #include <unistd.h> |
| + | #include <stdio.h> |
| #include <stdlib.h> | |
| + | #include <string.h> |
| #include "unarchive.h" | |
| #include "libbb.h" | |
| - | extern void seek_sub_file(const int src_fd, const unsigned int amount) |
| + | extern void archive_xread_all(const archive_handle_t *archive_handle, void *buf, const size_t count) |
| { | |
| - | if ((lseek(src_fd, amount, SEEK_CUR) == -1) && (errno == ESPIPE)) { |
| - | unsigned int i; |
| - | for (i = 0; i < amount; i++) { |
| - | xread_char(src_fd); |
| - | } |
| + | ssize_t size; |
| + | |
| + | size = archive_xread(archive_handle, buf, count); |
| + | if (size != count) { |
| + | error_msg_and_die("Short read"); |
| } | |
| + | return; |
| } | |
| @@ -0,0 +1,32 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include <stdio.h> |
| + | #include <stdlib.h> |
| + | #include <string.h> |
| + | #include "unarchive.h" |
| + | #include "libbb.h" |
| + | |
| + | extern ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned char *buf, size_t count) |
| + | { |
| + | ssize_t size; |
| + | |
| + | size = archive_xread(archive_handle, buf, count); |
| + | if ((size != 0) && (size != count)) { |
| + | perror_msg_and_die("Short read, read %d of %d", size, count); |
| + | } |
| + | return(size); |
| + | } |
| @@ -0,0 +1,30 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include <stdio.h> |
| + | #include <stdlib.h> |
| + | #include <string.h> |
| + | #include "unarchive.h" |
| + | #include "libbb.h" |
| + | |
| + | extern unsigned char archive_xread_char(const archive_handle_t *archive_handle) |
| + | { |
| + | unsigned char tmp; |
| + | |
| + | archive_xread(archive_handle, &tmp, 1); |
| + | |
| + | return(tmp); |
| + | } |
| @@ -1,33 +0,0 @@ | |
| - | #include <unistd.h> |
| - | #include <sys/types.h> |
| - | #include "libbb.h" |
| - | |
| - | /* Copy CHUNKSIZE bytes (or untill EOF if chunksize == -1) |
| - | * from SRC_FILE to DST_FILE. */ |
| - | extern int copy_file_chunk_fd(int src_fd, int dst_fd, off_t chunksize) |
| - | { |
| - | size_t nread, size; |
| - | char buffer[BUFSIZ]; |
| - | |
| - | while (chunksize != 0) { |
| - | if (chunksize > BUFSIZ) { |
| - | size = BUFSIZ; |
| - | } else { |
| - | size = chunksize; |
| - | } |
| - | nread = xread(src_fd, buffer, size); |
| - | if (nread == 0) { |
| - | return 1; |
| - | } |
| - | |
| - | if (write (dst_fd, buffer, nread) != nread) { |
| - | error_msg_and_die ("Short write"); |
| - | } |
| - | |
| - | if (chunksize != -1) { |
| - | chunksize -= nread; |
| - | } |
| - | } |
| - | |
| - | return 0; |
| - | } |
| @@ -1,13 +1,34 @@ | |
| - | #include <errno.h> |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| #include <sys/types.h> | |
| + | |
| + | #include <errno.h> |
| #include <unistd.h> | |
| - | #include "unarchive.h" |
| + | |
| #include "libbb.h" | |
| + | #include "unarchive.h" |
| - | extern const unsigned short data_align(const int src_fd, const unsigned int offset, const unsigned short align_to) |
| + | extern void data_align(archive_handle_t *archive_handle, const unsigned short boundary) |
| { | |
| - | const unsigned short skip_amount = (align_to - (offset % align_to)) % align_to; |
| - | seek_sub_file(src_fd, skip_amount); |
| + | const unsigned short skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary; |
| + | |
| + | archive_handle->seek(archive_handle, skip_amount); |
| + | |
| + | archive_handle->offset += skip_amount; |
| - | return(skip_amount); |
| + | return; |
| } | |
| @@ -1,4 +1,21 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| #include <sys/types.h> | |
| + | |
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include <stdlib.h> | |
| @@ -6,6 +23,7 @@ | |
| #include <utime.h> | |
| #include <unistd.h> | |
| #include <stdlib.h> | |
| + | |
| #include "libbb.h" | |
| #include "unarchive.h" | |
| @@ -21,7 +39,7 @@ extern void data_extract_all(archive_handle_t *archive_handle) | |
| free(name); | |
| } | |
| - | /* Create the file */ |
| + | /* Create the filesystem entry */ |
| switch(file_header->mode & S_IFMT) { | |
| case S_IFREG: { | |
| #ifdef CONFIG_CPIO | |
| @@ -36,7 +54,7 @@ extern void data_extract_all(archive_handle_t *archive_handle) | |
| { | |
| /* Regular file */ | |
| dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); | |
| - | copy_file_chunk_fd(archive_handle->src_fd, dst_fd, file_header->size); |
| + | archive_copy_file(archive_handle, dst_fd); |
| close(dst_fd); | |
| } | |
| break; | |
| @@ -1,11 +1,26 @@ | |
| - | #include <stdlib.h> |
| - | #include <stdio.h> |
| - | #include "unarchive.h" |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| #include "libbb.h" | |
| + | #include "unarchive.h" |
| extern void data_extract_to_buffer(archive_handle_t *archive_handle) | |
| { | |
| archive_handle->buffer = xmalloc(archive_handle->file_header->size + 1); | |
| - | xread_all(archive_handle->src_fd, archive_handle->buffer, archive_handle->file_header->size); |
| + | archive_xread_all(archive_handle, archive_handle->buffer, archive_handle->file_header->size); |
| + | |
| } | |
| @@ -1,8 +1,22 @@ | |
| - | #include <stdlib.h> |
| - | #include <stdio.h> |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| #include "unarchive.h" | |
| extern void data_extract_to_stdout(archive_handle_t *archive_handle) | |
| { | |
| - | copy_file_chunk_fd(archive_handle->src_fd, fileno(stdout), archive_handle->file_header->size); |
| + | archive_copy_file(archive_handle, fileno(stdout)); |
| } | |
| @@ -23,5 +23,5 @@ | |
| extern void data_skip(archive_handle_t *archive_handle) | |
| { | |
| - | seek_sub_file(archive_handle->src_fd, archive_handle->file_header->size); |
| + | archive_handle->seek(archive_handle, archive_handle->file_header->size); |
| } | |
| @@ -57,10 +57,8 @@ | |
| #include <string.h> | |
| #include <getopt.h> | |
| #include <unistd.h> | |
| - | #include <busybox.h> |
| - | //#define TRUE 1 |
| - | //#define FALSE 0 |
| + | #include "busybox.h" |
| #define MTFA_SIZE 4096 | |
| #define MTFL_SIZE 16 | |
| @@ -142,9 +140,10 @@ typedef struct { | |
| } bz_stream; | |
| + | #define BZ_MAX_UNUSED 5000 |
| typedef struct { | |
| bz_stream strm; | |
| - | FILE *handle; |
| + | int fd; |
| unsigned char initialisedOk; | |
| char buf[BZ_MAX_UNUSED]; | |
| int lastErr; | |
| @@ -237,18 +236,11 @@ typedef struct { | |
| int *save_gPerm; | |
| } DState; | |
| - | int BZ2_rNums[512]; |
| - | char inName[FILE_NAME_LEN]; |
| - | char outName[FILE_NAME_LEN]; |
| - | int srcMode; |
| - | int opMode; |
| - | unsigned char deleteOutputOnInterrupt; |
| - | FILE *outputHandleJustInCase; |
| - | int numFileNames; |
| - | int numFilesProcessed; |
| - | int exitValue; |
| + | static int BZ2_rNums[512]; |
| + | static bzFile *bzf; |
| + | static int bzerr = BZ_OK; |
| - | const unsigned int BZ2_crc32Table[256] = { |
| + | static const unsigned int BZ2_crc32Table[256] = { |
| /*-- Ugly, innit? --*/ | |
| @@ -330,16 +322,6 @@ static void bz_rand_udp_mask(DState *s) | |
| s->rNToGo--; | |
| } | |
| - | static unsigned char myfeof(FILE *f) |
| - | { |
| - | int c = fgetc(f); |
| - | if (c == EOF) { |
| - | return(TRUE); |
| - | } |
| - | ungetc(c, f); |
| - | return(FALSE); |
| - | } |
| - | |
| static void BZ2_hbCreateDecodeTables(int *limit, int *base, int *perm, unsigned char *length, int minLen, int maxLen, int alphaSize ) | |
| { | |
| int pp, i, j, vec; | |
| @@ -1292,43 +1274,8 @@ save_state_and_return: | |
| return retVal; | |
| } | |
| - | //int BZ2_bzDecompressInit(bz_stream* strm, int verbosity_level, int small) |
| - | static inline int BZ2_bzDecompressInit(bz_stream* strm) |
| - | { |
| - | DState* s; |
| - | |
| - | // if (verbosity_level < 0 || verbosity_level > 4) { |
| - | // return BZ_PARAM_ERROR; |
| - | // } |
| - | s = xmalloc(sizeof(DState)); |
| - | s->strm = strm; |
| - | strm->state = s; |
| - | s->state = BZ_X_MAGIC_1; |
| - | s->bsLive = 0; |
| - | s->bsBuff = 0; |
| - | s->calculatedCombinedCRC = 0; |
| - | s->tt = NULL; |
| - | s->currBlockNo = 0; |
| - | |
| - | return BZ_OK; |
| - | } |
| - | |
| - | static void bz_seterr(int eee, int *bzerror, bzFile **bzf) |
| + | static void BZ2_bzReadClose(void) |
| { | |
| - | if (bzerror != NULL) { |
| - | *bzerror = eee; |
| - | } |
| - | if (*bzf != NULL) { |
| - | (*bzf)->lastErr = eee; |
| - | } |
| - | } |
| - | |
| - | static void BZ2_bzReadClose(int *bzerror, void *b) |
| - | { |
| - | bzFile* bzf = (bzFile*)b; |
| - | |
| - | bz_seterr(BZ_OK, bzerror, &bzf); |
| - | |
| if (bzf->initialisedOk) { | |
| bz_stream *strm = &(bzf->strm); | |
| DState *s; | |
| @@ -1588,31 +1535,22 @@ int BZ2_bzDecompress(bz_stream *strm) | |
| return(0); /*NOTREACHED*/ | |
| } | |
| - | static inline int BZ2_bzRead(int *bzerror, void *b, void *buf, int len) |
| + | extern ssize_t read_bz2(int fd, void *buf, size_t count) |
| { | |
| int n, ret; | |
| - | bzFile *bzf = (bzFile*)b; |
| - | |
| - | bz_seterr(BZ_OK, bzerror, &bzf); |
| - | if (len == 0) { |
| - | bz_seterr(BZ_OK, bzerror, &bzf); |
| - | return 0; |
| + | bzerr = BZ_OK; |
| + | if (count == 0) { |
| + | return(0); |
| } | |
| - | |
| - | bzf->strm.avail_out = len; |
| + | bzf->strm.avail_out = count; |
| bzf->strm.next_out = buf; | |
| while (1) { | |
| - | if (ferror(bzf->handle)) { |
| - | bz_seterr(BZ_IO_ERROR, bzerror, &bzf); |
| - | return 0; |
| - | } |
| - | if ((bzf->strm.avail_in == 0) && !myfeof(bzf->handle)) { |
| - | n = fread(bzf->buf, sizeof(unsigned char), BZ_MAX_UNUSED, bzf->handle); |
| - | if (ferror(bzf->handle)) { |
| - | bz_seterr(BZ_IO_ERROR, bzerror, &bzf); |
| - | return 0; |
| + | if (bzf->strm.avail_in == 0) { |
| + | n = xread(bzf->fd, bzf->buf, BZ_MAX_UNUSED); |
| + | if (n == 0) { |
| + | break; |
| } | |
| bzf->bufN = n; | |
| bzf->strm.avail_in = bzf->bufN; | |
| @@ -1622,48 +1560,43 @@ static inline int BZ2_bzRead(int *bzerror, void *b, void *buf, int len) | |
| ret = BZ2_bzDecompress(&(bzf->strm)); | |
| if ((ret != BZ_OK) && (ret != BZ_STREAM_END)) { | |
| - | bz_seterr(ret, bzerror, &bzf); |
| - | return 0; |
| - | } |
| - | |
| - | if ((ret == BZ_OK) && myfeof(bzf->handle) && |
| - | (bzf->strm.avail_in == 0) && (bzf->strm.avail_out > 0)) { |
| - | bz_seterr(BZ_UNEXPECTED_EOF, bzerror, &bzf); |
| - | return(0); |
| + | error_msg_and_die("Error decompressing"); |
| } | |
| if (ret == BZ_STREAM_END) { | |
| - | bz_seterr(BZ_STREAM_END, bzerror, &bzf); |
| - | return(len - bzf->strm.avail_out); |
| + | bzerr = BZ_STREAM_END; |
| + | return(count - bzf->strm.avail_out); |
| } | |
| if (bzf->strm.avail_out == 0) { | |
| - | bz_seterr(BZ_OK, bzerror, &bzf); |
| - | return(len); |
| + | bzerr = BZ_OK; |
| + | return(count); |
| } | |
| } | |
| - | return(0); /*not reached*/ |
| + | return(0); |
| } | |
| - | static inline void *BZ2_bzReadOpen(int *bzerror, FILE *f, void *unused, int nUnused) |
| + | extern void BZ2_bzReadOpen(int fd, void *unused, int nUnused) |
| { | |
| - | bzFile *bzf = xmalloc(sizeof(bzFile)); |
| - | int ret; |
| - | |
| - | bz_seterr(BZ_OK, bzerror, &bzf); |
| + | DState *s; |
| + | bzf = xmalloc(sizeof(bzFile)); |
| bzf->initialisedOk = FALSE; | |
| - | bzf->handle = f; |
| - | bzf->bufN = 0; |
| - | |
| - | ret = BZ2_bzDecompressInit(&(bzf->strm)); |
| - | if (ret != BZ_OK) { |
| - | bz_seterr(ret, bzerror, &bzf); |
| - | free(bzf); |
| - | return NULL; |
| - | } |
| + | bzf->fd = fd; |
| + | bzf->bufN = 0; |
| + | |
| + | s = xmalloc(sizeof(DState)); |
| + | s->strm = &bzf->strm; |
| + | s->state = BZ_X_MAGIC_1; |
| + | s->bsLive = 0; |
| + | s->bsBuff = 0; |
| + | s->calculatedCombinedCRC = 0; |
| + | s->tt = NULL; |
| + | s->currBlockNo = 0; |
| + | bzf->strm.state = s; |
| while (nUnused > 0) { | |
| - | bzf->buf[bzf->bufN] = *((unsigned char *)(unused)); bzf->bufN++; |
| + | bzf->buf[bzf->bufN] = *((unsigned char *)(unused)); |
| + | bzf->bufN++; |
| unused = ((void *)( 1 + ((unsigned char *)(unused)) )); | |
| nUnused--; | |
| } | |
| @@ -1671,119 +1604,55 @@ static inline void *BZ2_bzReadOpen(int *bzerror, FILE *f, void *unused, int nUnu | |
| bzf->strm.next_in = bzf->buf; | |
| bzf->initialisedOk = TRUE; | |
| - | return bzf; |
| + | |
| + | return; |
| } | |
| - | extern unsigned char uncompressStream(FILE *zStream, FILE *stream) |
| + | extern unsigned char uncompressStream(int src_fd, int dst_fd) |
| { | |
| unsigned char unused[BZ_MAX_UNUSED]; | |
| unsigned char *unusedTmp; | |
| unsigned char obuf[5000]; | |
| - | bzFile *bzf = NULL; |
| - | int bzerr_dummy; |
| - | int bzerr; |
| int nread; | |
| int nUnused; | |
| int streamNo; | |
| - | int ret; |
| int i; | |
| nUnused = 0; | |
| streamNo = 0; | |
| - | if (ferror(stream)) { |
| - | goto errhandler_io; |
| - | } |
| - | if (ferror(zStream)) { |
| - | goto errhandler_io; |
| - | } |
| - | |
| while(1) { | |
| - | bzf = BZ2_bzReadOpen(&bzerr, zStream, unused, nUnused); |
| - | if (bzf == NULL || bzerr != BZ_OK) { |
| - | goto errhandler; |
| - | } |
| + | BZ2_bzReadOpen(src_fd, unused, nUnused); |
| streamNo++; | |
| while (bzerr == BZ_OK) { | |
| - | nread = BZ2_bzRead(&bzerr, bzf, obuf, 5000); |
| + | nread = read_bz2(src_fd, obuf, 5000); |
| if (bzerr == BZ_DATA_ERROR_MAGIC) { | |
| - | goto errhandler; |
| - | } |
| - | if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0) { |
| - | fwrite(obuf, sizeof(unsigned char), nread, stream); |
| + | error_msg_and_die("invalid magic"); |
| } | |
| - | if (ferror(stream)) { |
| - | goto errhandler_io; |
| + | if (((bzerr == BZ_OK) || (bzerr == BZ_STREAM_END)) && (nread > 0)) { |
| + | if (write(dst_fd, obuf, nread) != nread) { |
| + | BZ2_bzReadClose(); |
| + | perror_msg_and_die("Couldnt write to file"); |
| + | } |
| } | |
| } | |
| - | if (bzerr != BZ_STREAM_END) { |
| - | goto errhandler; |
| - | } |
| nUnused = bzf->strm.avail_in; | |
| unusedTmp = bzf->strm.next_in; | |
| - | bz_seterr(BZ_OK, &bzerr, &bzf); |
| + | |
| for (i = 0; i < nUnused; i++) { | |
| unused[i] = unusedTmp[i]; | |
| } | |
| - | BZ2_bzReadClose(&bzerr, bzf); |
| - | if ((nUnused == 0) && myfeof(zStream)) { |
| + | BZ2_bzReadClose(); |
| + | if (nUnused == 0) { |
| break; | |
| } | |
| } | |
| - | if (ferror(zStream)) { |
| - | goto errhandler_io; |
| - | } |
| - | ret = fclose(zStream); |
| - | if (ret == EOF) { |
| - | goto errhandler_io; |
| - | } |
| - | if (ferror(stream)) { |
| - | goto errhandler_io; |
| - | } |
| - | ret = fflush(stream); |
| - | if (ret != 0) { |
| - | goto errhandler_io; |
| - | } |
| - | if (stream != stdout) { |
| - | ret = fclose(stream); |
| - | if (ret == EOF) { |
| - | goto errhandler_io; |
| - | } |
| + | close(src_fd); |
| + | if (dst_fd != fileno(stdout)) { |
| + | close(dst_fd); |
| } | |
| return TRUE; | |
| - | |
| - | errhandler: |
| - | BZ2_bzReadClose ( &bzerr_dummy, bzf ); |
| - | switch (bzerr) { |
| - | case BZ_IO_ERROR: |
| - | errhandler_io: |
| - | error_msg("\n%s: I/O or other error, bailing out. " |
| - | "Possible reason follows.\n", applet_name); |
| - | perror(applet_name); |
| - | exit(1); |
| - | case BZ_DATA_ERROR: |
| - | error_msg("\n%s: Data integrity error when decompressing.\n", applet_name); |
| - | exit(2); |
| - | case BZ_UNEXPECTED_EOF: |
| - | error_msg("\n%s: Compressed file ends unexpectedly;\n\t" |
| - | "perhaps it is corrupted? *Possible* reason follows.\n", applet_name); |
| - | perror(applet_name); |
| - | exit(2); |
| - | case BZ_DATA_ERROR_MAGIC: |
| - | if (zStream != stdin) { |
| - | fclose(zStream); |
| - | } |
| - | if (stream != stdout) { |
| - | fclose(stream); |
| - | } |
| - | if (streamNo == 1) { |
| - | return FALSE; |
| - | } else { |
| - | return TRUE; |
| - | } |
| - | } |
| - | |
| - | return(TRUE); /*notreached*/ |
| } | |
| + | |
| @@ -50,9 +50,9 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |
| char *tmp; | |
| /* Align header */ | |
| - | archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 512); |
| + | data_align(archive_handle, 512); |
| - | if (xread_all_eof(archive_handle->src_fd, tar.raw, 512) == 0) { |
| + | if (archive_xread_all_eof(archive_handle, tar.raw, 512) == 0) { |
| /* End of file */ | |
| return(EXIT_FAILURE); | |
| } | |
| @@ -72,7 +72,6 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |
| #endif | |
| error_msg_and_die("Invalid tar magic"); | |
| } | |
| - | |
| /* Do checksum on headers */ | |
| for (i = 0; i < 148 ; i++) { | |
| sum += tar.raw[i]; | |
| @@ -138,7 +137,7 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |
| char *longname; | |
| longname = xmalloc(file_header->size + 1); | |
| - | xread_all(archive_handle->src_fd, longname, file_header->size); |
| + | archive_xread_all(archive_handle, longname, file_header->size); |
| longname[file_header->size] = '\0'; | |
| archive_handle->offset += file_header->size; | |
| @@ -150,7 +149,7 @@ extern char get_header_tar(archive_handle_t *archive_handle) | |
| char *linkname; | |
| linkname = xmalloc(file_header->size + 1); | |
| - | xread_all(archive_handle->src_fd, linkname, file_header->size); |
| + | archive_xread_all(archive_handle, linkname, file_header->size); |
| linkname[file_header->size] = '\0'; | |
| archive_handle->offset += file_header->size; | |
| @@ -29,7 +29,10 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) | |
| int pid; | |
| unsigned char magic[2]; | |
| - | xread_all(archive_handle->src_fd, &magic, 2); |
| + | /* Cant lseek over pipe's */ |
| + | archive_handle->seek = seek_by_char; |
| + | |
| + | archive_xread_all(archive_handle, &magic, 2); |
| if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { | |
| error_msg_and_die("Invalid gzip magic"); | |
| } | |
| @@ -1,3 +1,20 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include <unistd.h> |
| #include <string.h> | |
| #include "libbb.h" | |
| #include "unarchive.h" | |
| @@ -13,6 +30,8 @@ archive_handle_t *init_handle(void) | |
| archive_handle->action_header = header_skip; | |
| archive_handle->action_data = data_skip; | |
| archive_handle->filter = filter_accept_all; | |
| + | archive_handle->read = read; |
| + | archive_handle->seek = seek_by_jump; |
| return(archive_handle); | |
| } | |
| @@ -0,0 +1,25 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include "unarchive.h" |
| + | |
| + | extern void seek_by_char(const archive_handle_t *archive_handle, const unsigned int amount) |
| + | { |
| + | unsigned int i; |
| + | for (i = 0; i < amount; i++) { |
| + | archive_xread_char(archive_handle); |
| + | } |
| + | } |
| @@ -0,0 +1,35 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | #include <sys/types.h> |
| + | #include <errno.h> |
| + | #include <unistd.h> |
| + | #include <stdlib.h> |
| + | |
| + | #include "libbb.h" |
| + | #include "unarchive.h" |
| + | |
| + | extern void seek_by_jump(const archive_handle_t *archive_handle, const unsigned int amount) |
| + | { |
| + | if (lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1) { |
| + | #if CONFIG_FEATURE_UNARCHIVE_TAPE |
| + | if (errno == ESPIPE) { |
| + | seek_by_char(archive_handle, amount); |
| + | } else |
| + | #endif |
| + | perror_msg_and_die("Seek failure"); |
| + | } |
| + | } |
| @@ -24,7 +24,7 @@ extern void unpack_ar_archive(archive_handle_t *ar_archive) | |
| { | |
| char magic[7]; | |
| - | xread_all(ar_archive->src_fd, magic, 7); |
| + | archive_xread_all(ar_archive, magic, 7); |
| if (strncmp(magic, "!<arch>", 7) != 0) { | |
| error_msg_and_die("Invalid ar magic"); | |
| } | |
| @@ -627,7 +627,7 @@ int tar_main(int argc, char **argv) | |
| tar_handle = init_handle(); | |
| tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS; | |
| - | while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) { |
| + | while ((opt = getopt(argc, argv, "cjtxT:X:C:f:Opvz")) != -1) { |
| switch (opt) { | |
| /* One and only one of these is required */ | |
| #ifdef CONFIG_FEATURE_TAR_CREATE | |
| @@ -684,9 +684,8 @@ int tar_main(int argc, char **argv) | |
| break; | |
| #endif | |
| #ifdef CONFIG_FEATURE_TAR_BZIP2 | |
| - | /* Not enabled yet */ |
| case 'j': | |
| - | archive_handle->archive_action = bunzip2; |
| + | tar_handle->read = read_bz2; |
| break; | |
| #endif | |
| default: | |
| @@ -703,14 +702,8 @@ int tar_main(int argc, char **argv) | |
| /* Setup an array of filenames to work with */ | |
| /* TODO: This is the same as in ar, seperate function ? */ | |
| while (optind < argc) { | |
| - | #if 0 |
| - | char absolute_path[PATH_MAX]; |
| - | realpath(argv[optind], absolute_path); |
| - | tar_handle->accept = add_to_list(tar_handle->accept, absolute_path); |
| - | #endif |
| tar_handle->accept = add_to_list(tar_handle->accept, argv[optind]); | |
| optind++; | |
| - | |
| } | |
| if ((tar_handle->accept) || (tar_handle->reject)) { | |
| @@ -744,13 +737,21 @@ int tar_main(int argc, char **argv) | |
| if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) { | |
| tar_handle->src_fd = fileno(stdin); | |
| } else { | |
| + | tar_handle->seek = seek_by_jump; |
| tar_handle->src_fd = xopen(tar_filename, O_RDONLY); | |
| } | |
| #ifdef CONFIG_FEATURE_TAR_GZIP | |
| if (get_header_ptr == get_header_tar_gz) { | |
| + | tar_handle->seek = seek_by_char; |
| get_header_tar_gz(tar_handle); | |
| } else | |
| - | #endif /* CONFIG_FEATURE_TAR_CREATE */ |
| + | #endif /* CONFIG_FEATURE_TAR_GZIP */ |
| + | #ifdef CONFIG_FEATURE_TAR_BZIP2 |
| + | if (tar_handle->read == read_bz2) { |
| + | BZ2_bzReadOpen(tar_handle->src_fd, NULL, 0); |
| + | while (get_header_tar(tar_handle) == EXIT_SUCCESS); |
| + | } else |
| + | #endif /* CONFIG_FEATURE_TAR_BZIP2 */ |
| while (get_header_tar(tar_handle) == EXIT_SUCCESS); | |
| @@ -136,13 +136,14 @@ extern int unzip_main(int argc, char **argv) | |
| if (*argv[optind] == '-') { | |
| archive_handle->src_fd = fileno(stdin); | |
| - | } else { |
| + | archive_handle->seek = seek_by_char; |
| + | } else { |
| archive_handle->src_fd = xopen(argv[optind++], O_RDONLY); | |
| - | } |
| + | } |
| if ((base_dir) && (chdir(base_dir))) { | |
| perror_msg_and_die("Couldnt chdir"); | |
| - | } |
| + | } |
| while (optind < argc) { | |
| archive_handle->filter = filter_accept_list; | |
| @@ -155,7 +156,7 @@ extern int unzip_main(int argc, char **argv) | |
| int dst_fd; | |
| /* TODO Endian issues */ | |
| - | xread_all(archive_handle->src_fd, &magic, 4); |
| + | archive_xread_all(archive_handle, &magic, 4); |
| archive_handle->offset += 4; | |
| if (magic == ZIP_CDS_MAGIC) { | |
| @@ -166,7 +167,7 @@ extern int unzip_main(int argc, char **argv) | |
| } | |
| /* Read the file header */ | |
| - | xread_all(archive_handle->src_fd, zip_header.raw, 26); |
| + | archive_xread_all(archive_handle, zip_header.raw, 26); |
| archive_handle->offset += 26; | |
| archive_handle->file_header->mode = S_IFREG | 0777; | |
| @@ -176,7 +177,7 @@ extern int unzip_main(int argc, char **argv) | |
| /* Read filename */ | |
| archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); | |
| - | xread_all(archive_handle->src_fd, archive_handle->file_header->name, zip_header.formated.filename_len); |
| + | archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len); |
| archive_handle->offset += zip_header.formated.filename_len; | |
| archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; | |
| @@ -228,7 +229,7 @@ extern int unzip_main(int argc, char **argv) | |
| /* skip over duplicate crc, compressed size and uncompressed size */ | |
| unsigned short i; | |
| for (i = 0; i != 12; i++) { | |
| - | xread_char(archive_handle->src_fd); |
| + | archive_xread_char(archive_handle); |
| } | |
| archive_handle->offset += 12; | |
| } | |
| @@ -333,7 +333,6 @@ extern int obscure(const char *old, const char *newval, const struct passwd *pwd | |
| extern int xopen(const char *pathname, int flags); | |
| extern ssize_t xread(int fd, void *buf, size_t count); | |
| - | extern ssize_t xread_all_eof(int fd, void *buf, size_t count); |
| extern void xread_all(int fd, void *buf, size_t count); | |
| extern unsigned char xread_char(int fd); | |
| @@ -7,14 +7,8 @@ | |
| #define ARCHIVE_EXTRACT_QUIET 8 | |
| #include <sys/types.h> | |
| - | #include <stdio.h> |
| - | typedef struct gunzip_s { |
| - | unsigned short buffer_count; |
| - | unsigned char *buffer; |
| - | unsigned int crc; |
| - | unsigned int count; |
| - | } gunzip_t; |
| + | #include <stdio.h> |
| typedef struct file_headers_s { | |
| char *name; | |
| @@ -58,6 +52,12 @@ typedef struct archive_handle_s { | |
| /* Count the number of bytes processed */ | |
| off_t offset; | |
| + | /* Function that reads data: read or read_bz */ |
| + | ssize_t (*read)(int fd, void *buf, size_t count); |
| + | |
| + | /* Function that skips data: read_by_char or read_by_skip */ |
| + | void (*seek)(const struct archive_handle_s *archive_handle, const unsigned int amount); |
| + | |
| /* Temperary storage */ | |
| char *buffer; | |
| @@ -90,11 +90,21 @@ extern char get_header_ar(archive_handle_t *archive_handle); | |
| extern char get_header_tar(archive_handle_t *archive_handle); | |
| extern char get_header_tar_gz(archive_handle_t *archive_handle); | |
| - | extern unsigned char uncompressStream(FILE *zStream, FILE *stream); |
| + | extern void seek_by_jump(const archive_handle_t *archive_handle, const unsigned int amount); |
| + | extern void seek_by_char(const archive_handle_t *archive_handle, const unsigned int amount); |
| - | extern void seek_sub_file(int src_fd, unsigned int amount); |
| - | extern const unsigned short data_align(const int src_fd, const unsigned int offset, const unsigned short align_to); |
| + | extern unsigned char archive_xread_char(const archive_handle_t *archive_handle); |
| + | extern ssize_t archive_xread(const archive_handle_t *archive_handle, unsigned char *buf, const size_t count); |
| + | extern void archive_xread_all(const archive_handle_t *archive_handle, void *buf, const size_t count); |
| + | extern ssize_t archive_xread_all_eof(archive_handle_t *archive_handle, unsigned char *buf, size_t count); |
| + | |
| + | extern void data_align(archive_handle_t *archive_handle, const unsigned short boundary); |
| extern const llist_t *add_to_list(const llist_t *old_head, const char *new_item); | |
| - | extern int copy_file_chunk_fd(int src_fd, int dst_fd, unsigned long long chunksize); |
| + | extern void archive_copy_file(const archive_handle_t *archive_handle, const int dst_fd); |
| extern const llist_t *find_list_entry(const llist_t *list, const char *filename); | |
| + | |
| + | extern ssize_t read_bz2(int fd, void *buf, size_t count); |
| + | extern void BZ2_bzReadOpen(int fd, void *unused, int nUnused); |
| + | extern unsigned char uncompressStream(int src_fd, int dst_fd); |
| + | |
| #endif | |
| @@ -92,7 +92,7 @@ extern int xopen(const char *pathname, int flags) | |
| { | |
| int ret; | |
| - | ret = open(pathname, flags); |
| + | ret = open(pathname, flags, 0777); |
| if (ret == -1) { | |
| perror_msg_and_die("%s", pathname); | |
| } | |
| @@ -121,17 +121,6 @@ extern void xread_all(int fd, void *buf, size_t count) | |
| return; | |
| } | |
| - | extern ssize_t xread_all_eof(int fd, void *buf, size_t count) |
| - | { |
| - | ssize_t size; |
| - | |
| - | size = xread(fd, buf, count); |
| - | if ((size != 0) && (size != count)) { |
| - | error_msg_and_die("Short read"); |
| - | } |
| - | return(size); |
| - | } |
| - | |
| extern unsigned char xread_char(int fd) | |
| { | |
| char tmp; | |