static tarlong prev_written; /* bytes written on previous volumes */
static tarlong bytes_written; /* bytes written on this volume */
static void *record_buffer[2]; /* allocated memory */
-static int record_index;
+static bool record_index;
/* FIXME: The following variables should ideally be static to this
module. However, this cannot be done yet. The cleanup continues! */
off_t continued_file_offset;
\f
-static int volno = 1; /* which volume of a multi-volume tape we're
+static intmax_t volno = 1; /* which volume of a multi-volume tape we're
on */
-static int global_volno = 1; /* volume number to print in external
- messages */
+static intmax_t global_volno = 1; /* volume number to print in external
+ messages */
bool write_archive_to_stdout;
/* This variable, when set, inhibits updating the bufmap chain after
a write. This is necessary when writing extended POSIX headers. */
-static int inhibit_map;
+static bool inhibit_map;
void
mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft)
static const char *
compress_option (enum compress_type type)
{
- struct zip_program const *zp;
int i = 0;
- zp = find_zip_program (type, &i);
+ struct zip_program const *zp = find_zip_program (type, &i);
return zp ? zp->option : NULL;
}
return archive;
}
\f
-static int
+static intmax_t
print_stats (FILE *fp, const char *text, tarlong numbytes)
{
char abbr[LONGEST_HUMAN_READABLE + 1];
int human_opts = human_autoscale | human_base_1024 | human_SI | human_B;
double ulim = UINTMAX_MAX + 1.0;
- int n = fprintf (fp, "%s: "TARLONG_FORMAT" (", gettext (text), numbytes);
+ intmax_t n = fprintf (fp, "%s: "TARLONG_FORMAT" (", gettext (text), numbytes);
if (numbytes < ulim)
- n += fprintf (fp, "%s", human_readable (numbytes, abbr, human_opts, 1, 1));
+ n = add_printf (n, fprintf (fp, "%s", human_readable (numbytes, abbr,
+ human_opts, 1, 1)));
else
- n += fprintf (fp, "%g", numbytes);
+ n = add_printf (n, fprintf (fp, "%g", numbytes));
if (!duration_ns)
- n += fprintf (fp, ")");
+ n = add_printf (n, ! (fputc (')', fp) < 0));
else
{
double rate = 1e9 * numbytes / duration_ns;
- if (rate < ulim)
- n += fprintf (fp, ", %s/s)",
- human_readable (rate, abbr, human_opts, 1, 1));
- else
- n += fprintf (fp, ", %g/s)", rate);
+ n = add_printf (n, (rate < ulim
+ ? fprintf (fp, ", %s/s)",
+ human_readable (rate, abbr, human_opts,
+ 1, 1))
+ : fprintf (fp, ", %g/s)", rate)));
}
return n;
EOR is a delimiter to output after each item (used only if deleting
from the archive), EOL is a delimiter to add at the end of the output
line. */
-int
-format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
+intmax_t
+format_total_stats (FILE *fp, char const *const *formats, char eor, char eol)
{
- int n;
+ intmax_t n;
switch (subcommand_option)
{
n = print_stats (fp, formats[TF_READ],
records_read * record_size);
- fputc (eor, fp);
- n++;
+ n = add_printf (n, ! (fputc (eor, fp) < 0));
- n += print_stats (fp, formats[TF_WRITE],
- prev_written + bytes_written);
+ n = add_printf (n, print_stats (fp, formats[TF_WRITE],
+ prev_written + bytes_written));
intmax_t deleted = ((records_read - records_skipped) * record_size
- (prev_written + bytes_written));
- n += fprintf (fp, "%c%s: %jd", eor, gettext (formats[TF_DELETED]),
- deleted);
+ n = add_printf (n, fprintf (fp, "%c%s: %jd", eor,
+ gettext (formats[TF_DELETED]), deleted));
}
break;
abort ();
}
if (eol)
- {
- fputc (eol, fp);
- n++;
- }
+ n = add_printf (n, ! (fputc (eol, fp) < 0));
return n;
}
tar_stat_destroy (¤t_stat_info);
- record_index = 0;
+ record_index = false;
init_buffer ();
/* When updating the archive, we start with reading. */
if (file)
{
- if (fscanf (file, "%d", &global_volno) != 1
+ if (fscanf (file, "%jd", &global_volno) != 1
|| global_volno < 0)
paxfatal (0, _("%s: contains invalid volume number"),
quotearg_colon (volno_file_option));
if (file)
{
- fprintf (file, "%d\n", global_volno);
+ fprintf (file, "%jd\n", global_volno);
if (ferror (file))
write_error (volno_file_option);
if (fclose (file) != 0)
increase_volume_number (void)
{
global_volno++;
- if (global_volno < 0)
- paxfatal (0, _("Volume number overflow"));
volno++;
}
{
fputc ('\007', stderr);
fprintf (stderr,
- _("Prepare volume #%d for %s and hit return: "),
+ _("Prepare volume #%jd for %s and hit return: "),
global_volno + 1, quote (*archive_name_cursor));
fflush (stderr);
}
/* We've hit the end of the old volume. Close it and open the next one.
- Return nonzero on success.
+ Return true on success.
*/
static bool
new_volume (enum access_mode mode)
{
static FILE *read_file;
- static int looped;
- int prompt;
+ static bool looped;
+ bool prompt;
+
+ if (global_volno == INTMAX_MAX)
+ paxfatal (0, _("Volume number overflow"));
if (!read_file && !info_script_option)
/* FIXME: if fopen is used, it will never be closed. */
if (archive_name_cursor == archive_name_array + archive_names)
{
archive_name_cursor = archive_name_array;
- looped = 1;
+ looped = true;
}
prompt = looped;
{
if (volno_file_option)
closeout_volume_number ();
- if (sys_exec_info_script (archive_name_cursor, global_volno+1))
+ if (sys_exec_info_script (archive_name_cursor, global_volno + 1))
paxfatal (0, _("%s command failed"), quote (info_script_option));
}
else
open_warn (*archive_name_cursor);
if (!verify_option && mode == ACCESS_WRITE && backup_option)
undo_last_backup ();
- prompt = 1;
+ prompt = true;
goto tryagain;
}
{
static char const VOL_SUFFIX[] = "Volume";
char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX
- + INT_BUFSIZE_BOUND (int) + 2);
- sprintf (s, "%s %s %d", volume_label_option, VOL_SUFFIX, volno);
+ + INT_BUFSIZE_BOUND (intmax_t) + 2);
+ sprintf (s, "%s %s %jd", volume_label_option, VOL_SUFFIX, volno);
_write_volume_label (s);
free (s);
}
record_index = !record_index;
init_buffer ();
- inhibit_map = 1;
+ inhibit_map = true;
if (volume_label_option)
add_volume_label ();
header = find_next_block ();
bufmap_reset (map, header - record_start);
bufsize = available_space_after (header);
- inhibit_map = 0;
+ inhibit_map = false;
while (bufsize < copy_size)
{
memcpy (header->buffer, copy_ptr, bufsize);
void set_start_time (void);
enum { TF_READ, TF_WRITE, TF_DELETED };
-int format_total_stats (FILE *fp, char const *const *formats, int eor, int eol);
+intmax_t format_total_stats (FILE *fp, char const *const *formats,
+ char eor, char eol);
void print_total_stats (void);
void mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft);
const char *first_decompress_program (int *pstate);
const char *next_decompress_program (int *pstate);
+/* Sum values returned by printf to estimate the total bytes output.
+ Estimate -1 if there was a problem, e.g., int overflow or I/O error. */
+COMMON_INLINE intmax_t
+add_printf (intmax_t a, intmax_t b)
+{
+ intmax_t sum;
+ return (a < 0) | (b < 0) | ckd_add (&sum, a, b) ? -1 : sum;
+}
+
/* Module create.c. */
enum dump_status
bool sys_get_archive_stat (void);
int sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st);
void sys_wait_command (void);
-int sys_exec_info_script (const char **archive_name, int volume_number);
+int sys_exec_info_script (const char **archive_name, intmax_t volume_number);
void sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
intmax_t checkpoint_number);