X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fincremen.c;h=d5bc1e41d88fa6c0d8067da6d27a62f6a60e3774;hb=4ac671c49ba5df93c2f386bc8d7dbe50f4671a57;hp=c6d4f4c5849a2ecdb5e9633a36e718c95e195f93;hpb=8da503cad6e883b30c05749149084d24319063b4;p=chaz%2Ftar diff --git a/src/incremen.c b/src/incremen.c index c6d4f4c..d5bc1e4 100644 --- a/src/incremen.c +++ b/src/incremen.c @@ -300,6 +300,24 @@ dirlist_replace_prefix (const char *pref, const char *repl) 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 @@ -327,7 +345,8 @@ note_directory (char const *name, struct timespec mtime, 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 (); @@ -408,7 +427,7 @@ update_parent_directory (struct tar_stat_info *parent) 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); @@ -426,9 +445,9 @@ procdir (const char *name_buffer, struct tar_stat_info *st, { 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); - + bool perhaps_renamed = false; + if ((directory = find_directory (name_buffer)) != NULL) { if (DIR_IS_INITED (directory)) @@ -482,9 +501,7 @@ procdir (const char *name_buffer, struct tar_stat_info *st, } 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; @@ -540,18 +557,23 @@ procdir (const char *name_buffer, struct tar_stat_info *st, } } - /* 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); @@ -559,6 +581,11 @@ procdir (const char *name_buffer, struct tar_stat_info *st, *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) @@ -783,8 +810,7 @@ scan_directory (struct tar_stat_info *st) namebuf_free (nbuf); - if (dirp) - free (dirp); + free (dirp); return directory; } @@ -834,7 +860,7 @@ store_rename (struct directory *dir, struct obstack *stk) 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); @@ -890,7 +916,8 @@ append_incremental_renames (struct directory *dir) 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); @@ -1351,8 +1378,7 @@ read_directory_file (void) 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. @@ -1663,11 +1689,10 @@ try_purge_directory (char const *directory_name) { 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? */