static bool check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) { if (!lseek_or_error (file, beg)) return false; while (beg < end) { size_t bytes_read; size_t rdsize = BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg; char diff_buffer[BLOCKSIZE]; bytes_read = safe_read (file->fd, diff_buffer, rdsize); if (bytes_read == SAFE_READ_ERROR) { read_diag_details (file->stat_info->orig_file_name, beg, rdsize); return false; } if (!zero_block_p (diff_buffer, bytes_read)) { char begbuf[INT_BUFSIZE_BOUND (off_t)]; report_difference (file->stat_info, _("File fragment at %s is not a hole"), offtostr (beg, begbuf)); return false; } beg += bytes_read; } return true; }
/* Read incremental snapshot format 2 */ static void read_incr_db_2 (void) { struct obstack stk; char offbuf[INT_BUFSIZE_BOUND (off_t)]; obstack_init (&stk); read_timespec (listed_incremental_stream, &newer_mtime_option); for (;;) { intmax_t i; struct timespec mtime; dev_t dev; ino_t ino; bool nfs; char *name; char *content; size_t s; if (! read_num (listed_incremental_stream, "nfs", 0, 1, &i)) return; /* Normal return */ nfs = i; read_timespec (listed_incremental_stream, &mtime); if (! read_num (listed_incremental_stream, "dev", TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), &i)) break; dev = i; if (! read_num (listed_incremental_stream, "ino", TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), &i)) break; ino = i; if (read_obstack (listed_incremental_stream, &stk, &s)) break; name = obstack_finish (&stk); while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1) ; if (getc (listed_incremental_stream) != 0) FATAL_ERROR ((0, 0, _("%s: byte %s: %s"), quotearg_colon (listed_incremental_option), offtostr (ftello (listed_incremental_stream), offbuf), _("Missing record terminator"))); content = obstack_finish (&stk); note_directory (name, mtime, dev, ino, nfs, false, content); obstack_free (&stk, content); } FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (listed_incremental_option), _("Unexpected EOF in snapshot file"))); }
static bool read_num (FILE *fp, char const *fieldname, intmax_t min_val, uintmax_t max_val, intmax_t *pval) { int i; char buf[INT_BUFSIZE_BOUND (intmax_t)]; char offbuf[INT_BUFSIZE_BOUND (off_t)]; char minbuf[INT_BUFSIZE_BOUND (intmax_t)]; char maxbuf[INT_BUFSIZE_BOUND (intmax_t)]; int conversion_errno; int c = getc (fp); bool negative = c == '-'; for (i = 0; (i == 0 && negative) || ISDIGIT (c); i++) { buf[i] = c; if (i == sizeof buf - 1) FATAL_ERROR ((0, 0, _("%s: byte %s: %s %.*s... too long"), quotearg_colon (listed_incremental_option), offtostr (ftello (fp), offbuf), fieldname, i + 1, buf)); c = getc (fp); } buf[i] = 0; if (c < 0) { if (ferror (fp)) read_fatal (listed_incremental_option); if (i != 0) FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (listed_incremental_option), _("Unexpected EOF in snapshot file"))); return false; } if (c) { unsigned uc = c; FATAL_ERROR ((0, 0, _("%s: byte %s: %s %s followed by invalid byte 0x%02x"), quotearg_colon (listed_incremental_option), offtostr (ftello (fp), offbuf), fieldname, buf, uc)); } *pval = strtosysint (buf, NULL, min_val, max_val); conversion_errno = errno; switch (conversion_errno) { case ERANGE: FATAL_ERROR ((0, conversion_errno, _("%s: byte %s: (valid range %s..%s)\n\t%s %s"), quotearg_colon (listed_incremental_option), offtostr (ftello (fp), offbuf), imaxtostr (min_val, minbuf), umaxtostr (max_val, maxbuf), fieldname, buf)); default: FATAL_ERROR ((0, conversion_errno, _("%s: byte %s: %s %s"), quotearg_colon (listed_incremental_option), offtostr (ftello (fp), offbuf), fieldname, buf)); case 0: break; } return true; }