man/last.1 | 6 ++++-- src/last.c | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 13 deletions(-) Index: man/last.1 =================================================================== --- man/last.1 2005-12-05 18:05:40.000000000 +0100 +++ man/last.1 2005-12-05 18:09:27.000000000 +0100 @@ -12,7 +12,7 @@ last, lastb \- show listing of last logg .RB [ \-R ] .RB [ \-\fInum\fP ] .RB "[ \-\fBn\fP \fInum\fP ]" -.RB [ \-adiox ] +.RB [ \-adFiox ] .RB "[ \-\fBf\fP \fIfile\fP ]" .RB "[ \-\fBt\fP \fIYYYYMMDDHHMMSS\fP ]" .RI [ name... ] @@ -23,7 +23,7 @@ last, lastb \- show listing of last logg .RB [ \-\fInum\fP ] .RB "[ \-\fBn\fP \fInum\fP ]" .RB "[ \-\fBf\fP \fIfile\fP ]" -.RB [ \-adiox ] +.RB [ \-adFiox ] .RI [ name... ] .RI [ tty... ] .\"}}} @@ -69,6 +69,8 @@ with the next flag. For non-local logins, Linux stores not only the host name of the remote host but its IP number as well. This option translates the IP number back into a hostname. +.IP \fB\-F\fP +Print full login and logout times and dates. .IP \fB\-i\fP This option is like \fB-d\fP in that it displays the IP number of the remote host, but it displays the IP number in numbers-and-dots notation. Index: src/last.c =================================================================== --- src/last.c 2005-12-05 18:07:21.000000000 +0100 +++ src/last.c 2009-02-20 16:37:27.380797018 +0100 @@ -70,6 +70,7 @@ int showhost = 1; /* Show hostname too? int altlist = 0; /* Show hostname at the end. */ int usedns = 0; /* Use DNS to lookup the hostname. */ int useip = 0; /* Print IP address in number format */ +int fulltime = 0; /* Print full dates and times */ int oldfmt = 0; /* Use old libc5 format? */ char **show = NULL; /* What do they want us to show */ char *ufile; /* Filename of this file */ @@ -388,9 +389,13 @@ int list(struct utmp *p, time_t t, int w */ tmp = (time_t)p->ut_time; strcpy(logintime, ctime(&tmp)); - logintime[16] = 0; - sprintf(logouttime, "- %s", ctime(&t) + 11); - logouttime[7] = 0; + if (fulltime) + sprintf(logouttime, "- %s", ctime(&t)); + else { + logintime[16] = 0; + sprintf(logouttime, "- %s", ctime(&t) + 11); + logouttime[7] = 0; + } secs = t - p->ut_time; mins = (secs / 60) % 60; hours = (secs / 3600) % 24; @@ -409,13 +414,21 @@ int list(struct utmp *p, time_t t, int w break; case R_NOW: length[0] = 0; - sprintf(logouttime, " still"); - sprintf(length, "logged in"); + if (fulltime) + sprintf(logouttime, " still logged in"); + else { + sprintf(logouttime, " still"); + sprintf(length, "logged in"); + } break; case R_PHANTOM: length[0] = 0; - sprintf(logouttime, " gone"); - sprintf(length, "- no logout"); + if (fulltime) + sprintf(logouttime, " gone - no logout"); + else { + sprintf(logouttime, " gone"); + sprintf(length, "- no logout"); + } break; case R_REBOOT: logouttime[0] = 0; /* Print machine uptime */ @@ -450,23 +463,30 @@ int list(struct utmp *p, time_t t, int w strcmp(s + 1, domainname) == 0) *s = 0; #endif if (!altlist) { - snprintf(final, sizeof(final), - "%-8.8s %-12.12s %-16.16s " - "%-16.16s %-7.7s %-12.12s\n", + len = snprintf(final, sizeof(final), + fulltime ? + "%-8.8s %-12.12s %-16.16s %-24.24s %-26.26s %-12.12s\n" : + "%-8.8s %-12.12s %-16.16s %-16.16s %-7.7s %-12.12s\n", p->ut_name, utline, domain, logintime, logouttime, length); } else { - snprintf(final, sizeof(final), + len = snprintf(final, sizeof(final), + fulltime ? + "%-8.8s %-12.12s %-24.24s %-26.26s %-12.12s %s\n" : "%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s %s\n", p->ut_name, utline, logintime, logouttime, length, domain); } } else - snprintf(final, sizeof(final), + len = snprintf(final, sizeof(final), + fulltime ? + "%-8.8s %-12.12s %-24.24s %-26.26s %-12.12s\n" : "%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s\n", p->ut_name, utline, logintime, logouttime, length); + final[sizeof(final)-1] = '\0'; + /* * Print out "final" string safely. */ @@ -477,6 +497,9 @@ int list(struct utmp *p, time_t t, int w putchar('*'); } + if (len < 0 || len >= sizeof(final)) + putchar('\n'); + recsdone++; if (maxrecs && recsdone >= maxrecs) return 1; @@ -492,7 +515,7 @@ void usage(char *s) { fprintf(stderr, "Usage: %s [-num | -n num] [-f file] " "[-t YYYYMMDDHHMMSS] " - "[-R] [-a] [-d] [-i] [-o] [-x] " + "[-R] [-a] [-d] [-F] [-i] [-o] [-x] " "[username..] [tty..]\n", s); exit(1); @@ -563,7 +586,7 @@ int main(int argc, char **argv) progname = mybasename(argv[0]); /* Process the arguments. */ - while((c = getopt(argc, argv, "f:n:Rxadiot:0123456789")) != EOF) + while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789")) != EOF) switch(c) { case 'R': showhost = 0; @@ -594,6 +617,9 @@ int main(int argc, char **argv) case 'a': altlist++; break; + case 'F': + fulltime++; + break; case 't': if ((until = parsetm(optarg)) == (time_t)-1) { fprintf(stderr, "%s: Invalid time value \"%s\"\n",