}
\f
-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)
{
}
#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
{
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);
}
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)
{
/* 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 */
- char *name_buffer; /* directory, `/', and directory member */
- size_t name_buffer_size; /* allocated size of name_buffer, minus 2 */
- size_t name_length; /* used length in name_buffer */
+ namebuf_t nbuf;
+ char *tmp;
struct stat stat_data;
struct directory *directory;
char ch;
if (! dirp)
savedir_error (dir);
- name_buffer_size = strlen (dir) + NAME_FIELD_SIZE;
- name_buffer = xmalloc (name_buffer_size + 2);
- strcpy (name_buffer, dir);
- zap_slashes (name_buffer);
+ tmp = xstrdup (dir);
+ zap_slashes (tmp);
- if (deref_stat (dereference_option, name_buffer, &stat_data))
+ if (deref_stat (dereference_option, tmp, &stat_data))
{
- stat_diag (name_buffer);
- /* FIXME: used to be
- children = CHANGED_CHILDREN;
- but changed to: */
- free (name_buffer);
+ dir_removed_diag (tmp, cmdline, stat_diag);
+ free (tmp);
free (dirp);
return NULL;
}
- directory = procdir (name_buffer, &stat_data, device,
+ directory = procdir (tmp, &stat_data, device,
(cmdline ? PD_FORCE_INIT : 0),
&ch);
-
- name_length = strlen (name_buffer);
- if (! ISSLASH (name_buffer[name_length - 1]))
- {
- name_buffer[name_length] = DIRECTORY_SEPARATOR;
- /* name_buffer has been allocated an extra slot */
- name_buffer[++name_length] = 0;
- }
+
+ free (tmp);
+
+ nbuf = namebuf_create (dir);
if (dirp && directory->children != NO_CHILDREN)
{
char *entry; /* directory entry being scanned */
- size_t entrylen; /* length of directory entry */
dumpdir_iter_t itr;
makedumpdir (directory, dirp);
entry;
entry = dumpdir_next (itr))
{
- entrylen = strlen (entry);
- if (name_buffer_size <= entrylen - 1 + name_length)
- {
- do
- name_buffer_size += NAME_FIELD_SIZE;
- while (name_buffer_size <= entrylen - 1 + name_length);
- name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
- }
- strcpy (name_buffer + name_length, entry + 1);
+ char *full_name = namebuf_name (nbuf, entry + 1);
if (*entry == 'I') /* Ignored entry */
*entry = 'N';
- else if (excluded_name (name_buffer))
+ else if (excluded_name (full_name))
*entry = 'N';
else
{
- if (deref_stat (dereference_option, name_buffer, &stat_data))
+ if (deref_stat (dereference_option, full_name, &stat_data))
{
- stat_diag (name_buffer);
+ file_removed_diag (full_name, false, stat_diag);
*entry = 'N';
continue;
}
else if (directory->children == ALL_CHILDREN)
pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
*entry = 'D';
- procdir (name_buffer, &stat_data, device, pd_flag, entry);
+ procdir (full_name, &stat_data, device, pd_flag, entry);
}
else if (one_file_system_option && device != stat_data.st_dev)
free (itr);
}
- free (name_buffer);
+ namebuf_free (nbuf);
+
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)
{
- return scan_directory (dir, device, force);
+ 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)
+{
+ name->directory = scan_directory (name->name, device, cmdline);
}
\f
}
}
-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;
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);
}
\f
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;