aboutsummaryrefslogtreecommitdiff
path: root/archival/tar.c
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-12-26 14:01:37 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-12-26 14:01:37 +0000
commitce91c8ac2bb343f0b3303c608c5a8b5a2252204d (patch)
treefb1edb12638407a859d3fefcfc89d5c8c7c20964 /archival/tar.c
parentab8215431f43d132cbb0986dec6fbd542350f9d9 (diff)
downloadbusybox-w32-ce91c8ac2bb343f0b3303c608c5a8b5a2252204d.tar.gz
busybox-w32-ce91c8ac2bb343f0b3303c608c5a8b5a2252204d.tar.bz2
busybox-w32-ce91c8ac2bb343f0b3303c608c5a8b5a2252204d.zip
Isolate code better for unused options, config option to enable long
options, add some conditions to the tar tests in testsuite.
Diffstat (limited to 'archival/tar.c')
-rw-r--r--archival/tar.c182
1 files changed, 128 insertions, 54 deletions
diff --git a/archival/tar.c b/archival/tar.c
index cf9bc04d3..8074c2d1a 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -317,13 +317,9 @@ static inline int writeTarHeader(struct TarBallInfo *tbInfo,
317 return (TRUE); 317 return (TRUE);
318} 318}
319 319
320# if defined CONFIG_FEATURE_TAR_EXCLUDE 320# ifdef CONFIG_FEATURE_TAR_FROM
321static inline int exclude_file(const llist_t *excluded_files, const char *file) 321static inline int exclude_file(const llist_t *excluded_files, const char *file)
322{ 322{
323 if (excluded_files == NULL) {
324 return 0;
325 }
326
327 while (excluded_files) { 323 while (excluded_files) {
328 if (excluded_files->data[0] == '/') { 324 if (excluded_files->data[0] == '/') {
329 if (fnmatch(excluded_files->data, file, 325 if (fnmatch(excluded_files->data, file,
@@ -344,7 +340,7 @@ static inline int exclude_file(const llist_t *excluded_files, const char *file)
344 340
345 return 0; 341 return 0;
346} 342}
347#endif 343# endif
348 344
349static int writeFileToTarball(const char *fileName, struct stat *statbuf, 345static int writeFileToTarball(const char *fileName, struct stat *statbuf,
350 void *userData) 346 void *userData)
@@ -400,11 +396,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf,
400 if (header_name[0] == '\0') 396 if (header_name[0] == '\0')
401 return TRUE; 397 return TRUE;
402 398
403# if defined CONFIG_FEATURE_TAR_EXCLUDE 399# ifdef CONFIG_FEATURE_TAR_FROM
404 if (exclude_file(tbInfo->excludeList, header_name)) { 400 if (exclude_file(tbInfo->excludeList, header_name)) {
405 return SKIP; 401 return SKIP;
406 } 402 }
407# endif /* CONFIG_FEATURE_TAR_EXCLUDE */ 403# endif /* CONFIG_FEATURE_TAR_FROM */
408 404
409 if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) { 405 if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
410 return (FALSE); 406 return (FALSE);
@@ -555,7 +551,7 @@ static inline int writeTarFile(const int tar_fd, const int verboseFlag,
555} 551}
556#endif /* tar_create */ 552#endif /* tar_create */
557 553
558#ifdef CONFIG_FEATURE_TAR_EXCLUDE 554#ifdef CONFIG_FEATURE_TAR_FROM
559static llist_t *append_file_list_to_list(llist_t *list) 555static llist_t *append_file_list_to_list(llist_t *list)
560{ 556{
561 FILE *src_stream; 557 FILE *src_stream;
@@ -598,31 +594,105 @@ static char get_header_tar_Z(archive_handle_t *archive_handle)
598} 594}
599#endif 595#endif
600 596
601static const char tar_options[]="ctxjT:X:C:f:OpvzkZ"; 597#define CTX_TEST (1 << 0)
602 598#define CTX_EXTRACT (1 << 1)
603#define CTX_CREATE 1 599#define TAR_OPT_BASEDIR (1 << 2)
604#define CTX_TEST 2 600#define TAR_OPT_TARNAME (1 << 3)
605#define CTX_EXTRACT 4 601#define TAR_OPT_2STDOUT (1 << 4)
606#define TAR_OPT_BZIP2 8 602#define TAR_OPT_P (1 << 5)
607#define TAR_OPT_INCLUDE 16 603#define TAR_OPT_VERBOSE (1 << 6)
608#define TAR_OPT_EXCLUDE 32 604#define TAR_OPT_KEEP_OLD (1 << 7)
609#define TAR_OPT_BASEDIR 64 605
610#define TAR_OPT_ARNAME 128 606#ifdef CONFIG_FEATURE_TAR_CREATE
611#define TAR_OPT_2STDOUT 256 607# define CTX_CREATE (1 << 8)
612#define TAR_OPT_P 512 608# define TAR_OPT_STR_CREATE "c"
613#define TAR_OPT_VERBOSE 1024 609# define TAR_OPT_FLAG_CREATE 1
614#define TAR_OPT_GZIP 2048 610#else
615#define TAR_OPT_KEEP_OLD 4096 611//# define CTX_CREATE 0
616#define TAR_OPT_UNCOMPRESS 8192 612# define TAR_OPT_STR_CREATE ""
613# define TAR_OPT_FLAG_CREATE 0
614#endif
615
616#ifdef CONFIG_FEATURE_TAR_BZIP2
617# define TAR_OPT_BZIP2 (1 << (8 + TAR_OPT_FLAG_CREATE))
618# define TAR_OPT_STR_BZIP2 "j"
619# define TAR_OPT_FLAG_BZIP2 1
620#else
621# define TAR_OPT_STR_BZIP2 ""
622# define TAR_OPT_FLAG_BZIP2 0
623#endif
624
625#ifdef CONFIG_FEATURE_TAR_FROM
626# define TAR_OPT_FROM_FILE (1 << (8 + TAR_OPT_FLAG_CREATE + TAR_OPT_FLAG_BZIP2))
627# define TAR_OPT_EXCLUDE_FROM (1 << (8 + TAR_OPT_FLAG_CREATE + TAR_OPT_FLAG_BZIP2 + 1))
628# define TAR_OPT_STR_FROM "T:X:"
629# define TAR_OPT_FLAG_FROM 2
630#else
631# define TAR_OPT_STR_FROM ""
632# define TAR_OPT_FLAG_FROM 0
633#endif
634
635#ifdef CONFIG_FEATURE_TAR_GZIP
636# define TAR_OPT_GZIP (1 << (8 + TAR_OPT_FLAG_CREATE + TAR_OPT_FLAG_BZIP2 + TAR_OPT_FLAG_FROM))
637# define TAR_OPT_STR_GZIP "z"
638# define TAR_OPT_FLAG_GZIP 1
639#else
640# define TAR_OPT_STR_GZIP ""
641# define TAR_OPT_FLAG_GZIP 0
642#endif
643
644#ifdef CONFIG_FEATURE_TAR_COMPRESS
645# define TAR_OPT_UNCOMPRESS (1 << (8 + TAR_OPT_FLAG_CREATE + TAR_OPT_FLAG_BZIP2 + TAR_OPT_FLAG_FROM + TAR_OPT_FLAG_GZIP))
646# define TAR_OPT_STR_COMPRESS "Z"
647#else
648# define TAR_OPT_STR_COMPRESS ""
649#endif
650
651static const char tar_options[]="txC:f:Opvk" \
652 TAR_OPT_STR_CREATE \
653 TAR_OPT_STR_BZIP2 \
654 TAR_OPT_STR_FROM \
655 TAR_OPT_STR_GZIP \
656 TAR_OPT_STR_COMPRESS;
657
658#ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS
659static const struct option tar_long_options[] = {
660 { "list", 0, NULL, 't' },
661 { "extract", 0, NULL, 'x' },
662 { "directory", 1, NULL, 'C' },
663 { "file", 1, NULL, 'f' },
664 { "to-stdout", 0, NULL, 'O' },
665 { "same-permissions", 0, NULL, 'p' },
666 { "verbose", 0, NULL, 'v' },
667 { "keep-old", 0, NULL, 'k' },
668# ifdef CONFIG_FEATURE_TAR_CREATE
669 { "create", 0, NULL, 'c' },
670# endif
671# ifdef CONFIG_FEATURE_TAR_BZIP2
672 { "bzip2", 0, NULL, 'j' },
673# endif
674# ifdef CONFIG_FEATURE_TAR_FROM
675 { "from-file", 1, NULL, 'T' },
676 { "exclude-from", 1, NULL, 'X' },
677# endif
678# ifdef CONFIG_FEATURE_TAR_GZIP
679 { "gzip", 0, NULL, 'z' },
680# endif
681# ifdef CONFIG_FEATURE_TAR_COMPRESS
682 { "compress", 0, NULL, 'Z' },
683# endif
684 { 0, 0, 0, 0 }
685};
686#endif
617 687
618int tar_main(int argc, char **argv) 688int tar_main(int argc, char **argv)
619{ 689{
620 char (*get_header_ptr)(archive_handle_t *) = get_header_tar; 690 char (*get_header_ptr)(archive_handle_t *) = get_header_tar;
621 archive_handle_t *tar_handle; 691 archive_handle_t *tar_handle;
622 int opt;
623 char *base_dir = NULL; 692 char *base_dir = NULL;
624 const char *tar_filename = "-"; 693 const char *tar_filename = "-";
625 unsigned char ctx_flag = 0; 694 unsigned long opt;
695 unsigned long ctx_flag = 0;
626 696
627 if (argc < 2) { 697 if (argc < 2) {
628 bb_show_usage(); 698 bb_show_usage();
@@ -640,17 +710,29 @@ int tar_main(int argc, char **argv)
640 tar_handle = init_handle(); 710 tar_handle = init_handle();
641 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; 711 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL;
642 712
643 bb_opt_complementaly = "c~tx:t~cx:x~ct:X*"; 713 bb_opt_complementaly = "c~tx:t~cx:x~ct:X*:T*";
714#ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS
715 bb_applet_long_options = tar_long_options;
716#endif
717
644 opt = bb_getopt_ulflags(argc, argv, tar_options, 718 opt = bb_getopt_ulflags(argc, argv, tar_options,
645 NULL, /* T: arg is ignored by default
646 a list is an include list */
647 &(tar_handle->reject),
648 &base_dir, /* Change to dir <optarg> */ 719 &base_dir, /* Change to dir <optarg> */
649 &tar_filename); /* archive filename */ 720 &tar_filename /* archive filename */
721#ifdef CONFIG_FEATURE_TAR_FROM
722 , NULL,
723 &(tar_handle->reject)
724#endif
725 );
726
650 /* Check one and only one context option was given */ 727 /* Check one and only one context option was given */
651 if(opt & 0x80000000UL) 728 if(opt & 0x80000000UL) {
652 bb_show_usage(); 729 bb_show_usage();
730 }
731#ifdef CONFIG_FEATURE_TAR_CREATE
653 ctx_flag = opt & (CTX_CREATE | CTX_TEST | CTX_EXTRACT); 732 ctx_flag = opt & (CTX_CREATE | CTX_TEST | CTX_EXTRACT);
733#else
734 ctx_flag = opt & (CTX_TEST | CTX_EXTRACT);
735#endif
654 if (ctx_flag == 0) { 736 if (ctx_flag == 0) {
655 bb_show_usage(); 737 bb_show_usage();
656 } 738 }
@@ -683,34 +765,27 @@ int tar_main(int argc, char **argv)
683 tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; 765 tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL;
684 } 766 }
685 767
686 if(opt & TAR_OPT_GZIP) {
687#ifdef CONFIG_FEATURE_TAR_GZIP 768#ifdef CONFIG_FEATURE_TAR_GZIP
769 if(opt & TAR_OPT_GZIP) {
688 get_header_ptr = get_header_tar_gz; 770 get_header_ptr = get_header_tar_gz;
689#else
690 bb_show_usage();
691#endif
692 } 771 }
693 if(opt & TAR_OPT_BZIP2) { 772#endif
694#ifdef CONFIG_FEATURE_TAR_BZIP2 773#ifdef CONFIG_FEATURE_TAR_BZIP2
774 if(opt & TAR_OPT_BZIP2) {
695 get_header_ptr = get_header_tar_bz2; 775 get_header_ptr = get_header_tar_bz2;
696#else
697 bb_show_usage();
698#endif
699 } 776 }
700 if(opt & TAR_OPT_UNCOMPRESS) { 777#endif
701#ifdef CONFIG_FEATURE_TAR_COMPRESS 778#ifdef CONFIG_FEATURE_TAR_COMPRESS
779 if(opt & TAR_OPT_UNCOMPRESS) {
702 get_header_ptr = get_header_tar_Z; 780 get_header_ptr = get_header_tar_Z;
703#else
704 bb_show_usage();
705#endif
706 } 781 }
707 if(opt & TAR_OPT_EXCLUDE) {
708#ifdef CONFIG_FEATURE_TAR_EXCLUDE
709 tar_handle->reject = append_file_list_to_list(tar_handle->reject);
710#else
711 bb_show_usage();
712#endif 782#endif
783#ifdef CONFIG_FEATURE_TAR_FROM
784 if(opt & TAR_OPT_EXCLUDE_FROM) {
785 tar_handle->reject = append_file_list_to_list(tar_handle->reject);
713 } 786 }
787#endif
788
714 /* Check if we are reading from stdin */ 789 /* Check if we are reading from stdin */
715 if ((argv[optind]) && (*argv[optind] == '-')) { 790 if ((argv[optind]) && (*argv[optind] == '-')) {
716 /* Default is to read from stdin, so just skip to next arg */ 791 /* Default is to read from stdin, so just skip to next arg */
@@ -720,8 +795,7 @@ int tar_main(int argc, char **argv)
720 /* Setup an array of filenames to work with */ 795 /* Setup an array of filenames to work with */
721 /* TODO: This is the same as in ar, seperate function ? */ 796 /* TODO: This is the same as in ar, seperate function ? */
722 while (optind < argc) { 797 while (optind < argc) {
723 char *filename_ptr; 798 char *filename_ptr = last_char_is(argv[optind], '/');
724 filename_ptr = last_char_is(argv[optind], '/');
725 if (filename_ptr) { 799 if (filename_ptr) {
726 *filename_ptr = '\0'; 800 *filename_ptr = '\0';
727 } 801 }
@@ -739,7 +813,7 @@ int tar_main(int argc, char **argv)
739 int flags; 813 int flags;
740 814
741#ifdef CONFIG_FEATURE_TAR_CREATE 815#ifdef CONFIG_FEATURE_TAR_CREATE
742 if (ctx_flag == CTX_CREATE) { 816 if (opt & CTX_CREATE) {
743 /* Make sure there is at least one file to tar up. */ 817 /* Make sure there is at least one file to tar up. */
744 if (tar_handle->accept == NULL) { 818 if (tar_handle->accept == NULL) {
745 bb_error_msg_and_die("Cowardly refusing to create an empty archive"); 819 bb_error_msg_and_die("Cowardly refusing to create an empty archive");
@@ -768,7 +842,7 @@ int tar_main(int argc, char **argv)
768 842
769#ifdef CONFIG_FEATURE_TAR_CREATE 843#ifdef CONFIG_FEATURE_TAR_CREATE
770 /* create an archive */ 844 /* create an archive */
771 if (ctx_flag == CTX_CREATE) { 845 if (opt & CTX_CREATE) {
772 int verboseFlag = FALSE; 846 int verboseFlag = FALSE;
773 int gzipFlag = FALSE; 847 int gzipFlag = FALSE;
774 848