int pathcmp(const char *a, const char *b);
void safe_fprintf(FILE *, const char *fmt, ...);
void set_chdir(struct bsdtar *, const char *newdir);
+const char *tar_i64toa(int64_t);
void tar_mode_c(struct bsdtar *bsdtar);
void tar_mode_r(struct bsdtar *bsdtar);
void tar_mode_t(struct bsdtar *bsdtar);
# endif
#endif
-
-/*
- * We need to be able to display a filesize using printf(). The type
- * and format string here must be compatible with one another and
- * large enough for any file.
- */
-#if HAVE_UINTMAX_T
-#define BSDTAR_FILESIZE_TYPE uintmax_t
-#define BSDTAR_FILESIZE_PRINTF "%ju"
-#else
-#if HAVE_UNSIGNED_LONG_LONG
-#define BSDTAR_FILESIZE_TYPE unsigned long long
-#define BSDTAR_FILESIZE_PRINTF "%llu"
-#else
-#define BSDTAR_FILESIZE_TYPE unsigned long
-#define BSDTAR_FILESIZE_PRINTF "%lu"
-#endif
-#endif
-
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctimespec.tv_nsec
#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtimespec.tv_nsec
struct bsdtar *bsdtar = progress_data->bsdtar;
struct archive *a = progress_data->archive;
struct archive_entry *entry = progress_data->entry;
- uintmax_t comp, uncomp;
+ uint64_t comp, uncomp;
if (!need_report())
return;
comp = archive_position_compressed(a);
uncomp = archive_position_uncompressed(a);
fprintf(stderr,
- "In: %ju bytes, compression %d%%;",
- comp, (int)((uncomp - comp) * 100 / uncomp));
- fprintf(stderr, " Out: %d files, %ju bytes\n",
- archive_file_count(a), uncomp);
+ "In: %s bytes, compression %d%%;",
+ tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp));
+ fprintf(stderr, " Out: %d files, %s bytes\n",
+ archive_file_count(a), tar_i64toa(uncomp));
}
if (entry != NULL) {
- safe_fprintf(stderr, "Current: %s (%ju bytes)",
- archive_entry_pathname(entry),
- (uintmax_t)archive_entry_size(entry));
- fprintf(stderr, "\n");
+ safe_fprintf(stderr, "Current: %s",
+ archive_entry_pathname(entry));
+ fprintf(stderr, " (%s bytes)\n",
+ tar_i64toa(archive_entry_size(entry)));
}
}
(unsigned long)archive_entry_rdevmajor(entry),
(unsigned long)archive_entry_rdevminor(entry));
} else {
- /*
- * Note the use of platform-dependent macros to format
- * the filesize here. We need the format string and the
- * corresponding type for the cast.
- */
- sprintf(tmp, BSDTAR_FILESIZE_PRINTF,
- (BSDTAR_FILESIZE_TYPE)archive_entry_size(entry));
+ strcpy(tmp, tar_i64toa(archive_entry_size(entry)));
}
if (w + strlen(tmp) >= bsdtar->gs_width)
bsdtar->gs_width = w+strlen(tmp)+1;
return (0);
}
+/*
+ * It would be nice to just use printf() for formatting large numbers,
+ * but the compatibility problems are quite a headache. Hence the
+ * following simple utility function.
+ */
+const char *
+tar_i64toa(int64_t n0)
+{
+ static char buff[24];
+ int64_t n = n0 < 0 ? -n0 : n0;
+ char *p = buff + sizeof(buff);
+
+ *--p = '\0';
+ do {
+ *--p = '0' + (n % 10);
+ n /= 10;
+ } while (n > 0);
+ if (n0 < 0)
+ *--p = '-';
+ return p;
+}
+
/*
* Like strcmp(), but try to be a little more aware of the fact that
* we're comparing two paths. Right now, it just handles leading
bsdtar->diskreader = NULL;
if (bsdtar->option_totals) {
- fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
- (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
+ fprintf(stderr, "Total bytes written: %s\n",
+ tar_i64toa(archive_position_compressed(a)));
}
archive_write_finish(a);
report_write(struct bsdtar *bsdtar, struct archive *a,
struct archive_entry *entry, int64_t progress)
{
- uintmax_t comp, uncomp;
+ uint64_t comp, uncomp;
if (bsdtar->verbose)
fprintf(stderr, "\n");
comp = archive_position_compressed(a);
uncomp = archive_position_uncompressed(a);
- fprintf(stderr, "In: %d files, %ju bytes;",
- archive_file_count(a), uncomp);
+ fprintf(stderr, "In: %d files, %s bytes;",
+ archive_file_count(a), tar_i64toa(uncomp));
fprintf(stderr,
- " Out: %ju bytes, compression %d%%\n",
- comp, (int)((uncomp - comp) * 100 / uncomp));
- safe_fprintf(stderr, "Current: %s (%ju/%ju bytes)",
+ " Out: %s bytes, compression %d%%\n",
+ tar_i64toa(comp), (int)((uncomp - comp) * 100 / uncomp));
+ /* Can't have two calls to tar_i64toa() pending, so split the output. */
+ safe_fprintf(stderr, "Current: %s (%s",
archive_entry_pathname(entry),
- (uintmax_t)progress,
- (uintmax_t)archive_entry_size(entry));
- fprintf(stderr, "\n");
+ tar_i64toa(progress));
+ fprintf(stderr, "/%s bytes)\n",
+ tar_i64toa(archive_entry_size(entry)));
}