Subject: bin/35354: more on last -f -
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dholland@eecs.harvard.edu>
List: netbsd-bugs
Date: 01/02/2007 23:55:01
>Number:         35354
>Category:       bin
>Synopsis:       followup on last -f -
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 02 23:55:00 +0000 2007
>Originator:     David A. Holland <dholland@eecs.harvard.edu>
>Release:        -current of 20060102
>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:

Last week I sent a patch (bin/35329) to add support for "-f -" to
last(1).

Christian Biere correctly points out that my patch does two things
that can and should be separated: recognizing "-f -" and dealing with
non-seekable input.

I have separated these. With this (additional) patch you can do 
last -f /dev/stdin too.

In the course of doing this I found a stupidity in my original patch:
it copies the input in chunks of sizeof(struct utmp *), using only the
first few bytes of the utmp buffer. I think I was intending to declare
a separate transfer buffer instead of reusing the utmp buffer, or
something, forgot to sort it out, and didn't notice because it works
correctly as it is. Anyway. The patch below corrects this mistake and
also doesn't shadow the variable "len".

>How-To-Repeat:
	-
>Fix:

Index: usr.bin/last/want.c
===================================================================
RCS file: /cvsroot/src/usr.bin/last/want.c,v
retrieving revision 1.7
diff -u -r1.7 want.c
--- usr.bin/last/want.c	27 Dec 2006 18:03:26 -0000	1.7
+++ usr.bin/last/want.c	2 Jan 2007 23:39:00 -0000
@@ -87,36 +87,38 @@
 	crmsg = NULL;
 
 	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;
-		}
+		wfd = STDIN_FILENO;
 		file = "<stdin>";
 	} else if ((wfd = open(file, O_RDONLY, 0)) < 0) {
 		err(1, "%s", file);
 	}
 
+	if (lseek(STDIN_FILENO, 0, SEEK_CUR) < 0) {
+		char tfile[] = _PATH_TMP "last.XXXXXX";
+		int tempfd;
+		ssize_t tlen;
+
+		tempfd = mkstemp(tfile);
+		if (tempfd < 0) {
+			err(1, "mkstemp");
+		}
+		unlink(tfile);
+		for (;;) {
+		   	tlen = read(wfd, buf, len);
+			if (tlen < 0) {
+				err(1, "stdin: read");
+			}
+			if (tlen == 0) {
+				break;
+			}
+			tlen = write(tempfd, buf, len);
+			if (tlen < 0) {
+				err(1, "%s: write", tfile);
+			}
+		}
+		wfd = tempfd;
+	}
+
 	if (fstat(wfd, &stb) == -1)
 		err(1, "%s: fstat", file);
 	bl = (stb.st_size + len - 1) / len;