+/* Base 64 digits; see Internet RFC 2045 Table 1. */
+char const base_64_digits[64] =
+{
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+#define base_8_digits (base_64_digits + 26 * 2)
+
+/* The maximum uintmax_t value that can be represented with DIGITS digits,
+ assuming that each digit is BITS_PER_DIGIT wide. */
+#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
+ ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
+ ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
+ : (uintmax_t) -1)
+
+/* Convert VALUE to a representation suitable for tar headers,
+ using base 1 << BITS_PER_DIGIT.
+ Use the digits in DIGIT_CHAR[0] ... DIGIT_CHAR[base - 1].
+ Output to buffer WHERE with size SIZE.
+ The result is undefined if SIZE is 0 or if VALUE is too large to fit. */
+
+static void
+to_base (uintmax_t value, int bits_per_digit, char const *digit_char,
+ char *where, size_t size)
+{
+ uintmax_t v = value;
+ size_t i = size;
+ unsigned digit_mask = (1 << bits_per_digit) - 1;
+
+ do
+ {
+ where[--i] = digit_char[v & digit_mask];
+ v >>= bits_per_digit;
+ }
+ while (i);
+}
+
+/* NEGATIVE is nonzero if VALUE was negative before being cast to
+ uintmax_t; its original bitpattern can be deduced from VALSIZE, its
+ original size before casting. Convert VALUE to external form,
+ using SUBSTITUTE (...) if VALUE won't fit. Output to buffer WHERE
+ with size SIZE. TYPE is the kind of value being output (useful for
+ diagnostics). Prefer the POSIX format of SIZE - 1 octal digits
+ (with leading zero digits), followed by '\0'. If this won't work,
+ and if GNU format is allowed, use '+' or '-' followed by SIZE - 1
+ base-64 digits. If neither format works, use SUBSTITUTE (...)
+ instead. Pass to SUBSTITUTE the address of an 0-or-1 flag
+ recording whether the substitute value is negative. */