Subject: bin/35329: add -f - support to last(1)
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dholland@eecs.harvard.edu>
List: netbsd-bugs
Date: 12/27/2006 17:50:00
>Number:         35329
>Category:       bin
>Synopsis:       patch to add -f - support to last(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Dec 27 17:50:00 +0000 2006
>Originator:     David A. Holland <dholland@eecs.harvard.edu>
>Release:        NetBSD 4.99.3 (patch against -20061226)
>Organization:
   Harvard EECS
>Environment:
System: NetBSD tanaqui 4.99.3 NetBSD 4.99.3 (TANAQUI) #6: Tue Oct 10 19:32:37 EDT 2006 dholland@tanaqui:/usr/src/sys/arch/i386/compile/TANAQUI i386
Architecture: i386
Machine: i386
>Description:

Reading old wtmp files is a nuisance because they're stored compressed
by default, and last has no direct ability to handle this. You can't
do "gzcat /var/log/wtmp.0.gz | last -f -", either, because last
doesn't accept that. You end up having to decompress the files by
hand.

The enclosed patch adds support for "-f -". I also did a patch that
adds a -z option to read gzip files, but it's fairly untidy and I
think this is a better approach.

Note that because last reads the file back to front, it can't
necessarily just read from stdin but has to make a copy into a
temporary file. It would be nice if there were a general-purpose
solution for this situation, but I dunno what it would be.

>How-To-Repeat:
-
>Fix:

Index: usr.bin/last/last.1
===================================================================
RCS file: /cvsroot/src/usr.bin/last/last.1,v
retrieving revision 1.16
diff -u -r1.16 last.1
--- usr.bin/last/last.1	5 Mar 2005 14:28:31 -0000	1.16
+++ usr.bin/last/last.1	27 Dec 2006 14:42:25 -0000
@@ -83,6 +83,7 @@
 format file, else it is treated as a
 .Xr utmp 5
 format file.
+If the file is ``-'', standard input is used.
 .It Fl H Ar hostsize
 Use the provided hostsize as the width to format the host name field.
 .It Fl h Ar host
Index: usr.bin/last/want.c
===================================================================
RCS file: /cvsroot/src/usr.bin/last/want.c,v
retrieving revision 1.6
diff -u -r1.6 want.c
--- usr.bin/last/want.c	28 Feb 2006 17:17:43 -0000	1.6
+++ usr.bin/last/want.c	27 Dec 2006 14:42:25 -0000
@@ -86,8 +86,41 @@
 
 	crmsg = NULL;
 
-	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
+	if (!strcmp(file, "-")) {
+		if (lseek(STDIN_FILENO, 0, SEEK_CUR) < 0) {
+			char tfile[] = _PATH_TMP "last.XXXXXX";
+			ssize_t len;
+
+			wfd = mkstemp(tfile);
+			if (wfd < 0) {
+				err(1, "mkstemp");
+			}
+			unlink(tfile);
+			for (;;) {
+			   	len = read(STDIN_FILENO, buf, sizeof(buf));
+				if (len < 0) {
+					err(1, "stdin: read");
+				}
+				if (len == 0) {
+					break;
+				}
+				len = write(wfd, buf, len);
+				if (len < 0) {
+					err(1, "%s: write", tfile);
+				}
+			}
+		}
+		else {
+			wfd = STDIN_FILENO;
+		}
+		file = "<stdin>";
+	}
+	else if ((wfd = open(file, O_RDONLY, 0)) < 0) {
 		err(1, "%s", file);
+	}
+
+	if (fstat(wfd, &stb) == -1)
+		err(1, "%s: fstat", file);
 	bl = (stb.st_size + len - 1) / len;
 
 	buf[FIRSTVALID].ut_timefld = time(NULL);