X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Ftar.c;h=0dd48b3ebd57f11ecaf7f473306c0c53b63555e4;hb=91493ea9b62a24ab139eedd4c919e4fcda9750c3;hp=dcf6a3e3fb2a67bea96fcb6f8d0f282188fce7f9;hpb=91b2d65e9dccae981f308a659d6c7bdd32285598;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index dcf6a3e..0dd48b3 100644 --- a/src/tar.c +++ b/src/tar.c @@ -158,6 +158,17 @@ archive_format_string (enum archive_format fmt) return "unknown?"; } +#define FORMAT_MASK(n) (1<<(n)) + +static void +assert_format(unsigned fmt_mask) +{ + if ((FORMAT_MASK(archive_format) & fmt_mask) == 0) + USAGE_ERROR ((0, 0, + _("GNU features wanted on incompatible archive format"))); +} + + /* Options. */ @@ -176,6 +187,7 @@ enum CHECKPOINT_OPTION, DELETE_OPTION, EXCLUDE_OPTION, + FIRST_COPY_OPTION, FORCE_LOCAL_OPTION, FORMAT_OPTION, GROUP_OPTION, @@ -215,6 +227,10 @@ static int show_help; /* If nonzero, print the version on standard output and exit. */ static int show_version; +/* If nonzero, stop processing when all the files from the namelist + where handled */ +static int first_copy_option; + static struct option long_options[] = { {"absolute-names", no_argument, 0, 'P'}, @@ -244,6 +260,7 @@ static struct option long_options[] = {"extract", no_argument, 0, 'x'}, {"file", required_argument, 0, 'f'}, {"files-from", required_argument, 0, 'T'}, + {"first-copy", no_argument, &first_copy_option, 1}, {"force-local", no_argument, 0, FORCE_LOCAL_OPTION}, {"format", required_argument, 0, FORMAT_OPTION}, {"get", no_argument, 0, 'x'}, @@ -374,7 +391,9 @@ Operation modifiers:\n\ -G, --incremental handle old GNU-format incremental backup\n\ -g, --listed-incremental=FILE\n\ handle new GNU-format incremental backup\n\ - --ignore-failed-read do not exit with nonzero on unreadable files\n"), + --ignore-failed-read do not exit with nonzero on unreadable files\n\ + --first-copy process only the first copy of each file in the\ + archive\n"), stdout); fputs (_("\ \n\ @@ -1219,8 +1238,8 @@ decode_options (int argc, char **argv) if (show_version) { - printf ("tar (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - printf (_("Copyright (C) %d Free Software Foundation, Inc.\n"), 2003); + printf ("tar (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION, + "Copyright (C) 2003 Free Software Foundation, Inc."); puts (_("\ This program comes with NO WARRANTY, to the extent permitted by law.\n\ You may redistribute it under the terms of the GNU General Public License;\n\ @@ -1248,6 +1267,29 @@ see the file named COPYING for details.")); USAGE_ERROR ((0, 0, _("GNU features wanted on incompatible archive format"))); + if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND) + assert_format (FORMAT_MASK (OLDGNU_FORMAT) + | FORMAT_MASK (GNU_FORMAT)); + + if (incremental_option + || multi_volume_option + || sparse_option) + assert_format (FORMAT_MASK (OLDGNU_FORMAT) + | FORMAT_MASK (GNU_FORMAT)); + + if (first_copy_option) + { + if (!input_files && !files_from_option) + USAGE_ERROR ((0, 0, + _("--first-copy is meaningless without file list"))); + if (subcommand_option != DELETE_SUBCOMMAND + && subcommand_option != DIFF_SUBCOMMAND + && subcommand_option != EXTRACT_SUBCOMMAND + && subcommand_option != LIST_SUBCOMMAND) + USAGE_ERROR ((0, 0, + _("--first-copy cannot be used in the requested operation mode"))); + } + if (archive_names == 0) { /* If no archive file name given, try TAPE from the environment, or @@ -1347,6 +1389,13 @@ see the file named COPYING for details.")); textual_date_option, treated_as)); } } + +bool +all_names_found () +{ + return first_copy_option && names_done (); +} + /* Tar proper. */