From 6eb57b59add3f7c7c70c0c6579efd0809b0632e0 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Tue, 22 Jun 2004 15:00:53 +0000 Subject: [PATCH] The 2004-06-19 fix for who and pinky was incomplete, as ctime has undefined behavior if the year precedes -999 or follows 9999. Since we have to stop using ctime anyway, we might as well use strftime and fix the FIXME, and support internationalized dates. * src/who.c: Include "hard-locale.h". (time_format, time_format_width): New vars. (time_string, print_line): Use them. (main): Set them. (time_string): Use localtime + strftime instead of ctime, to avoid problems with years before -999 or after 9999. * src/pinky.c: Likewise. --- src/pinky.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/pinky.c b/src/pinky.c index f3c157b2bf..dacf8e26d0 100644 --- a/src/pinky.c +++ b/src/pinky.c @@ -26,6 +26,7 @@ #include "system.h" #include "error.h" +#include "hard-locale.h" #include "inttostr.h" #include "readutmp.h" @@ -77,6 +78,11 @@ static int do_short_format = 1; static int include_where = 1; #endif +/* The strftime format to use for login times, and its expected + output width. */ +static char const *time_format; +static int time_format_width; + static struct option const longopts[] = { {GETOPT_HELP_OPTION_DECL}, @@ -161,31 +167,28 @@ idle_string (time_t when) return (const char *) idle_hhmm; } -/* Return a standard time string, "mon dd hh:mm" - FIXME: handle localization */ +/* Return a time string. */ static const char * time_string (const STRUCT_UTMP *utmp_ent) { + static char buf[INT_STRLEN_BOUND (intmax_t) + sizeof "-%m-%d %H:%M"]; + /* Don't take the address of UT_TIME_MEMBER directly. Ulrich Drepper wrote: ``... GNU libc (and perhaps other libcs as well) have extended utmp file formats which do not use a simple time_t ut_time field. In glibc, ut_time is a macro which selects for backward compatibility the tv_sec member of a struct timeval value.'' */ - time_t tm = UT_TIME_MEMBER (utmp_ent); + time_t t = UT_TIME_MEMBER (utmp_ent); + struct tm *tmp = localtime (&t); - char *ptr = ctime (&tm); - if (ptr) + if (tmp) { - ptr += 4; - ptr[12] = '\0'; + strftime (buf, sizeof buf, time_format, tmp); + return buf; } else - { - static char buf[INT_BUFSIZE_BOUND (intmax_t)]; - ptr = (TYPE_SIGNED (time_t) ? imaxtostr (tm, buf) : umaxtostr (tm, buf)); - } - return ptr; + return TYPE_SIGNED (time_t) ? imaxtostr (t, buf) : umaxtostr (t, buf); } /* Display a line of information about UTMP_ENT. */ @@ -408,7 +411,7 @@ print_heading (void) printf (" %-9s", _(" TTY")); if (include_idle) printf (" %-6s", _("Idle")); - printf (" %-12s", _("When")); + printf (" %-*s", time_format_width, _("When")); #ifdef HAVE_UT_HOST if (include_where) printf (" %s", _("Where")); @@ -422,6 +425,17 @@ static void scan_entries (int n, const STRUCT_UTMP *utmp_buf, const int argc_names, char *const argv_names[]) { + if (hard_locale (LC_TIME)) + { + time_format = "%Y-%m-%d %H:%M"; + time_format_width = 4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2; + } + else + { + time_format = "%b %e %H:%M"; + time_format_width = 3 + 1 + 2 + 1 + 2 + 1 + 2; + } + if (include_heading) print_heading (); -- 2.47.2