svn commit: r314640 - head/usr.bin/ruptime

Bruce Evans bde at FreeBSD.org
Sat Mar 4 04:06:35 UTC 2017


Author: bde
Date: Sat Mar  4 04:06:33 2017
New Revision: 314640
URL: https://svnweb.freebsd.org/changeset/base/314640

Log:
  Fix formatting.  ruptime output on FreeBSD cluster machines annoyed me
  by usually being double-spaced due to auto-wrap at column 80.
  
  r212771 increased width of the hostname field from 12 to 25.  This was
  supposed to allow for 80-column output with all 3 load averages taking
  5 characters each, but it actually gave width exactly 80 and thus worse
  than useless auto-wrap in that case.  3 wide load average fields are
  unusual, but later expansion of another field gave the auto-wrap with
  just 2 wide load average fields.
  
  Change to dynamic field widths for all fields except the uptime.  This
  also fixes the formatting of high (above 9999) user counts and not
  very high (above 9.99) load averages.  The formatting for numbers now
  breaks at 99999.99, but scientific notation should be used starting
  well below that.
  
  The field width for the uptime remains hard-coded to work consistently
  for uptimes less than 10000 days, but this gives too much space for
  small uptimes.  Punctuation between fields could be improved in many
  ways, for example by removing it.

Modified:
  head/usr.bin/ruptime/ruptime.c

Modified: head/usr.bin/ruptime/ruptime.c
==============================================================================
--- head/usr.bin/ruptime/ruptime.c	Sat Mar  4 00:33:41 2017	(r314639)
+++ head/usr.bin/ruptime/ruptime.c	Sat Mar  4 04:06:33 2017	(r314640)
@@ -69,6 +69,7 @@ static DIR *dirp;
 
 static int	 hscmp(const void *, const void *);
 static char	*interval(time_t, const char *);
+static int	 iwidth(int);
 static int	 lcmp(const void *, const void *);
 static void	 ruptime(const char *, int, int (*)(const void *, const void *));
 static int	 tcmp(const void *, const void *);
@@ -143,6 +144,21 @@ interval(time_t tval, const char *updown
 	return (resbuf);
 }
 
+/* Width to print a small nonnegative integer. */
+static int
+iwidth(int w)
+{
+	if (w < 10)
+		return (1);
+	if (w < 100)
+		return (2);
+	if (w < 1000)
+		return (3);
+	if (w < 10000)
+		return (4);
+	return (5);
+}
+
 #define	HS(a)	((const struct hs *)(a))
 
 /* Alphabetical comparison. */
@@ -176,14 +192,17 @@ ruptime(const char *host, int aflg, int 
 	struct whod *wd;
 	struct whoent *we;
 	struct dirent *dp;
-	const char *hostname;
-	int fd, i, maxloadav;
+	int fd, hostnamewidth, i, loadavwidth[3], userswidth, w;
 	size_t hspace;
 	ssize_t cc;
 
 	rewinddir(dirp);
 	hsp = NULL;
-	maxloadav = -1;
+	hostnamewidth = 0;
+	loadavwidth[0] = 4;
+	loadavwidth[1] = 4;
+	loadavwidth[2] = 4;
+	userswidth = 1;
 	(void)time(&now);
 	for (nhosts = hspace = 0; (dp = readdir(dirp)) != NULL;) {
 		if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0)
@@ -206,22 +225,25 @@ ruptime(const char *host, int aflg, int 
 		if (cc < (ssize_t)WHDRSIZE)
 			continue;
 
-		if (host != NULL) {
-			hostname = wd->wd_hostname;
-			if (strcasecmp(hostname, host) != 0)
-				continue;
-		}
+		if (host != NULL && strcasecmp(wd->wd_hostname, host) != 0)
+			continue;
 		if (LEFTEARTH(wd->wd_recvtime))
 			continue;
 
-		for (i = 0; i < 2; i++)
-			if (wd->wd_loadav[i] > maxloadav)
-				maxloadav = wd->wd_loadav[i];
+		if (hostnamewidth < (int)strlen(wd->wd_hostname))
+			hostnamewidth = (int)strlen(wd->wd_hostname);
+		for (i = 0; i < 3; i++) {
+			w = iwidth(wd->wd_loadav[i] / 100) + 3;
+			if (loadavwidth[i] < w)
+				loadavwidth[i] = w;
+		}
 
 		for (hsp->hs_nusers = 0, we = &wd->wd_we[0];
 		    (char *)(we + 1) <= (char *)wd + cc; we++)
 			if (aflg || we->we_idle < 3600)
 				++hsp->hs_nusers;
+		if (userswidth < iwidth(hsp->hs_nusers))
+			userswidth = iwidth(hsp->hs_nusers);
 		++hsp;
 		++nhosts;
 	}
@@ -233,27 +255,28 @@ ruptime(const char *host, int aflg, int 
 	}
 
 	qsort(hs, nhosts, sizeof(hs[0]), cmp);
+	w = userswidth + loadavwidth[0] + loadavwidth[1] + loadavwidth[2];
+	if (hostnamewidth + w > 41)
+		hostnamewidth = 41 - w;	/* limit to 79 cols */
 	for (i = 0; i < (int)nhosts; i++) {
 		hsp = &hs[i];
 		wd = &hsp->hs_wd;
 		if (ISDOWN(hsp)) {
-			(void)printf("%-25.25s%s\n", wd->wd_hostname,
+			(void)printf("%-*.*s%s\n",
+			    hostnamewidth, hostnamewidth, wd->wd_hostname,
 			    interval(now - hsp->hs_wd.wd_recvtime, "down"));
 			continue;
 		}
 		(void)printf(
-		    "%-25.25s%s,  %4d user%s  load %*.2f, %*.2f, %*.2f\n",
-		    wd->wd_hostname,
+		    "%-*.*s  %s,  %*d user%s  load %*.2f, %*.2f, %*.2f\n",
+		    hostnamewidth, hostnamewidth, wd->wd_hostname,
 		    interval((time_t)wd->wd_sendtime -
 		        (time_t)wd->wd_boottime, "  up"),
-		    hsp->hs_nusers,
+		    userswidth, hsp->hs_nusers,
 		    hsp->hs_nusers == 1 ? ", " : "s,",
-		    maxloadav >= 1000 ? 5 : 4,
-		        wd->wd_loadav[0] / 100.0,
-		    maxloadav >= 1000 ? 5 : 4,
-		        wd->wd_loadav[1] / 100.0,
-		    maxloadav >= 1000 ? 5 : 4,
-		        wd->wd_loadav[2] / 100.0);
+		    loadavwidth[0], wd->wd_loadav[0] / 100.0,
+		    loadavwidth[1], wd->wd_loadav[1] / 100.0,
+		    loadavwidth[2], wd->wd_loadav[2] / 100.0);
 	}
 	free(hs);
 	hs = NULL;


More information about the svn-src-all mailing list