+void
+update_parent_directory (const char *name)
+{
+ struct directory *directory;
+ char *p;
+
+ p = dir_name (name);
+ directory = find_directory (p);
+ if (directory)
+ {
+ struct stat st;
+ if (deref_stat (dereference_option, p, &st) != 0)
+ stat_diag (name);
+ else
+ directory->mtime = get_stat_mtime (&st);
+ }
+ free (p);
+}
+
+static struct directory *
+procdir (char *name_buffer, struct stat *stat_data,
+ dev_t device,
+ enum children children,
+ bool verbose)
+{
+ struct directory *directory;
+ bool nfs = NFS_FILE_STAT (*stat_data);
+
+ if ((directory = find_directory (name_buffer)) != NULL)
+ {
+ if (DIR_IS_INITED (directory))
+ return directory;
+
+ /* 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 (! (((DIR_IS_NFS (directory) & nfs)
+ || directory->device_number == stat_data->st_dev)
+ && directory->inode_number == stat_data->st_ino))
+ {
+ /* FIXME: find_directory_meta ignores nfs */
+ struct directory *d = find_directory_meta (stat_data->st_dev,
+ stat_data->st_ino);
+ if (d)
+ {
+ if (verbose_option)
+ WARN ((0, 0, _("%s: Directory has been renamed from %s"),
+ quotearg_colon (name_buffer),
+ quote_n (1, d->name)));
+ directory->orig = d;
+ DIR_SET_FLAG (directory, DIRF_RENAMED);
+ directory->children = CHANGED_CHILDREN;
+ }
+ else
+ {
+ if (verbose_option)
+ WARN ((0, 0, _("%s: Directory has been renamed"),
+ quotearg_colon (name_buffer)));
+ directory->children = ALL_CHILDREN;
+ directory->device_number = stat_data->st_dev;
+ directory->inode_number = stat_data->st_ino;
+ }
+ if (nfs)
+ DIR_SET_FLAG (directory, DIRF_NFS);
+ }
+ else
+ directory->children = CHANGED_CHILDREN;
+
+ 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,
+ stat_data->st_ino,
+ nfs,
+ true,
+ NULL);
+
+ if (d)
+ {
+ if (verbose)
+ WARN ((0, 0, _("%s: Directory has been renamed from %s"),
+ quotearg_colon (name_buffer),
+ quote_n (1, d->name)));
+ directory->orig = d;
+ DIR_SET_FLAG (directory, DIRF_RENAMED);
+ directory->children = CHANGED_CHILDREN;
+ }
+ else
+ {
+ DIR_SET_FLAG (directory, DIRF_NEW);
+ if (verbose)
+ WARN ((0, 0, _("%s: Directory is new"),
+ quotearg_colon (name_buffer)));
+ directory->children =
+ (listed_incremental_option
+ || (OLDER_STAT_TIME (*stat_data, m)
+ || (after_date_option
+ && OLDER_STAT_TIME (*stat_data, c))))
+ ? ALL_CHILDREN
+ : CHANGED_CHILDREN;
+ }
+ }
+
+ /* 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))
+ directory->children = NO_CHILDREN;
+ else if (children == ALL_CHILDREN)
+ directory->children = ALL_CHILDREN;
+
+ DIR_SET_FLAG (directory, DIRF_INIT);
+
+ return directory;
+}
+
+/* Locate NAME in the dumpdir array DUMP.
+ Return pointer to the slot in the array, or NULL if not found */
+const char *
+dumpdir_locate (const char *dump, const char *name)
+{
+ if (dump)
+ while (*dump)
+ {
+ /* Ignore 'R' (rename) and 'X' (tempname) entries, since they break
+ alphabetical ordering.
+ They normally do not occur in dumpdirs from the snapshot files,
+ but this function is also used by purge_directory, which operates
+ on a dumpdir from the archive, hence the need for this test. */
+ if (!strchr ("RX", *dump))
+ {
+ int rc = strcmp (dump + 1, name);
+ if (rc == 0)
+ return dump;
+ if (rc > 1)
+ break;
+ }
+ dump += strlen (dump) + 1;
+ }
+ return NULL;
+}
+
+/* Return size in bytes of the dumpdir array P */
+size_t
+dumpdir_size (const char *p)
+{
+ size_t totsize = 0;
+
+ while (*p)
+ {
+ size_t size = strlen (p) + 1;
+ totsize += size;
+ p += size;
+ }
+ return totsize + 1;
+}
+