]> Dogcows Code - chaz/tar/blobdiff - src/tar.c
Include bounds in forward declaration for xhdr_tab.
[chaz/tar] / src / tar.c
index 6a875ca070ccdf90403b40a4998113334ea9a4a4..b648c8f25ba91bc67b5d79b2e7c3c6756611ef31 100644 (file)
--- 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")));
+}
+
+
 \f
 /* Options.  */
 
@@ -191,6 +202,7 @@ enum
   NO_WILDCARDS_MATCH_SLASH_OPTION,
   NULL_OPTION,
   NUMERIC_OWNER_OPTION,
+  OCCURRENCE_OPTION,
   OVERWRITE_OPTION,
   OWNER_OPTION,
   POSIX_OPTION,
@@ -278,6 +290,7 @@ static struct option long_options[] =
   {"no-same-owner", no_argument, &same_owner_option, -1},
   {"no-same-permissions", no_argument, &same_permissions_option, -1},
   {"numeric-owner", no_argument, 0, NUMERIC_OWNER_OPTION},
+  {"occurrence", optional_argument, 0, OCCURRENCE_OPTION},
   {"old-archive", no_argument, 0, 'o'},
   {"one-file-system", no_argument, 0, 'l'},
   {"overwrite", no_argument, 0, OVERWRITE_OPTION},
@@ -374,7 +387,14 @@ 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\
+      --occurrence[=NUM]     process only the NUMth occurrence of each file in\n\
+                             the archive. This option is valid only in\n\
+                             conjunction with one of the subcommands --delete,\n\
+                             --diff, --extract or --list and when a list of\n\
+                             files is given either on the command line or\n\
+                             via -T option.\n\
+                             NUM defaults to 1.\n"),
             stdout);
       fputs (_("\
 \n\
@@ -1019,6 +1039,20 @@ decode_options (int argc, char **argv)
        numeric_owner_option = true;
        break;
 
+      case OCCURRENCE_OPTION:
+       if (!optarg)
+         occurrence_option = 1;
+       else
+         {
+           uintmax_t u;
+           if (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK)
+             occurrence_option = u;
+           else
+             FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
+                           _("Invalid number")));
+         }
+       break;
+       
       case OVERWRITE_OPTION:
        old_files_option = OVERWRITE_OLD_FILES;
        break;
@@ -1242,12 +1276,29 @@ see the file named COPYING for details."));
   if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT"))
     archive_format = POSIX_FORMAT;
 
-  if (((volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
-       || incremental_option || multi_volume_option || sparse_option)
-      && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT)
-    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 (occurrence_option)
+    {
+      if (!input_files && !files_from_option)
+       USAGE_ERROR ((0, 0,
+                     _("--occurrence 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,
+                         _("--occurrence 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 +1398,7 @@ see the file named COPYING for details."));
               textual_date_option, treated_as));
     }
 }
+
 \f
 /* Tar proper.  */
 
This page took 0.02268 seconds and 4 git commands to generate.