#include <system.h>
#include <fnmatch.h>
-#include <getline.h>
#include <argp.h>
#include <argp-namefrob.h>
#include <argp-fmtstream.h>
ANCHORED_OPTION = CHAR_MAX + 1,
ATIME_PRESERVE_OPTION,
BACKUP_OPTION,
+ CHECK_DEVICE_OPTION,
CHECKPOINT_OPTION,
+ CHECKPOINT_ACTION_OPTION,
DELAY_DIRECTORY_RESTORE_OPTION,
+ HARD_DEREFERENCE_OPTION,
DELETE_OPTION,
EXCLUDE_CACHES_OPTION,
EXCLUDE_CACHES_UNDER_OPTION,
EXCLUDE_TAG_OPTION,
EXCLUDE_TAG_UNDER_OPTION,
EXCLUDE_TAG_ALL_OPTION,
+ EXCLUDE_VCS_OPTION,
FORCE_LOCAL_OPTION,
GROUP_OPTION,
HANG_OPTION,
MTIME_OPTION,
NEWER_MTIME_OPTION,
NO_ANCHORED_OPTION,
+ NO_AUTO_COMPRESS_OPTION,
+ NO_CHECK_DEVICE_OPTION,
NO_DELAY_DIRECTORY_RESTORE_OPTION,
NO_IGNORE_CASE_OPTION,
NO_IGNORE_COMMAND_ERROR_OPTION,
/* NOTE:
- Available option letters are DEIJQY and aeqy. Consider the following
+ Available option letters are DEIQY and eqy. Consider the following
assignments:
[For Solaris tar compatibility =/= Is it important at all?]
" NUMBER defaults to 1"), GRID+1 },
{"seek", 'n', NULL, 0,
N_("archive is seekable"), GRID+1 },
+ {"no-check-device", NO_CHECK_DEVICE_OPTION, NULL, 0,
+ N_("do not check device numbers when creating incremental archives"),
+ GRID+1 },
+ {"check-device", CHECK_DEVICE_OPTION, NULL, 0,
+ N_("check device numbers when creating incremental archives (default)"),
+ GRID+1 },
#undef GRID
#define GRID 30
N_("control pax keywords"), GRID+8 },
{"label", 'V', N_("TEXT"), 0,
N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID+8 },
+#undef GRID
+
+#define GRID 90
+ {NULL, 0, NULL, 0,
+ N_("Compression options:"), GRID },
+ {"auto-compress", 'a', 0, 0,
+ N_("use archive suffix to determine the compression program"), GRID+1 },
+ {"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0,
+ N_("do not use use archive suffix to determine the compression program"),
+ GRID+1 },
{"bzip2", 'j', 0, 0,
- N_("filter the archive through bzip2"), GRID+8 },
+ N_("filter the archive through bzip2"), GRID+1 },
{"gzip", 'z', 0, 0,
- N_("filter the archive through gzip"), GRID+8 },
- {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
- {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
+ N_("filter the archive through gzip"), GRID+1 },
+ {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
+ {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
{"compress", 'Z', 0, 0,
- N_("filter the archive through compress"), GRID+8 },
- {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
+ N_("filter the archive through compress"), GRID+1 },
+ {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
+ {"lzma", 'J', 0, 0,
+ N_("filter the archive through lzma"), GRID+1 },
{"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0,
- N_("filter through PROG (must accept -d)"), GRID+8 },
+ N_("filter through PROG (must accept -d)"), GRID+1 },
#undef GRID
-
-#define GRID 90
+
+#define GRID 100
{NULL, 0, NULL, 0,
N_("Local file selection:"), GRID },
N_("exclude everything under directories containing FILE"), GRID+1 },
{"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
N_("exclude directories containing FILE"), GRID+1 },
+ {"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
+ N_("exclude version control system directories"), GRID+1 },
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
N_("avoid descending automatically in directories"), GRID+1 },
{"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
N_("don't strip leading `/'s from file names"), GRID+1 },
{"dereference", 'h', 0, 0,
N_("follow symlinks; archive and dump the files they point to"), GRID+1 },
+ {"hard-dereference", HARD_DEREFERENCE_OPTION, 0, 0,
+ N_("follow hard links; archive and dump the files they refer to"), GRID+1 },
{"starting-file", 'K', N_("MEMBER-NAME"), 0,
N_("begin at member MEMBER-NAME in the archive"), GRID+1 },
{"newer", 'N', N_("DATE-OR-FILE"), 0,
N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID+1 },
#undef GRID
-#define GRID 92
+#define GRID 110
{NULL, 0, NULL, 0,
N_("File name transformations:"), GRID },
{"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
#undef GRID
-#define GRID 95
+#define GRID 120
{NULL, 0, NULL, 0,
N_("File name matching options (affect both exclude and include patterns):"),
GRID },
N_("wildcards match `/' (default for exclusion)"), GRID+1 },
#undef GRID
-#define GRID 100
+#define GRID 130
{NULL, 0, NULL, 0,
N_("Informative output:"), GRID },
{"verbose", 'v', 0, 0,
N_("verbosely list files processed"), GRID+1 },
- {"checkpoint", CHECKPOINT_OPTION, N_("[.]NUMBER"), OPTION_ARG_OPTIONAL,
+ {"checkpoint", CHECKPOINT_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
N_("display progress messages every NUMBERth record (default 10)"),
GRID+1 },
+ {"checkpoint-action", CHECKPOINT_ACTION_OPTION, N_("ACTION"), 0,
+ N_("execute ACTION on each checkpoint"),
+ GRID+1 },
{"check-links", 'l', 0, 0,
N_("print a message if not all links are dumped"), GRID+1 },
{"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL,
N_("disable quoting for characters from STRING"), GRID+1 },
#undef GRID
-#define GRID 110
+#define GRID 140
{NULL, 0, NULL, 0,
N_("Compatibility options:"), GRID },
N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID+1 },
#undef GRID
-#define GRID 120
+#define GRID 150
{NULL, 0, NULL, 0,
N_("Other options:"), GRID },
char const *backup_suffix_string; /* --suffix option argument */
char const *version_control_string; /* --backup option argument */
bool input_files; /* True if some input files where given */
+ int compress_autodetect; /* True if compression autodetection should
+ be attempted when creating archives */
};
+\f
#define MAKE_EXCL_OPTIONS(args) \
((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
| (args)->matching_flags \
| (args)->matching_flags \
| recursion_option)
+void
+exclude_vcs_files ()
+{
+ int i;
+ static char *vcs_file[] = {
+ /* CVS: */
+ "CVS",
+ ".cvsignore",
+ /* RCS: */
+ "RCS",
+ /* SCCS: */
+ "SCCS",
+ /* SVN: */
+ ".svn",
+ /* git: */
+ ".git",
+ ".gitignore",
+ /* Arch: */
+ ".arch-ids",
+ "{arch}",
+ "=RELEASE-ID",
+ "=meta-update",
+ "=update",
+ /* Bazaar */
+ ".bzr",
+ ".bzrignore",
+ ".bzrtags",
+ /* Mercurial */
+ ".hg",
+ ".hgignore",
+ ".hgtags",
+ /* darcs */
+ "_darcs",
+ NULL
+ };
+
+ for (i = 0; vcs_file[i]; i++)
+ add_exclude (excluded, vcs_file[i], 0);
+}
+
+\f
#ifdef REMOTE_SHELL
# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \
{ \
set_subcommand_option (CAT_SUBCOMMAND);
break;
+ case 'a':
+ args->compress_autodetect = true;
+ break;
+
+ case NO_AUTO_COMPRESS_OPTION:
+ args->compress_autodetect = false;
+ break;
+
case 'b':
{
uintmax_t u;
dereference_option = true;
break;
+ case HARD_DEREFERENCE_OPTION:
+ hard_dereference_option = true;
+ break;
+
case 'i':
/* Ignore zero blocks (eofs). This can't be the default,
because Unix tar writes two blocks of zeros, then pads out
set_use_compress_program_option ("bzip2");
break;
+ case 'J':
+ set_use_compress_program_option ("lzma");
+ break;
+
case 'k':
/* Don't replace existing files. */
old_files_option = KEEP_OLD_FILES;
" on this platform")));
break;
+ case CHECK_DEVICE_OPTION:
+ check_device_option = true;
+ break;
+
+ case NO_CHECK_DEVICE_OPTION:
+ check_device_option = false;
+ break;
+
case CHECKPOINT_OPTION:
if (arg)
{
if (*arg == '.')
{
- checkpoint_style = checkpoint_dot;
+ checkpoint_compile_action (".");
arg++;
}
checkpoint_option = strtoul (arg, &p, 0);
_("--checkpoint value is not an integer")));
}
else
- checkpoint_option = 10;
+ checkpoint_option = DEFAULT_CHECKPOINT;
break;
+ case CHECKPOINT_ACTION_OPTION:
+ checkpoint_compile_action (arg);
+ break;
+
case BACKUP_OPTION:
backup_option = true;
if (arg)
add_exclusion_tag (arg, exclusion_tag_all, NULL);
break;
+ case EXCLUDE_VCS_OPTION:
+ exclude_vcs_files ();
+ break;
+
case FORCE_LOCAL_OPTION:
force_local_option = true;
break;
/* Parse the options for tar. */
static struct argp_option *
-find_argp_option (struct argp_option *options, int letter)
+find_argp_option (struct argp_option *o, int letter)
{
for (;
- !(options->name == NULL
- && options->key == 0
- && options->arg == 0
- && options->flags == 0
- && options->doc == NULL); options++)
- if (options->key == letter)
- return options;
+ !(o->name == NULL
+ && o->key == 0
+ && o->arg == 0
+ && o->flags == 0
+ && o->doc == NULL); o++)
+ if (o->key == letter)
+ return o;
return NULL;
}
static void
decode_options (int argc, char **argv)
{
- int index;
+ int idx;
struct tar_args args;
/* Set some default option values. */
args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
args.version_control_string = 0;
args.input_files = false;
-
+ args.compress_autodetect = false;
+
subcommand_option = UNKNOWN_SUBCOMMAND;
archive_format = DEFAULT_FORMAT;
blocking_factor = DEFAULT_BLOCKING;
owner_option = -1;
group_option = -1;
+ check_device_option = true;
+
/* Convert old-style tar call by exploding option element and rearranging
options accordingly. */
prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
- &index, &args))
+ &idx, &args))
exit (TAREXIT_FAILURE);
}
/* Handle operands after any "--" argument. */
- for (; index < argc; index++)
+ for (; idx < argc; idx++)
{
- name_add_name (argv[index], MAKE_INCL_OPTIONS (&args));
+ name_add_name (argv[idx], MAKE_INCL_OPTIONS (&args));
args.input_files = true;
}
else if (utc_option)
verbose_option = 2;
+ if (tape_length_option && tape_length_option < record_size)
+ USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
+
/* Forbid using -c with no input files whatsoever. Check that `-f -',
explicit or implied, is used correctly. */
if (!args.input_files && !files_from_option)
USAGE_ERROR ((0, 0,
_("Cowardly refusing to create an empty archive")));
+ if (args.compress_autodetect && archive_names
+ && strcmp (archive_name_array[0], "-"))
+ set_comression_program_by_suffix (archive_name_array[0],
+ use_compress_program_option);
break;
case EXTRACT_SUBCOMMAND:
backup_option = false;
}
+ checkpoint_finish_compile ();
+
if (verbose_option)
report_textual_dates (&args);
}
name_term ();
if (exit_status == TAREXIT_FAILURE)
- error (0, 0, _("Error exit delayed from previous errors"));
+ error (0, 0, _("Exiting with failure status due to previous errors"));
if (stdlis == stdout)
close_stdout ();