---
 man/last.1 |   25 +++++++++++++++-
 src/last.c |   90 ++++++++++++++++++++++++++++++++++++-------------------------
 2 files changed, 77 insertions(+), 38 deletions(-)

--- man/last.1
+++ man/last.1	2015-01-20 15:30:49.113522123 +0000
@@ -1,3 +1,20 @@
+'\" -*- coding: UTF-8 -*-
+.\" Copyright (C) 1998-2004 Miquel van Smoorenburg.
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+.\"
 .\"{{{}}}
 .\"{{{  Title
 .TH LAST,LASTB 1 "Jul 31, 2004" "" "Linux System Administrator's Manual"
@@ -12,7 +29,7 @@ last, lastb \- show listing of last logg
 .RB [ \-R ]
 .RB [ \-\fInum\fP ]
 .RB "[ \-\fBn\fP \fInum\fP ]"
-.RB [ \-adFiox ]
+.RB [ \-adFiowx ]
 .RB "[ \-\fBf\fP \fIfile\fP ]"
 .RB "[ \-\fBt\fP \fIYYYYMMDDHHMMSS\fP ]"
 .RI [ name... ]
@@ -23,7 +40,7 @@ last, lastb \- show listing of last logg
 .RB [ \-\fInum\fP ]
 .RB "[ \-\fBn\fP \fInum\fP ]"
 .RB "[ \-\fBf\fP \fIfile\fP ]"
-.RB [ \-adFiox ]
+.RB [ \-adFiowx ]
 .RI [ name... ]
 .RI [ tty... ]
 .\"}}}
@@ -51,6 +68,8 @@ of the file \fB/var/log/btmp\fP, which c
 .\"}}}
 .\"{{{  Options
 .SH OPTIONS
+.IP "\fB\-f\fP \fIfile\fP"
+Tells \fBlast\fP to use a specific file instead of \fB/var/log/wtmp\fP.
 .IP \fB\-\fP\fInum\fP
 This is a count telling \fBlast\fP how many lines to show.
 .IP "\fB\-n\fP \fInum\fP"
@@ -76,6 +95,8 @@ This option is like \fB-d\fP in that it
 host, but it displays the IP number in numbers-and-dots notation.
 .IP \fB\-o\fP
 Read an old-type wtmp file (written by linux-libc5 applications).
+.IP \fB\-w\fP
+Display full user and domain names in the output.
 .IP \fB\-x\fP
 Display the system shutdown entries and run level changes.
 .\"}}}
--- src/last.c
+++ src/last.c	2015-01-20 15:30:11.393518283 +0000
@@ -9,12 +9,21 @@
  * Version:	@(#)last  2.85  30-Jul-2004  miquels@cistron.nl
  *
  *		This file is part of the sysvinit suite,
- *		Copyright 1991-2004 Miquel van Smoorenburg.
+ *		Copyright (C) 1991-2004 Miquel van Smoorenburg.
  *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
+ *		This program is free software; you can redistribute it and/or modify
+ *		it under the terms of the GNU General Public License as published by
+ *		the Free Software Foundation; either version 2 of the License, or
+ *		(at your option) any later version.
+ *
+ *		This program is distributed in the hope that it will be useful,
+ *		but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *		GNU General Public License for more details.
+ *
+ *		You should have received a copy of the GNU General Public License
+ *		along with this program; if not, write to the Free Software
+ *		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <sys/types.h>
@@ -71,6 +80,8 @@ int altlist = 0;	/* Show hostname at the
 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 name_len = 8;	/* Default print 8 characters of name */
+int domain_len = 16;	/* Default print 16 characters of domain */
 int oldfmt = 0;		/* Use old libc5 format? */
 char **show = NULL;	/* What do they want us to show */
 char *ufile;		/* Filename of this file */
@@ -307,25 +318,22 @@ int dns_lookup(char *result, int size, i
 	struct sockaddr_in6	sin6;
 	struct sockaddr		*sa;
 	int			salen, flags;
-	unsigned int		topnibble;
 	int			mapped = 0;
 
 	flags = useip ? NI_NUMERICHOST : 0;
 
 	/*
-	 *	IPv4 or IPv6 ? We use 2 heuristics:
-	 *	1. Current IPv6 range uses 2000-3fff. Outside of
-	 *	   that is illegal and must be IPv4.
-	 *	2. If last 3 bytes are 0, must be IPv4
-	 *	3. If IPv6 in IPv4, handle as IPv4
+	 *	IPv4 or IPv6 ?
+	 *	1. If last 3 4bytes are 0, must be IPv4
+	 *	2. If IPv6 in IPv4, handle as IPv4
+	 *	3. Anything else is IPv6
 	 *
 	 *	Ugly.
 	 */
-	if (a[0] == 0 && a[1] == 0 && a[2] == htonl (0xffff))
+	if (a[0] == 0 && a[1] == 0 && a[2] == (int32_t)htonl (0xffff))
 		mapped = 1;
-	topnibble = ntohl((unsigned int)a[0]) >> 28;
-	if (topnibble < 2 || topnibble > 3 || mapped ||
-	    (a[1] == 0 && a[2] == 0 && a[3] == 0)) {
+
+	if (mapped || (a[1] == 0 && a[2] == 0 && a[3] == 0)) {
 		/* IPv4 */
 		sin.sin_family = AF_INET;
 		sin.sin_port = 0;
@@ -354,7 +362,7 @@ int list(struct utmp *p, time_t t, int w
 	char		logintime[32];
 	char		logouttime[32];
 	char		length[32];
-	char		final[128];
+	char		final[512];
 	char		utline[UT_LINESIZE+1];
 	char		domain[256];
 	char		*s, **walk;
@@ -431,7 +439,6 @@ int list(struct utmp *p, time_t t, int w
 			}
 			break;
 		case R_REBOOT:
-			logouttime[0] = 0;      /* Print machine uptime */
 			break;
 		case R_TIMECHANGE:
 			logouttime[0] = 0;
@@ -449,7 +456,7 @@ int list(struct utmp *p, time_t t, int w
 		r = dns_lookup(domain, sizeof(domain), useip, p->ut_addr_v6);
 	if (r < 0) {
 		len = UT_HOSTSIZE;
-		if (len >= sizeof(domain)) len = sizeof(domain) - 1;
+		if (len >= (int)sizeof(domain)) len = sizeof(domain) - 1;
 		domain[0] = 0;
 		strncat(domain, p->ut_host, len);
 	}
@@ -465,27 +472,31 @@ int list(struct utmp *p, time_t t, int w
 		if (!altlist) {
 			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);
+				"%-8.*s %-12.12s %-16.*s %-24.24s %-26.26s %-12.12s\n" :
+				"%-8.*s %-12.12s %-16.*s %-16.16s %-7.7s %-12.12s\n",
+				name_len, p->ut_name, utline,
+				domain_len, domain, logintime, logouttime, length);
 		} else {
 			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,
+				"%-8.*s %-12.12s %-24.24s %-26.26s %-12.12s %s\n" :
+				"%-8.*s %-12.12s %-16.16s %-7.7s %-12.12s %s\n",
+				name_len, p->ut_name, utline,
 				logintime, logouttime, length, domain);
 		}
 	} else
 		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,
+			"%-8.*s %-12.12s %-24.24s %-26.26s %-12.12s\n" :
+			"%-8.*s %-12.12s %-16.16s %-7.7s %-12.12s\n",
+			name_len, p->ut_name, utline,
 			logintime, logouttime, length);
 
+#if defined(__GLIBC__)
+#  if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
 	final[sizeof(final)-1] = '\0';
+#  endif
+#endif
 
 	/*
 	 *	Print out "final" string safely.
@@ -497,7 +508,7 @@ int list(struct utmp *p, time_t t, int w
 			putchar('*');
 	}
 
-	if (len < 0 || len >= sizeof(final))
+	if (len < 0 || (size_t)len >= sizeof(final))
 		putchar('\n');
 
 	recsdone++;
@@ -515,17 +526,17 @@ void usage(char *s)
 {
 	fprintf(stderr, "Usage: %s [-num | -n num] [-f file] "
 			"[-t YYYYMMDDHHMMSS] "
-			"[-R] [-a] [-d] [-F] [-i] [-o] [-x] "
-			"[username..] [tty..]\n", s);
-
+			"[-R] [-adioxFw] [username..] [tty..]\n", s);
 	exit(1);
 }
 
 time_t parsetm(char *ts)
 {
-	struct tm	u = {0}, origu;
+	struct tm	u, origu;
 	time_t		tm;
 
+	memset(&tm, 0, sizeof(tm));
+
 	if (sscanf(ts, "%4d%2d%2d%2d%2d%2d", &u.tm_year,
 	    &u.tm_mon, &u.tm_mday, &u.tm_hour, &u.tm_min,
 	    &u.tm_sec) != 6)
@@ -586,7 +597,7 @@ int main(int argc, char **argv)
   progname = mybasename(argv[0]);
 
   /* Process the arguments. */
-  while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789")) != EOF)
+  while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789w")) != EOF)
     switch(c) {
 	case 'R':
 		showhost = 0;
@@ -627,6 +638,12 @@ int main(int argc, char **argv)
 			usage(progname);
 		}
 		break;
+	case 'w':
+		if (UT_NAMESIZE > name_len)
+			name_len = UT_NAMESIZE;
+		if (UT_HOSTSIZE > domain_len)
+			domain_len = UT_HOSTSIZE;
+		break;
 	case '0': case '1': case '2': case '3': case '4':
 	case '5': case '6': case '7': case '8': case '9':
 		maxrecs = 10*maxrecs + c - '0';
@@ -745,7 +762,7 @@ int main(int argc, char **argv)
 			ut.ut_type = SHUTDOWN_TIME;
 		else if (strncmp(ut.ut_user, "reboot", 6) == 0)
 			ut.ut_type = BOOT_TIME;
-		else if (strncmp(ut.ut_user, "runlevel", 7) == 0)
+		else if (strncmp(ut.ut_user, "runlevel", 8) == 0)
 			ut.ut_type = RUN_LVL;
 	}
 #if 1 /*def COMPAT*/
@@ -780,7 +797,7 @@ int main(int argc, char **argv)
 		case SHUTDOWN_TIME:
 			if (extended) {
 				strcpy(ut.ut_line, "system down");
-				quit = list(&ut, lastdown, R_NORMAL);
+				quit = list(&ut, lastboot, R_NORMAL);
 			}
 			lastdown = lastrch = ut.ut_time;
 			down = 1;
@@ -797,6 +814,7 @@ int main(int argc, char **argv)
 		case BOOT_TIME:
 			strcpy(ut.ut_line, "system boot");
 			quit = list(&ut, lastdown, R_REBOOT);
+			lastboot = ut.ut_time;
 			down = 1;
 			break;
 		case RUN_LVL:
