/* Extract files from a tar archive.
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
- 2001, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
Written by John Gilmore, on 1985-11-19.
#include <system.h>
#include <quotearg.h>
+#include <utimens.h>
#include <errno.h>
#include <xgetcwd.h>
-#if HAVE_UTIME_H
-# include <utime.h>
-#else
-struct utimbuf
- {
- long actime;
- long modtime;
- };
-#endif
-
#include "common.h"
static bool we_are_root; /* true if our effective uid == 0 */
/* Check time after successfully setting FILE_NAME's time stamp to T. */
static void
-check_time (char const *file_name, time_t t)
+check_time (char const *file_name, struct timespec t)
{
- time_t now;
- if (t <= 0)
+ if (t.tv_sec <= 0)
WARN ((0, 0, _("%s: implausibly old time stamp %s"),
- file_name, tartime (t)));
- else if (start_time < t && (now = time (0)) < t)
- WARN ((0, 0, _("%s: time stamp %s is %lu s in the future"),
- file_name, tartime (t), (unsigned long) (t - now)));
+ file_name, tartime (t, true)));
+ else if (timespec_lt (start_time, t))
+ {
+ struct timespec now;
+ gettime (&now);
+ if (timespec_lt (now, t))
+ {
+ unsigned long int ds = t.tv_sec - now.tv_sec;
+ int dns = t.tv_nsec - now.tv_nsec;
+ char dnsbuf[sizeof ".FFFFFFFFF"];
+ if (dns < 0)
+ {
+ dns += 1000000000;
+ ds--;
+ }
+ code_ns_fraction (dns, dnsbuf);
+ WARN ((0, 0, _("%s: time stamp %s is %lu%s s in the future"),
+ file_name, tartime (t, true), ds, dnsbuf));
+ }
+ }
}
/* Restore stat attributes (owner, group, mode and times) for
mode_t invert_permissions, enum permstatus permstatus,
char typeflag)
{
- struct utimbuf utimbuf;
-
if (typeflag != SYMTYPE)
{
/* We do the utime before the chmod because some versions of utime are
/* FIXME: incremental_option should set ctime too, but how? */
- if (incremental_option)
- utimbuf.actime = stat_info->st_atime;
- else
- utimbuf.actime = start_time;
-
- utimbuf.modtime = stat_info->st_mtime;
+ struct timespec ts[2];
+ ts[0] = incremental_option ? get_stat_atime (stat_info) : start_time;
+ ts[1] = get_stat_mtime (stat_info);
- if (utime (file_name, &utimbuf) < 0)
+ if (utimens (file_name, ts) != 0)
utime_error (file_name);
else
{
- check_time (file_name, utimbuf.actime);
- check_time (file_name, utimbuf.modtime);
+ check_time (file_name, ts[0]);
+ check_time (file_name, ts[1]);
}
}
static int
extract_link (char *file_name, int typeflag)
{
- char const *link_name = safer_name_suffix (current_stat_info.link_name, true);
+ char const *link_name = safer_name_suffix (current_stat_info.link_name,
+ true, absolute_names_option);
int interdir_made = 0;
do
if (verbose_option)
print_header (¤t_stat_info, -1);
- file_name = safer_name_suffix (current_stat_info.file_name, false);
+ file_name = safer_name_suffix (current_stat_info.file_name,
+ false, absolute_names_option);
if (strip_name_components)
{
size_t prefix_len = stripped_prefix_len (file_name, strip_name_components);