Abstract read and seek in unarchiving code, convert bunzip to file descriptors, support tar -j
This commit is contained in:
parent
2fc54a9258
commit
237ae42fc9
@ -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;
|
||||
} 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;
|
||||
|
@ -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
|
||||
|
48
archival/libunarchive/archive_copy_file.c
Normal file
48
archival/libunarchive/archive_copy_file.c
Normal 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;
|
||||
}
|
33
archival/libunarchive/archive_xread.c
Normal file
33
archival/libunarchive/archive_xread.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
32
archival/libunarchive/archive_xread_all_eof.c
Normal file
32
archival/libunarchive/archive_xread_all_eof.c
Normal 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);
|
||||
}
|
30
archival/libunarchive/archive_xread_char.c
Normal file
30
archival/libunarchive/archive_xread_char.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
|
||||
return(skip_amount);
|
||||
archive_handle->seek(archive_handle, skip_amount);
|
||||
|
||||
archive_handle->offset += 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)
|
||||
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*/
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
25
archival/libunarchive/seek_by_char.c
Normal file
25
archival/libunarchive/seek_by_char.c
Normal 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);
|
||||
}
|
||||
}
|
35
archival/libunarchive/seek_by_jump.c
Normal file
35
archival/libunarchive/seek_by_jump.c
Normal 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");
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user