aboutsummaryrefslogtreecommitdiff
path: root/archival/tar.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-24 21:54:44 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-24 21:54:44 +0000
commitd031ffa623203b1dc756a1e02e06f261fdc30872 (patch)
tree26f4426eba02d3b7f22da62ef3af151a89c99e3f /archival/tar.c
parentb833ca9d2d705943bb980c7a705aa3f07c7b5618 (diff)
downloadbusybox-w32-d031ffa623203b1dc756a1e02e06f261fdc30872.tar.gz
busybox-w32-d031ffa623203b1dc756a1e02e06f261fdc30872.tar.bz2
busybox-w32-d031ffa623203b1dc756a1e02e06f261fdc30872.zip
tar: sanitize option handling
Diffstat (limited to 'archival/tar.c')
-rw-r--r--archival/tar.c208
1 files changed, 85 insertions, 123 deletions
diff --git a/archival/tar.c b/archival/tar.c
index be661cc32..4d237f880 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -28,7 +28,7 @@
28#include <fnmatch.h> 28#include <fnmatch.h>
29#include <getopt.h> 29#include <getopt.h>
30 30
31#ifdef CONFIG_FEATURE_TAR_CREATE 31#if ENABLE_FEATURE_TAR_CREATE
32 32
33/* Tar file constants */ 33/* Tar file constants */
34 34
@@ -289,7 +289,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
289 return TRUE; 289 return TRUE;
290} 290}
291 291
292# ifdef CONFIG_FEATURE_TAR_FROM 292# if ENABLE_FEATURE_TAR_FROM
293static int exclude_file(const llist_t *excluded_files, const char *file) 293static int exclude_file(const llist_t *excluded_files, const char *file)
294{ 294{
295 while (excluded_files) { 295 while (excluded_files) {
@@ -534,7 +534,7 @@ int writeTarFile(const int tar_fd, const int verboseFlag,
534 const llist_t *exclude, const int gzip); 534 const llist_t *exclude, const int gzip);
535#endif /* tar_create */ 535#endif /* tar_create */
536 536
537#ifdef CONFIG_FEATURE_TAR_FROM 537#if ENABLE_FEATURE_TAR_FROM
538static llist_t *append_file_list_to_list(llist_t *list) 538static llist_t *append_file_list_to_list(llist_t *list)
539{ 539{
540 FILE *src_stream; 540 FILE *src_stream;
@@ -562,7 +562,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
562#define append_file_list_to_list(x) 0 562#define append_file_list_to_list(x) 0
563#endif 563#endif
564 564
565#ifdef CONFIG_FEATURE_TAR_COMPRESS 565#if ENABLE_FEATURE_TAR_COMPRESS
566static char get_header_tar_Z(archive_handle_t *archive_handle) 566static char get_header_tar_Z(archive_handle_t *archive_handle)
567{ 567{
568 /* Can't lseek over pipes */ 568 /* Can't lseek over pipes */
@@ -587,88 +587,38 @@ static char get_header_tar_Z(archive_handle_t *archive_handle)
587#define get_header_tar_Z 0 587#define get_header_tar_Z 0
588#endif 588#endif
589 589
590#define CTX_TEST (1 << 0) 590enum {
591#define CTX_EXTRACT (1 << 1) 591 OPTBIT_KEEP_OLD = 7,
592#define TAR_OPT_BASEDIR (1 << 2) 592 USE_FEATURE_TAR_CREATE( OPTBIT_CREATE ,)
593#define TAR_OPT_TARNAME (1 << 3) 593 USE_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,)
594#define TAR_OPT_2STDOUT (1 << 4) 594 USE_FEATURE_TAR_BZIP2( OPTBIT_BZIP2 ,)
595#define TAR_OPT_P (1 << 5) 595 USE_FEATURE_TAR_LZMA( OPTBIT_LZMA ,)
596#define TAR_OPT_VERBOSE (1 << 6) 596 USE_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,)
597#define TAR_OPT_KEEP_OLD (1 << 7) 597 USE_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,)
598 598 USE_FEATURE_TAR_GZIP( OPTBIT_GZIP ,)
599#define TAR_OPT_AFTER_START 8 599 USE_FEATURE_TAR_COMPRESS(OPTBIT_COMPRESS ,)
600 600 OPTBIT_NOPRESERVE_OWN,
601#define CTX_CREATE (1 << (TAR_OPT_AFTER_START)) 601 OPTBIT_NOPRESERVE_PERM,
602#define TAR_OPT_DEREFERENCE (1 << (TAR_OPT_AFTER_START + 1)) 602 OPT_TEST = 1 << 0, // t
603#ifdef CONFIG_FEATURE_TAR_CREATE 603 OPT_EXTRACT = 1 << 1, // x
604# define TAR_OPT_STR_CREATE "ch" 604 OPT_BASEDIR = 1 << 2, // C
605# define TAR_OPT_AFTER_CREATE TAR_OPT_AFTER_START + 2 605 OPT_TARNAME = 1 << 3, // f
606#else 606 OPT_2STDOUT = 1 << 4, // O
607# define TAR_OPT_STR_CREATE "" 607 OPT_P = 1 << 5, // p
608# define TAR_OPT_AFTER_CREATE TAR_OPT_AFTER_START 608 OPT_VERBOSE = 1 << 6, // v
609#endif 609 OPT_KEEP_OLD = 1 << 7, // k
610 610 OPT_CREATE = USE_FEATURE_TAR_CREATE( (1<<OPTBIT_CREATE )) + 0, // c
611#define TAR_OPT_BZIP2 (1 << (TAR_OPT_AFTER_CREATE)) 611 OPT_DEREFERENCE = USE_FEATURE_TAR_CREATE( (1<<OPTBIT_DEREFERENCE )) + 0, // h
612#ifdef CONFIG_FEATURE_TAR_BZIP2 612 OPT_BZIP2 = USE_FEATURE_TAR_BZIP2( (1<<OPTBIT_BZIP2 )) + 0, // j
613# define TAR_OPT_STR_BZIP2 "j" 613 OPT_LZMA = USE_FEATURE_TAR_LZMA( (1<<OPTBIT_LZMA )) + 0, // a
614# define TAR_OPT_AFTER_BZIP2 TAR_OPT_AFTER_CREATE + 1 614 OPT_INCLUDE_FROM = USE_FEATURE_TAR_FROM( (1<<OPTBIT_INCLUDE_FROM)) + 0, // T
615#else 615 OPT_EXCLUDE_FROM = USE_FEATURE_TAR_FROM( (1<<OPTBIT_EXCLUDE_FROM)) + 0, // X
616# define TAR_OPT_STR_BZIP2 "" 616 OPT_GZIP = USE_FEATURE_TAR_GZIP( (1<<OPTBIT_GZIP )) + 0, // z
617# define TAR_OPT_AFTER_BZIP2 TAR_OPT_AFTER_CREATE 617 OPT_COMPRESS = USE_FEATURE_TAR_COMPRESS((1<<OPTBIT_COMPRESS )) + 0, // Z
618#endif 618 OPT_NOPRESERVE_OWN = 1 << OPTBIT_NOPRESERVE_OWN , // no-same-owner
619 619 OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions
620#define TAR_OPT_LZMA (1 << (TAR_OPT_AFTER_BZIP2)) 620};
621#ifdef CONFIG_FEATURE_TAR_LZMA 621#if ENABLE_FEATURE_TAR_LONG_OPTIONS
622# define TAR_OPT_STR_LZMA "a"
623# define TAR_OPT_AFTER_LZMA TAR_OPT_AFTER_BZIP2 + 1
624#else
625# define TAR_OPT_STR_LZMA ""
626# define TAR_OPT_AFTER_LZMA TAR_OPT_AFTER_BZIP2
627#endif
628
629#define TAR_OPT_INCLUDE_FROM (1 << (TAR_OPT_AFTER_LZMA))
630#define TAR_OPT_EXCLUDE_FROM (1 << (TAR_OPT_AFTER_LZMA + 1))
631#ifdef CONFIG_FEATURE_TAR_FROM
632# define TAR_OPT_STR_FROM "T:X:"
633# define TAR_OPT_AFTER_FROM TAR_OPT_AFTER_LZMA + 2
634#else
635# define TAR_OPT_STR_FROM ""
636# define TAR_OPT_AFTER_FROM TAR_OPT_AFTER_LZMA
637#endif
638
639#define TAR_OPT_GZIP (1 << (TAR_OPT_AFTER_FROM))
640#ifdef CONFIG_FEATURE_TAR_GZIP
641# define TAR_OPT_STR_GZIP "z"
642# define TAR_OPT_AFTER_GZIP TAR_OPT_AFTER_FROM + 1
643#else
644# define TAR_OPT_STR_GZIP ""
645# define TAR_OPT_AFTER_GZIP TAR_OPT_AFTER_FROM
646#endif
647
648#define TAR_OPT_UNCOMPRESS (1 << (TAR_OPT_AFTER_GZIP))
649#ifdef CONFIG_FEATURE_TAR_COMPRESS
650# define TAR_OPT_STR_COMPRESS "Z"
651# define TAR_OPT_AFTER_COMPRESS TAR_OPT_AFTER_GZIP + 1
652#else
653# define TAR_OPT_STR_COMPRESS ""
654# define TAR_OPT_AFTER_COMPRESS TAR_OPT_AFTER_GZIP
655#endif
656
657#define TAR_OPT_NOPRESERVE_OWN (1 << (TAR_OPT_AFTER_COMPRESS))
658#define TAR_OPT_NOPRESERVE_PERM (1 << (TAR_OPT_AFTER_COMPRESS + 1))
659#define TAR_OPT_STR_NOPRESERVE "\203\213"
660#define TAR_OPT_AFTER_NOPRESERVE TAR_OPT_AFTER_COMPRESS + 2
661
662static const char tar_options[] = "txC:f:Opvk" \
663 TAR_OPT_STR_CREATE \
664 TAR_OPT_STR_BZIP2 \
665 TAR_OPT_STR_LZMA \
666 TAR_OPT_STR_FROM \
667 TAR_OPT_STR_GZIP \
668 TAR_OPT_STR_COMPRESS \
669 TAR_OPT_STR_NOPRESERVE;
670
671#ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS
672static const struct option tar_long_options[] = { 622static const struct option tar_long_options[] = {
673 { "list", 0, NULL, 't' }, 623 { "list", 0, NULL, 't' },
674 { "extract", 0, NULL, 'x' }, 624 { "extract", 0, NULL, 'x' },
@@ -678,29 +628,29 @@ static const struct option tar_long_options[] = {
678 { "same-permissions", 0, NULL, 'p' }, 628 { "same-permissions", 0, NULL, 'p' },
679 { "verbose", 0, NULL, 'v' }, 629 { "verbose", 0, NULL, 'v' },
680 { "keep-old", 0, NULL, 'k' }, 630 { "keep-old", 0, NULL, 'k' },
681 { "no-same-owner", 0, NULL, '\203' }, 631# if ENABLE_FEATURE_TAR_CREATE
682 { "no-same-permissions",0, NULL, '\213' },
683# ifdef CONFIG_FEATURE_TAR_CREATE
684 { "create", 0, NULL, 'c' }, 632 { "create", 0, NULL, 'c' },
685 { "dereference", 0, NULL, 'h' }, 633 { "dereference", 0, NULL, 'h' },
686# endif 634# endif
687# ifdef CONFIG_FEATURE_TAR_BZIP2 635# if ENABLE_FEATURE_TAR_BZIP2
688 { "bzip2", 0, NULL, 'j' }, 636 { "bzip2", 0, NULL, 'j' },
689# endif 637# endif
690# ifdef CONFIG_FEATURE_TAR_LZMA 638# if ENABLE_FEATURE_TAR_LZMA
691 { "lzma", 0, NULL, 'a' }, 639 { "lzma", 0, NULL, 'a' },
692# endif 640# endif
693# ifdef CONFIG_FEATURE_TAR_FROM 641# if ENABLE_FEATURE_TAR_FROM
694 { "files-from", 1, NULL, 'T' }, 642 { "files-from", 1, NULL, 'T' },
695 { "exclude-from", 1, NULL, 'X' }, 643 { "exclude-from", 1, NULL, 'X' },
696 { "exclude", 1, NULL, '\n' }, 644 { "exclude", 1, NULL, 0xfd },
697# endif 645# endif
698# ifdef CONFIG_FEATURE_TAR_GZIP 646# if ENABLE_FEATURE_TAR_GZIP
699 { "gzip", 0, NULL, 'z' }, 647 { "gzip", 0, NULL, 'z' },
700# endif 648# endif
701# ifdef CONFIG_FEATURE_TAR_COMPRESS 649# if ENABLE_FEATURE_TAR_COMPRESS
702 { "compress", 0, NULL, 'Z' }, 650 { "compress", 0, NULL, 'Z' },
703# endif 651# endif
652 { "no-same-owner", 0, NULL, 0xfe },
653 { "no-same-permissions",0, NULL, 0xff },
704 { 0, 0, 0, 0 } 654 { 0, 0, 0, 0 }
705}; 655};
706#else 656#else
@@ -718,25 +668,37 @@ int tar_main(int argc, char **argv)
718 668
719 /* Initialise default values */ 669 /* Initialise default values */
720 tar_handle = init_handle(); 670 tar_handle = init_handle();
721 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; 671 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS
672 | ARCHIVE_PRESERVE_DATE
673 | ARCHIVE_EXTRACT_UNCONDITIONAL;
722 674
723 /* Prepend '-' to the first argument if required */ 675 /* Prepend '-' to the first argument if required */
724 opt_complementary = ENABLE_FEATURE_TAR_CREATE ? 676 opt_complementary = "--:" // first arg is options
725 "--:X::T::\n::c:t:x:?:c--tx:t--cx:x--ct" : 677 "?:" // bail out with usage instead of error return
726 "--:X::T::\n::t:x:?:t--x:x--t"; 678 "X::T::" // cumulative lists
679 "\xfd::" // cumulative lists for --exclude
680 USE_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
681 USE_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
682 SKIP_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive
727 if (ENABLE_FEATURE_TAR_LONG_OPTIONS) 683 if (ENABLE_FEATURE_TAR_LONG_OPTIONS)
728 applet_long_options = tar_long_options; 684 applet_long_options = tar_long_options;
729 opt = getopt32(argc, argv, tar_options, 685 opt = getopt32(argc, argv,
730 &base_dir, /* Change to dir <optarg> */ 686 "txC:f:Opvk"
731 &tar_filename /* archive filename */ 687 USE_FEATURE_TAR_CREATE( "ch" )
732#ifdef CONFIG_FEATURE_TAR_FROM 688 USE_FEATURE_TAR_BZIP2( "j" )
733 , &(tar_handle->accept), 689 USE_FEATURE_TAR_LZMA( "a" )
734 &(tar_handle->reject), 690 USE_FEATURE_TAR_FROM( "T:X:")
735 &excludes 691 USE_FEATURE_TAR_GZIP( "z" )
736#endif 692 USE_FEATURE_TAR_COMPRESS("Z" )
737 ); 693 ,
738 694 &base_dir, // -C dir
739 if (opt & CTX_TEST) { 695 &tar_filename, // -f filename
696 USE_FEATURE_TAR_FROM(&(tar_handle->accept),) // T
697 USE_FEATURE_TAR_FROM(&(tar_handle->reject),) // X
698 USE_FEATURE_TAR_FROM(&excludes ) // --exclude
699 );
700
701 if (opt & OPT_TEST) {
740 if (tar_handle->action_header == header_list 702 if (tar_handle->action_header == header_list
741 || tar_handle->action_header == header_verbose_list 703 || tar_handle->action_header == header_verbose_list
742 ) { 704 ) {
@@ -744,13 +706,13 @@ int tar_main(int argc, char **argv)
744 } else 706 } else
745 tar_handle->action_header = header_list; 707 tar_handle->action_header = header_list;
746 } 708 }
747 if ((opt & CTX_EXTRACT) && tar_handle->action_data != data_extract_to_stdout) 709 if ((opt & OPT_EXTRACT) && tar_handle->action_data != data_extract_to_stdout)
748 tar_handle->action_data = data_extract_all; 710 tar_handle->action_data = data_extract_all;
749 711
750 if (opt & TAR_OPT_2STDOUT) 712 if (opt & OPT_2STDOUT)
751 tar_handle->action_data = data_extract_to_stdout; 713 tar_handle->action_data = data_extract_to_stdout;
752 714
753 if (opt & TAR_OPT_VERBOSE) { 715 if (opt & OPT_VERBOSE) {
754 if (tar_handle->action_header == header_list 716 if (tar_handle->action_header == header_list
755 || tar_handle->action_header == header_verbose_list 717 || tar_handle->action_header == header_verbose_list
756 ) { 718 ) {
@@ -758,25 +720,25 @@ int tar_main(int argc, char **argv)
758 } else 720 } else
759 tar_handle->action_header = header_list; 721 tar_handle->action_header = header_list;
760 } 722 }
761 if (opt & TAR_OPT_KEEP_OLD) 723 if (opt & OPT_KEEP_OLD)
762 tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; 724 tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL;
763 725
764 if (opt & TAR_OPT_NOPRESERVE_OWN) 726 if (opt & OPT_NOPRESERVE_OWN)
765 tar_handle->flags |= ARCHIVE_NOPRESERVE_OWN; 727 tar_handle->flags |= ARCHIVE_NOPRESERVE_OWN;
766 728
767 if (opt & TAR_OPT_NOPRESERVE_PERM) 729 if (opt & OPT_NOPRESERVE_PERM)
768 tar_handle->flags |= ARCHIVE_NOPRESERVE_PERM; 730 tar_handle->flags |= ARCHIVE_NOPRESERVE_PERM;
769 731
770 if (ENABLE_FEATURE_TAR_GZIP && (opt & TAR_OPT_GZIP)) 732 if (opt & OPT_GZIP)
771 get_header_ptr = get_header_tar_gz; 733 get_header_ptr = get_header_tar_gz;
772 734
773 if (ENABLE_FEATURE_TAR_BZIP2 && (opt & TAR_OPT_BZIP2)) 735 if (opt & OPT_BZIP2)
774 get_header_ptr = get_header_tar_bz2; 736 get_header_ptr = get_header_tar_bz2;
775 737
776 if (ENABLE_FEATURE_TAR_LZMA && (opt & TAR_OPT_LZMA)) 738 if (opt & OPT_LZMA)
777 get_header_ptr = get_header_tar_lzma; 739 get_header_ptr = get_header_tar_lzma;
778 740
779 if (ENABLE_FEATURE_TAR_COMPRESS && (opt & TAR_OPT_UNCOMPRESS)) 741 if (opt & OPT_COMPRESS)
780 get_header_ptr = get_header_tar_Z; 742 get_header_ptr = get_header_tar_Z;
781 743
782 if (ENABLE_FEATURE_TAR_FROM) { 744 if (ENABLE_FEATURE_TAR_FROM) {
@@ -816,7 +778,7 @@ int tar_main(int argc, char **argv)
816 FILE *tar_stream; 778 FILE *tar_stream;
817 int flags; 779 int flags;
818 780
819 if (ENABLE_FEATURE_TAR_CREATE && (opt & CTX_CREATE)) { 781 if (opt & OPT_CREATE) {
820 /* Make sure there is at least one file to tar up. */ 782 /* Make sure there is at least one file to tar up. */
821 if (tar_handle->accept == NULL) 783 if (tar_handle->accept == NULL)
822 bb_error_msg_and_die("empty archive"); 784 bb_error_msg_and_die("empty archive");
@@ -842,7 +804,7 @@ int tar_main(int argc, char **argv)
842 xchdir(base_dir); 804 xchdir(base_dir);
843 805
844 /* create an archive */ 806 /* create an archive */
845 if (ENABLE_FEATURE_TAR_CREATE && (opt & CTX_CREATE)) { 807 if (opt & OPT_CREATE) {
846 int verboseFlag = FALSE; 808 int verboseFlag = FALSE;
847 int zipMode = 0; 809 int zipMode = 0;
848 810
@@ -856,7 +818,7 @@ int tar_main(int argc, char **argv)
856 ) { 818 ) {
857 verboseFlag = TRUE; 819 verboseFlag = TRUE;
858 } 820 }
859 writeTarFile(tar_handle->src_fd, verboseFlag, opt & TAR_OPT_DEREFERENCE, 821 writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE,
860 tar_handle->accept, 822 tar_handle->accept,
861 tar_handle->reject, zipMode); 823 tar_handle->reject, zipMode);
862 /* NB: writeTarFile() closes tar_handle->src_fd */ 824 /* NB: writeTarFile() closes tar_handle->src_fd */