X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fincremen.c;h=fcfdaa949321cba4cb99ad6fe4cd3cf44690fb62;hb=84a55f12e5880196623d4193bf1d7f5141e6b0d5;hp=564121796d7b2e8023c44580373e44c4f982fb63;hpb=1bcbbcf1ff2c537ffa970dbf82e3843d4ad110e5;p=chaz%2Ftar diff --git a/src/incremen.c b/src/incremen.c index 5641217..fcfdaa9 100644 --- a/src/incremen.c +++ b/src/incremen.c @@ -290,24 +290,6 @@ attach_directory (const char *name) } -static void -replace_prefix (char **pname, const char *samp, size_t slen, - const char *repl, size_t rlen) -{ - char *name = *pname; - size_t nlen = strlen (name); - if (nlen > slen && memcmp (name, samp, slen) == 0 && ISSLASH (name[slen])) - { - if (rlen > slen) - { - name = xrealloc (name, nlen - slen + rlen + 1); - *pname = name; - } - memmove (name + rlen, name + slen, nlen - slen + 1); - memcpy (name, repl, rlen); - } -} - void dirlist_replace_prefix (const char *pref, const char *repl) { @@ -389,28 +371,15 @@ remove_directory (const char *caname) } #endif -/* Find a directory entry for NAME. If first OLD_PREFIX_LEN - bytes of its name match OLD_PREFIX, replace them with - NEW_PREFIX. */ +/* If first OLD_PREFIX_LEN bytes of DIR->NAME name match OLD_PREFIX, + replace them with NEW_PREFIX. */ void -rebase_directory (const char *name, size_t old_prefix_len, - const char *old_prefix, - const char *new_prefix) +rebase_directory (struct directory *dir, + const char *old_prefix, size_t old_prefix_len, + const char *new_prefix, size_t new_prefix_len) { - struct directory *dir = find_directory (name); - if (dir) - { - size_t len = strlen (dir->name); - if (len > old_prefix_len - && memcmp (dir->name, old_prefix, old_prefix_len) == 0) - { - char *newp = xmalloc (len - old_prefix_len + strlen (new_prefix)); - strcpy (newp, new_prefix); - strcat (newp, dir->name + old_prefix_len); - free (dir->name); - dir->name = newp; - } - } + replace_prefix (&dir->name, old_prefix, old_prefix_len, + new_prefix, new_prefix_len); } /* Return a directory entry for a given combination of device and inode @@ -444,7 +413,11 @@ update_parent_directory (const char *name) { struct stat st; if (deref_stat (dereference_option, p, &st) != 0) - stat_diag (name); + { + if (errno != ENOENT) + stat_diag (directory->name); + /* else: should have been already reported */ + } else directory->mtime = get_stat_mtime (&st); } @@ -580,6 +553,12 @@ procdir (const char *name_buffer, struct stat *stat_data, 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; else if (flag & PD_FORCE_CHILDREN) { @@ -706,8 +685,10 @@ makedumpdir (struct directory *directory, const char *dir) /* 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. */ -const char * + command line. + Unless *PDIR is NULL, store there a pointer to the struct directory + describing DIR. */ +struct directory * scan_directory (char *dir, dev_t device, bool cmdline) { char *dirp = savedir (dir); /* for scanning directory */ @@ -728,10 +709,7 @@ scan_directory (char *dir, dev_t device, bool cmdline) if (deref_stat (dereference_option, name_buffer, &stat_data)) { - stat_diag (name_buffer); - /* FIXME: used to be - children = CHANGED_CHILDREN; - but changed to: */ + dir_removed_diag (name_buffer, cmdline, stat_diag); free (name_buffer); free (dirp); return NULL; @@ -740,7 +718,7 @@ scan_directory (char *dir, dev_t device, bool cmdline) directory = procdir (name_buffer, &stat_data, device, (cmdline ? PD_FORCE_INIT : 0), &ch); - + name_length = strlen (name_buffer); if (! ISSLASH (name_buffer[name_length - 1])) { @@ -779,7 +757,7 @@ scan_directory (char *dir, dev_t device, bool cmdline) { if (deref_stat (dereference_option, name_buffer, &stat_data)) { - stat_diag (name_buffer); + file_removed_diag (name_buffer, false, stat_diag); *entry = 'N'; continue; } @@ -818,13 +796,30 @@ scan_directory (char *dir, dev_t device, bool cmdline) if (dirp) free (dirp); - return directory->dump ? directory->dump->contents : NULL; + return directory; +} + +/* Return pointer to the contents of the directory DIR */ +const char * +directory_contents (struct directory *dir) +{ + if (!dir) + return NULL; + return dir->dump ? dir->dump->contents : NULL; } +/* A "safe" version of directory_contents, which never returns NULL. */ const char * -get_directory_contents (char *dir, dev_t device, bool force) +safe_directory_contents (struct directory *dir) +{ + const char *ret = directory_contents (dir); + return ret ? ret : "\0\0\0\0"; +} + +void +name_fill_directory (struct name *name, dev_t device, bool cmdline) { - return scan_directory (dir, device, force); + name->directory = scan_directory (name->name, device, cmdline); } @@ -887,17 +882,19 @@ store_rename (struct directory *dir, struct obstack *stk) } } -const char * -append_incremental_renames (const char *dump) +void +append_incremental_renames (struct directory *dir) { struct obstack stk; size_t size; struct directory *dp; + const char *dump; if (dirhead == NULL) - return dump; + return; obstack_init (&stk); + dump = directory_contents (dir); if (dump) { size = dumpdir_size (dump) - 1; @@ -912,11 +909,10 @@ append_incremental_renames (const char *dump) if (obstack_object_size (&stk) != size) { obstack_1grow (&stk, 0); - dump = obstack_finish (&stk); + dumpdir_free (dir->dump); + dir->dump = dumpdir_create (obstack_finish (&stk)); } - else - obstack_free (&stk, NULL); - return dump; + obstack_free (&stk, NULL); } @@ -1325,6 +1321,13 @@ read_directory_file (void) return; } + /* Consume the first name from the name list and reset the + list afterwards. This is done to change to the new + directory, if the first name is a chdir request (-C dir), + which is necessary to recreate absolute file names. */ + name_from_list (); + blank_name_list (); + if (0 < getline (&buf, &bufsize, listed_incremental_stream)) { char *ebuf;