#define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT)
#define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS)
#define DIR_IS_FOUND(d) ((d)->flags & DIRF_FOUND)
-#define DIR_IS_NEW(d) ((d)->flags & DIRF_NEW)
+/* #define DIR_IS_NEW(d) ((d)->flags & DIRF_NEW) FIXME: not used */
#define DIR_IS_RENAMED(d) ((d)->flags & DIRF_RENAMED)
#define DIR_SET_FLAG(d,f) (d)->flags |= (f)
char *name; /* file name of directory */
};
-struct dumpdir *
+static struct dumpdir *
dumpdir_create0 (const char *contents, const char *cmask)
{
struct dumpdir *dump;
return dump;
}
-struct dumpdir *
+static struct dumpdir *
dumpdir_create (const char *contents)
{
return dumpdir_create0 (contents, "YND");
}
-void
+static void
dumpdir_free (struct dumpdir *dump)
{
free (dump->elv);
/* Locate NAME in the dumpdir array DUMP.
Return pointer to the slot in DUMP->contents, or NULL if not found */
-char *
+static char *
dumpdir_locate (struct dumpdir *dump, const char *name)
{
char **ptr;
size_t next; /* Index of the next element */
};
-char *
+static char *
dumpdir_next (struct dumpdir_iter *itr)
{
size_t cur = itr->next;
return ret;
}
-char *
+static char *
dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
{
struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
}
void
-update_parent_directory (const char *name)
+update_parent_directory (struct tar_stat_info *parent)
{
- struct directory *directory;
- char *p;
-
- p = dir_name (name);
- directory = find_directory (p);
+ struct directory *directory = find_directory (parent->orig_file_name);
if (directory)
{
struct stat st;
- if (deref_stat (dereference_option, p, &st) != 0)
- {
- if (errno != ENOENT)
- stat_diag (directory->name);
- /* else: should have been already reported */
- }
+ if (fstat (parent->fd, &st) != 0)
+ stat_diag (directory->name);
else
directory->mtime = get_stat_mtime (&st);
}
- free (p);
}
#define PD_FORCE_CHILDREN 0x10
#define PD_CHILDREN(f) ((f) & 3)
static struct directory *
-procdir (const char *name_buffer, struct stat *stat_data,
- dev_t device,
+procdir (const char *name_buffer, struct tar_stat_info *st,
int flag,
char *entry)
{
struct directory *directory;
+ struct stat *stat_data = &st->stat;
+ dev_t device = st->parent ? st->parent->stat.st_dev : 0;
bool nfs = NFS_FILE_STAT (*stat_data);
if ((directory = find_directory (name_buffer)) != NULL)
{
const char *tag_file_name;
- switch (check_exclusion_tags (name_buffer, &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
free (array);
}
-/* Recursively scan the given directory DIR.
- DEVICE is the device number where DIR resides (for --one-file-system).
- If CMDLINE is true, the directory name was explicitly listed in the
- command line.
- Unless *PDIR is NULL, store there a pointer to the struct directory
- describing DIR. */
+/* Recursively scan the directory identified by ST. */
struct directory *
-scan_directory (char *dir, dev_t device, bool cmdline)
+scan_directory (struct tar_stat_info *st)
{
- char *dirp = savedir (dir); /* for scanning directory */
+ char const *dir = st->orig_file_name;
+ char *dirp = get_directory_entries (st);
+ dev_t device = st->stat.st_dev;
+ bool cmdline = ! st->parent;
namebuf_t nbuf;
char *tmp;
- struct stat stat_data;
struct directory *directory;
char ch;
tmp = xstrdup (dir);
zap_slashes (tmp);
- if (deref_stat (dereference_option, tmp, &stat_data))
- {
- dir_removed_diag (tmp, cmdline, stat_diag);
- free (tmp);
- free (dirp);
- return NULL;
- }
-
- directory = procdir (tmp, &stat_data, device,
+ directory = procdir (tmp, st,
(cmdline ? PD_FORCE_INIT : 0),
&ch);
if (dirp && directory->children != NO_CHILDREN)
{
char *entry; /* directory entry being scanned */
- dumpdir_iter_t itr;
+ struct dumpdir_iter *itr;
makedumpdir (directory, dirp);
*entry = 'N';
else
{
- if (deref_stat (dereference_option, full_name, &stat_data))
+ int fd = st->fd;
+ void (*diag) (char const *) = 0;
+ struct tar_stat_info stsub;
+ tar_stat_init (&stsub);
+
+ if (fd < 0)
{
- file_removed_diag (full_name, false, stat_diag);
- *entry = 'N';
- continue;
+ 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))
+ {
+ int subfd = subfile_open (st, entry + 1, open_read_flags);
+ if (subfd < 0)
+ diag = open_diag;
+ else
+ {
+ stsub.fd = subfd;
+ if (fstat (subfd, &stsub.stat) != 0)
+ diag = stat_diag;
+ }
}
- if (S_ISDIR (stat_data.st_mode))
+ if (diag)
+ {
+ file_removed_diag (full_name, false, diag);
+ *entry = 'N';
+ }
+ else if (S_ISDIR (stsub.stat.st_mode))
{
int pd_flag = 0;
if (!recursion_option)
else if (directory->children == ALL_CHILDREN)
pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
*entry = 'D';
- procdir (full_name, &stat_data, device, pd_flag, entry);
- }
- else if (one_file_system_option && device != stat_data.st_dev)
+ 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';
-
else if (*entry == 'Y')
/* New entry, skip further checks */;
-
/* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
-
- else if (OLDER_STAT_TIME (stat_data, m)
+ else if (OLDER_STAT_TIME (stsub.stat, m)
&& (!after_date_option
- || OLDER_STAT_TIME (stat_data, c)))
+ || OLDER_STAT_TIME (stsub.stat, c)))
*entry = 'N';
else
*entry = 'Y';
+
+ tar_stat_destroy (&stsub);
}
}
free (itr);
return ret ? ret : "\0\0\0\0";
}
-void
-name_fill_directory (struct name *name, dev_t device, bool cmdline)
-{
- name->directory = scan_directory (name->name, device, cmdline);
-}
-
\f
static void
obstack_code_rename (struct obstack *stk, char const *from, char const *to)
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 (directory->dump)
{
const char *p;
- dumpdir_iter_t itr;
+ struct dumpdir_iter *itr;
for (p = dumpdir_first (directory->dump, 0, &itr);
p;
to = archive_dir;
set_next_block_after (current_header);
- mv_begin (stat_info);
+ mv_begin_read (stat_info);
for (; size > 0; size -= copied)
{
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? */