summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griebl <griebl@gmx.de>2002-07-23 22:05:47 +0000
committerRobert Griebl <griebl@gmx.de>2002-07-23 22:05:47 +0000
commitf2f26e7fdddfb92a8ef3654e14092dcbe3420331 (patch)
tree04b2388564e5f3244b3a4e6d304a00a8b9caeed9
parent967c3d44066d3f8b290953d8896765ec1edf4ef7 (diff)
downloadbusybox-w32-f2f26e7fdddfb92a8ef3654e14092dcbe3420331.tar.gz
busybox-w32-f2f26e7fdddfb92a8ef3654e14092dcbe3420331.tar.bz2
busybox-w32-f2f26e7fdddfb92a8ef3654e14092dcbe3420331.zip
Added tar -cz support (creating gzipped tar files without a gzip pipe)
-rw-r--r--archival/config.in2
-rw-r--r--archival/tar.c119
2 files changed, 95 insertions, 26 deletions
diff --git a/archival/config.in b/archival/config.in
index 5a064dc89..ac90ec0a9 100644
--- a/archival/config.in
+++ b/archival/config.in
@@ -18,7 +18,7 @@ bool 'tar' CONFIG_TAR
18if [ "$CONFIG_TAR" = "y" ] ; then 18if [ "$CONFIG_TAR" = "y" ] ; then
19 bool ' Enable archive creation' CONFIG_FEATURE_TAR_CREATE 19 bool ' Enable archive creation' CONFIG_FEATURE_TAR_CREATE
20 bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE 20 bool ' Enable -X and --exclude options (exclude files)' CONFIG_FEATURE_TAR_EXCLUDE
21 bool ' Enable -z option (currently only for extracting)' CONFIG_FEATURE_TAR_GZIP 21 bool ' Enable -z option' CONFIG_FEATURE_TAR_GZIP
22fi 22fi
23if [ "$CONFIG_CPIO" = "y" -o "$CONFIG_TAR" = "y" ] ; then 23if [ "$CONFIG_CPIO" = "y" -o "$CONFIG_TAR" = "y" ] ; then
24 bool ' Enable tape drive support' CONFIG_FEATURE_UNARCHIVE_TAPE 24 bool ' Enable tape drive support' CONFIG_FEATURE_UNARCHIVE_TAPE
diff --git a/archival/tar.c b/archival/tar.c
index b18f1f87f..2aa5f0788 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -47,6 +47,9 @@
47#include <fnmatch.h> 47#include <fnmatch.h>
48#include <string.h> 48#include <string.h>
49#include <errno.h> 49#include <errno.h>
50#include <signal.h>
51#include <sys/wait.h>
52#include <sys/socket.h>
50#include "unarchive.h" 53#include "unarchive.h"
51#include "busybox.h" 54#include "busybox.h"
52 55
@@ -305,9 +308,10 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name,
305 write(tbInfo->tarFd, "\0", 1); 308 write(tbInfo->tarFd, "\0", 1);
306 } 309 }
307 /* Now do the verbose thing (or not) */ 310 /* Now do the verbose thing (or not) */
308 if (tbInfo->verboseFlag==TRUE) { 311
312 if (tbInfo->verboseFlag) {
309 FILE *vbFd = stdout; 313 FILE *vbFd = stdout;
310 if (tbInfo->tarFd == fileno(stdout)) // If the archive goes to stdout, verbose to stderr 314 if (tbInfo->verboseFlag == 2) // If the archive goes to stdout, verbose to stderr
311 vbFd = stderr; 315 vbFd = stderr;
312 fprintf(vbFd, "%s\n", header.name); 316 fprintf(vbFd, "%s\n", header.name);
313 } 317 }
@@ -445,13 +449,17 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
445} 449}
446 450
447static int writeTarFile(const char* tarName, int verboseFlag, char **argv, 451static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
448 char** excludeList) 452 char** excludeList, int gzip)
449{ 453{
450 int tarFd=-1; 454#ifdef CONFIG_FEATURE_TAR_GZIP
455 int gzipDataPipe [2] = { -1, -1 };
456 int gzipStatusPipe [2] = { -1, -1 };
457 pid_t gzipPid = 0;
458#endif
459
451 int errorFlag=FALSE; 460 int errorFlag=FALSE;
452 ssize_t size; 461 ssize_t size;
453 struct TarBallInfo tbInfo; 462 struct TarBallInfo tbInfo;
454 tbInfo.verboseFlag = verboseFlag;
455 tbInfo.hlInfoHead = NULL; 463 tbInfo.hlInfoHead = NULL;
456 464
457 /* Make sure there is at least one file to tar up. */ 465 /* Make sure there is at least one file to tar up. */
@@ -459,21 +467,78 @@ static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
459 error_msg_and_die("Cowardly refusing to create an empty archive"); 467 error_msg_and_die("Cowardly refusing to create an empty archive");
460 468
461 /* Open the tar file for writing. */ 469 /* Open the tar file for writing. */
462 if (tarName == NULL) 470 if (tarName == NULL) {
463 tbInfo.tarFd = fileno(stdout); 471 tbInfo.tarFd = fileno(stdout);
464 else 472 tbInfo.verboseFlag = verboseFlag ? 2 : 0;
473 }
474 else {
465 tbInfo.tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644); 475 tbInfo.tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
476 tbInfo.verboseFlag = verboseFlag ? 1 : 0;
477 }
478
466 if (tbInfo.tarFd < 0) { 479 if (tbInfo.tarFd < 0) {
467 perror_msg( "Error opening '%s'", tarName); 480 perror_msg( "Error opening '%s'", tarName);
468 freeHardLinkInfo(&tbInfo.hlInfoHead); 481 freeHardLinkInfo(&tbInfo.hlInfoHead);
469 return ( FALSE); 482 return ( FALSE);
470 } 483 }
471 tbInfo.excludeList=excludeList; 484
472 /* Store the stat info for the tarball's file, so 485 /* Store the stat info for the tarball's file, so
473 * can avoid including the tarball into itself.... */ 486 * can avoid including the tarball into itself.... */
474 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) 487 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
475 error_msg_and_die(io_error, tarName, strerror(errno)); 488 error_msg_and_die(io_error, tarName, strerror(errno));
476 489
490#ifdef CONFIG_FEATURE_TAR_GZIP
491 if ( gzip ) {
492 if ( socketpair ( AF_UNIX, SOCK_STREAM, 0, gzipDataPipe ) < 0 || pipe ( gzipStatusPipe ) < 0 )
493 perror_msg_and_die ( "Failed to create gzip pipe" );
494
495 signal ( SIGPIPE, SIG_IGN ); // we only want EPIPE on errors
496
497 gzipPid = fork ( );
498
499 if ( gzipPid == 0 ) {
500 dup2 ( gzipDataPipe [0], 0 );
501 close ( gzipDataPipe [1] );
502
503 if ( tbInfo. tarFd != 1 );
504 dup2 ( tbInfo. tarFd, 1 );
505
506 close ( gzipStatusPipe [0] );
507 fcntl( gzipStatusPipe [1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess
508
509 execl ( "/bin/gzip", "gzip", "-f", 0 );
510
511 write ( gzipStatusPipe [1], "", 1 );
512 close ( gzipStatusPipe [1] );
513
514 exit ( -1 );
515 }
516 else if ( gzipPid > 0 ) {
517 close ( gzipDataPipe [0] );
518 close ( gzipStatusPipe [1] );
519
520 while ( 1 ) {
521 char buf;
522
523 int n = read ( gzipStatusPipe [0], &buf, 1 );
524 if ( n == 1 )
525 error_msg_and_die ( "Could not exec gzip process" ); // socket was not closed => error
526 else if (( n < 0 ) && ( errno==EAGAIN || errno==EINTR ))
527 continue; // try it again
528 break;
529 }
530 close ( gzipStatusPipe [0] );
531
532 tbInfo. tarFd = gzipDataPipe [1];
533 }
534 else {
535 perror_msg_and_die ( "Failed to fork gzip process" );
536 }
537 }
538#endif
539
540 tbInfo.excludeList=excludeList;
541
477 /* Read the directory/files and iterate over them one at a time */ 542 /* Read the directory/files and iterate over them one at a time */
478 while (*argv != NULL) { 543 while (*argv != NULL) {
479 if (! recursive_action(*argv++, TRUE, FALSE, FALSE, 544 if (! recursive_action(*argv++, TRUE, FALSE, FALSE,
@@ -493,14 +558,20 @@ static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
493 * so is considered a waste of space */ 558 * so is considered a waste of space */
494 559
495 /* Hang up the tools, close up shop, head home */ 560 /* Hang up the tools, close up shop, head home */
496 close(tarFd); 561 close(tbInfo.tarFd);
497 if (errorFlag) { 562 if (errorFlag)
498 error_msg("Error exit delayed from previous errors"); 563 error_msg("Error exit delayed from previous errors");
499 freeHardLinkInfo(&tbInfo.hlInfoHead); 564
500 return(FALSE);
501 }
502 freeHardLinkInfo(&tbInfo.hlInfoHead); 565 freeHardLinkInfo(&tbInfo.hlInfoHead);
503 return( TRUE); 566
567#ifdef CONFIG_FEATURE_TAR_GZIP
568 if ( gzip && gzipPid ) {
569 if ( waitpid ( gzipPid, NULL, 0 ) == -1 )
570 printf ( "Couldnt wait ?" );
571 }
572#endif
573
574 return !errorFlag;
504} 575}
505#endif //tar_create 576#endif //tar_create
506 577
@@ -653,10 +724,7 @@ int tar_main(int argc, char **argv)
653 case 'p': 724 case 'p':
654 break; 725 break;
655 case 'v': 726 case 'v':
656 if (extract_function & extract_list) { 727 extract_function |= extract_verbose_list;
657 extract_function |= extract_verbose_list;
658 }
659 extract_function |= extract_list;
660 break; 728 break;
661#ifdef CONFIG_FEATURE_TAR_GZIP 729#ifdef CONFIG_FEATURE_TAR_GZIP
662 case 'z': 730 case 'z':
@@ -711,22 +779,23 @@ int tar_main(int argc, char **argv)
711 /* create an archive */ 779 /* create an archive */
712 else if (untar_funct & untar_create) { 780 else if (untar_funct & untar_create) {
713 int verboseFlag = FALSE; 781 int verboseFlag = FALSE;
782 int gzipFlag = FALSE;
714 783
715#ifdef CONFIG_FEATURE_TAR_GZIP 784#ifdef CONFIG_FEATURE_TAR_GZIP
716 if (untar_funct & untar_unzip) { 785 if (untar_funct & untar_unzip)
717 error_msg_and_die("Creation of compressed tarfile not internally support by tar, pipe to busybox gunzip"); 786 gzipFlag = TRUE;
718 } 787
719#endif // CONFIG_FEATURE_TAR_GZIP 788#endif // CONFIG_FEATURE_TAR_GZIP
720 if (extract_function & extract_verbose_list) { 789 if (extract_function & extract_verbose_list)
721 verboseFlag = TRUE; 790 verboseFlag = TRUE;
722 } 791
723 writeTarFile(src_filename, verboseFlag, include_list, exclude_list); 792 writeTarFile(src_filename, verboseFlag, include_list, exclude_list, gzipFlag);
724 } 793 }
725#endif // CONFIG_FEATURE_TAR_CREATE 794#endif // CONFIG_FEATURE_TAR_CREATE
726 795
727 /* Cleanups */ 796 /* Cleanups */
728#ifdef CONFIG_FEATURE_TAR_GZIP 797#ifdef CONFIG_FEATURE_TAR_GZIP
729 if (untar_funct & untar_unzip) { 798 if ( !( untar_funct & untar_create ) && ( untar_funct & untar_unzip )) {
730 fclose(src_stream); 799 fclose(src_stream);
731 close(gz_fd); 800 close(gz_fd);
732 gz_close(gunzip_pid); 801 gz_close(gunzip_pid);