replace_prefix (&dp->name, pref, pref_len, repl, repl_len);
}
+void
+clear_directory_table (void)
+{
+ struct directory *dp;
+
+ if (directory_table)
+ hash_clear (directory_table);
+ if (directory_meta_table)
+ hash_clear (directory_meta_table);
+ for (dp = dirhead; dp; )
+ {
+ struct directory *next = dp->next;
+ free_directory (dp);
+ dp = next;
+ }
+ dirhead = dirtail = NULL;
+}
+
/* Create and link a new directory entry for directory NAME, having a
device number DEV and an inode number INO, with NFS indicating
whether it is an NFS device and FOUND indicating whether we have
if (! ((directory_table
|| (directory_table = hash_initialize (0, 0,
hash_directory_canonical_name,
- compare_directory_canonical_names, 0)))
+ compare_directory_canonical_names,
+ 0)))
&& hash_insert (directory_table, directory)))
xalloc_die ();
if (directory)
{
struct stat st;
- if (fstatat (parent->fd, ".", &st, fstatat_flags) != 0)
+ if (fstat (parent->fd, &st) != 0)
stat_diag (directory->name);
else
directory->mtime = get_stat_mtime (&st);
{
struct directory *directory;
struct stat *stat_data = &st->stat;
- int fd = st->fd;
- dev_t device = st->parent ? st->parent->stat.st_dev : 0;
bool nfs = NFS_FILE_STAT (*stat_data);
-
+ bool perhaps_renamed = false;
+
if ((directory = find_directory (name_buffer)) != NULL)
{
if (DIR_IS_INITED (directory))
}
else
{
- WARNOPT (WARN_RENAME_DIRECTORY,
- (0, 0, _("%s: Directory has been renamed"),
- quotearg_colon (name_buffer)));
+ perhaps_renamed = true;
directory->children = ALL_CHILDREN;
directory->device_number = stat_data->st_dev;
directory->inode_number = stat_data->st_ino;
}
}
- /* If the directory is on another device and --one-file-system was given,
- omit it... */
- if (one_file_system_option && device != stat_data->st_dev
- /* ... except if it was explicitely given in the command line */
- && !is_individual_file (name_buffer))
- /* FIXME:
- WARNOPT (WARN_XDEV,
- (0, 0,
- _("%s: directory is on a different filesystem; not dumped"),
- quotearg_colon (directory->name)));
- */
- directory->children = NO_CHILDREN;
+ if (one_file_system_option && st->parent
+ && stat_data->st_dev != st->parent->stat.st_dev)
+ {
+ WARNOPT (WARN_XDEV,
+ (0, 0,
+ _("%s: directory is on a different filesystem; not dumped"),
+ quotearg_colon (directory->name)));
+ directory->children = NO_CHILDREN;
+ /* If there is any dumpdir info in that directory, remove it */
+ if (directory->dump)
+ {
+ dumpdir_free (directory->dump);
+ directory->dump = NULL;
+ }
+ perhaps_renamed = false;
+ }
+
else if (flag & PD_FORCE_CHILDREN)
{
directory->children = PD_CHILDREN(flag);
*entry = 'N';
}
+ if (perhaps_renamed)
+ WARNOPT (WARN_RENAME_DIRECTORY,
+ (0, 0, _("%s: Directory has been renamed"),
+ quotearg_colon (name_buffer)));
+
DIR_SET_FLAG (directory, DIRF_INIT);
if (directory->children != NO_CHILDREN)
{
const char *tag_file_name;
- switch (check_exclusion_tags (fd, &tag_file_name))
+ switch (check_exclusion_tags (st, &tag_file_name))
{
case exclusion_tag_all:
/* This warning can be duplicated by code in dump_file0, but only
scan_directory (struct tar_stat_info *st)
{
char const *dir = st->orig_file_name;
- int fd = st->fd;
- char *dirp = 0;
+ char *dirp = get_directory_entries (st);
dev_t device = st->stat.st_dev;
bool cmdline = ! st->parent;
namebuf_t nbuf;
struct directory *directory;
char ch;
- int dupfd = dup (fd);
- if (0 <= dupfd)
- {
- dirp = fdsavedir (dupfd);
- if (! dirp)
- {
- int e = errno;
- close (dupfd);
- errno = e;
- }
- }
-
if (! dirp)
savedir_error (dir);
*entry = 'N';
else
{
+ int fd = st->fd;
void (*diag) (char const *) = 0;
struct tar_stat_info stsub;
tar_stat_init (&stsub);
- if (fstatat (fd, entry + 1, &stsub.stat, fstatat_flags) != 0)
+ if (fd < 0)
+ {
+ errno = - fd;
+ diag = open_diag;
+ }
+ else if (fstatat (fd, entry + 1, &stsub.stat, fstatat_flags) != 0)
diag = stat_diag;
else if (S_ISDIR (stsub.stat.st_mode))
{
- stsub.fd = openat (fd, entry + 1, open_read_flags);
- if (stsub.fd < 0)
+ int subfd = subfile_open (st, entry + 1, open_read_flags);
+ if (subfd < 0)
diag = open_diag;
- else if (fstat (stsub.fd, &stsub.stat) != 0)
- diag = stat_diag;
+ else
+ {
+ stsub.fd = subfd;
+ if (fstat (subfd, &stsub.stat) != 0)
+ diag = stat_diag;
+ }
}
if (diag)
else if (directory->children == ALL_CHILDREN)
pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
*entry = 'D';
+
+ stsub.parent = st;
procdir (full_name, &stsub, pd_flag, entry);
+ restore_parent_fd (&stsub);
}
else if (one_file_system_option && device != stsub.stat.st_dev)
*entry = 'N';
namebuf_free (nbuf);
- if (dirp)
- free (dirp);
+ free (dirp);
return directory;
}
are ignored when hit by this function next time.
If the chain forms a cycle, prev points to the entry DIR is renamed
from. In this case it still retains DIRF_RENAMED flag, which will be
- cleared in the `else' branch below */
+ cleared in the 'else' branch below */
for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
for (dp = dirhead; dp; dp = dp->next)
store_rename (dp, &stk);
- if (obstack_object_size (&stk) != size)
+ /* FIXME: Is this the right thing to do when DIR is null? */
+ if (dir && obstack_object_size (&stk) != size)
{
obstack_1grow (&stk, 0);
dumpdir_free (dir->dump);
if (ferror (listed_incremental_stream))
read_error (listed_incremental_option);
- if (buf)
- free (buf);
+ free (buf);
}
/* Output incremental data for the directory ENTRY to the file DATA.
{
const char *entry;
struct stat st;
- if (p)
- free (p);
+ free (p);
p = new_name (directory_name, cur);
- if (deref_stat (false, p, &st))
+ if (deref_stat (p, &st) != 0)
{
if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
dirs and check it here? */