-/*-------------------------------------------------------------------------.
-| Actually print it. |
-| |
-| Plain and fancy file header block logging. Non-verbose just prints the |
-| name, e.g. for "tar t" or "tar x". This should just contain file names, |
-| so it can be fed back into tar with xargs or the "-T" option. The |
-| verbose option can give a bunch of info, one line per file. I doubt |
-| anybody tries to parse its format, or if they do, they shouldn't. Unix |
-| tar is pretty random here anyway. |
-`-------------------------------------------------------------------------*/
+
+/* Return a printable representation of T. The result points to
+ static storage that can be reused in the next call to this
+ function, to ctime, or to asctime. If FULL_TIME, then output the
+ time stamp to its full resolution; otherwise, just output it to
+ 1-minute resolution. */
+char const *
+tartime (struct timespec t, bool full_time)
+{
+ enum { fraclen = sizeof ".FFFFFFFFF" - 1 };
+ static char buffer[max (UINTMAX_STRSIZE_BOUND + 1,
+ INT_STRLEN_BOUND (int) + 16)
+ + fraclen];
+ struct tm *tm;
+ time_t s = t.tv_sec;
+ int ns = t.tv_nsec;
+ bool negative = s < 0;
+ char *p;
+
+ if (negative && ns != 0)
+ {
+ s++;
+ ns = 1000000000 - ns;
+ }
+
+ tm = utc_option ? gmtime (&s) : localtime (&s);
+ if (tm)
+ {
+ if (full_time)
+ {
+ sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d",
+ tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ code_ns_fraction (ns, buffer + strlen (buffer));
+ }
+ else
+ sprintf (buffer, "%04ld-%02d-%02d %02d:%02d",
+ tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min);
+ return buffer;
+ }
+
+ /* The time stamp cannot be broken down, most likely because it
+ is out of range. Convert it as an integer,
+ right-adjusted in a field with the same width as the usual
+ 4-year ISO time format. */
+ p = umaxtostr (negative ? - (uintmax_t) s : s,
+ buffer + sizeof buffer - UINTMAX_STRSIZE_BOUND - fraclen);
+ if (negative)
+ *--p = '-';
+ while ((buffer + sizeof buffer - sizeof "YYYY-MM-DD HH:MM"
+ + (full_time ? sizeof ":SS.FFFFFFFFF" - 1 : 0))
+ < p)
+ *--p = ' ';
+ if (full_time)
+ code_ns_fraction (ns, buffer + sizeof buffer - 1 - fraclen);
+ return p;
+}
+
+/* Actually print it.
+
+ Plain and fancy file header block logging. Non-verbose just prints
+ the name, e.g. for "tar t" or "tar x". This should just contain
+ file names, so it can be fed back into tar with xargs or the "-T"
+ option. The verbose option can give a bunch of info, one line per
+ file. I doubt anybody tries to parse its format, or if they do,
+ they shouldn't. Unix tar is pretty random here anyway. */
+