From 4e675bab3122aa5fc0cf328db284c74fb86fee00 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Sun, 4 Aug 2019 15:30:12 +0200
Subject: [PATCH 17/18] last(1): Clean up better.

---
 usr.bin/last/last.c | 202 +++++++++++++++++++++++++++++++++++++---
 usr.bin/last/want.c | 222 --------------------------------------------
 2 files changed, 190 insertions(+), 234 deletions(-)
 delete mode 100644 usr.bin/last/want.c

diff --git a/usr.bin/last/last.c b/usr.bin/last/last.c
index 9cc2e8952f..9f68b11e82 100644
--- a/usr.bin/last/last.c
+++ b/usr.bin/last/last.c
@@ -89,6 +89,7 @@ typedef struct ttytab {
 } TTY;
 static TTY	*ttylist;		/* head of linked list */
 
+static struct utmpx *bufx;
 static time_t	currentout;		/* current logout value */
 static long	maxrec;			/* records to display */
 static int	fulltime = 0;		/* Display seconds? */
@@ -100,6 +101,8 @@ static char	*ttyconv(char *);
 static void	 wtmpx(const char *, int, int, int);
 static char	*fmttime(time_t, int);
 static void	 usage(void);
+static void	 onintrx(int);
+static int	 wantx(struct utmpx *, int);
 
 static
 void usage(void)
@@ -304,15 +307,190 @@ fmttime(time_t t, int flags)
 	return (tbuf);
 }
 
-#define utmp utmpx
-#define want wantx
-#define wtmp wtmpx
-#define buf bufx
-#define onintr onintrx
-#define TYPE(a) (a)->ut_type
-#define NAMESIZE UTX_USERSIZE
-#define LINESIZE UTX_LINESIZE
-#define HOSTSIZE UTX_HOSTSIZE
-#define ut_timefld ut_xtime
-#define FIRSTVALID 1
-#include "want.c"
+/*
+ * wtmpx --
+ *	read through the wtmpx file
+ */
+static void
+wtmpx(const char *file, int namesz, int linesz, int hostsz)
+{
+	struct utmpx	*bp;		/* current structure */
+	TTY	*T;			/* tty list entry */
+	struct stat	stb;		/* stat of file for sz */
+	time_t	delta;			/* time difference */
+	off_t	bl;
+	int	bytes, wfd;
+	char	*ct;
+	const char *crmsg;
+	size_t  len = sizeof(*bufx) * MAXUTMP;
+
+	if ((bufx = malloc(len)) == NULL)
+		err(1, "Cannot allocate utmpx buffer");
+
+	crmsg = NULL;
+
+	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
+		err(1, "%s", file);
+	bl = (stb.st_size + len - 1) / len;
+
+	bufx[1].ut_xtime = time(NULL);
+	(void)signal(SIGINT, onintrx);
+	(void)signal(SIGQUIT, onintrx);
+
+	while (--bl >= 0) {
+		if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
+		    (bytes = read(wfd, bufx, len)) == -1)
+			err(1, "%s", file);
+		for (bp = &bufx[bytes / sizeof(*bufx) - 1]; bp >= bufx; --bp) {
+			/*
+			 * if the terminal line is '~', the machine stopped.
+			 * see utmpx(5) for more info.
+			 */
+			if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
+				/* everybody just logged out */
+				for (T = ttylist; T; T = T->next)
+					T->logout = -bp->ut_xtime;
+				currentout = -bp->ut_xtime;
+				crmsg = strncmp(bp->ut_name, "shutdown",
+				    namesz) ? "crash" : "shutdown";
+				if (wantx(bp, NO)) {
+					ct = fmttime(bp->ut_xtime, fulltime);
+					printf("%-*.*s  %-*.*s %-*.*s %s\n",
+					    namesz, namesz, bp->ut_name,
+					    linesz, linesz, bp->ut_line,
+					    hostsz, hostsz, bp->ut_host, ct);
+					if (maxrec != -1 && !--maxrec)
+						return;
+				}
+				continue;
+			}
+			/*
+			 * if the line is '{' or '|', date got set; see
+			 * utmpx(5) for more info.
+			 */
+			if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
+			    && !bp->ut_line[1]) {
+				if (wantx(bp, NO)) {
+					ct = fmttime(bp->ut_xtime, fulltime);
+				printf("%-*.*s  %-*.*s %-*.*s %s\n",
+				    namesz, namesz,
+				    bp->ut_name,
+				    linesz, linesz,
+				    bp->ut_line,
+				    hostsz, hostsz,
+				    bp->ut_host,
+				    ct);
+					if (maxrec && !--maxrec)
+						return;
+				}
+				continue;
+			}
+			/* find associated tty */
+			for (T = ttylist;; T = T->next) {
+				if (!T) {
+					/* add new one */
+					T = addtty(bp->ut_line);
+					break;
+				}
+				if (!strncmp(T->tty, bp->ut_line, UTX_LINESIZE))
+					break;
+			}
+			if (bp->ut_type == SIGNATURE)
+				continue;
+			if (bp->ut_name[0] && wantx(bp, YES)) {
+				ct = fmttime(bp->ut_xtime, fulltime);
+				printf("%-*.*s  %-*.*s %-*.*s %s ",
+				    namesz, namesz, bp->ut_name,
+				    linesz, linesz, bp->ut_line,
+				    hostsz, hostsz, bp->ut_host,
+				    ct);
+				if (!T->logout)
+					puts("  still logged in");
+				else {
+					if (T->logout < 0) {
+						T->logout = -T->logout;
+						printf("- %s", crmsg);
+					}
+					else
+						printf("- %s",
+						    fmttime(T->logout,
+						    fulltime | TIMEONLY));
+					delta = T->logout - bp->ut_xtime;
+					if (delta < SECSPERDAY)
+						printf("  (%s)\n",
+						    fmttime(delta,
+						    fulltime | TIMEONLY | GMT));
+					else
+						printf(" (%ld+%s)\n",
+						    delta / SECSPERDAY,
+						    fmttime(delta,
+						    fulltime | TIMEONLY | GMT));
+				}
+				if (maxrec != -1 && !--maxrec)
+					return;
+			}
+			T->logout = bp->ut_xtime;
+		}
+	}
+	fulltime = 1;	/* show full time */
+	crmsg = fmttime(bufx[1].ut_xtime, FULLTIME);
+	if ((ct = strrchr(file, '/')) != NULL)
+		ct++;
+	printf("\n%s begins %s\n", ct ? ct : file, crmsg);
+}
+
+/*
+ * wantx --
+ *	see if want this entry
+ */
+static int
+wantx(struct utmpx *bp, int check)
+{
+	ARG *step;
+
+	if (check) {
+		/*
+		 * when uucp and ftp log in over a network, the entry in
+		 * the utmpx file is the name plus their process id.  See
+		 * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
+		 */
+		if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
+			bp->ut_line[3] = '\0';
+		else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
+			bp->ut_line[4] = '\0';
+	}
+	if (!arglist)
+		return (YES);
+
+	for (step = arglist; step; step = step->next)
+		switch(step->type) {
+		case HOST_TYPE:
+			if (!strncasecmp(step->name, bp->ut_host, UTX_HOSTSIZE))
+				return (YES);
+			break;
+		case TTY_TYPE:
+			if (!strncmp(step->name, bp->ut_line, UTX_LINESIZE))
+				return (YES);
+			break;
+		case USER_TYPE:
+			if (!strncmp(step->name, bp->ut_name, UTX_USERSIZE))
+				return (YES);
+			break;
+	}
+	return (NO);
+}
+
+/*
+ * onintrx --
+ *	on interrupt, we inform the user how far we've gotten
+ */
+static void
+onintrx(int signo)
+{
+
+	printf("\ninterrupted %s\n", fmttime(bufx[1].ut_xtime,
+	    FULLTIME));
+	if (signo == SIGINT)
+		exit(1);
+	(void)fflush(stdout);		/* fix required for rsh */
+}
diff --git a/usr.bin/last/want.c b/usr.bin/last/want.c
deleted file mode 100644
index 3edcd56917..0000000000
--- a/usr.bin/last/want.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*	$NetBSD: last.c,v 1.15 2000/06/30 06:19:58 simonb Exp $	*/
-
-/*
- * Copyright (c) 1987, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-static struct utmp *buf;
-
-static void onintr(int);
-static int want(struct utmp *, int);
-
-/*
- * wtmp --
- *	read through the wtmp file
- */
-void
-wtmp(const char *file, int namesz, int linesz, int hostsz)
-{
-	struct utmp	*bp;		/* current structure */
-	TTY	*T;			/* tty list entry */
-	struct stat	stb;		/* stat of file for sz */
-	time_t	delta;			/* time difference */
-	off_t	bl;
-	int	bytes, wfd;
-	char	*ct;
-	const char *crmsg;
-	size_t  len = sizeof(*buf) * MAXUTMP;
-
-	if ((buf = malloc(len)) == NULL)
-		err(1, "Cannot allocate utmp buffer");
-
-	crmsg = NULL;
-
-	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
-		err(1, "%s", file);
-	bl = (stb.st_size + len - 1) / len;
-
-	buf[FIRSTVALID].ut_timefld = time(NULL);
-	(void)signal(SIGINT, onintr);
-	(void)signal(SIGQUIT, onintr);
-
-	while (--bl >= 0) {
-		if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
-		    (bytes = read(wfd, buf, len)) == -1)
-			err(1, "%s", file);
-		for (bp = &buf[bytes / sizeof(*buf) - 1]; bp >= buf; --bp) {
-			/*
-			 * if the terminal line is '~', the machine stopped.
-			 * see utmp(5) for more info.
-			 */
-			if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
-				/* everybody just logged out */
-				for (T = ttylist; T; T = T->next)
-					T->logout = -bp->ut_timefld;
-				currentout = -bp->ut_timefld;
-				crmsg = strncmp(bp->ut_name, "shutdown",
-				    namesz) ? "crash" : "shutdown";
-				if (want(bp, NO)) {
-					ct = fmttime(bp->ut_timefld, fulltime);
-					printf("%-*.*s  %-*.*s %-*.*s %s\n",
-					    namesz, namesz, bp->ut_name,
-					    linesz, linesz, bp->ut_line,
-					    hostsz, hostsz, bp->ut_host, ct);
-					if (maxrec != -1 && !--maxrec)
-						return;
-				}
-				continue;
-			}
-			/*
-			 * if the line is '{' or '|', date got set; see
-			 * utmp(5) for more info.
-			 */
-			if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
-			    && !bp->ut_line[1]) {
-				if (want(bp, NO)) {
-					ct = fmttime(bp->ut_timefld, fulltime);
-				printf("%-*.*s  %-*.*s %-*.*s %s\n",
-				    namesz, namesz,
-				    bp->ut_name,
-				    linesz, linesz,
-				    bp->ut_line,
-				    hostsz, hostsz,
-				    bp->ut_host,
-				    ct);
-					if (maxrec && !--maxrec)
-						return;
-				}
-				continue;
-			}
-			/* find associated tty */
-			for (T = ttylist;; T = T->next) {
-				if (!T) {
-					/* add new one */
-					T = addtty(bp->ut_line);
-					break;
-				}
-				if (!strncmp(T->tty, bp->ut_line, LINESIZE))
-					break;
-			}
-			if (TYPE(bp) == SIGNATURE)
-				continue;
-			if (bp->ut_name[0] && want(bp, YES)) {
-				ct = fmttime(bp->ut_timefld, fulltime);
-				printf("%-*.*s  %-*.*s %-*.*s %s ",
-				    namesz, namesz, bp->ut_name,
-				    linesz, linesz, bp->ut_line,
-				    hostsz, hostsz, bp->ut_host,
-				    ct);
-				if (!T->logout)
-					puts("  still logged in");
-				else {
-					if (T->logout < 0) {
-						T->logout = -T->logout;
-						printf("- %s", crmsg);
-					}
-					else
-						printf("- %s",
-						    fmttime(T->logout,
-						    fulltime | TIMEONLY));
-					delta = T->logout - bp->ut_timefld;
-					if (delta < SECSPERDAY)
-						printf("  (%s)\n",
-						    fmttime(delta,
-						    fulltime | TIMEONLY | GMT));
-					else
-						printf(" (%ld+%s)\n",
-						    delta / SECSPERDAY,
-						    fmttime(delta,
-						    fulltime | TIMEONLY | GMT));
-				}
-				if (maxrec != -1 && !--maxrec)
-					return;
-			}
-			T->logout = bp->ut_timefld;
-		}
-	}
-	fulltime = 1;	/* show full time */
-	crmsg = fmttime(buf[FIRSTVALID].ut_timefld, FULLTIME);
-	if ((ct = strrchr(file, '/')) != NULL)
-		ct++;
-	printf("\n%s begins %s\n", ct ? ct : file, crmsg);
-}
-
-/*
- * want --
- *	see if want this entry
- */
-static int
-want(struct utmp *bp, int check)
-{
-	ARG *step;
-
-	if (check) {
-		/*
-		 * when uucp and ftp log in over a network, the entry in
-		 * the utmp file is the name plus their process id.  See
-		 * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
-		 */
-		if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
-			bp->ut_line[3] = '\0';
-		else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
-			bp->ut_line[4] = '\0';
-	}
-	if (!arglist)
-		return (YES);
-
-	for (step = arglist; step; step = step->next)
-		switch(step->type) {
-		case HOST_TYPE:
-			if (!strncasecmp(step->name, bp->ut_host, HOSTSIZE))
-				return (YES);
-			break;
-		case TTY_TYPE:
-			if (!strncmp(step->name, bp->ut_line, LINESIZE))
-				return (YES);
-			break;
-		case USER_TYPE:
-			if (!strncmp(step->name, bp->ut_name, NAMESIZE))
-				return (YES);
-			break;
-	}
-	return (NO);
-}
-
-/*
- * onintr --
- *	on interrupt, we inform the user how far we've gotten
- */
-static void
-onintr(int signo)
-{
-
-	printf("\ninterrupted %s\n", fmttime(buf[FIRSTVALID].ut_timefld,
-	    FULLTIME));
-	if (signo == SIGINT)
-		exit(1);
-	(void)fflush(stdout);		/* fix required for rsh */
-}
-- 
2.22.0

