commit 2e31e44ffa614c5202edfe2abcc05a7880902640
parent d90036de3c72730ae2797844b36eb5ae9fd3843f
Author: Quentin Rameau <quinq@fifth.space>
Date:   Fri, 29 Dec 2017 10:52:39 +0100
Truncate output to the terminal size
Thanks to Hiltjo for his input, making this patch a little better.
Diffstat:
| ui_ti.c |  |  | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++---------------------- | 
| ui_txt.c |  |  | 58 | +++++++++++++++++++++++++++++++++++++++++++--------------- | 
2 files changed, 92 insertions(+), 37 deletions(-)
diff --git a/ui_ti.c b/ui_ti.c
@@ -13,6 +13,7 @@
 #define C(c) #c
 #define S(c) C(c)
 
+static char bufout[256];
 static struct termios tsave;
 static struct termios tsacc;
 #if defined(__NetBSD__)
@@ -50,8 +51,8 @@ uiprompt(char *fmt, ...)
 {
 	va_list ap;
 	char *input = NULL;
-	size_t n = 0;
-	ssize_t r = 0;
+	size_t n;
+	ssize_t r;
 
 	putp(tparm(save_cursor));
 
@@ -60,19 +61,23 @@ uiprompt(char *fmt, ...)
 	putp(tparm(enter_standout_mode));
 
 	va_start(ap, fmt);
-	r += vprintf(fmt, ap);
+	if (vsnprintf(bufout, sizeof(bufout), fmt, ap) >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
 	va_end(ap);
+	printf("%.*s", columns, bufout);
 
 	putp(tparm(exit_standout_mode));
 
-	printf("%*s", columns-r, " ");
+	if ((n = strlen(bufout)) < columns)
+		printf("%*s", columns - n, " ");
 
-	putp(tparm(cursor_address, lines-1, r));
+	putp(tparm(cursor_address, lines-1, n));
 
 	tsacc.c_lflag |= (ECHO|ICANON);
 	tcsetattr(0, TCSANOW, &tsacc);
 	fflush(stdout);
 
+	n = 0;
 	r = getline(&input, &n, stdin);
 
 	tsacc.c_lflag &= ~(ECHO|ICANON);
@@ -93,7 +98,10 @@ uiprompt(char *fmt, ...)
 static void
 printitem(Item *item)
 {
-	printf("%s %s\r", typedisplay(item->type), item->username);
+	if (snprintf(bufout, sizeof(bufout), "%s %s", typedisplay(item->type),
+	    item->username) >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+	printf("%.*s\r", columns, bufout);
 }
 
 static Item *
@@ -127,7 +135,7 @@ void
 uistatus(char *fmt, ...)
 {
 	va_list ap;
-	int n = 0;
+	size_t n;
 
 	putp(tparm(save_cursor));
 
@@ -135,12 +143,20 @@ uistatus(char *fmt, ...)
 	putp(tparm(enter_standout_mode));
 
 	va_start(ap, fmt);
-	n += vprintf(fmt, ap);
+	n = vsnprintf(bufout + n, sizeof(bufout) - n, fmt, ap);
 	va_end(ap);
 
-	n += printf(" [Press a key to continue ☃]");
+	if (n < sizeof(bufout)-1) {
+		n += snprintf(bufout + n, sizeof(bufout) - n,
+		              " [Press a key to continue ☃]");
+	}
+	if (n >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+
+	printf("%.*s", columns, bufout);
 	putp(tparm(exit_standout_mode));
-	printf("%*s", columns-n, " ");
+	if ((n = strlen(bufout)) < columns)
+		printf("%*s", columns - n, " ");
 
 	putp(tparm(restore_cursor));
 	fflush(stdout);
@@ -153,9 +169,8 @@ displaystatus(Item *item)
 {
 	Dir *dir = item->dat;
 	char *fmt;
-	size_t nitems = dir ? dir->nitems : 0;
+	size_t n, nitems = dir ? dir->nitems : 0;
 	unsigned long long printoff = dir ? dir->printoff : 0;
-	int n;
 
 	putp(tparm(save_cursor));
 
@@ -163,12 +178,16 @@ displaystatus(Item *item)
 	putp(tparm(enter_standout_mode));
 	fmt = (strcmp(item->port, "70") && strcmp(item->port, "gopher")) ?
 	      "%1$3lld%%| %2$s:%5$s/%3$c%4$s" : "%3lld%%| %s/%c%s";
-	n = printf(fmt,
-	           (printoff + lines-1 >= nitems) ? 100 :
-	           (printoff + lines-1) * 100 / nitems,
-	           item->host, item->type, item->selector, item->port);
+	if (snprintf(bufout, sizeof(bufout), fmt,
+	             (printoff + lines-1 >= nitems) ? 100 :
+	             (printoff + lines-1) * 100 / nitems,
+	             item->host, item->type, item->selector, item->port)
+	    >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+	printf("%.*s", columns, bufout);
 	putp(tparm(exit_standout_mode));
-	printf("%*s", columns-n, " ");
+	if ((n = strlen(bufout)) < columns)
+		printf("%*s", columns - n, " ");
 
 	putp(tparm(restore_cursor));
 	fflush(stdout);
@@ -178,7 +197,7 @@ static void
 displayuri(Item *item)
 {
 	char *fmt;
-	int n;
+	size_t n;
 
 	if (item->type == 0 || item->type == 'i')
 		return;
@@ -189,18 +208,26 @@ displayuri(Item *item)
 	putp(tparm(enter_standout_mode));
 	switch (item->type) {
 	case 'h':
-		n = printf("%s: %s", item->username, item->selector);
+		n = snprintf(bufout, sizeof(bufout), "%s: %s",
+		             item->username, item->selector);
 		break;
 	default:
 		fmt = strcmp(item->port, "70") ?
 		      "%1$s: gopher://%2$s:%5$s/%3$c%4$s" :
 		      "%s: gopher://%s/%c%s";
-		n = printf(fmt, item->username,
-		           item->host, item->type, item->selector, item->port);
+		n = snprintf(bufout, sizeof(bufout), fmt,
+		             item->username, item->host, item->type,
+		             item->selector, item->port);
 		break;
 	}
+
+	if (n >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+
+	printf("%.*s", columns, bufout);
 	putp(tparm(exit_standout_mode));
-	printf("%*s", columns-n, " ");
+	if ((n = strlen(bufout)) < columns)
+		printf("%*s", columns - n, " ");
 
 	putp(tparm(restore_cursor));
 	fflush(stdout);
diff --git a/ui_txt.c b/ui_txt.c
@@ -10,6 +10,7 @@
 
 #include "common.h"
 
+static char bufout[256];
 int lines, columns;
 
 static void
@@ -67,12 +68,20 @@ void
 uistatus(char *fmt, ...)
 {
 	va_list arg;
+	int n;
 
 	va_start(arg, fmt);
-	vprintf(fmt, arg);
+	n = vsnprintf(bufout, sizeof(bufout), fmt, arg);
 	va_end(arg);
 
-	printf(" [Press Enter to continue ☃]");
+	if (n < sizeof(bufout)-1) {
+		n += snprintf(bufout + n, sizeof(bufout) - n,
+		              " [Press Enter to continue ☃]");
+	}
+	if (n >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+
+	printf("%.*s", columns, bufout);
 	fflush(stdout);
 
 	getchar();
@@ -89,9 +98,13 @@ printstatus(Item *item, char c)
 	fmt = (strcmp(item->port, "70") && strcmp(item->port, "gopher")) ?
 	      "%1$3lld%%%*2$3$c %4$s:%8$s/%5$c%6$s [%7$c]: " :
               "%3lld%%%*c %s/%c%s [%c]: ";
-	printf(fmt, (printoff + lines-1 >= nitems) ? 100 :
-	       (printoff + lines) * 100 / nitems, ndigits(nitems)+2, '|',
-	       item->host, item->type, item->selector, c, item->port);
+	if (snprintf(bufout, sizeof(bufout), fmt,
+	             (printoff + lines-1 >= nitems) ? 100 :
+	             (printoff + lines) * 100 / nitems, ndigits(nitems)+2, '|',
+	             item->host, item->type, item->selector, c, item->port)
+	    >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+	printf("%.*s", columns, bufout);
 }
 
 char *
@@ -103,9 +116,12 @@ uiprompt(char *fmt, ...)
 	ssize_t r;
 
 	va_start(ap, fmt);
-	vprintf(fmt, ap);
+	if (vsnprintf(bufout, sizeof(bufout), fmt, ap) >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
 	va_end(ap);
 
+	printf("%.*s", columns, bufout);
+
 	fflush(stdout);
 
 	if ((r = getline(&input, &n, stdin)) < 0) {
@@ -138,8 +154,12 @@ uidisplay(Item *entry)
 	nd = ndigits(nitems);
 
 	for (i = dir->printoff; i < nitems && i < nlines; ++i) {
-		printf("%*zu %s %s\n",
-		       nd, i+1, typedisplay(items[i].type), items[i].username);
+		if (snprintf(bufout, sizeof(bufout), "%*zu %s %s",
+		             nd, i+1, typedisplay(items[i].type),
+		             items[i].username)
+		    >= sizeof(bufout))
+			bufout[sizeof(bufout)-1] = '\0';
+		printf("%.*s\n", columns, bufout);
 	}
 
 	fflush(stdout);
@@ -149,27 +169,35 @@ void
 printuri(Item *item, size_t i)
 {
 	char *fmt;
+	int n;
 
 	if (!item)
 		return;
 
 	switch (item->type) {
 	case 0:
-		break;
+		return;
 	case 'i':
-		printf("%zu: %s\n", i, item->username);
+		n = snprintf(bufout, sizeof(bufout), "%zu: %s",
+		             i, item->username);
 		break;
 	case 'h':
-		printf("%zu: %s: %s\n", i, item->username, item->selector);
+		n = snprintf(bufout, sizeof(bufout), "%zu: %s: %s",
+		         i, item->username, item->selector);
 		break;
 	default:
 		fmt = strcmp(item->port, "70") ?
-		      "%1$zu: %2$s: gopher://%3$s:%6$s/%4$c%5$s\n" :
-		      "%zu: %s: gopher://%s/%c%s\n";
-		printf(fmt, i, item->username,
-		       item->host, item->type, item->selector, item->port);
+		      "%1$zu: %2$s: gopher://%3$s:%6$s/%4$c%5$s" :
+		      "%zu: %s: gopher://%s/%c%s";
+		n = snprintf(bufout, sizeof(bufout), fmt, i, item->username,
+		             item->host, item->type, item->selector, item->port);
 		break;
 	}
+	
+	if (n >= sizeof(bufout))
+		bufout[sizeof(bufout)-1] = '\0';
+
+	printf("%.*s\n", columns, bufout);
 }
 
 void