#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_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_RENAMED(d) ((d)->flags & DIRF_RENAMED)
#define DIR_SET_FLAG(d,f) (d)->flags |= (f)
#define DIR_IS_RENAMED(d) ((d)->flags & DIRF_RENAMED)
#define DIR_SET_FLAG(d,f) (d)->flags |= (f)
dumpdir_create0 (const char *contents, const char *cmask)
{
struct dumpdir *dump;
size_t i, total, ctsize, len;
char *p;
const char *q;
dumpdir_create0 (const char *contents, const char *cmask)
{
struct dumpdir *dump;
size_t i, total, ctsize, len;
char *p;
const char *q;
for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
{
len = strlen (q) + 1;
for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
{
len = strlen (q) + 1;
dumpdir_create (const char *contents)
{
return dumpdir_create0 (contents, "YND");
}
dumpdir_create (const char *contents)
{
return dumpdir_create0 (contents, "YND");
}
/* Locate NAME in the dumpdir array DUMP.
Return pointer to the slot in DUMP->contents, or NULL if not found */
/* Locate NAME in the dumpdir array DUMP.
Return pointer to the slot in DUMP->contents, or NULL if not found */
dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
{
struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
{
struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
namelen--;
directory->name = xmalloc (namelen + 1);
memcpy (directory->name, name, namelen);
namelen--;
directory->name = xmalloc (namelen + 1);
memcpy (directory->name, name, namelen);
- 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);
/* With NFS, the same file can have two different devices
if an NFS directory is mounted in multiple locations,
which is relatively common when automounting.
To avoid spurious incremental redumping of
directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */
/* With NFS, the same file can have two different devices
if an NFS directory is mounted in multiple locations,
which is relatively common when automounting.
To avoid spurious incremental redumping of
directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */
if (! ((!check_device_option
|| (DIR_IS_NFS (directory) && nfs)
|| directory->device_number == stat_data->st_dev)
if (! ((!check_device_option
|| (DIR_IS_NFS (directory) && nfs)
|| directory->device_number == stat_data->st_dev)
DIR_SET_FLAG (directory, DIRF_FOUND);
}
else
{
struct directory *d = find_directory_meta (stat_data->st_dev,
stat_data->st_ino);
DIR_SET_FLAG (directory, DIRF_FOUND);
}
else
{
struct directory *d = find_directory_meta (stat_data->st_dev,
stat_data->st_ino);
directory = note_directory (name_buffer,
get_stat_mtime(stat_data),
stat_data->st_dev,
directory = note_directory (name_buffer,
get_stat_mtime(stat_data),
stat_data->st_dev,
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))
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))
DIR_SET_FLAG (directory, DIRF_INIT);
if (directory->children != NO_CHILDREN)
{
const char *tag_file_name;
DIR_SET_FLAG (directory, DIRF_INIT);
if (directory->children != NO_CHILDREN)
{
const char *tag_file_name;
case exclusion_tag_under:
exclusion_tag_warning (name_buffer, tag_file_name,
_("contents not dumped"));
directory->tagfile = tag_file_name;
break;
case exclusion_tag_under:
exclusion_tag_warning (name_buffer, tag_file_name,
_("contents not dumped"));
directory->tagfile = tag_file_name;
break;
DIRECTORY->dump is replaced with the created template. Each entry is
prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
DIRECTORY->dump is replaced with the created template. Each entry is
prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
-/* 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. */
- 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;
- 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;
+ }
- 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)
s = from[0] == 0 ? from :
safer_name_suffix (from, false, absolute_names_option);
s = from[0] == 0 ? from :
safer_name_suffix (from, false, absolute_names_option);