Version 1.20.
* configure.ac: Raise version number to 1.20 * src/compare.c (diff_dumpdir): const. * src/common.h (dumpdir_t,dumpdir_iter_t): New data types. (dumpdir_create0,dumpdir_create,dumpdir_free,dumpdir_locate) (dumpdir_first,dumpdir_next): New functions. * src/incremen.c (dumpdir_create0,dumpdir_create,dumpdir_free) (dumpdir_first,dumpdir_next): New functions. (dumpdir_locate): Rewrite using binary search. (struct directory): Change members char *contents, *icontents to struct dumpdir *dump, *idump. All references updated. (note_directory): Last arg is const. * src/names.c (add_hierarchy_to_namelist): buffer is const. * tests/incr03.at, tests/incr04.at, tests/rename02.at, tests/rename03.at: Insert calls to sleep between creation of files and adding them to the archive.
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
# 02110-1301, USA.
|
# 02110-1301, USA.
|
||||||
|
|
||||||
AC_INIT([GNU tar], [1.19.90], [bug-tar@gnu.org])
|
AC_INIT([GNU tar], [1.20], [bug-tar@gnu.org])
|
||||||
AC_CONFIG_SRCDIR([src/tar.c])
|
AC_CONFIG_SRCDIR([src/tar.c])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_HEADERS([config.h:config.hin])
|
AC_CONFIG_HEADERS([config.h:config.hin])
|
||||||
|
|||||||
14
src/common.h
14
src/common.h
@@ -1,7 +1,7 @@
|
|||||||
/* Common declarations for the tar program.
|
/* Common declarations for the tar program.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@@ -489,8 +489,18 @@ bool rename_directory (char *src, char *dst);
|
|||||||
void delete_archive_members (void);
|
void delete_archive_members (void);
|
||||||
|
|
||||||
/* Module incremen.c. */
|
/* Module incremen.c. */
|
||||||
|
typedef struct dumpdir *dumpdir_t;
|
||||||
|
typedef struct dumpdir_iter *dumpdir_iter_t;
|
||||||
|
|
||||||
char *get_directory_contents (char *dir_name, dev_t device);
|
dumpdir_t dumpdir_create0 (const char *contents, const char *cmask);
|
||||||
|
dumpdir_t dumpdir_create (const char *contents);
|
||||||
|
void dumpdir_free (dumpdir_t);
|
||||||
|
char *dumpdir_locate (dumpdir_t dump, const char *name);
|
||||||
|
char *dumpdir_next (dumpdir_iter_t itr);
|
||||||
|
char *dumpdir_first (dumpdir_t dump, int all, dumpdir_iter_t *pitr);
|
||||||
|
|
||||||
|
|
||||||
|
const char *get_directory_contents (char *dir_name, dev_t device);
|
||||||
const char *append_incremental_renames (const char *dump);
|
const char *append_incremental_renames (const char *dump);
|
||||||
void read_directory_file (void);
|
void read_directory_file (void);
|
||||||
void write_directory_file (void);
|
void write_directory_file (void);
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ dumpdir_cmp (const char *a, const char *b)
|
|||||||
static void
|
static void
|
||||||
diff_dumpdir (void)
|
diff_dumpdir (void)
|
||||||
{
|
{
|
||||||
char *dumpdir_buffer;
|
const char *dumpdir_buffer;
|
||||||
dev_t dev = 0;
|
dev_t dev = 0;
|
||||||
struct stat stat_data;
|
struct stat stat_data;
|
||||||
|
|
||||||
|
|||||||
254
src/incremen.c
254
src/incremen.c
@@ -1,7 +1,7 @@
|
|||||||
/* GNU dump extensions to tar.
|
/* GNU dump extensions to tar.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@@ -49,14 +49,22 @@ enum children
|
|||||||
#define DIR_SET_FLAG(d,f) (d)->flags |= (f)
|
#define DIR_SET_FLAG(d,f) (d)->flags |= (f)
|
||||||
#define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
|
#define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
|
||||||
|
|
||||||
|
struct dumpdir /* Dump directory listing */
|
||||||
|
{
|
||||||
|
char *contents; /* Actual contents */
|
||||||
|
size_t total; /* Total number of elements */
|
||||||
|
size_t elc; /* Number of D/N/Y elements. */
|
||||||
|
char **elv; /* Array of D/N/Y elements */
|
||||||
|
};
|
||||||
|
|
||||||
/* Directory attributes. */
|
/* Directory attributes. */
|
||||||
struct directory
|
struct directory
|
||||||
{
|
{
|
||||||
struct timespec mtime; /* Modification time */
|
struct timespec mtime; /* Modification time */
|
||||||
dev_t device_number; /* device number for directory */
|
dev_t device_number; /* device number for directory */
|
||||||
ino_t inode_number; /* inode number for directory */
|
ino_t inode_number; /* inode number for directory */
|
||||||
char *contents; /* Directory contents */
|
struct dumpdir *dump; /* Directory contents */
|
||||||
char *icontents; /* Initial contents if the directory was
|
struct dumpdir *idump; /* Initial contents if the directory was
|
||||||
rescanned */
|
rescanned */
|
||||||
enum children children; /* What to save under this directory */
|
enum children children; /* What to save under this directory */
|
||||||
unsigned flags; /* See DIRF_ macros above */
|
unsigned flags; /* See DIRF_ macros above */
|
||||||
@@ -67,6 +75,127 @@ struct directory
|
|||||||
char name[1]; /* file name of directory */
|
char name[1]; /* file name of directory */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dumpdir *
|
||||||
|
dumpdir_create0 (const char *contents, const char *cmask)
|
||||||
|
{
|
||||||
|
struct dumpdir *dump;
|
||||||
|
size_t i, total, ctsize, len;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
for (i = 0, total = 0, ctsize = 1, p = contents; *p; total++, p += len)
|
||||||
|
{
|
||||||
|
len = strlen (p) + 1;
|
||||||
|
ctsize += len;
|
||||||
|
if (!cmask || strchr (cmask, *p))
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dump = xmalloc (sizeof (*dump) + ctsize);
|
||||||
|
dump->contents = (char*)(dump + 1);
|
||||||
|
memcpy (dump->contents, contents, ctsize);
|
||||||
|
dump->total = total;
|
||||||
|
dump->elc = i;
|
||||||
|
dump->elv = xcalloc (i + 1, sizeof (dump->elv[0]));
|
||||||
|
|
||||||
|
for (i = 0, p = dump->contents; *p; p += strlen (p) + 1)
|
||||||
|
{
|
||||||
|
if (!cmask || strchr (cmask, *p))
|
||||||
|
dump->elv[i++] = p + 1;
|
||||||
|
}
|
||||||
|
dump->elv[i] = NULL;
|
||||||
|
return dump;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dumpdir *
|
||||||
|
dumpdir_create (const char *contents)
|
||||||
|
{
|
||||||
|
return dumpdir_create0 (contents, "YND");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dumpdir_free (struct dumpdir *dump)
|
||||||
|
{
|
||||||
|
free (dump->elv);
|
||||||
|
free (dump);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_dirnames (const void *first, const void *second)
|
||||||
|
{
|
||||||
|
char const *const *name1 = first;
|
||||||
|
char const *const *name2 = second;
|
||||||
|
return strcmp (*name1, *name2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate NAME in the dumpdir array DUMP.
|
||||||
|
Return pointer to the slot in DUMP->contents, or NULL if not found */
|
||||||
|
char *
|
||||||
|
dumpdir_locate (struct dumpdir *dump, const char *name)
|
||||||
|
{
|
||||||
|
char **ptr;
|
||||||
|
if (!dump)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ptr = bsearch (&name, dump->elv, dump->elc, sizeof (dump->elv[0]),
|
||||||
|
compare_dirnames);
|
||||||
|
return ptr ? *ptr - 1: NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dumpdir_iter
|
||||||
|
{
|
||||||
|
struct dumpdir *dump; /* Dumpdir being iterated */
|
||||||
|
int all; /* Iterate over all entries, not only D/N/Y */
|
||||||
|
size_t next; /* Index of the next element */
|
||||||
|
};
|
||||||
|
|
||||||
|
char *
|
||||||
|
dumpdir_next (struct dumpdir_iter *itr)
|
||||||
|
{
|
||||||
|
size_t cur = itr->next;
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
if (itr->all)
|
||||||
|
{
|
||||||
|
ret = itr->dump->contents + cur;
|
||||||
|
if (*ret == 0)
|
||||||
|
return NULL;
|
||||||
|
itr->next += strlen (ret) + 1;
|
||||||
|
}
|
||||||
|
else if (cur < itr->dump->elc)
|
||||||
|
{
|
||||||
|
ret = itr->dump->elv[cur] - 1;
|
||||||
|
itr->next++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
|
||||||
|
{
|
||||||
|
struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
|
||||||
|
itr->dump = dump;
|
||||||
|
itr->all = all;
|
||||||
|
itr->next = 0;
|
||||||
|
*pitr = itr;
|
||||||
|
return dumpdir_next (itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Hash_table *directory_table;
|
static Hash_table *directory_table;
|
||||||
static Hash_table *directory_meta_table;
|
static Hash_table *directory_meta_table;
|
||||||
|
|
||||||
@@ -120,7 +249,7 @@ make_directory (const char *name)
|
|||||||
size_t namelen = strlen (name);
|
size_t namelen = strlen (name);
|
||||||
size_t size = offsetof (struct directory, name) + namelen + 1;
|
size_t size = offsetof (struct directory, name) + namelen + 1;
|
||||||
struct directory *directory = xmalloc (size);
|
struct directory *directory = xmalloc (size);
|
||||||
directory->contents = directory->icontents = NULL;
|
directory->dump = directory->idump = NULL;
|
||||||
directory->orig = NULL;
|
directory->orig = NULL;
|
||||||
directory->flags = false;
|
directory->flags = false;
|
||||||
strcpy (directory->name, name);
|
strcpy (directory->name, name);
|
||||||
@@ -136,7 +265,8 @@ make_directory (const char *name)
|
|||||||
found that the directory exists. */
|
found that the directory exists. */
|
||||||
static struct directory *
|
static struct directory *
|
||||||
note_directory (char const *name, struct timespec mtime,
|
note_directory (char const *name, struct timespec mtime,
|
||||||
dev_t dev, ino_t ino, bool nfs, bool found, char *contents)
|
dev_t dev, ino_t ino, bool nfs, bool found,
|
||||||
|
const char *contents)
|
||||||
{
|
{
|
||||||
struct directory *directory = make_directory (name);
|
struct directory *directory = make_directory (name);
|
||||||
|
|
||||||
@@ -149,13 +279,9 @@ note_directory (char const *name, struct timespec mtime,
|
|||||||
if (found)
|
if (found)
|
||||||
DIR_SET_FLAG (directory, DIRF_FOUND);
|
DIR_SET_FLAG (directory, DIRF_FOUND);
|
||||||
if (contents)
|
if (contents)
|
||||||
{
|
directory->dump = dumpdir_create (contents);
|
||||||
size_t size = dumpdir_size (contents);
|
|
||||||
directory->contents = xmalloc (size);
|
|
||||||
memcpy (directory->contents, contents, size);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
directory->contents = NULL;
|
directory->dump = NULL;
|
||||||
|
|
||||||
if (! ((directory_table
|
if (! ((directory_table
|
||||||
|| (directory_table = hash_initialize (0, 0,
|
|| (directory_table = hash_initialize (0, 0,
|
||||||
@@ -371,64 +497,15 @@ procdir (char *name_buffer, struct stat *stat_data,
|
|||||||
return directory;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_dirnames (const void *first, const void *second)
|
|
||||||
{
|
|
||||||
char const *const *name1 = first;
|
|
||||||
char const *const *name2 = second;
|
|
||||||
return strcmp (*name1, *name2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare dumpdir array from DIRECTORY with directory listing DIR and
|
/* Compare dumpdir array from DIRECTORY with directory listing DIR and
|
||||||
build a new dumpdir template.
|
build a new dumpdir template.
|
||||||
|
|
||||||
DIR must be returned by a previous call to savedir().
|
DIR must be returned by a previous call to savedir().
|
||||||
|
|
||||||
File names in DIRECTORY->contents must be sorted
|
File names in DIRECTORY->dump->contents must be sorted
|
||||||
alphabetically.
|
alphabetically.
|
||||||
|
|
||||||
DIRECTORY->contents is replaced with the created template. Each entry is
|
DIRECTORY->dump is replaced with the created template. Each entry is
|
||||||
prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
|
prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -440,15 +517,15 @@ makedumpdir (struct directory *directory, const char *dir)
|
|||||||
const char *p;
|
const char *p;
|
||||||
char const **array;
|
char const **array;
|
||||||
char *new_dump, *new_dump_ptr;
|
char *new_dump, *new_dump_ptr;
|
||||||
const char *dump;
|
struct dumpdir *dump;
|
||||||
|
|
||||||
if (directory->children == ALL_CHILDREN)
|
if (directory->children == ALL_CHILDREN)
|
||||||
dump = NULL;
|
dump = NULL;
|
||||||
else if (DIR_IS_RENAMED (directory))
|
else if (DIR_IS_RENAMED (directory))
|
||||||
dump = directory->orig->icontents ?
|
dump = directory->orig->idump ?
|
||||||
directory->orig->icontents : directory->orig->contents;
|
directory->orig->idump : directory->orig->dump;
|
||||||
else
|
else
|
||||||
dump = directory->contents;
|
dump = directory->dump;
|
||||||
|
|
||||||
/* Count the size of DIR and the number of elements it contains */
|
/* Count the size of DIR and the number of elements it contains */
|
||||||
dirsize = 0;
|
dirsize = 0;
|
||||||
@@ -476,11 +553,10 @@ makedumpdir (struct directory *directory, const char *dir)
|
|||||||
{
|
{
|
||||||
if (directory->tagfile)
|
if (directory->tagfile)
|
||||||
*new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
|
*new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
|
||||||
' ' : 'I';
|
' ' : 'I';
|
||||||
else
|
else
|
||||||
*new_dump_ptr = ' ';
|
*new_dump_ptr = ' ';
|
||||||
new_dump_ptr++;
|
new_dump_ptr++;
|
||||||
dump = loc + strlen (loc) + 1;
|
|
||||||
}
|
}
|
||||||
else if (directory->tagfile)
|
else if (directory->tagfile)
|
||||||
*new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
|
*new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
|
||||||
@@ -493,13 +569,13 @@ makedumpdir (struct directory *directory, const char *dir)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
*new_dump_ptr = 0;
|
*new_dump_ptr = 0;
|
||||||
directory->icontents = directory->contents;
|
directory->idump = directory->dump;
|
||||||
directory->contents = new_dump;
|
directory->dump = dumpdir_create0 (new_dump, NULL);
|
||||||
free (array);
|
free (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively scan the given directory. */
|
/* Recursively scan the given directory. */
|
||||||
static char *
|
static const char *
|
||||||
scan_directory (char *dir, dev_t device)
|
scan_directory (char *dir, dev_t device)
|
||||||
{
|
{
|
||||||
char *dirp = savedir (dir); /* for scanning directory */
|
char *dirp = savedir (dir); /* for scanning directory */
|
||||||
@@ -535,15 +611,17 @@ scan_directory (char *dir, dev_t device)
|
|||||||
|
|
||||||
if (dirp && directory->children != NO_CHILDREN)
|
if (dirp && directory->children != NO_CHILDREN)
|
||||||
{
|
{
|
||||||
char *entry; /* directory entry being scanned */
|
char *entry; /* directory entry being scanned */
|
||||||
size_t entrylen; /* length of directory entry */
|
size_t entrylen; /* length of directory entry */
|
||||||
|
dumpdir_iter_t itr;
|
||||||
|
|
||||||
makedumpdir (directory, dirp);
|
makedumpdir (directory, dirp);
|
||||||
|
|
||||||
for (entry = directory->contents;
|
for (entry = dumpdir_first (directory->dump, 1, &itr);
|
||||||
(entrylen = strlen (entry)) != 0;
|
entry;
|
||||||
entry += entrylen + 1)
|
entry = dumpdir_next (itr))
|
||||||
{
|
{
|
||||||
|
entrylen = strlen (entry);
|
||||||
if (name_buffer_size <= entrylen - 1 + name_length)
|
if (name_buffer_size <= entrylen - 1 + name_length)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
@@ -590,16 +668,17 @@ scan_directory (char *dir, dev_t device)
|
|||||||
*entry = 'Y';
|
*entry = 'Y';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free (itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (name_buffer);
|
free (name_buffer);
|
||||||
if (dirp)
|
if (dirp)
|
||||||
free (dirp);
|
free (dirp);
|
||||||
|
|
||||||
return directory->contents;
|
return directory->dump ? directory->dump->contents : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
const char *
|
||||||
get_directory_contents (char *dir, dev_t device)
|
get_directory_contents (char *dir, dev_t device)
|
||||||
{
|
{
|
||||||
return scan_directory (dir, device);
|
return scan_directory (dir, device);
|
||||||
@@ -1171,14 +1250,16 @@ write_directory_file_entry (void *entry, void *data)
|
|||||||
fwrite (s, strlen (s) + 1, 1, fp);
|
fwrite (s, strlen (s) + 1, 1, fp);
|
||||||
|
|
||||||
fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
|
fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
|
||||||
if (directory->contents)
|
if (directory->dump)
|
||||||
{
|
{
|
||||||
char *p;
|
const char *p;
|
||||||
for (p = directory->contents; *p; p += strlen (p) + 1)
|
dumpdir_iter_t itr;
|
||||||
{
|
|
||||||
if (strchr ("YND", *p))
|
for (p = dumpdir_first (directory->dump, 0, &itr);
|
||||||
fwrite (p, strlen (p) + 1, 1, fp);
|
p;
|
||||||
}
|
p = dumpdir_next (itr))
|
||||||
|
fwrite (p, strlen (p) + 1, 1, fp);
|
||||||
|
free (itr);
|
||||||
}
|
}
|
||||||
fwrite ("\0\0", 2, 1, fp);
|
fwrite ("\0\0", 2, 1, fp);
|
||||||
}
|
}
|
||||||
@@ -1366,6 +1447,7 @@ try_purge_directory (char const *directory_name)
|
|||||||
char *current_dir;
|
char *current_dir;
|
||||||
char *cur, *arc, *p;
|
char *cur, *arc, *p;
|
||||||
char *temp_stub = NULL;
|
char *temp_stub = NULL;
|
||||||
|
struct dumpdir *dump;
|
||||||
|
|
||||||
if (!is_dumpdir (¤t_stat_info))
|
if (!is_dumpdir (¤t_stat_info))
|
||||||
return false;
|
return false;
|
||||||
@@ -1442,6 +1524,7 @@ try_purge_directory (char const *directory_name)
|
|||||||
free (temp_stub);
|
free (temp_stub);
|
||||||
|
|
||||||
/* Process deletes */
|
/* Process deletes */
|
||||||
|
dump = dumpdir_create (current_stat_info.dumpdir);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
for (cur = current_dir; *cur; cur += strlen (cur) + 1)
|
for (cur = current_dir; *cur; cur += strlen (cur) + 1)
|
||||||
{
|
{
|
||||||
@@ -1463,7 +1546,7 @@ try_purge_directory (char const *directory_name)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(entry = dumpdir_locate (current_stat_info.dumpdir, cur))
|
if (!(entry = dumpdir_locate (dump, cur))
|
||||||
|| (*entry == 'D' && !S_ISDIR (st.st_mode))
|
|| (*entry == 'D' && !S_ISDIR (st.st_mode))
|
||||||
|| (*entry == 'Y' && S_ISDIR (st.st_mode)))
|
|| (*entry == 'Y' && S_ISDIR (st.st_mode)))
|
||||||
{
|
{
|
||||||
@@ -1489,6 +1572,7 @@ try_purge_directory (char const *directory_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (p);
|
free (p);
|
||||||
|
dumpdir_free (dump);
|
||||||
|
|
||||||
free (current_dir);
|
free (current_dir);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -734,7 +734,7 @@ static void
|
|||||||
add_hierarchy_to_namelist (struct name *name, dev_t device)
|
add_hierarchy_to_namelist (struct name *name, dev_t device)
|
||||||
{
|
{
|
||||||
char *file_name = name->name;
|
char *file_name = name->name;
|
||||||
char *buffer = get_directory_contents (file_name, device);
|
const char *buffer = get_directory_contents (file_name, device);
|
||||||
|
|
||||||
if (! buffer)
|
if (! buffer)
|
||||||
name->dir_contents = "\0\0\0\0";
|
name->dir_contents = "\0\0\0\0";
|
||||||
@@ -746,7 +746,7 @@ add_hierarchy_to_namelist (struct name *name, dev_t device)
|
|||||||
: NAME_FIELD_SIZE);
|
: NAME_FIELD_SIZE);
|
||||||
char *namebuf = xmalloc (allocated_length + 1);
|
char *namebuf = xmalloc (allocated_length + 1);
|
||||||
/* FIXME: + 2 above? */
|
/* FIXME: + 2 above? */
|
||||||
char *string;
|
const char *string;
|
||||||
size_t string_length;
|
size_t string_length;
|
||||||
int change_dir = name->change_dir;
|
int change_dir = name->change_dir;
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ mkdir directory
|
|||||||
genfile --file=directory/x
|
genfile --file=directory/x
|
||||||
genfile --file=directory/y
|
genfile --file=directory/y
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
tar -cf archive.1 -g db directory
|
tar -cf archive.1 -g db directory
|
||||||
|
|
||||||
mv directory/x directory/z
|
mv directory/x directory/z
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ awk 'BEGIN {
|
|||||||
printf("NAME_PREFIX[%03d]\n", i);
|
printf("NAME_PREFIX[%03d]\n", i);
|
||||||
}' < /dev/null | genfile --files-from -
|
}' < /dev/null | genfile --files-from -
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
echo "Initial dump"
|
echo "Initial dump"
|
||||||
tar cvf a0.tar -g a.sna a
|
tar cvf a0.tar -g a.sna a
|
||||||
mv a/b a/c
|
mv a/b a/c
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ genfile --file foo/bar/file.r
|
|||||||
mkdir foo/bar/baz
|
mkdir foo/bar/baz
|
||||||
genfile --file foo/bar/baz/file.z
|
genfile --file foo/bar/baz/file.z
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
echo "Creating base archive"
|
echo "Creating base archive"
|
||||||
tar -g incr -cf arch.1 -v foo
|
tar -g incr -cf arch.1 -v foo
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ genfile --file foo/b/fileb
|
|||||||
mkdir foo/c
|
mkdir foo/c
|
||||||
genfile --file foo/c/filec
|
genfile --file foo/c/filec
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
echo "First dump"
|
echo "First dump"
|
||||||
echo "First dump">&2
|
echo "First dump">&2
|
||||||
tar -g incr -cf arch.1 -v foo 2>tmperr
|
tar -g incr -cf arch.1 -v foo 2>tmperr
|
||||||
|
|||||||
Reference in New Issue
Block a user