- if (!fp)
- return;
- fgets (buf, sizeof (buf), fp);
-
- /* FIXME: Using after_date_option as a first time flag looks fairly
- dubious to me! So, using -N with incremental might be buggy just
- because of the next few lines. I saw a few unexplained, almost harsh
- advices, from other GNU people, about *not* using -N with incremental
- dumps, and here might lie (part of) the reason. */
- if (!after_date_option)
- {
- newer_mtime_option = atol (buf);
- after_date_option = 1;
- }
-
- while (fgets (buf, sizeof (buf), fp))
- {
- strp = &buf[strlen (buf)];
- if (strp[-1] == '\n')
- strp[-1] = '\0';
- /* FIXME: For files ending with an incomplete line, maybe a NUL might
- be missing, here... */
-
- strp = buf;
- device_number = atol (strp);
- while (ISDIGIT (*strp))
- strp++;
- inode_number = atol (strp);
- while (ISSPACE (*strp))
- strp++;
- while (ISDIGIT (*strp))
- strp++;
+
+ 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)
+ 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;
+ errno = 0;
+ u = strtoumax (buf_ns, &ebuf, 10);
+ if (!errno && BILLION <= u)
+ errno = ERANGE;
+ if (errno || buf_ns == ebuf)
+ {
+ ERROR ((0, errno, "%s:%ld: %s",
+ quotearg_colon (listed_incremental_option),
+ lineno,
+ _("Invalid time stamp")));
+ sec = TYPE_MINIMUM (time_t);
+ }
+ else
+ nsec = u;
+ }
+ else
+ {
+ /* pre-1 incremental format does not contain nanoseconds */
+ nsec = 0;
+ }
+ }
+ newer_mtime_option.tv_sec = sec;
+ newer_mtime_option.tv_nsec = nsec;
+
+
+ while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
+ {
+ dev_t dev;
+ ino_t ino;
+ bool nfs = buf[0] == '+';
+ char *strp = buf + nfs;
+ struct timespec mtime;
+
+ lineno++;
+
+ if (buf[n - 1] == '\n')
+ buf[n - 1] = '\0';
+
+ 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;
+ strp = ebuf;
+
+ errno = 0;
+ u = strtoumax (strp, &ebuf, 10);
+ if (!errno && BILLION <= u)
+ errno = ERANGE;
+ if (errno || strp == ebuf || *ebuf != ' ')
+ {
+ ERROR ((0, errno, "%s:%ld: %s",
+ quotearg_colon (listed_incremental_option), lineno,
+ _("Invalid modification time (nanoseconds)")));
+ nsec = -1;
+ }
+ else
+ nsec = u;
+ mtime.tv_sec = sec;
+ mtime.tv_nsec = nsec;
+ strp = ebuf;
+ }
+ else
+ memset (&mtime, 0, sizeof mtime);
+
+ 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;
+ strp = ebuf;
+
+ 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;
+ strp = ebuf;
+