Support for tar -z option for uncompressing only

This commit is contained in:
Glenn L McGrath 2000-12-10 01:57:30 +00:00
parent 00732b57c7
commit 46f44d24fc
6 changed files with 163 additions and 48 deletions

View File

@ -1,5 +1,7 @@
0.48 0.48
* Glenn McGrath -- tar now supports uncompressing tar files,
define BB_FEATURE_TAR_GZIP to use the -z option.
* Matt Kraai -- fix all usage of TRUE and FALSE so all apps now * Matt Kraai -- fix all usage of TRUE and FALSE so all apps now
return EXIT_SUCCESS or EXIT_FAILURE to the system. return EXIT_SUCCESS or EXIT_FAILURE to the system.
Now TRUE and FALSE are set to the C standard where TRUE=1. Now TRUE and FALSE are set to the C standard where TRUE=1.

View File

@ -225,6 +225,9 @@
// Enable support for "--exclude" and "-X" for excluding files // Enable support for "--exclude" and "-X" for excluding files
#define BB_FEATURE_TAR_EXCLUDE #define BB_FEATURE_TAR_EXCLUDE
// //
// Enable support for tar -z option (currently only works for inflating)
#define BB_FEATURE_TAR_GZIP
//
//// Enable reverse sort //// Enable reverse sort
#define BB_FEATURE_SORT_REVERSE #define BB_FEATURE_SORT_REVERSE
// //
@ -324,6 +327,12 @@
#endif #endif
#endif #endif
// //
#ifdef BB_FEATURE_TAR_GZIP
#ifndef BB_GUNZIP
#define BB_GUNZIP
#endif
#endif
//
#if defined BB_MOUNT && defined BB_FEATURE_NFSMOUNT #if defined BB_MOUNT && defined BB_FEATURE_NFSMOUNT
#define BB_NFSMOUNT #define BB_NFSMOUNT
#endif #endif

View File

@ -1084,7 +1084,7 @@ int inflate()
* the compressed data, from offsets inptr to insize-1 included. * the compressed data, from offsets inptr to insize-1 included.
* The magic header has already been checked. The output buffer is cleared. * The magic header has already been checked. The output buffer is cleared.
*/ */
int unzip(in, out) extern int unzip(in, out)
int in, out; /* input and output file descriptors */ int in, out; /* input and output file descriptors */
{ {
int ext_header = 0; /* set if extended local header */ int ext_header = 0; /* set if extended local header */
@ -1179,7 +1179,7 @@ void clear_bufs(void)
/* =========================================================================== /* ===========================================================================
* Initialize gunzip buffers and signals * Initialize gunzip buffers and signals
*/ */
static int gunzip_init() extern int gunzip_init()
{ {
foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
if (foreground) { if (foreground) {

View File

@ -52,6 +52,11 @@
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <getopt.h> #include <getopt.h>
#ifdef BB_FEATURE_TAR_GZIP
extern int unzip(int in, int out);
extern int gunzip_init();
#endif
/* Tar file constants */ /* Tar file constants */
#ifndef MAJOR #ifndef MAJOR
#define MAJOR(dev) (((dev)>>8)&0xff) #define MAJOR(dev) (((dev)>>8)&0xff)
@ -129,29 +134,64 @@ struct TarInfo
typedef struct TarInfo TarInfo; typedef struct TarInfo TarInfo;
/* Local procedures to restore files from a tar file. */ /* Local procedures to restore files from a tar file. */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, static int readTarFile(int tarFd, int extractFlag, int listFlag,
int tostdoutFlag, int verboseFlag, char** extractList, int tostdoutFlag, int verboseFlag, char** extractList,
char** excludeList); char** excludeList);
#ifdef BB_FEATURE_TAR_CREATE #ifdef BB_FEATURE_TAR_CREATE
/* Local procedures to save files into a tar file. */ /* Local procedures to save files into a tar file. */
static int writeTarFile(const char* tarName, int verboseFlag, char **argv, static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
char** excludeList); char** excludeList);
#endif #endif
#ifdef BB_FEATURE_TAR_GZIP
/* Signal handler for when child gzip process dies... */
void child_died()
{
fflush(stdout);
fflush(stderr);
exit(EXIT_FAILURE);
}
static int tar_unzip_init(int tarFd)
{
int child_pid;
static int unzip_pipe[2];
/* Cope if child dies... Otherwise we block forever in read()... */
signal(SIGCHLD, child_died);
if (pipe(unzip_pipe)!=0)
error_msg_and_die("pipe error\n");
if ( (child_pid = fork()) == -1)
error_msg_and_die("fork failure\n");
if (child_pid==0) {
/* child process */
gunzip_init();
unzip(tarFd, unzip_pipe[1]);
exit(EXIT_SUCCESS);
}
else
/* return fd of uncompressed data to parent process */
return(unzip_pipe[0]);
}
#endif
extern int tar_main(int argc, char **argv) extern int tar_main(int argc, char **argv)
{ {
char** excludeList=NULL; char** excludeList=NULL;
char** extractList=NULL; char** extractList=NULL;
const char *tarName="-";
#if defined BB_FEATURE_TAR_EXCLUDE #if defined BB_FEATURE_TAR_EXCLUDE
int excludeListSize=0; int excludeListSize=0;
char *excludeFileName ="-"; char *excludeFileName ="-";
FILE *fileList; FILE *fileList;
char file[256]; char file[256];
#endif
#if defined BB_FEATURE_TAR_GZIP
int unzipFlag = FALSE;
#endif #endif
const char *tarName="-";
int listFlag = FALSE; int listFlag = FALSE;
int extractFlag = FALSE; int extractFlag = FALSE;
int createFlag = FALSE; int createFlag = FALSE;
@ -160,7 +200,6 @@ extern int tar_main(int argc, char **argv)
int status = FALSE; int status = FALSE;
int firstOpt = TRUE; int firstOpt = TRUE;
int stopIt; int stopIt;
if (argc <= 1) if (argc <= 1)
usage(tar_usage); usage(tar_usage);
@ -185,6 +224,11 @@ extern int tar_main(int argc, char **argv)
goto flagError; goto flagError;
listFlag = TRUE; listFlag = TRUE;
break; break;
#ifdef BB_FEATURE_TAR_GZIP
case 'z':
unzipFlag = TRUE;
break;
#endif
case 'v': case 'v':
verboseFlag = TRUE; verboseFlag = TRUE;
break; break;
@ -255,13 +299,31 @@ extern int tar_main(int argc, char **argv)
#ifndef BB_FEATURE_TAR_CREATE #ifndef BB_FEATURE_TAR_CREATE
error_msg_and_die( "This version of tar was not compiled with tar creation support.\n"); error_msg_and_die( "This version of tar was not compiled with tar creation support.\n");
#else #else
#ifdef BB_FEATURE_TAR_GZIP
if (unzipFlag==TRUE)
error_msg_and_die("Creation of compressed not internally support by tar, pipe to busybox gunzip\n");
#endif
status = writeTarFile(tarName, verboseFlag, argv, excludeList); status = writeTarFile(tarName, verboseFlag, argv, excludeList);
#endif #endif
} }
if (listFlag == TRUE || extractFlag == TRUE) { if (listFlag == TRUE || extractFlag == TRUE) {
int tarFd;
if (*argv) if (*argv)
extractList = argv; extractList = argv;
status = readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, /* Open the tar file for reading. */
if (!strcmp(tarName, "-"))
tarFd = fileno(stdin);
else
tarFd = open(tarName, O_RDONLY);
if (tarFd < 0)
error_msg_and_die( "Error opening '%s': %s\n", tarName, strerror(errno));
#ifdef BB_FEATURE_TAR_GZIP
/* unzip tarFd in a seperate process */
if (unzipFlag == TRUE)
tarFd = tar_unzip_init(tarFd);
#endif
status = readTarFile(tarFd, extractFlag, listFlag, tostdoutFlag,
verboseFlag, extractList, excludeList); verboseFlag, extractList, excludeList);
} }
@ -521,27 +583,17 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
* Read a tar file and extract or list the specified files within it. * Read a tar file and extract or list the specified files within it.
* If the list is empty than all files are extracted or listed. * If the list is empty than all files are extracted or listed.
*/ */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, extern int readTarFile(int tarFd, int extractFlag, int listFlag,
int tostdoutFlag, int verboseFlag, char** extractList, int tostdoutFlag, int verboseFlag, char** extractList,
char** excludeList) char** excludeList)
{ {
int status, tarFd=-1; int status;
int errorFlag=FALSE; int errorFlag=FALSE;
int skipNextHeaderFlag=FALSE; int skipNextHeaderFlag=FALSE;
TarHeader rawHeader; TarHeader rawHeader;
TarInfo header; TarInfo header;
char** tmpList; char** tmpList;
/* Open the tar file for reading. */
if (!strcmp(tarName, "-"))
tarFd = fileno(stdin);
else
tarFd = open(tarName, O_RDONLY);
if (tarFd < 0) {
error_msg( "Error opening '%s': %s\n", tarName, strerror(errno));
return ( FALSE);
}
/* Set the umask for this process so it doesn't /* Set the umask for this process so it doesn't
* screw up permission setting for us later. */ * screw up permission setting for us later. */
umask(0); umask(0);
@ -739,7 +791,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
close(tarFd); close(tarFd);
if (status > 0) { if (status > 0) {
/* Bummer - we read a partial header */ /* Bummer - we read a partial header */
error_msg( "Error reading '%s': %s\n", tarName, strerror(errno)); error_msg( "Error reading tar file: %s\n", strerror(errno));
return ( FALSE); return ( FALSE);
} }
else if (errorFlag==TRUE) { else if (errorFlag==TRUE) {

View File

@ -1084,7 +1084,7 @@ int inflate()
* the compressed data, from offsets inptr to insize-1 included. * the compressed data, from offsets inptr to insize-1 included.
* The magic header has already been checked. The output buffer is cleared. * The magic header has already been checked. The output buffer is cleared.
*/ */
int unzip(in, out) extern int unzip(in, out)
int in, out; /* input and output file descriptors */ int in, out; /* input and output file descriptors */
{ {
int ext_header = 0; /* set if extended local header */ int ext_header = 0; /* set if extended local header */
@ -1179,7 +1179,7 @@ void clear_bufs(void)
/* =========================================================================== /* ===========================================================================
* Initialize gunzip buffers and signals * Initialize gunzip buffers and signals
*/ */
static int gunzip_init() extern int gunzip_init()
{ {
foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
if (foreground) { if (foreground) {

96
tar.c
View File

@ -52,6 +52,11 @@
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <getopt.h> #include <getopt.h>
#ifdef BB_FEATURE_TAR_GZIP
extern int unzip(int in, int out);
extern int gunzip_init();
#endif
/* Tar file constants */ /* Tar file constants */
#ifndef MAJOR #ifndef MAJOR
#define MAJOR(dev) (((dev)>>8)&0xff) #define MAJOR(dev) (((dev)>>8)&0xff)
@ -129,29 +134,64 @@ struct TarInfo
typedef struct TarInfo TarInfo; typedef struct TarInfo TarInfo;
/* Local procedures to restore files from a tar file. */ /* Local procedures to restore files from a tar file. */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, static int readTarFile(int tarFd, int extractFlag, int listFlag,
int tostdoutFlag, int verboseFlag, char** extractList, int tostdoutFlag, int verboseFlag, char** extractList,
char** excludeList); char** excludeList);
#ifdef BB_FEATURE_TAR_CREATE #ifdef BB_FEATURE_TAR_CREATE
/* Local procedures to save files into a tar file. */ /* Local procedures to save files into a tar file. */
static int writeTarFile(const char* tarName, int verboseFlag, char **argv, static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
char** excludeList); char** excludeList);
#endif #endif
#ifdef BB_FEATURE_TAR_GZIP
/* Signal handler for when child gzip process dies... */
void child_died()
{
fflush(stdout);
fflush(stderr);
exit(EXIT_FAILURE);
}
static int tar_unzip_init(int tarFd)
{
int child_pid;
static int unzip_pipe[2];
/* Cope if child dies... Otherwise we block forever in read()... */
signal(SIGCHLD, child_died);
if (pipe(unzip_pipe)!=0)
error_msg_and_die("pipe error\n");
if ( (child_pid = fork()) == -1)
error_msg_and_die("fork failure\n");
if (child_pid==0) {
/* child process */
gunzip_init();
unzip(tarFd, unzip_pipe[1]);
exit(EXIT_SUCCESS);
}
else
/* return fd of uncompressed data to parent process */
return(unzip_pipe[0]);
}
#endif
extern int tar_main(int argc, char **argv) extern int tar_main(int argc, char **argv)
{ {
char** excludeList=NULL; char** excludeList=NULL;
char** extractList=NULL; char** extractList=NULL;
const char *tarName="-";
#if defined BB_FEATURE_TAR_EXCLUDE #if defined BB_FEATURE_TAR_EXCLUDE
int excludeListSize=0; int excludeListSize=0;
char *excludeFileName ="-"; char *excludeFileName ="-";
FILE *fileList; FILE *fileList;
char file[256]; char file[256];
#endif
#if defined BB_FEATURE_TAR_GZIP
int unzipFlag = FALSE;
#endif #endif
const char *tarName="-";
int listFlag = FALSE; int listFlag = FALSE;
int extractFlag = FALSE; int extractFlag = FALSE;
int createFlag = FALSE; int createFlag = FALSE;
@ -160,7 +200,6 @@ extern int tar_main(int argc, char **argv)
int status = FALSE; int status = FALSE;
int firstOpt = TRUE; int firstOpt = TRUE;
int stopIt; int stopIt;
if (argc <= 1) if (argc <= 1)
usage(tar_usage); usage(tar_usage);
@ -185,6 +224,11 @@ extern int tar_main(int argc, char **argv)
goto flagError; goto flagError;
listFlag = TRUE; listFlag = TRUE;
break; break;
#ifdef BB_FEATURE_TAR_GZIP
case 'z':
unzipFlag = TRUE;
break;
#endif
case 'v': case 'v':
verboseFlag = TRUE; verboseFlag = TRUE;
break; break;
@ -255,13 +299,31 @@ extern int tar_main(int argc, char **argv)
#ifndef BB_FEATURE_TAR_CREATE #ifndef BB_FEATURE_TAR_CREATE
error_msg_and_die( "This version of tar was not compiled with tar creation support.\n"); error_msg_and_die( "This version of tar was not compiled with tar creation support.\n");
#else #else
#ifdef BB_FEATURE_TAR_GZIP
if (unzipFlag==TRUE)
error_msg_and_die("Creation of compressed not internally support by tar, pipe to busybox gunzip\n");
#endif
status = writeTarFile(tarName, verboseFlag, argv, excludeList); status = writeTarFile(tarName, verboseFlag, argv, excludeList);
#endif #endif
} }
if (listFlag == TRUE || extractFlag == TRUE) { if (listFlag == TRUE || extractFlag == TRUE) {
int tarFd;
if (*argv) if (*argv)
extractList = argv; extractList = argv;
status = readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, /* Open the tar file for reading. */
if (!strcmp(tarName, "-"))
tarFd = fileno(stdin);
else
tarFd = open(tarName, O_RDONLY);
if (tarFd < 0)
error_msg_and_die( "Error opening '%s': %s\n", tarName, strerror(errno));
#ifdef BB_FEATURE_TAR_GZIP
/* unzip tarFd in a seperate process */
if (unzipFlag == TRUE)
tarFd = tar_unzip_init(tarFd);
#endif
status = readTarFile(tarFd, extractFlag, listFlag, tostdoutFlag,
verboseFlag, extractList, excludeList); verboseFlag, extractList, excludeList);
} }
@ -521,27 +583,17 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
* Read a tar file and extract or list the specified files within it. * Read a tar file and extract or list the specified files within it.
* If the list is empty than all files are extracted or listed. * If the list is empty than all files are extracted or listed.
*/ */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, extern int readTarFile(int tarFd, int extractFlag, int listFlag,
int tostdoutFlag, int verboseFlag, char** extractList, int tostdoutFlag, int verboseFlag, char** extractList,
char** excludeList) char** excludeList)
{ {
int status, tarFd=-1; int status;
int errorFlag=FALSE; int errorFlag=FALSE;
int skipNextHeaderFlag=FALSE; int skipNextHeaderFlag=FALSE;
TarHeader rawHeader; TarHeader rawHeader;
TarInfo header; TarInfo header;
char** tmpList; char** tmpList;
/* Open the tar file for reading. */
if (!strcmp(tarName, "-"))
tarFd = fileno(stdin);
else
tarFd = open(tarName, O_RDONLY);
if (tarFd < 0) {
error_msg( "Error opening '%s': %s\n", tarName, strerror(errno));
return ( FALSE);
}
/* Set the umask for this process so it doesn't /* Set the umask for this process so it doesn't
* screw up permission setting for us later. */ * screw up permission setting for us later. */
umask(0); umask(0);
@ -739,7 +791,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
close(tarFd); close(tarFd);
if (status > 0) { if (status > 0) {
/* Bummer - we read a partial header */ /* Bummer - we read a partial header */
error_msg( "Error reading '%s': %s\n", tarName, strerror(errno)); error_msg( "Error reading tar file: %s\n", strerror(errno));
return ( FALSE); return ( FALSE);
} }
else if (errorFlag==TRUE) { else if (errorFlag==TRUE) {