<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16440">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  George Joseph: Approved for Submit

</div><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, 78 insertions(+), 27 deletions(-)<br><br></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..be10163 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 < HEADER_LEN) {</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,36 +182,15 @@</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>           if (termfd > -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        parseokay = parse_terminfo_file(termfd);</span><br><span style="color: hsl(120, 100%, 40%);">+                      close(termfd);</span><br><span>               }</span><br><span>    }</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 style="color: hsl(0, 100%, 40%);">-</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(0, 100%, 40%);">-</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 style="color: hsl(0, 100%, 40%);">-               close(termfd);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span> </span><br><span>        if (!parseokay) {</span><br><span>            /* These comparisons should not be substrings nor case-insensitive, as</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16440">change 16440</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/+/16440"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: I27a4fcfab502219924af2d6b1c46feba92903cb3 </div>
<div style="display:none"> Gerrit-Change-Number: 16440 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean@seanbright.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>