<p>Sean Bright has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16441">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">term.c: Add support for extended number format terminfo files.<br><br>ncurses 6.1 introduced an extended number format for terminfo files<br>which the terminfo parsing in Asterisk is not able to parse. This<br>results in some TERM values that do support color (screen-256color on<br>Ubuntu 20.04 for example) to not get a color console.<br><br>ASTERISK-29630 #close<br><br>Change-Id: I27a4fcfab502219924af2d6b1c46feba92903cb3<br>---<br>M main/term.c<br>1 file changed, 79 insertions(+), 25 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/41/16441/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/main/term.c b/main/term.c</span><br><span>index 617f82e..aed41d6 100644</span><br><span>--- a/main/term.c</span><br><span>+++ b/main/term.c</span><br><span>@@ -74,7 +74,7 @@</span><br><span> }</span><br><span> </span><br><span> /* Ripped off from Ross Ridge, but it's public domain code (libmytinfo) */</span><br><span style="color: hsl(0, 100%, 40%);">-static short convshort(char *s)</span><br><span style="color: hsl(120, 100%, 40%);">+static short convshort(unsigned char *s)</span><br><span> {</span><br><span> register int a, b;</span><br><span> </span><br><span>@@ -89,11 +89,83 @@</span><br><span> return a + b * 256;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static inline int convint(unsigned char *s)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return s[0]</span><br><span style="color: hsl(120, 100%, 40%);">+ | s[1] << 8</span><br><span style="color: hsl(120, 100%, 40%);">+ | s[2] << 16</span><br><span style="color: hsl(120, 100%, 40%);">+ | s[3] << 24;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAGIC_LEGACY (00432)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAGIC_EXTNUM (01036)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define HEADER_LEN (12)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_COLORS_INDEX (13)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int parse_terminfo_file(int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int bytes_read, bytes_needed, num_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ short magic, sz_names, sz_bools;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char buffer[1024];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bytes_read = read(fd, buffer, sizeof(buffer));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bytes_read == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ magic = convshort(buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (magic == MAGIC_LEGACY) {</span><br><span style="color: hsl(120, 100%, 40%);">+ num_size = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (magic == MAGIC_EXTNUM) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Extended number format (ncurses 6.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+ num_size = 4;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* We don't know how to parse this file */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sz_names = convshort(buffer + 2);</span><br><span style="color: hsl(120, 100%, 40%);">+ sz_bools = convshort(buffer + 4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* From term(5):</span><br><span style="color: hsl(120, 100%, 40%);">+ * Between the boolean section and the number section, a null byte will be</span><br><span style="color: hsl(120, 100%, 40%);">+ * inserted, if necessary, to ensure that the number section begins on an</span><br><span style="color: hsl(120, 100%, 40%);">+ * even byte. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((sz_names + sz_bools) & 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ sz_bools++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bytes_needed = HEADER_LEN + sz_names + sz_bools + ((MAX_COLORS_INDEX + 1) * num_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bytes_needed <= bytes_read) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Offset 13 is defined in /usr/include/term.h, though we do not</span><br><span style="color: hsl(120, 100%, 40%);">+ * include it here, as it conflicts with include/asterisk/term.h */</span><br><span style="color: hsl(120, 100%, 40%);">+ int max_colors;</span><br><span style="color: hsl(120, 100%, 40%);">+ int offset = HEADER_LEN + sz_names + sz_bools + MAX_COLORS_INDEX * num_size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (num_size == 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* In the legacy terminfo format, numbers are signed shorts */</span><br><span style="color: hsl(120, 100%, 40%);">+ max_colors = convshort(buffer + offset);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Extended number format makes them signed ints */</span><br><span style="color: hsl(120, 100%, 40%);">+ max_colors = convint(buffer + offset);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (max_colors > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ vt100compat = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int ast_term_init(void)</span><br><span> {</span><br><span> char *term = getenv("TERM");</span><br><span> char termfile[256] = "";</span><br><span style="color: hsl(0, 100%, 40%);">- char buffer[512] = "";</span><br><span> int termfd = -1, parseokay = 0, i;</span><br><span> </span><br><span> if (ast_opt_no_color) {</span><br><span>@@ -110,34 +182,16 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0;; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (termpath[i] == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; !parseokay && termpath[i]; i++) {</span><br><span> snprintf(termfile, sizeof(termfile), "%s/%c/%s", termpath[i], *term, term);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> termfd = open(termfile, O_RDONLY);</span><br><span style="color: hsl(0, 100%, 40%);">- if (termfd > -1) {</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (termfd == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (termfd > -1) {</span><br><span style="color: hsl(0, 100%, 40%);">- int actsize = read(termfd, buffer, sizeof(buffer) - 1);</span><br><span style="color: hsl(0, 100%, 40%);">- short sz_names = convshort(buffer + 2);</span><br><span style="color: hsl(0, 100%, 40%);">- short sz_bools = convshort(buffer + 4);</span><br><span style="color: hsl(0, 100%, 40%);">- short n_nums = convshort(buffer + 6);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* if ((sz_names + sz_bools) & 1)</span><br><span style="color: hsl(0, 100%, 40%);">- sz_bools++; */</span><br><span style="color: hsl(120, 100%, 40%);">+ parseokay = parse_terminfo_file(termfd);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (sz_names + sz_bools + n_nums < actsize) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Offset 13 is defined in /usr/include/term.h, though we do not</span><br><span style="color: hsl(0, 100%, 40%);">- * include it here, as it conflicts with include/asterisk/term.h */</span><br><span style="color: hsl(0, 100%, 40%);">- short max_colors = convshort(buffer + 12 + sz_names + sz_bools + 13 * 2);</span><br><span style="color: hsl(0, 100%, 40%);">- if (max_colors > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- vt100compat = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- parseokay = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> close(termfd);</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16441">change 16441</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/16441"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I27a4fcfab502219924af2d6b1c46feba92903cb3 </div>
<div style="display:none"> Gerrit-Change-Number: 16441 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean@seanbright.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>