summaryrefslogtreecommitdiff
path: root/src/pinky.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2004-06-22 15:00:53 +0000
committerJim Meyering <jim@meyering.net>2004-06-22 15:00:53 +0000
commit6eb57b59add3f7c7c70c0c6579efd0809b0632e0 (patch)
treea214f746ee8de25ca4303dd3fc56f5636c3733fd /src/pinky.c
parentf581b96e7fa8342329a82d0cd88280917d8f701c (diff)
downloadcoreutils-6eb57b59add3f7c7c70c0c6579efd0809b0632e0.tar.xz
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.
Diffstat (limited to 'src/pinky.c')
-rw-r--r--src/pinky.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/pinky.c b/src/pinky.c
index f3c157b2b..dacf8e26d 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 ();