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 /archival/libunarchive | |
parent | 2fc54a9258c3aa5dad2ce9807ba85cf29af2668e (diff) | |
download | busybox-237ae42fc96ede945d28d9054f045b73e419d089.tar.gz |
Abstract read and seek in unarchiving code, convert bunzip to file descriptors, support tar -j
Diffstat (limited to 'archival/libunarchive')
19 files changed, 392 insertions, 256 deletions
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:= \ 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 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 @@ +/* + * 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; +} 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 @@ +/* + * 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); +} 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 @@ * 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; } 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 @@ +/* + * 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); +} 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 @@ +/* + * 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); +} 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 @@ -#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; -} 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 @@ -#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; } 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 @@ +/* + * 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; 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 @@ -#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); + } 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 @@ -#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)); } 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 @@ 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); } 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 @@ #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*/ } + 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) 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; 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) 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"); } 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 @@ +/* + * 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); } 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 @@ +/* + * 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); + } +} 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 @@ +/* + * 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"); + } +} 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) { 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"); } |