+void
+major_to_chars (major_t v, char *p, size_t s)
+{
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
+}
+
+void
+minor_to_chars (minor_t v, char *p, size_t s)
+{
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
+}
+
+void
+mode_to_chars (mode_t v, char *p, size_t s)
+{
+ /* In the common case where the internal and external mode bits are the same,
+ and we are not using POSIX or GNU format,
+ propagate all unknown bits to the external mode.
+ This matches historical practice.
+ Otherwise, just copy the bits we know about. */
+ int negative;
+ uintmax_t u;
+ if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
+ && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
+ && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
+ && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC
+ && archive_format != POSIX_FORMAT
+ && archive_format != USTAR_FORMAT
+ && archive_format != GNU_FORMAT)
+ {
+ negative = v < 0;
+ u = v;
+ }
+ else
+ {
+ negative = 0;
+ u = ((v & S_ISUID ? TSUID : 0)
+ | (v & S_ISGID ? TSGID : 0)
+ | (v & S_ISVTX ? TSVTX : 0)
+ | (v & S_IRUSR ? TUREAD : 0)
+ | (v & S_IWUSR ? TUWRITE : 0)
+ | (v & S_IXUSR ? TUEXEC : 0)
+ | (v & S_IRGRP ? TGREAD : 0)
+ | (v & S_IWGRP ? TGWRITE : 0)
+ | (v & S_IXGRP ? TGEXEC : 0)
+ | (v & S_IROTH ? TOREAD : 0)
+ | (v & S_IWOTH ? TOWRITE : 0)
+ | (v & S_IXOTH ? TOEXEC : 0));
+ }
+ to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
+}
+
+void
+off_to_chars (off_t v, char *p, size_t s)
+{
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
+}
+
+void
+size_to_chars (size_t v, char *p, size_t s)
+{
+ to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
+}
+
+void
+time_to_chars (time_t v, char *p, size_t s)
+{
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
+}
+
+static uintmax_t
+uid_substitute (int *negative)
+{
+ uid_t r;
+#ifdef UID_NOBODY
+ r = UID_NOBODY;