GNAME_TO_CHARS (tmpname, header->header.gname);
free (tmpname);
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ strcpy (header->buffer + offsetof (struct posix_header, magic),
+ OLDGNU_MAGIC);
header->header.typeflag = type;
finish_header (st, header, -1);
case OLDGNU_FORMAT:
case GNU_FORMAT: /*FIXME?*/
/* Overwrite header->header.magic and header.version in one blow. */
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ strcpy (header->buffer + offsetof (struct posix_header, magic),
+ OLDGNU_MAGIC);
break;
case POSIX_FORMAT:
char *
get_directory_entries (struct tar_stat_info *st)
{
- DIR *dirstream;
- while (! (dirstream = fdopendir (st->fd)) && open_failure_recover (st))
- continue;
-
- if (! dirstream)
- return 0;
- else
- {
- char *entries = streamsavedir (dirstream);
- int streamsavedir_errno = errno;
-
- int fd = dirfd (dirstream);
- if (fd < 0)
- {
- /* The dirent.h implementation doesn't use file descriptors
- for directory streams, so open the directory again. */
- char const *name = st->orig_file_name;
- if (closedir (dirstream) != 0)
- close_diag (name);
- dirstream = 0;
- fd = subfile_open (st->parent,
- st->parent ? last_component (name) : name,
- open_searchdir_flags);
- if (fd < 0)
- fd = - errno;
- else
- {
- struct stat dirst;
- if (! (fstat (fd, &dirst) == 0
- && st->stat.st_ino == dirst.st_ino
- && st->stat.st_dev == dirst.st_dev))
- {
- close (fd);
- fd = - IMPOSTOR_ERRNO;
- }
- }
- }
-
- st->fd = fd;
- st->dirstream = dirstream;
- errno = streamsavedir_errno;
- return entries;
- }
+ while (! (st->dirstream = fdopendir (st->fd)))
+ if (! open_failure_recover (st))
+ return 0;
+ return streamsavedir (st->dirstream);
}
/* Dump the directory ST. Return true if successful, false (emitting
{
if (! st.orig_file_name)
{
- int fd = open (p->name, open_searchdir_flags);
+ int fd = openat (chdir_fd, p->name,
+ open_searchdir_flags);
if (fd < 0)
{
open_diag (p->name);
gettext ("");
}
- while ((fd = openat (dir ? dir->fd : AT_FDCWD, file, flags)) < 0
+ while ((fd = openat (dir ? dir->fd : chdir_fd, file, flags)) < 0
&& open_failure_recover (dir))
continue;
return fd;
if (parentfd < 0)
{
- int origfd = open (parent->orig_file_name, open_searchdir_flags);
+ int origfd = openat (chdir_fd, parent->orig_file_name,
+ open_searchdir_flags);
if (0 <= origfd)
{
if (fstat (parentfd, &parentstat) == 0
char type;
off_t original_size;
struct timespec original_ctime;
- struct timespec restore_times[2];
off_t block_ordinal = -1;
int fd = 0;
bool is_dir;
struct tar_stat_info const *parent = st->parent;
bool top_level = ! parent;
- int parentfd = top_level ? AT_FDCWD : parent->fd;
+ int parentfd = top_level ? chdir_fd : parent->fd;
void (*diag) (char const *) = 0;
if (interactive_option && !confirm ("add", p))
}
st->archive_file_size = original_size = st->stat.st_size;
- st->atime = restore_times[0] = get_stat_atime (&st->stat);
- st->mtime = restore_times[1] = get_stat_mtime (&st->stat);
+ st->atime = get_stat_atime (&st->stat);
+ st->mtime = get_stat_mtime (&st->stat);
st->ctime = original_ctime = get_stat_ctime (&st->stat);
#ifdef S_ISHIDDEN
ok = dump_dir (st);
fd = st->fd;
- parentfd = top_level ? AT_FDCWD : parent->fd;
+ parentfd = top_level ? chdir_fd : parent->fd;
}
else
{
set_exit_status (TAREXIT_DIFFERS);
}
else if (atime_preserve_option == replace_atime_preserve
- && set_file_atime (fd, p, restore_times) != 0)
+ && set_file_atime (fd, parentfd, name, st->atime) != 0)
utime_error (p);
}