Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Sep 2019 21:53:05 +0000 (UTC)
From:      Mike Karels <karels@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r351966 - stable/12/usr.bin/w
Message-ID:  <201909062153.x86Lr53t051927@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: karels
Date: Fri Sep  6 21:53:04 2019
New Revision: 351966
URL: https://svnweb.freebsd.org/changeset/base/351966

Log:
  MFC r351379 r351385 r351592:
  
  Change w(1) to compute FROM (host) field size dynamically
  
  It's nice to be able to display a full IPv6 host address if
  needed, but it's also nice to display more than 3 characters of a command
  line. Compute the needed size for the FROM column in an earlier pass,
  and determine the maximum, then print what fits for the command.
  
  Fix address annotation in xml output from w
  
  The libxo xml feature of adding an annotation with the "original"
  address from the utmpx file if it is different than the final "from"
  field was broken by r351379. This was pointed out by the gcc error
  that save_p might be used uninitialized. Save the original address
  as needed in each entry, don't just use the last one from the previous
  loop.
  
  Reviewed by:    marcel@
  Differential Revision:  https://reviews.freebsd.org/D21211
  Differential Revision:  https://reviews.freebsd.org/D21390

Modified:
  stable/12/usr.bin/w/w.c

Modified: stable/12/usr.bin/w/w.c
==============================================================================
--- stable/12/usr.bin/w/w.c	Fri Sep  6 20:38:25 2019	(r351965)
+++ stable/12/usr.bin/w/w.c	Fri Sep  6 21:53:04 2019	(r351966)
@@ -96,7 +96,8 @@ static struct winsize ws;
 static kvm_t   *kd;
 static time_t	now;		/* the current time of day */
 static int	ttywidth;	/* width of tty */
-static int	argwidth;	/* width of tty */
+static int	fromwidth = 0;	/* max width of "from" field */
+static int	argwidth;	/* width of arguments */
 static int	header = 1;	/* true if -h flag: don't print heading */
 static int	nflag;		/* true if -n flag: don't convert addrs */
 static int	dflag;		/* true if -d flag: output debug info */
@@ -116,13 +117,15 @@ static struct entry {
 	struct	kinfo_proc *kp;		/* `most interesting' proc */
 	char	*args;			/* arg list of interesting process */
 	struct	kinfo_proc *dkp;	/* debug option proc list */
+	char	*from;			/* "from": name or addr */
+	char	*save_from;		/* original "from": name or addr */
 } *ep, *ehead = NULL, **nextp = &ehead;
 
 #define	debugproc(p) *(&((struct kinfo_proc *)p)->ki_udata)
 
 #define	W_DISPUSERSIZE	10
 #define	W_DISPLINESIZE	8
-#define	W_DISPHOSTSIZE	40
+#define	W_MAXHOSTSIZE	40
 
 static void		 pr_header(time_t *, int);
 static struct stat	*ttystat(char *);
@@ -209,6 +212,13 @@ main(int argc, char *argv[])
 
 	setutxent();
 	for (nusers = 0; (utmp = getutxent()) != NULL;) {
+		struct addrinfo hints, *res;
+		struct sockaddr_storage ss;
+		struct sockaddr *sa = (struct sockaddr *)&ss;
+		struct sockaddr_in *lsin = (struct sockaddr_in *)&ss;
+		struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)&ss;
+		int isaddr;
+
 		if (utmp->ut_type != USER_PROCESS)
 			continue;
 		if (!(stp = ttystat(utmp->ut_line)))
@@ -250,9 +260,78 @@ main(int argc, char *argv[])
 		}
 		if ((ep->idle = now - touched) < 0)
 			ep->idle = 0;
+
+		save_p = p = *ep->utmp.ut_host ? ep->utmp.ut_host : "-";
+		if ((x_suffix = strrchr(p, ':')) != NULL) {
+			if ((dot = strchr(x_suffix, '.')) != NULL &&
+			    strchr(dot+1, '.') == NULL)
+				*x_suffix++ = '\0';
+			else
+				x_suffix = NULL;
+		}
+
+		isaddr = 0;
+		memset(&ss, '\0', sizeof(ss));
+		if (inet_pton(AF_INET6, p, &lsin6->sin6_addr) == 1) {
+			lsin6->sin6_len = sizeof(*lsin6);
+			lsin6->sin6_family = AF_INET6;
+			isaddr = 1;
+		} else if (inet_pton(AF_INET, p, &lsin->sin_addr) == 1) {
+			lsin->sin_len = sizeof(*lsin);
+			lsin->sin_family = AF_INET;
+			isaddr = 1;
+		}
+		if (nflag == 0) {
+			/* Attempt to change an IP address into a name */
+			if (isaddr && realhostname_sa(fn, sizeof(fn), sa,
+			    sa->sa_len) == HOSTNAME_FOUND)
+				p = fn;
+		} else if (!isaddr && nflag > 1) {
+			/*
+			 * If a host has only one A/AAAA RR, change a
+			 * name into an IP address
+			 */
+			memset(&hints, 0, sizeof(hints));
+			hints.ai_flags = AI_PASSIVE;
+			hints.ai_family = AF_UNSPEC;
+			hints.ai_socktype = SOCK_STREAM;
+			if (getaddrinfo(p, NULL, &hints, &res) == 0) {
+				if (res->ai_next == NULL &&
+				    getnameinfo(res->ai_addr, res->ai_addrlen,
+					fn, sizeof(fn), NULL, 0,
+					NI_NUMERICHOST) == 0)
+					p = fn;
+				freeaddrinfo(res);
+			}
+		}
+
+		if (x_suffix) {
+			(void)snprintf(buf, sizeof(buf), "%s:%s", p, x_suffix);
+			p = buf;
+		}
+		ep->from = strdup(p);
+		if ((i = strlen(p)) > fromwidth)
+			fromwidth = i;
+		if (save_p != p)
+			ep->save_from = strdup(save_p);
 	}
 	endutxent();
 
+#define HEADER_USER		"USER"
+#define HEADER_TTY		"TTY"
+#define HEADER_FROM		"FROM"
+#define HEADER_LOGIN_IDLE	"LOGIN@  IDLE "
+#define HEADER_WHAT		"WHAT\n"
+#define WUSED  (W_DISPUSERSIZE + W_DISPLINESIZE + fromwidth + \
+		sizeof(HEADER_LOGIN_IDLE) + 3)	/* header width incl. spaces */ 
+
+
+	if ((int) sizeof(HEADER_FROM) > fromwidth)
+		fromwidth = sizeof(HEADER_FROM);
+	fromwidth++;
+	if (fromwidth > W_MAXHOSTSIZE)
+		fromwidth = W_MAXHOSTSIZE;
+
 	xo_open_container("uptime-information");
 
 	if (header || wcmd == 0) {
@@ -265,17 +344,10 @@ main(int argc, char *argv[])
 			exit(0);
 		}
 
-#define HEADER_USER		"USER"
-#define HEADER_TTY		"TTY"
-#define HEADER_FROM		"FROM"
-#define HEADER_LOGIN_IDLE	"LOGIN@  IDLE "
-#define HEADER_WHAT		"WHAT\n"
-#define WUSED  (W_DISPUSERSIZE + W_DISPLINESIZE + W_DISPHOSTSIZE + \
-		sizeof(HEADER_LOGIN_IDLE) + 3)	/* header width incl. spaces */ 
 		xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s}  {T:/%s}", 
 				W_DISPUSERSIZE, W_DISPUSERSIZE, HEADER_USER,
 				W_DISPLINESIZE, W_DISPLINESIZE, HEADER_TTY,
-				W_DISPHOSTSIZE, W_DISPHOSTSIZE, HEADER_FROM,
+				fromwidth, fromwidth, HEADER_FROM,
 				HEADER_LOGIN_IDLE HEADER_WHAT);
 	}
 
@@ -350,64 +422,10 @@ main(int argc, char *argv[])
 	xo_open_list("user-entry");
 
 	for (ep = ehead; ep != NULL; ep = ep->next) {
-		struct addrinfo hints, *res;
-		struct sockaddr_storage ss;
-		struct sockaddr *sa = (struct sockaddr *)&ss;
-		struct sockaddr_in *lsin = (struct sockaddr_in *)&ss;
-		struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)&ss;
 		time_t t;
-		int isaddr;
 
 		xo_open_instance("user-entry");
 
-		save_p = p = *ep->utmp.ut_host ? ep->utmp.ut_host : "-";
-		if ((x_suffix = strrchr(p, ':')) != NULL) {
-			if ((dot = strchr(x_suffix, '.')) != NULL &&
-			    strchr(dot+1, '.') == NULL)
-				*x_suffix++ = '\0';
-			else
-				x_suffix = NULL;
-		}
-
-		isaddr = 0;
-		memset(&ss, '\0', sizeof(ss));
-		if (inet_pton(AF_INET6, p, &lsin6->sin6_addr) == 1) {
-			lsin6->sin6_len = sizeof(*lsin6);
-			lsin6->sin6_family = AF_INET6;
-			isaddr = 1;
-		} else if (inet_pton(AF_INET, p, &lsin->sin_addr) == 1) {
-			lsin->sin_len = sizeof(*lsin);
-			lsin->sin_family = AF_INET;
-			isaddr = 1;
-		}
-		if (nflag == 0) {
-			/* Attempt to change an IP address into a name */
-			if (isaddr && realhostname_sa(fn, sizeof(fn), sa,
-			    sa->sa_len) == HOSTNAME_FOUND)
-				p = fn;
-		} else if (!isaddr && nflag > 1) {
-			/*
-			 * If a host has only one A/AAAA RR, change a
-			 * name into an IP address
-			 */
-			memset(&hints, 0, sizeof(hints));
-			hints.ai_flags = AI_PASSIVE;
-			hints.ai_family = AF_UNSPEC;
-			hints.ai_socktype = SOCK_STREAM;
-			if (getaddrinfo(p, NULL, &hints, &res) == 0) {
-				if (res->ai_next == NULL &&
-				    getnameinfo(res->ai_addr, res->ai_addrlen,
-					fn, sizeof(fn), NULL, 0,
-					NI_NUMERICHOST) == 0)
-					p = fn;
-				freeaddrinfo(res);
-			}
-		}
-
-		if (x_suffix) {
-			(void)snprintf(buf, sizeof(buf), "%s:%s", p, x_suffix);
-			p = buf;
-		}
 		if (dflag) {
 		        xo_open_container("process-table");
 		        xo_open_list("process-entry");
@@ -435,10 +453,10 @@ main(int argc, char *argv[])
 			 strncmp(ep->utmp.ut_line, "cua", 3) ?
 			 ep->utmp.ut_line : ep->utmp.ut_line + 3) : "-");
 
-		if (save_p && save_p != p)
-		    xo_attr("address", "%s", save_p);
+		if (ep->save_from)
+		    xo_attr("address", "%s", ep->save_from);
 		xo_emit("{:from/%-*.*s/%@**@s} ",
-		    W_DISPHOSTSIZE, W_DISPHOSTSIZE, *p ? p : "-");
+		    fromwidth, fromwidth, ep->from);
 		t = ep->utmp.ut_tv.tv_sec;
 		longattime = pr_attime(&t, &now);
 		longidle = pr_idle(ep->idle);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909062153.x86Lr53t051927>