/* A tar (tape archiver) program.
- Copyright (C) 1988, 92,93,94,95,96,97, 1999 Free Software Foundation, Inc.
+ Copyright 1988, 92,93,94,95,96,97, 1999 Free Software Foundation, Inc.
Written by John Gilmore, starting 1985-08-25.
This program is free software; you can redistribute it and/or modify it
#include <getopt.h>
+#include <signal.h>
+#if ! defined SIGCHLD && defined SIGCLD
+# define SIGCHLD SIGCLD
+#endif
+
/* The following causes "common.h" to produce definitions of all the global
variables, rather than just "extern" declarations of them. GNU tar does
depend on the system loader to preset all GLOBAL variables to neutral (or
{"block-number", no_argument, NULL, 'R'},
{"block-size", required_argument, NULL, OBSOLETE_BLOCKING_FACTOR},
{"blocking-factor", required_argument, NULL, 'b'},
+ {"bzip2", no_argument, NULL, 'y'},
{"catenate", no_argument, NULL, 'A'},
{"checkpoint", no_argument, &checkpoint_option, 1},
{"compare", no_argument, NULL, 'd'},
PATTERN at list/extract time, a globbing PATTERN\n\
-o, --old-archive, --portability write a V7 format archive\n\
--posix write a POSIX conformant archive\n\
+ -y, --bzip2 filter the archive through bzip2\n\
-z, --gzip, --ungzip filter the archive through gzip\n\
-Z, --compress, --uncompress filter the archive through compress\n\
--use-compress-program=PROG filter through PROG (must accept -d)\n"),
DEFAULT_ARCHIVE, DEFAULT_BLOCKING);
fputs (_("\
\n\
-Report bugs to <tar-bugs@gnu.org>.\n"),
+Report bugs to <bug-tar@gnu.org>.\n"),
stdout);
}
exit (status);
Y per-block gzip compression */
#define OPTION_STRING \
- "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz"
+ "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxyz"
static void
set_subcommand_option (enum subcommand subcommand)
use_compress_program_option = string;
}
+/* Ignore DUMMY (which will always be null in practice), and add
+ PATTERN to the proper set of patterns to be excluded -- either
+ patterns with slashes, or patterns without. */
+static void
+add_filtered_exclude (struct exclude *dummy, char const *pattern)
+{
+ add_exclude ((strchr (pattern, '/')
+ ? excluded_with_slash
+ : excluded_without_slash),
+ pattern);
+}
+
static void
decode_options (int argc, char *const *argv)
{
archive_format = DEFAULT_FORMAT;
blocking_factor = DEFAULT_BLOCKING;
record_size = DEFAULT_BLOCKING * BLOCKSIZE;
+ excluded_with_slash = new_exclude ();
+ excluded_without_slash = new_exclude ();
+ newer_mtime_option = TYPE_MINIMUM (time_t);
owner_option = -1;
group_option = -1;
case 'b':
{
- long l;
- if (! (xstrtol (optarg, (char **) 0, 10, &l, "") == LONGINT_OK
- && l == (blocking_factor = l)
+ uintmax_t u;
+ if (! (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONGINT_OK
+ && u == (blocking_factor = u)
&& 0 < blocking_factor
- && l == (record_size = l * (size_t) BLOCKSIZE) / BLOCKSIZE))
+ && u == (record_size = u * (size_t) BLOCKSIZE) / BLOCKSIZE))
USAGE_ERROR ((0, 0, _("Invalid blocking factor")));
}
break;
case 'g':
listed_incremental_option = optarg;
+ after_date_option = 1;
/* Fall through. */
case 'G':
case 'L':
{
- unsigned long u;
- if (xstrtoul (optarg, (char **) 0, 10, &u, "") != LONG_MAX)
+ uintmax_t u;
+ if (xstrtoumax (optarg, (char **) 0, 10, &u, "") != LONG_MAX)
USAGE_ERROR ((0, 0, _("Invalid tape length")));
- clear_tarlong (tape_length_option);
- add_to_tarlong (tape_length_option, u);
- mult_tarlong (tape_length_option, 1024);
+ tape_length_option = 1024 * (tarlong) u;
multi_volume_option = 1;
}
break;
/* Fall through. */
case NEWER_MTIME_OPTION:
- if (newer_mtime_option)
+ if (newer_mtime_option != TYPE_MINIMUM (time_t))
USAGE_ERROR ((0, 0, _("More than one threshold date")));
newer_mtime_option = get_date (optarg, (voidstar) 0);
break;
case 'X':
- exclude_option = 1;
- add_exclude_file (optarg);
+ if (add_exclude_file (add_filtered_exclude, NULL, optarg, '\n') != 0)
+ FATAL_ERROR ((0, errno, "%s", optarg));
+ break;
+
+ case 'y':
+ set_use_compress_program_option ("bzip2");
break;
case 'z':
break;
case EXCLUDE_OPTION:
- exclude_option = 1;
- add_exclude (optarg);
+ add_filtered_exclude (NULL, optarg);
break;
case GROUP_OPTION:
&& g == (gid_t) g)
group_option = g;
else
- ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option")));
+ FATAL_ERROR ((0, 0, _("Invalid group given on option")));
}
break;
= mode_compile (optarg,
MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
if (mode_option == MODE_INVALID)
- ERROR ((TAREXIT_FAILURE, 0, _("Invalid mode given on option")));
+ FATAL_ERROR ((0, 0, _("Invalid mode given on option")));
if (mode_option == MODE_MEMORY_EXHAUSTED)
- ERROR ((TAREXIT_FAILURE, 0, _("Memory exhausted")));
+ FATAL_ERROR ((0, 0, _("Memory exhausted")));
break;
case NO_RECURSE_OPTION:
&& u == (uid_t) u)
owner_option = u;
else
- ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option")));
+ FATAL_ERROR ((0, 0, _("Invalid owner given on option")));
}
break;
printf ("tar (GNU %s) %s\n", PACKAGE, VERSION);
fputs (_("\
\n\
-Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"),
+Copyright 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"),
stdout);
fputs (_("\
This is free software; see the source for copying conditions. There is NO\n\
USAGE_ERROR ((0, 0,
_("Multiple archive files requires `-M' option")));
+ if (listed_incremental_option
+ && newer_mtime_option != TYPE_MINIMUM (time_t))
+ USAGE_ERROR ((0, 0,
+ _("Cannot combine --listed-incremental with --newer")));
+
/* If ready to unlink hierarchies, so we are for simpler files. */
if (recursive_unlink_option)
unlink_first_option = 1;
xmalloc (sizeof (const char *) * allocated_archive_names);
archive_names = 0;
+#ifdef SIGCHLD
+ /* System V fork+wait does not work if SIGCHLD is ignored. */
+ signal (SIGCHLD, SIG_DFL);
+#endif
+
init_names ();
/* Decode options. */
break;
case CREATE_SUBCOMMAND:
- if (totals_option)
- init_total_written ();
-
create_archive ();
name_close ();