#include <closeout.h>
#include <configmake.h>
#include <exitfail.h>
-#include <getdate.h>
+#include <parse-datetime.h>
#include <rmt.h>
#include <rmt-command.h>
#include <prepargs.h>
static const char *stdin_used_by;
/* Doesn't return if stdin already requested. */
-void
+static void
request_stdin (const char *option)
{
if (stdin_used_by)
|| *str == '.')
{
struct stat st;
- if (deref_stat (dereference_option, str, &st) != 0)
+ if (stat (str, &st) != 0)
{
stat_error (str);
USAGE_ERROR ((0, 0, _("Date sample file not found")));
}
else
{
- if (! get_date (ts, str, NULL))
+ if (! parse_datetime (ts, str, NULL))
{
WARN ((0, 0, _("Substituting %s for unknown date format %s"),
tartime (*ts, false), quote (str)));
}
\f
+#define TAR_SIZE_SUFFIXES "bBcGgkKMmPTtw"
+
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
case 'L':
{
uintmax_t u;
- if (xstrtoumax (arg, 0, 10, &u, "") != LONGINT_OK)
+ char *p;
+
+ if (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES) != LONGINT_OK)
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
_("Invalid tape length")));
- tape_length_option = 1024 * (tarlong) u;
+ if (p > arg && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
+ tape_length_option = 1024 * (tarlong) u;
+ else
+ tape_length_option = (tarlong) u;
multi_volume_option = true;
}
break;
case RECORD_SIZE_OPTION:
{
uintmax_t u;
- if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
+
+ if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
&& u == (size_t) u))
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
_("Invalid record size")));
if (recursive_unlink_option)
old_files_option = UNLINK_FIRST_OLD_FILES;
+ /* Flags for accessing files to be read from or copied into. POSIX says
+ O_NONBLOCK has unspecified effect on most types of files, but in
+ practice it never harms and sometimes helps. */
+ {
+ int base_open_flags =
+ (O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
+ | (dereference_option ? 0 : O_NOFOLLOW)
+ | (atime_preserve_option == system_atime_preserve ? O_NOATIME : 0));
+ open_read_flags = O_RDONLY | base_open_flags;
+ open_searchdir_flags = O_SEARCH | O_DIRECTORY | base_open_flags;
+ }
+ fstatat_flags = dereference_option ? 0 : AT_SYMLINK_NOFOLLOW;
if (subcommand_option == TEST_LABEL_SUBCOMMAND)
{
_("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);
+ set_compression_program_by_suffix (archive_name_array[0],
+ use_compress_program_option);
break;
case EXTRACT_SUBCOMMAND:
memset (st, 0, sizeof (*st));
}
+/* Close the stream or file descriptor associated with ST, and remove
+ all traces of it from ST. Return true if successful, false (with a
+ diagnostic) otherwise. */
+bool
+tar_stat_close (struct tar_stat_info *st)
+{
+ int status = (st->dirstream ? closedir (st->dirstream)
+ : 0 < st->fd ? close (st->fd)
+ : 0);
+ st->dirstream = 0;
+ st->fd = 0;
+
+ if (status == 0)
+ return true;
+ else
+ {
+ close_diag (st->orig_file_name);
+ return false;
+ }
+}
+
void
tar_stat_destroy (struct tar_stat_info *st)
{
+ tar_stat_close (st);
free (st->orig_file_name);
free (st->file_name);
free (st->link_name);