Abstract read and seek in unarchiving code, convert bunzip to file descriptors, support tar -j

This commit is contained in:
Glenn L McGrath 2002-11-03 14:05:15 +00:00
parent 2fc54a9258
commit 237ae42fc9
28 changed files with 466 additions and 332 deletions

View File

@ -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");
}

View File

@ -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;
} else {
dst_stream = xfopen(save_name, "w");
}
if (uncompressStream(src_stream, dst_stream)) {
if (!(flags & bunzip_to_stdout))
if (flags & bunzip_to_stdout) {
dst_fd = fileno(stdout);
} else {
dst_fd = xopen(save_name, O_WRONLY | O_CREAT);
}
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;

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
return(skip_amount);
archive_handle->seek(archive_handle, skip_amount);
archive_handle->offset += skip_amount;
return;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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)
static void BZ2_bzReadClose(void)
{
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)
{
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;
bzf->fd = fd;
bzf->bufN = 0;
ret = BZ2_bzDecompressInit(&(bzf->strm));
if (ret != BZ_OK) {
bz_seterr(ret, bzerror, &bzf);
free(bzf);
return NULL;
}
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;
error_msg_and_die("invalid magic");
}
if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0) {
fwrite(obuf, sizeof(unsigned char), nread, stream);
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 (ferror(stream)) {
goto errhandler_io;
}
}
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*/
}

View File

@ -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;

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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");
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;