[Asterisk-code-review] term.c: Add support for extended number format terminfo files. (asterisk[18])

Sean Bright asteriskteam at digium.com
Sat Sep 4 12:14:14 CDT 2021


Sean Bright has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/16439 )


Change subject: term.c: Add support for extended number format terminfo files.
......................................................................

term.c: Add support for extended number format terminfo files.

ncurses 6.1 introduced an extended number format for terminfo files
which the terminfo parsing in Asterisk is not able to parse. This
results in some TERM values that do support color (screen-256color on
Ubuntu 20.04 for example) to not get a color console.

ASTERISK-29630 #close

Change-Id: I27a4fcfab502219924af2d6b1c46feba92903cb3
---
M main/term.c
1 file changed, 79 insertions(+), 25 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/39/16439/1

diff --git a/main/term.c b/main/term.c
index 617f82e..aed41d6 100644
--- a/main/term.c
+++ b/main/term.c
@@ -74,7 +74,7 @@
 }
 
 /* Ripped off from Ross Ridge, but it's public domain code (libmytinfo) */
-static short convshort(char *s)
+static short convshort(unsigned char *s)
 {
 	register int a, b;
 
@@ -89,11 +89,83 @@
 	return a + b * 256;
 }
 
+static inline int convint(unsigned char *s)
+{
+	return s[0]
+		| s[1] << 8
+		| s[2] << 16
+		| s[3] << 24;
+}
+
+#define MAGIC_LEGACY (00432)
+#define MAGIC_EXTNUM (01036)
+
+#define HEADER_LEN (12)
+#define MAX_COLORS_INDEX (13)
+
+static int parse_terminfo_file(int fd)
+{
+	int bytes_read, bytes_needed, num_size;
+	short magic, sz_names, sz_bools;
+	unsigned char buffer[1024];
+
+	bytes_read = read(fd, buffer, sizeof(buffer));
+	if (bytes_read == -1) {
+		return 0;
+	}
+
+	magic = convshort(buffer);
+
+	if (magic == MAGIC_LEGACY) {
+		num_size = 2;
+	} else if (magic == MAGIC_EXTNUM) {
+		/* Extended number format (ncurses 6.1) */
+		num_size = 4;
+	} else {
+		/* We don't know how to parse this file */
+		return 0;
+	}
+
+	sz_names = convshort(buffer + 2);
+	sz_bools = convshort(buffer + 4);
+
+	/* >From term(5):
+	 * Between the boolean section and the number section, a null byte will be
+	 * inserted, if necessary, to ensure that the number section begins on an
+	 * even byte. */
+	if ((sz_names + sz_bools) & 1) {
+		sz_bools++;
+	}
+
+	bytes_needed = HEADER_LEN + sz_names + sz_bools + ((MAX_COLORS_INDEX + 1) * num_size);
+	if (bytes_needed <= bytes_read) {
+		/* Offset 13 is defined in /usr/include/term.h, though we do not
+		 * include it here, as it conflicts with include/asterisk/term.h */
+		int max_colors;
+		int offset = HEADER_LEN + sz_names + sz_bools + MAX_COLORS_INDEX * num_size;
+
+		if (num_size == 2) {
+			/* In the legacy terminfo format, numbers are signed shorts */
+			max_colors = convshort(buffer + offset);
+		} else {
+			/* Extended number format makes them signed ints */
+			max_colors = convint(buffer + offset);
+		}
+
+		if (max_colors > 0) {
+			vt100compat = 1;
+		}
+
+		return 1;
+	}
+
+	return 0;
+}
+
 int ast_term_init(void)
 {
 	char *term = getenv("TERM");
 	char termfile[256] = "";
-	char buffer[512] = "";
 	int termfd = -1, parseokay = 0, i;
 
 	if (ast_opt_no_color) {
@@ -110,34 +182,16 @@
 		return 0;
 	}
 
-	for (i = 0;; i++) {
-		if (termpath[i] == NULL) {
-			break;
-		}
+	for (i = 0; !parseokay && termpath[i]; i++) {
 		snprintf(termfile, sizeof(termfile), "%s/%c/%s", termpath[i], *term, term);
+
 		termfd = open(termfile, O_RDONLY);
-		if (termfd > -1) {
-			break;
+		if (termfd == -1) {
+			continue;
 		}
-	}
-	if (termfd > -1) {
-		int actsize = read(termfd, buffer, sizeof(buffer) - 1);
-		short sz_names = convshort(buffer + 2);
-		short sz_bools = convshort(buffer + 4);
-		short n_nums   = convshort(buffer + 6);
 
-		/* if ((sz_names + sz_bools) & 1)
-			sz_bools++; */
+		parseokay = parse_terminfo_file(termfd);
 
-		if (sz_names + sz_bools + n_nums < actsize) {
-			/* Offset 13 is defined in /usr/include/term.h, though we do not
-			 * include it here, as it conflicts with include/asterisk/term.h */
-			short max_colors = convshort(buffer + 12 + sz_names + sz_bools + 13 * 2);
-			if (max_colors > 0) {
-				vt100compat = 1;
-			}
-			parseokay = 1;
-		}
 		close(termfd);
 	}
 

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/16439
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 18
Gerrit-Change-Id: I27a4fcfab502219924af2d6b1c46feba92903cb3
Gerrit-Change-Number: 16439
Gerrit-PatchSet: 1
Gerrit-Owner: Sean Bright <sean at seanbright.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210904/d05d886e/attachment-0001.html>


More information about the asterisk-code-review mailing list