-/*
- * 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.
- *
- * Note that print_header uses the globals <head>, <hstat>, and
- * <head_standard>, which must be set up in advance. This is not very clean
- * and should be cleaned up. FIXME.
- */
-#define UGSWIDTH 18 /* min width of User, group, size */
-/* UGSWIDTH of 18 means that with user and group names <= 8 chars the columns
- never shift during the listing. */
-#define DATEWIDTH 19 /* Last mod date */
-static int ugswidth = UGSWIDTH; /* Max width encountered so far */
+/*-------------------------------------------.
+| Return the time formatted along ISO 8601. |
+`-------------------------------------------*/
+
+/* Also, see http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html. */
+
+static char *
+isotime (const time_t *time)
+{
+ static char buffer[21];
+ struct tm *tm;
+
+ tm = localtime (time);
+ sprintf (buffer, "%4d-%02d-%02d %02d:%02d:%02d\n",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ return buffer;
+}
+
+#endif /* not USE_OLD_CTIME */
+
+/*-------------------------------------------------------------------------.
+| Decode MODE from its binary form in a stat structure, and encode it into |
+| a 9 characters string STRING, terminated with a NUL. |
+`-------------------------------------------------------------------------*/
+
+static void
+decode_mode (unsigned mode, char *string)
+{
+ unsigned mask;
+ const char *rwx = "rwxrwxrwx";
+
+ for (mask = 0400; mask != 0; mask >>= 1)
+ if (mode & mask)
+ *string++ = *rwx++;
+ else
+ {
+ *string++ = '-';
+ rwx++;
+ }
+
+ if (mode & S_ISUID)
+ string[-7] = string[-7] == 'x' ? 's' : 'S';
+ if (mode & S_ISGID)
+ string[-4] = string[-4] == 'x' ? 's' : 'S';
+ if (mode & S_ISVTX)
+ string[-1] = string[-1] == 'x' ? 't' : 'T';
+
+ *string = '\0';
+}
+
+/*-------------------------------------------------------------------------.
+| 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. |
+`-------------------------------------------------------------------------*/
+
+/* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
+ HEAD_STANDARD, which must be set up in advance. Not very clean... */
+
+/* UGSWIDTH starts with 18, so with user and group names <= 8 chars, the
+ columns never shift during the listing. */
+#define UGSWIDTH 18
+static int ugswidth = UGSWIDTH; /* maximum width encountered so far */
+
+/* DATEWIDTH is the number of columns taken by the date and time fields. */
+#if USE_OLD_CDATE
+# define DATEWIDTH 19
+#else
+# define DATEWIDTH 18
+#endif