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
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 ();
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);
{
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)
{
}
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;
stat_data->st_ino);
directory = note_directory (name_buffer,
- get_stat_mtime(stat_data),
+ get_stat_mtime (stat_data),
stat_data->st_dev,
stat_data->st_ino,
nfs,
}
}
- /* 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);
*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)
namebuf_free (nbuf);
- if (dirp)
- free (dirp);
+ free (dirp);
return directory;
}
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);
{
int n;
uintmax_t u;
- time_t sec;
- long int nsec;
char *buf = NULL;
size_t bufsize = 0;
char *ebuf;
bufsize = strlen (buf) + 1;
}
- sec = TYPE_MINIMUM (time_t);
- nsec = -1;
- errno = 0;
- u = strtoumax (buf, &ebuf, 10);
- if (!errno && TYPE_MAXIMUM (time_t) < u)
- errno = ERANGE;
- if (errno || buf == ebuf)
+ newer_mtime_option = decode_timespec (buf, &ebuf, false);
+
+ if (! valid_timespec (newer_mtime_option))
ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option),
lineno,
_("Invalid time stamp")));
else
{
- sec = u;
-
if (version == 1 && *ebuf)
{
char const *buf_ns = ebuf + 1;
quotearg_colon (listed_incremental_option),
lineno,
_("Invalid time stamp")));
- sec = TYPE_MINIMUM (time_t);
+ newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
+ newer_mtime_option.tv_nsec = -1;
}
else
- nsec = u;
- }
- else
- {
- /* pre-1 incremental format does not contain nanoseconds */
- nsec = 0;
+ newer_mtime_option.tv_nsec = u;
}
}
- newer_mtime_option.tv_sec = sec;
- newer_mtime_option.tv_nsec = nsec;
-
while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
{
if (version == 1)
{
- errno = 0;
- u = strtoumax (strp, &ebuf, 10);
- if (!errno && TYPE_MAXIMUM (time_t) < u)
- errno = ERANGE;
- if (errno || strp == ebuf || *ebuf != ' ')
- {
- ERROR ((0, errno, "%s:%ld: %s",
- quotearg_colon (listed_incremental_option), lineno,
- _("Invalid modification time (seconds)")));
- sec = (time_t) -1;
- }
- else
- sec = u;
+ mtime = decode_timespec (strp, &ebuf, false);
strp = ebuf;
+ if (!valid_timespec (mtime) || *strp != ' ')
+ ERROR ((0, errno, "%s:%ld: %s",
+ quotearg_colon (listed_incremental_option), lineno,
+ _("Invalid modification time")));
errno = 0;
u = strtoumax (strp, &ebuf, 10);
ERROR ((0, errno, "%s:%ld: %s",
quotearg_colon (listed_incremental_option), lineno,
_("Invalid modification time (nanoseconds)")));
- nsec = -1;
+ mtime.tv_nsec = -1;
}
else
- nsec = u;
- mtime.tv_sec = sec;
- mtime.tv_nsec = nsec;
+ mtime.tv_nsec = u;
strp = ebuf;
}
else
- memset (&mtime, 0, sizeof mtime);
+ mtime.tv_sec = mtime.tv_nsec = 0;
- errno = 0;
- u = strtoumax (strp, &ebuf, 10);
- if (!errno && TYPE_MAXIMUM (dev_t) < u)
- errno = ERANGE;
- if (errno || strp == ebuf || *ebuf != ' ')
- {
- ERROR ((0, errno, "%s:%ld: %s",
- quotearg_colon (listed_incremental_option), lineno,
- _("Invalid device number")));
- dev = (dev_t) -1;
- }
- else
- dev = u;
+ dev = strtosysint (strp, &ebuf,
+ TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t));
strp = ebuf;
+ if (errno || *strp != ' ')
+ ERROR ((0, errno, "%s:%ld: %s",
+ quotearg_colon (listed_incremental_option), lineno,
+ _("Invalid device number")));
- errno = 0;
- u = strtoumax (strp, &ebuf, 10);
- if (!errno && TYPE_MAXIMUM (ino_t) < u)
- errno = ERANGE;
- if (errno || strp == ebuf || *ebuf != ' ')
- {
- ERROR ((0, errno, "%s:%ld: %s",
- quotearg_colon (listed_incremental_option), lineno,
- _("Invalid inode number")));
- ino = (ino_t) -1;
- }
- else
- ino = u;
+ ino = strtosysint (strp, &ebuf,
+ TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t));
strp = ebuf;
+ if (errno || *strp != ' ')
+ ERROR ((0, errno, "%s:%ld: %s",
+ quotearg_colon (listed_incremental_option), lineno,
+ _("Invalid inode number")));
strp++;
unquote_string (strp);
}
/* Read from file FP a nul-terminated string and convert it to
- uintmax_t. Return the resulting value in PVAL. Assume C has
- already been read.
+ uintmax_t. Return an intmax_t representation of the resulting
+ value in PVAL. Assume C has already been read.
Throw a fatal error if the string cannot be converted or if the
converted value exceeds MAX_VAL.
Return the last character read or EOF on end of file. */
static int
-read_unsigned_num (int c, FILE *fp, uintmax_t max_val, uintmax_t *pval)
+read_unsigned_num (int c, FILE *fp, uintmax_t max_val, intmax_t *pval)
{
size_t i;
+ uintmax_t u;
char buf[UINTMAX_STRSIZE_BOUND], *ep;
for (i = 0; ISDIGIT (c); i++)
buf[i] = 0;
errno = 0;
- *pval = strtoumax (buf, &ep, 10);
- if (c || errno || max_val < *pval)
+ u = strtoumax (buf, &ep, 10);
+ if (c || errno || max_val < u)
FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
+ *pval = represent_uintmax (u);
return c;
}
/* Read from file FP a nul-terminated string and convert it to
- uintmax_t. Return the resulting value in PVAL.
+ an integer in the range MIN_VAL..MAXVAL. Return the resulting
+ value, converted to intmax_t, in PVAL. MINVAL must be nonpositive.
Throw a fatal error if the string cannot be converted or if the
- converted value exceeds MAX_VAL.
+ converted value is out of range.
Return the last character read or EOF on end of file. */
static int
-read_num (FILE *fp, uintmax_t max_val, uintmax_t *pval)
+read_num (FILE *fp, intmax_t min_val, uintmax_t max_val, intmax_t *pval)
{
- return read_unsigned_num (getc (fp), fp, max_val, pval);
+ int c = getc (fp);
+ if (c == '-')
+ {
+ read_negative_num (fp, min_val, pval);
+ return 0;
+ }
+ return read_unsigned_num (c, fp, max_val, pval);
}
/* Read from FP two NUL-terminated strings representing a struct
static void
read_timespec (FILE *fp, struct timespec *pval)
{
- int c = getc (fp);
intmax_t i;
- uintmax_t u;
-
- if (c == '-')
- {
- read_negative_num (fp, TYPE_MINIMUM (time_t), &i);
- c = 0;
- pval->tv_sec = i;
- }
- else
- {
- c = read_unsigned_num (c, fp, TYPE_MAXIMUM (time_t), &u);
- pval->tv_sec = u;
- }
+ int c = read_num (fp, TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t), &i);
+ pval->tv_sec = i;
- if (c || read_num (fp, BILLION - 1, &u))
+ if (c || read_num (fp, 0, BILLION - 1, &i))
FATAL_ERROR ((0, 0, "%s: %s",
quotearg_colon (listed_incremental_option),
_("Unexpected EOF in snapshot file")));
- pval->tv_nsec = u;
+ pval->tv_nsec = i;
}
/* Read incremental snapshot format 2 */
static void
read_incr_db_2 (void)
{
- uintmax_t u;
struct obstack stk;
obstack_init (&stk);
for (;;)
{
+ intmax_t i;
struct timespec mtime;
dev_t dev;
ino_t ino;
char *content;
size_t s;
- if (read_num (listed_incremental_stream, 1, &u))
+ if (read_num (listed_incremental_stream, 0, 1, &i))
return; /* Normal return */
- nfs = u;
+ nfs = i;
read_timespec (listed_incremental_stream, &mtime);
- if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u))
+ if (read_num (listed_incremental_stream,
+ TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), &i))
break;
- dev = u;
+ dev = i;
- if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u))
+ if (read_num (listed_incremental_stream,
+ TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), &i))
break;
- ino = u;
+ ino = i;
if (read_obstack (listed_incremental_stream, &stk, &s))
break;
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.
if (DIR_IS_FOUND (directory))
{
- char buf[UINTMAX_STRSIZE_BOUND];
+ char buf[max (SYSINT_BUFSIZE, INT_BUFSIZE_BOUND (intmax_t))];
char const *s;
s = DIR_IS_NFS (directory) ? "1" : "0";
fwrite (s, 2, 1, fp);
- s = (TYPE_SIGNED (time_t)
- ? imaxtostr (directory->mtime.tv_sec, buf)
- : umaxtostr (directory->mtime.tv_sec, buf));
+ s = sysinttostr (directory->mtime.tv_sec, TYPE_MINIMUM (time_t),
+ TYPE_MAXIMUM (time_t), buf);
fwrite (s, strlen (s) + 1, 1, fp);
- s = umaxtostr (directory->mtime.tv_nsec, buf);
+ s = imaxtostr (directory->mtime.tv_nsec, buf);
fwrite (s, strlen (s) + 1, 1, fp);
- s = umaxtostr (directory->device_number, buf);
+ s = sysinttostr (directory->device_number,
+ TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
fwrite (s, strlen (s) + 1, 1, fp);
- s = umaxtostr (directory->inode_number, buf);
+ s = sysinttostr (directory->inode_number,
+ TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf);
fwrite (s, strlen (s) + 1, 1, fp);
fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
{
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? */