diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-11-24 21:55:55 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-11-24 21:55:55 +0000 |
commit | 3feb2fc535db445951314f57a8f7ecc460b456d9 (patch) | |
tree | e843dcb27558f2121d9b0ce351364aa07960610a | |
parent | d031ffa623203b1dc756a1e02e06f261fdc30872 (diff) | |
download | busybox-w32-3feb2fc535db445951314f57a8f7ecc460b456d9.tar.gz busybox-w32-3feb2fc535db445951314f57a8f7ecc460b456d9.tar.bz2 busybox-w32-3feb2fc535db445951314f57a8f7ecc460b456d9.zip |
tar: fix multiple -t and/or -v options handling.
do not process list of files to tar up in reverse order.
-rw-r--r-- | archival/tar.c | 57 | ||||
-rw-r--r-- | libbb/last_char_is.c | 15 |
2 files changed, 28 insertions, 44 deletions
diff --git a/archival/tar.c b/archival/tar.c index 4d237f880..b326d1e88 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -276,13 +276,13 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
276 | xwrite(tbInfo->tarFd, &header, sizeof(struct TarHeader)); | 276 | xwrite(tbInfo->tarFd, &header, sizeof(struct TarHeader)); |
277 | 277 | ||
278 | /* Now do the verbose thing (or not) */ | 278 | /* Now do the verbose thing (or not) */ |
279 | |||
280 | if (tbInfo->verboseFlag) { | 279 | if (tbInfo->verboseFlag) { |
281 | FILE *vbFd = stdout; | 280 | FILE *vbFd = stdout; |
282 | 281 | ||
283 | if (tbInfo->tarFd == STDOUT_FILENO) /* If the archive goes to stdout, verbose to stderr */ | 282 | if (tbInfo->tarFd == STDOUT_FILENO) /* If the archive goes to stdout, verbose to stderr */ |
284 | vbFd = stderr; | 283 | vbFd = stderr; |
285 | 284 | /* GNU "tar cvvf" prints "extended" listing a-la "ls -l" */ | |
285 | /* We don't have such excesses here: for us "v" == "vv" */ | ||
286 | fprintf(vbFd, "%s\n", header.name); | 286 | fprintf(vbFd, "%s\n", header.name); |
287 | } | 287 | } |
288 | 288 | ||
@@ -549,9 +549,10 @@ static llist_t *append_file_list_to_list(llist_t *list) | |||
549 | cur = cur->link; | 549 | cur = cur->link; |
550 | free(tmp); | 550 | free(tmp); |
551 | while ((line = xmalloc_getline(src_stream)) != NULL) { | 551 | while ((line = xmalloc_getline(src_stream)) != NULL) { |
552 | char *filename_ptr = last_char_is(line, '/'); | 552 | /* kill trailing '/' unless the string is just "/" */ |
553 | if (filename_ptr > line) | 553 | char *cp = last_char_is(line, '/'); |
554 | *filename_ptr = '\0'; | 554 | if (cp > line) |
555 | *cp = '\0'; | ||
555 | llist_add_to(&newlist, line); | 556 | llist_add_to(&newlist, line); |
556 | } | 557 | } |
557 | fclose(src_stream); | 558 | fclose(src_stream); |
@@ -664,6 +665,7 @@ int tar_main(int argc, char **argv) | |||
664 | char *base_dir = NULL; | 665 | char *base_dir = NULL; |
665 | const char *tar_filename = "-"; | 666 | const char *tar_filename = "-"; |
666 | unsigned opt; | 667 | unsigned opt; |
668 | int verboseFlag = 0; | ||
667 | llist_t *excludes = NULL; | 669 | llist_t *excludes = NULL; |
668 | 670 | ||
669 | /* Initialise default values */ | 671 | /* Initialise default values */ |
@@ -674,6 +676,7 @@ int tar_main(int argc, char **argv) | |||
674 | 676 | ||
675 | /* Prepend '-' to the first argument if required */ | 677 | /* Prepend '-' to the first argument if required */ |
676 | opt_complementary = "--:" // first arg is options | 678 | opt_complementary = "--:" // first arg is options |
679 | "tt:vv:" // count -t,-v | ||
677 | "?:" // bail out with usage instead of error return | 680 | "?:" // bail out with usage instead of error return |
678 | "X::T::" // cumulative lists | 681 | "X::T::" // cumulative lists |
679 | "\xfd::" // cumulative lists for --exclude | 682 | "\xfd::" // cumulative lists for --exclude |
@@ -695,31 +698,20 @@ int tar_main(int argc, char **argv) | |||
695 | &tar_filename, // -f filename | 698 | &tar_filename, // -f filename |
696 | USE_FEATURE_TAR_FROM(&(tar_handle->accept),) // T | 699 | USE_FEATURE_TAR_FROM(&(tar_handle->accept),) // T |
697 | USE_FEATURE_TAR_FROM(&(tar_handle->reject),) // X | 700 | USE_FEATURE_TAR_FROM(&(tar_handle->reject),) // X |
698 | USE_FEATURE_TAR_FROM(&excludes ) // --exclude | 701 | USE_FEATURE_TAR_FROM(&excludes ,) // --exclude |
702 | &verboseFlag, // combined count for -t and -v | ||
703 | &verboseFlag // combined count for -t and -v | ||
699 | ); | 704 | ); |
700 | 705 | ||
701 | if (opt & OPT_TEST) { | 706 | if (verboseFlag) tar_handle->action_header = header_verbose_list; |
702 | if (tar_handle->action_header == header_list | 707 | if (verboseFlag == 1) tar_handle->action_header = header_list; |
703 | || tar_handle->action_header == header_verbose_list | 708 | |
704 | ) { | ||
705 | tar_handle->action_header = header_verbose_list; | ||
706 | } else | ||
707 | tar_handle->action_header = header_list; | ||
708 | } | ||
709 | if ((opt & OPT_EXTRACT) && tar_handle->action_data != data_extract_to_stdout) | 709 | if ((opt & OPT_EXTRACT) && tar_handle->action_data != data_extract_to_stdout) |
710 | tar_handle->action_data = data_extract_all; | 710 | tar_handle->action_data = data_extract_all; |
711 | 711 | ||
712 | if (opt & OPT_2STDOUT) | 712 | if (opt & OPT_2STDOUT) |
713 | tar_handle->action_data = data_extract_to_stdout; | 713 | tar_handle->action_data = data_extract_to_stdout; |
714 | 714 | ||
715 | if (opt & OPT_VERBOSE) { | ||
716 | if (tar_handle->action_header == header_list | ||
717 | || tar_handle->action_header == header_verbose_list | ||
718 | ) { | ||
719 | tar_handle->action_header = header_verbose_list; | ||
720 | } else | ||
721 | tar_handle->action_header = header_list; | ||
722 | } | ||
723 | if (opt & OPT_KEEP_OLD) | 715 | if (opt & OPT_KEEP_OLD) |
724 | tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; | 716 | tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; |
725 | 717 | ||
@@ -762,13 +754,14 @@ int tar_main(int argc, char **argv) | |||
762 | /* Setup an array of filenames to work with */ | 754 | /* Setup an array of filenames to work with */ |
763 | /* TODO: This is the same as in ar, separate function ? */ | 755 | /* TODO: This is the same as in ar, separate function ? */ |
764 | while (optind < argc) { | 756 | while (optind < argc) { |
765 | char *filename_ptr = last_char_is(argv[optind], '/'); | 757 | /* kill trailing '/' unless the string is just "/" */ |
766 | if (filename_ptr > argv[optind]) | 758 | char *cp = last_char_is(argv[optind], '/'); |
767 | *filename_ptr = '\0'; | 759 | if (cp > argv[optind]) |
768 | 760 | *cp = '\0'; | |
769 | llist_add_to(&(tar_handle->accept), argv[optind]); | 761 | llist_add_to(&tar_handle->accept, argv[optind]); |
770 | optind++; | 762 | optind++; |
771 | } | 763 | } |
764 | tar_handle->accept = rev_llist(tar_handle->accept); | ||
772 | 765 | ||
773 | if (tar_handle->accept || tar_handle->reject) | 766 | if (tar_handle->accept || tar_handle->reject) |
774 | tar_handle->filter = filter_accept_reject_list; | 767 | tar_handle->filter = filter_accept_reject_list; |
@@ -805,22 +798,14 @@ int tar_main(int argc, char **argv) | |||
805 | 798 | ||
806 | /* create an archive */ | 799 | /* create an archive */ |
807 | if (opt & OPT_CREATE) { | 800 | if (opt & OPT_CREATE) { |
808 | int verboseFlag = FALSE; | ||
809 | int zipMode = 0; | 801 | int zipMode = 0; |
810 | |||
811 | if (ENABLE_FEATURE_TAR_GZIP && get_header_ptr == get_header_tar_gz) | 802 | if (ENABLE_FEATURE_TAR_GZIP && get_header_ptr == get_header_tar_gz) |
812 | zipMode = 1; | 803 | zipMode = 1; |
813 | if (ENABLE_FEATURE_TAR_BZIP2 && get_header_ptr == get_header_tar_bz2) | 804 | if (ENABLE_FEATURE_TAR_BZIP2 && get_header_ptr == get_header_tar_bz2) |
814 | zipMode = 2; | 805 | zipMode = 2; |
815 | |||
816 | if (tar_handle->action_header == header_list | ||
817 | || tar_handle->action_header == header_verbose_list | ||
818 | ) { | ||
819 | verboseFlag = TRUE; | ||
820 | } | ||
821 | writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, | 806 | writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, |
822 | tar_handle->accept, | 807 | tar_handle->accept, |
823 | tar_handle->reject, zipMode); | 808 | tar_handle->reject, zipMode); |
824 | /* NB: writeTarFile() closes tar_handle->src_fd */ | 809 | /* NB: writeTarFile() closes tar_handle->src_fd */ |
825 | return EXIT_SUCCESS; | 810 | return EXIT_SUCCESS; |
826 | } | 811 | } |
diff --git a/libbb/last_char_is.c b/libbb/last_char_is.c index 9194ac05f..80a6fe2e4 100644 --- a/libbb/last_char_is.c +++ b/libbb/last_char_is.c | |||
@@ -7,20 +7,19 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <string.h> | ||
11 | #include "libbb.h" | 10 | #include "libbb.h" |
12 | 11 | ||
13 | /* Find out if the last character of a string matches the one given Don't | 12 | /* Find out if the last character of a string matches the one given Don't |
14 | * underrun the buffer if the string length is 0. Also avoids a possible | 13 | * underrun the buffer if the string length is 0. Also avoids a possible |
15 | * space-hogging inline of strlen() per usage. | 14 | * space-hogging inline of strlen() per usage. |
16 | */ | 15 | */ |
17 | char * last_char_is(const char *s, int c) | 16 | char* last_char_is(const char *s, int c) |
18 | { | 17 | { |
19 | char *sret = (char *)s; | 18 | char *sret; |
20 | if (sret) { | 19 | if (s) { |
21 | sret = strrchr(sret, c); | 20 | sret = strrchr(s, c); |
22 | if(sret != NULL && *(sret+1) != 0) | 21 | if (sret && !sret[1]) |
23 | sret = NULL; | 22 | return sret; |
24 | } | 23 | } |
25 | return sret; | 24 | return NULL; |
26 | } | 25 | } |