The branch main has been updated by asomers:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0726c6574f889507e5030173bf4c82c80911394d

commit 0726c6574f889507e5030173bf4c82c80911394d
Author:     Damin Rido <r...@freebsd.com>
AuthorDate: 2025-06-12 09:12:49 +0000
Commit:     Alan Somers <asom...@freebsd.org>
CommitDate: 2025-06-27 15:54:41 +0000

    sockstat: Add automatic column sizing and remove -w option
    
    Refactor sockstat to dynamically size table columns based on content.
    This eliminates the need for the -w option, which is now ignored
    for backwards compatibility.
    
    Numeric columns are now right-aligned for improved readability;
    previously, they were left-aligned.
    
    Unknown fields are now consistently shown as "??" instead of a mix
    of "", "?", and "?" for output uniformity.
    
    Sponsored by:   Google, LLC (GSoC 2025)
    MFC after:      2 weeks
    Reviewed by:    asomers
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1720
---
 usr.bin/sockstat/sockstat.1 |   6 +-
 usr.bin/sockstat/sockstat.c | 622 +++++++++++++++++++++++++++-----------------
 2 files changed, 392 insertions(+), 236 deletions(-)

diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1
index b13c6afdd9c0..da658e33e542 100644
--- a/usr.bin/sockstat/sockstat.1
+++ b/usr.bin/sockstat/sockstat.1
@@ -25,7 +25,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 6, 2025
+.Dd June 27, 2025
 .Dt SOCKSTAT 1
 .Os
 .Sh NAME
@@ -33,7 +33,7 @@
 .Nd list open sockets
 .Sh SYNOPSIS
 .Nm
-.Op Fl 46ACcfIiLlnqSsUuvw
+.Op Fl 46ACcfIiLlnqSsUuv
 .Op Fl j Ar jail
 .Op Fl p Ar ports
 .Op Fl P Ar protocols
@@ -119,8 +119,6 @@ Show
 sockets.
 .It Fl v
 Verbose mode.
-.It Fl w
-Use wider field size for displaying addresses.
 .El
 .Pp
 If neither
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index e1a52c57b3d1..52243910a31c 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -97,7 +97,6 @@ static bool    opt_s;         /* Show protocol state if 
applicable */
 static bool     opt_U;         /* Show remote UDP encapsulation port number */
 static bool     opt_u;         /* Show Unix domain sockets */
 static u_int    opt_v;         /* Verbose mode */
-static bool     opt_w;         /* Wide print area for addresses */
 
 /*
  * Default protocols to use if no -P was defined.
@@ -193,20 +192,6 @@ static cap_channel_t *capnetdb;
 static cap_channel_t *capsysctl;
 static cap_channel_t *cappwd;
 
-static int
-xprintf(const char *fmt, ...)
-{
-       va_list ap;
-       int len;
-
-       va_start(ap, fmt);
-       len = vprintf(fmt, ap);
-       va_end(ap);
-       if (len < 0)
-               err(1, "printf()");
-       return (len);
-}
-
 static bool
 _check_ksize(size_t received_size, size_t expected_size, const char 
*struct_name)
 {
@@ -941,7 +926,7 @@ getfiles(void)
 }
 
 static int
-printaddr(struct sockaddr_storage *ss)
+formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
 {
        struct sockaddr_un *sun;
        char addrstr[NI_MAXHOST] = { '\0', '\0' };
@@ -961,18 +946,18 @@ printaddr(struct sockaddr_storage *ss)
        case AF_UNIX:
                sun = sstosun(ss);
                off = (int)((char *)&sun->sun_path - (char *)sun);
-               return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
+               return snprintf(buf, bufsize, "%.*s",
+                               sun->sun_len - off, sun->sun_path);
        }
        if (addrstr[0] == '\0') {
                error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
-                   addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
+                       addrstr, sizeof(addrstr), buf, bufsize, NI_NUMERICHOST);
                if (error)
                        errx(1, "cap_getnameinfo()");
        }
        if (port == 0)
-               return xprintf("%s:*", addrstr);
-       else
-               return xprintf("%s:%d", addrstr, port);
+               return snprintf(buf, bufsize, "%s:*", addrstr);
+       return snprintf(buf, bufsize, "%s:%d", addrstr, port);
 }
 
 static const char *
@@ -1107,235 +1092,408 @@ sctp_path_state(int state)
        }
 }
 
+static int
+format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
+       #define SAFEBUF  (buf == NULL ? NULL : buf + pos)
+       #define SAFESIZE (buf == NULL ? 0 : bufsize - pos)
+
+       size_t pos = 0;
+       /* Remote peer we connect(2) to, if any. */
+       if (faddr->conn != 0) {
+               struct sock *p;
+               pos += strlcpy(buf, "-> ", bufsize);
+               p = RB_FIND(pcbs_t, &pcbs,
+                       &(struct sock){ .pcb = faddr->conn });
+               if (__predict_false(p == NULL)) {
+                       /* XXGL: can this happen at all? */
+                       pos += snprintf(SAFEBUF, SAFESIZE, "??");
+               } else if (p->laddr->address.ss_len == 0) {
+                       struct file *f;
+                       f = RB_FIND(files_t, &ftree,
+                               &(struct file){ .xf_data =
+                               p->socket });
+                       if (f != NULL) {
+                               pos += snprintf(SAFEBUF, SAFESIZE, "[%lu %d]",
+                                       (u_long)f->xf_pid, f->xf_fd);
+                       }
+               } else
+                       pos += formataddr(&p->laddr->address,
+                               SAFEBUF, SAFESIZE);
+       }
+       /* Remote peer(s) connect(2)ed to us, if any. */
+       if (faddr->firstref != 0) {
+               struct sock *p;
+               struct file *f;
+               kvaddr_t ref = faddr->firstref;
+               bool fref = true;
+
+               pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
+
+               while ((p = RB_FIND(pcbs_t, &pcbs,
+                       &(struct sock){ .pcb = ref })) != 0) {
+                       f = RB_FIND(files_t, &ftree,
+                               &(struct file){ .xf_data =
+                               p->socket });
+                       if (f != NULL) {
+                               pos += snprintf(SAFEBUF, SAFESIZE,
+                                       "%s[%lu %d]", fref ? "" : ",",
+                                       (u_long)f->xf_pid, f->xf_fd);
+                       }
+                       ref = p->faddr->nextref;
+                       fref = false;
+               }
+       }
+       return pos;
+}
+
+struct col_widths {
+       int user;
+       int command;
+       int pid;
+       int fd;
+       int proto;
+       int local_addr;
+       int foreign_addr;
+       int pcb_kva;
+       int fib;
+       int splice_address;
+       int inp_gencnt;
+       int encaps;
+       int path_state;
+       int conn_state;
+       int stack;
+       int cc;
+};
+
 static void
-displaysock(struct sock *s, int pos)
+calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
 {
-       int first, offset;
        struct addr *laddr, *faddr;
-
-       while (pos < 30)
-               pos += xprintf(" ");
-       pos += xprintf("%s", s->protoname);
-       if (s->vflag & INP_IPV4)
-               pos += xprintf("4");
-       if (s->vflag & INP_IPV6)
-               pos += xprintf("6");
-       if (s->vflag & (INP_IPV4 | INP_IPV6))
-               pos += xprintf(" ");
+       bool first = true;
+       int len = 0;
        laddr = s->laddr;
        faddr = s->faddr;
-       first = 1;
+       first = true;
+
+       len = strlen(s->protoname);
+       if (s->vflag & (INP_IPV4 | INP_IPV6))
+               len += 1;
+       if (laddr != NULL && faddr != NULL && s->family == AF_UNIX &&
+               laddr->address.ss_len == 0 && faddr->conn == 0)
+               len += strlen(" (not connected)");
+       cw->proto = MAX(cw->proto, len);
+
        while (laddr != NULL || faddr != NULL) {
-               offset = 37;
-               while (pos < offset)
-                       pos += xprintf(" ");
-               switch (s->family) {
-               case AF_INET:
-               case AF_INET6:
-                       if (laddr != NULL)
-                               pos += printaddr(&laddr->address);
-                       offset += opt_w ? 46 : 22;
-                       do
-                               pos += xprintf(" ");
-                       while (pos < offset);
-                       if (faddr != NULL)
-                               pos += printaddr(&faddr->address);
-                       offset += opt_w ? 46 : 22;
-                       break;
-               case AF_UNIX:
+               if (s->family == AF_UNIX) {
                        if ((laddr == NULL) || (faddr == NULL))
                                errx(1, "laddr = %p or faddr = %p is NULL",
-                                   (void *)laddr, (void *)faddr);
-                       if (laddr->address.ss_len == 0 && faddr->conn == 0) {
-                               pos += xprintf("(not connected)");
-                               offset += opt_w ? 92 : 44;
-                               break;
-                       }
-                       /* Local bind(2) address, if any. */
+                                       (void *)laddr, (void *)faddr);
                        if (laddr->address.ss_len > 0)
-                               pos += printaddr(&laddr->address);
-                       /* Remote peer we connect(2) to, if any. */
-                       if (faddr->conn != 0) {
-                               struct sock *p;
-
-                               pos += xprintf("%s-> ",
-                                   laddr->address.ss_len > 0 ? " " : "");
-                               p = RB_FIND(pcbs_t, &pcbs,
-                                   &(struct sock){ .pcb = faddr->conn });
-                               if (__predict_false(p == NULL)) {
-                                       /* XXGL: can this happen at all? */
-                                       pos += xprintf("??");
-                               }  else if (p->laddr->address.ss_len == 0) {
-                                       struct file *f;
-
-                                       f = RB_FIND(files_t, &ftree,
-                                           &(struct file){ .xf_data =
-                                           p->socket });
-                                       if (f != NULL) {
-                                               pos += xprintf("[%lu %d]",
-                                                   (u_long)f->xf_pid,
-                                                   f->xf_fd);
-                                       }
-                               } else
-                                       pos += printaddr(&p->laddr->address);
+                               len = formataddr(&laddr->address, NULL, 0);
+                       cw->local_addr = MAX(cw->local_addr, len);
+                       len = format_unix_faddr(faddr, NULL, 0);
+                       cw->foreign_addr = MAX(cw->foreign_addr, len);
+               } else {
+                       if (laddr != NULL) {
+                               len = formataddr(&laddr->address, NULL, 0);
+                               cw->local_addr = MAX(cw->local_addr, len);
                        }
-                       /* Remote peer(s) connect(2)ed to us, if any. */
-                       if (faddr->firstref != 0) {
-                               struct sock *p;
-                               struct file *f;
-                               kvaddr_t ref = faddr->firstref;
-                               bool fref = true;
-
-                               pos += xprintf(" <- ");
-
-                               while ((p = RB_FIND(pcbs_t, &pcbs,
-                                   &(struct sock){ .pcb = ref })) != 0) {
-                                       f = RB_FIND(files_t, &ftree,
-                                           &(struct file){ .xf_data =
-                                           p->socket });
-                                       if (f != NULL) {
-                                               pos += xprintf("%s[%lu %d]",
-                                                   fref ? "" : ",",
-                                                   (u_long)f->xf_pid,
-                                                   f->xf_fd);
-                                       }
-                                       ref = p->faddr->nextref;
-                                       fref = false;
-                               }
+                       if (faddr != NULL) {
+                               len = formataddr(&faddr->address, NULL, 0);
+                               cw->foreign_addr = MAX(cw->foreign_addr, len);
                        }
-                       offset += opt_w ? 92 : 44;
-                       break;
-               default:
-                       abort();
-               }
-               while (pos < offset)
-                       pos += xprintf(" ");
-               if (opt_A) {
-                       pos += xprintf("0x%16lx", s->pcb);
-                       offset += 18;
                }
                if (opt_f) {
-                       pos += xprintf("%d", s->fibnum);
-                       offset += 7;
+                       len = snprintf(NULL, 0, "%d", s->fibnum);
+                       cw->fib = MAX(cw->fib, len);
                }
                if (opt_I) {
                        if (s->splice_socket != 0) {
                                struct sock *sp;
 
                                sp = RB_FIND(socks_t, &socks, &(struct sock)
-                                   { .socket = s->splice_socket });
+                                       { .socket = s->splice_socket });
                                if (sp != NULL) {
-                                       do
-                                               pos += xprintf(" ");
-                                       while (pos < offset);
-                                       pos += printaddr(&sp->laddr->address);
-                               } else {
-                                       do
-                                               pos += xprintf(" ");
-                                       while (pos < offset);
-                                       pos += xprintf("??");
-                                       offset += opt_w ? 46 : 22;
+                                       len = formataddr(&sp->laddr->address,
+                                                NULL, 0);
+                                       cw->splice_address = MAX(
+                                               cw->splice_address, len);
                                }
                        }
-                       offset += opt_w ? 46 : 22;
                }
                if (opt_i) {
-                       if (s->proto == IPPROTO_TCP ||
-                           s->proto == IPPROTO_UDP) {
-                               do
-                                       pos += xprintf(" ");
-                               while (pos < offset);
-                               pos += xprintf("%" PRIu64, s->inp_gencnt);
+                       if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
+                       {
+                               len = snprintf(NULL, 0,
+                                       "%" PRIu64, s->inp_gencnt);
+                               cw->inp_gencnt = MAX(cw->inp_gencnt, len);
                        }
-                       offset += 9;
                }
                if (opt_U) {
                        if (faddr != NULL &&
-                           ((s->proto == IPPROTO_SCTP &&
-                             s->state != SCTP_CLOSED &&
-                             s->state != SCTP_BOUND &&
-                             s->state != SCTP_LISTEN) ||
-                            (s->proto == IPPROTO_TCP &&
-                             s->state != TCPS_CLOSED &&
-                             s->state != TCPS_LISTEN))) {
-                               do
-                                       pos += xprintf(" ");
-                               while (pos < offset);
-                               pos += xprintf("%u",
-                                   ntohs(faddr->encaps_port));
+                               ((s->proto == IPPROTO_SCTP &&
+                                       s->state != SCTP_CLOSED &&
+                                       s->state != SCTP_BOUND &&
+                                       s->state != SCTP_LISTEN) ||
+                                       (s->proto == IPPROTO_TCP &&
+                                       s->state != TCPS_CLOSED &&
+                                       s->state != TCPS_LISTEN))) {
+                               len = snprintf(NULL, 0, "%u",
+                                       ntohs(faddr->encaps_port));
+                               cw->encaps = MAX(cw->encaps, len);
                        }
-                       offset += 7;
                }
                if (opt_s) {
                        if (faddr != NULL &&
-                           s->proto == IPPROTO_SCTP &&
-                           s->state != SCTP_CLOSED &&
-                           s->state != SCTP_BOUND &&
-                           s->state != SCTP_LISTEN) {
-                               do
-                                       pos += xprintf(" ");
-                               while (pos < offset);
-                               pos += xprintf("%s",
-                                   sctp_path_state(faddr->state));
+                               s->proto == IPPROTO_SCTP &&
+                               s->state != SCTP_CLOSED &&
+                               s->state != SCTP_BOUND &&
+                               s->state != SCTP_LISTEN) {
+                               len = strlen(sctp_path_state(faddr->state));
+                               cw->path_state = MAX(cw->path_state, len);
                        }
-                       offset += 13;
+               }
+               if (first) {
+                       if (opt_s) {
+                               if (s->proto == IPPROTO_SCTP ||
+                                       s->proto == IPPROTO_TCP) {
+                                       switch (s->proto) {
+                                       case IPPROTO_SCTP:
+                                               len = strlen(
+                                                   sctp_conn_state(s->state));
+                                               cw->conn_state = MAX(
+                                                       cw->conn_state, len);
+                                               break;
+                                       case IPPROTO_TCP:
+                                               if (s->state >= 0 &&
+                                                   s->state < TCP_NSTATES) {
+                                                   len = strlen(
+                                                       tcpstates[s->state]);
+                                                   cw->conn_state = MAX(
+                                                       cw->conn_state, len);
+                                               }
+                                               break;
+                                       }
+                               }
+                       }
+                       if (opt_S && s->proto == IPPROTO_TCP) {
+                               len = strlen(s->stack);
+                               cw->stack = MAX(cw->stack, len);
+                       }
+                       if (opt_C && s->proto == IPPROTO_TCP) {
+                               len = strlen(s->cc);
+                               cw->cc = MAX(cw->cc, len);
+                       }
+               }
+               if (laddr != NULL)
+                       laddr = laddr->next;
+               if (faddr != NULL)
+                       faddr = faddr->next;
+               first = false;
+       }
+}
+
+static void
+calculate_column_widths(struct col_widths *cw)
+{
+       cw->user = 4;
+       cw->command = 10;
+       cw->pid = 3;
+       cw->fd = 2;
+       cw->proto = 5;
+       cw->local_addr = 13;
+       cw->foreign_addr = 15;
+       cw->pcb_kva = 18;
+       cw->fib = 3;
+       cw->splice_address = 14;
+       cw->inp_gencnt = 2;
+       cw->encaps = 6;
+       cw->path_state = 10;
+       cw->conn_state = 10;
+       cw->stack = 5;
+       cw->cc = 2;
+
+       int n, len;
+       struct file *xf;
+       struct sock *s;
+       struct passwd *pwd;
+
+       for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
+               if (xf->xf_data == 0)
+                       continue;
+               if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
+                       continue;
+               s = RB_FIND(socks_t, &socks,
+                       &(struct sock){ .socket = xf->xf_data});
+               if (s == NULL || (!check_ports(s)))
+                       continue;
+               s->shown = 1;
+               if (opt_n ||
+                       (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
+                       len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_uid);
+               else
+                       len = snprintf(NULL, 0, "%s", pwd->pw_name);
+               cw->user = MAX(cw->user, len);
+               len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_pid);
+               cw->pid = MAX(cw->pid, len);
+               len = snprintf(NULL, 0, "%d", xf->xf_fd);
+               cw->fd = MAX(cw->fd, len);
+
+               calculate_sock_column_widths(cw, s);
+       }
+       if (opt_j >= 0)
+               return;
+       SLIST_FOREACH(s, &nosocks, socket_list) {
+               if (!check_ports(s))
+                       continue;
+               calculate_sock_column_widths(cw, s);
+       }
+       RB_FOREACH(s, socks_t, &socks) {
+               if (s->shown)
+                       continue;
+               if (!check_ports(s))
+                       continue;
+               calculate_sock_column_widths(cw, s);
+       }
+}
+
+static void
+display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
+{
+       struct addr *laddr, *faddr;
+       bool first;
+       laddr = s->laddr;
+       faddr = s->faddr;
+       first = true;
+
+       snprintf(buf, bufsize, "%s%s%s%s",
+               s->protoname,
+               s->vflag & INP_IPV4 ? "4" : "",
+               s->vflag & INP_IPV6 ? "6" : "",
+               (laddr != NULL && faddr != NULL &&
+               s->family == AF_UNIX && laddr->address.ss_len == 0 &&
+               faddr->conn == 0) ? " (not connected)" : "");
+       printf(" %-*s", cw->proto, buf);
+       while (laddr != NULL || faddr != NULL) {
+               if (s->family == AF_UNIX) {
+                       if ((laddr == NULL) || (faddr == NULL))
+                               errx(1, "laddr = %p or faddr = %p is NULL",
+                                       (void *)laddr, (void *)faddr);
+                       if (laddr->address.ss_len > 0)
+                               formataddr(&laddr->address, buf, bufsize);
+                       else
+                               strlcpy(buf, "??", bufsize);
+                       printf(" %-*s", cw->local_addr, buf);
+                       if (format_unix_faddr(faddr, buf, bufsize) == 0)
+                               strlcpy(buf, "??", bufsize);
+                       printf(" %-*s", cw->foreign_addr, buf);
+               } else {
+                       if (laddr != NULL)
+                               formataddr(&laddr->address, buf, bufsize);
+                       else
+                               strlcpy(buf, "??", bufsize);
+                       printf(" %-*s", cw->local_addr, buf);
+                       if (faddr != NULL)
+                               formataddr(&faddr->address, buf, bufsize);
+                       else
+                               strlcpy(buf, "??", bufsize);
+                       printf(" %-*s", cw->foreign_addr, buf);
+               }
+               if (opt_A)
+                       printf(" %#*" PRIx64, cw->pcb_kva, s->pcb);
+               if (opt_f)
+                       printf(" %*d", cw->fib, s->fibnum);
+               if (opt_I) {
+                       if (s->splice_socket != 0) {
+                               struct sock *sp;
+                               sp = RB_FIND(socks_t, &socks, &(struct sock)
+                                       { .socket = s->splice_socket });
+                               if (sp != NULL)
+                                       formataddr(&sp->laddr->address,
+                                                               buf, bufsize);
+                       } else
+                               strlcpy(buf, "??", bufsize);
+                       printf(" %-*s", cw->splice_address, buf);
+               }
+               if (opt_i) {
+                       if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
+                               printf(" %*" PRIu64, cw->inp_gencnt,
+                                       s->inp_gencnt);
+                       else
+                               printf(" %*s", cw->inp_gencnt, "??");
+               }
+               if (opt_U) {
+                       if (faddr != NULL &&
+                               ((s->proto == IPPROTO_SCTP &&
+                                       s->state != SCTP_CLOSED &&
+                                       s->state != SCTP_BOUND &&
+                                       s->state != SCTP_LISTEN) ||
+                                       (s->proto == IPPROTO_TCP &&
+                                       s->state != TCPS_CLOSED &&
+                                       s->state != TCPS_LISTEN))) {
+                               printf(" %*u", cw->encaps,
+                                       ntohs(faddr->encaps_port));
+                       } else
+                               printf(" %*s", cw->encaps, "??");
+               }
+               if (opt_s) {
+                       if (faddr != NULL &&
+                               s->proto == IPPROTO_SCTP &&
+                               s->state != SCTP_CLOSED &&
+                               s->state != SCTP_BOUND &&
+                               s->state != SCTP_LISTEN) {
+                               printf(" %-*s", cw->path_state,
+                                       sctp_path_state(faddr->state));
+                       } else
+                               printf(" %-*s", cw->path_state, "??");
                }
                if (first) {
                        if (opt_s) {
                                if (s->proto == IPPROTO_SCTP ||
                                    s->proto == IPPROTO_TCP) {
-                                       do
-                                               pos += xprintf(" ");
-                                       while (pos < offset);
                                        switch (s->proto) {
                                        case IPPROTO_SCTP:
-                                               pos += xprintf("%s",
+                                               printf(" %-*s", cw->conn_state,
                                                    sctp_conn_state(s->state));
                                                break;
                                        case IPPROTO_TCP:
                                                if (s->state >= 0 &&
-                                                   s->state < TCP_NSTATES)
-                                                       pos += xprintf("%s",
-                                                           
tcpstates[s->state]);
+                                                       s->state < TCP_NSTATES)
+                                                       printf(" %-*s",
+                                                       cw->conn_state,
+                                                       tcpstates[s->state]);
                                                else
-                                                       pos += xprintf("?");
+                                                       printf(" %-*s",
+                                                       cw->conn_state, "??");
                                                break;
                                        }
-                               }
-                               offset += 13;
+                               } else
+                                       printf(" %-*s", cw->conn_state, "??");
                        }
                        if (opt_S) {
-                               if (s->proto == IPPROTO_TCP) {
-                                       do
-                                               pos += xprintf(" ");
-                                       while (pos < offset);
-                                       pos += xprintf("%.*s",
-                                           TCP_FUNCTION_NAME_LEN_MAX,
-                                           s->stack);
-                               }
-                               offset += TCP_FUNCTION_NAME_LEN_MAX + 1;
+                               if (s->proto == IPPROTO_TCP)
+                                       printf(" %-*s", cw->stack, s->stack);
+                               else
+                                       printf(" %-*s", cw->stack, "??");
                        }
                        if (opt_C) {
-                               if (s->proto == IPPROTO_TCP) {
-                                       do
-                                               pos += xprintf(" ");
-                                       while (pos < offset);
-                                       xprintf("%.*s", TCP_CA_NAME_MAX, s->cc);
-                               }
-                               offset += TCP_CA_NAME_MAX + 1;
+                               if (s->proto == IPPROTO_TCP)
+                                       printf(" %-*s", cw->cc, s->cc);
+                               else
+                                       printf(" %-*s", cw->cc, "??");
                        }
                }
                if (laddr != NULL)
                        laddr = laddr->next;
                if (faddr != NULL)
                        faddr = faddr->next;
-               if ((laddr != NULL) || (faddr != NULL)) {
-                       xprintf("\n");
-                       pos = 0;
-               }
-               first = 0;
+               if (laddr != NULL || faddr != NULL)
+                       printf("%-*s %-*s %-*s %-*s %-*s", cw->user, "",
+                               cw->command, "", cw->pid, "", cw->fd, "",
+                               cw->proto, "");
+               first = false;
        }
-       xprintf("\n");
+       printf("\n");
 }
 
 static void
@@ -1344,33 +1502,41 @@ display(void)
        struct passwd *pwd;
        struct file *xf;
        struct sock *s;
-       int n, pos;
+       int n;
+       struct col_widths cw;
+       const size_t bufsize = 512;
+       void *buf;
+       if ((buf = (char *)malloc(bufsize)) == NULL) {
+               err(1, "malloc()");
+               return;
+       }
+       calculate_column_widths(&cw);
 
        if (!opt_q) {
-               printf("%-8s %-10s %-5s %-3s %-6s %-*s %-*s",
-                   "USER", "COMMAND", "PID", "FD", "PROTO",
-                   opt_w ? 45 : 21, "LOCAL ADDRESS",
-                   opt_w ? 45 : 21, "FOREIGN ADDRESS");
+               printf("%-*s %-*s %*s %*s %-*s %-*s %-*s",
+                               cw.user, "USER", cw.command, "COMMAND",
+                               cw.pid, "PID", cw.fd, "FD", cw.proto, "PROTO",
+                               cw.local_addr, "LOCAL ADDRESS",
+                               cw.foreign_addr,"FOREIGN ADDRESS");
                if (opt_A)
-                       printf(" %-18s", "PCB KVA");
+                       printf(" %-*s", cw.pcb_kva, "PCB KVA");
                if (opt_f)
                        /* RT_MAXFIBS is 65535. */
-                       printf(" %-6s", "FIB");
+                       printf(" %*s", cw.fib, "FIB");
                if (opt_I)
-                       printf(" %-*s", opt_w ? 45 : 21, "SPLICE ADDRESS");
+                       printf(" %-*s", cw.splice_address, "SPLICE ADDRESS");
                if (opt_i)
-                       printf(" %-8s", "ID");
+                       printf(" %*s", cw.inp_gencnt, "ID");
                if (opt_U)
-                       printf(" %-6s", "ENCAPS");
+                       printf(" %*s", cw.encaps, "ENCAPS");
                if (opt_s) {
-                       printf(" %-12s", "PATH STATE");
-                       printf(" %-12s", "CONN STATE");
+                       printf(" %-*s", cw.path_state, "PATH STATE");
+                       printf(" %-*s", cw.conn_state, "CONN STATE");
                }
                if (opt_S)
-                       printf(" %-*.*s", TCP_FUNCTION_NAME_LEN_MAX,
-                           TCP_FUNCTION_NAME_LEN_MAX, "STACK");
+                       printf(" %-*s", cw.stack, "STACK");
                if (opt_C)
-                       printf(" %-.*s", TCP_CA_NAME_MAX, "CC");
+                       printf(" %-*s", cw.cc, "CC");
                printf("\n");
        }
        cap_setpassent(cappwd, 1);
@@ -1380,28 +1546,19 @@ display(void)
                if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
                        continue;
                s = RB_FIND(socks_t, &socks,
-                   &(struct sock){ .socket = xf->xf_data});
+                       &(struct sock){ .socket = xf->xf_data});
                if (s != NULL && check_ports(s)) {
                        s->shown = 1;
-                       pos = 0;
                        if (opt_n ||
                            (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
-                               pos += xprintf("%lu", (u_long)xf->xf_uid);
+                               printf("%-*lu", cw.user, (u_long)xf->xf_uid);
                        else
-                               pos += xprintf("%s", pwd->pw_name);
-                       do
-                               pos += xprintf(" ");
-                       while (pos < 9);
-                       pos += xprintf("%.10s", getprocname(xf->xf_pid));
-                       do
-                               pos += xprintf(" ");
-                       while (pos < 20);
-                       pos += xprintf("%5lu", (u_long)xf->xf_pid);
-                       do
-                               pos += xprintf(" ");
-                       while (pos < 26);
-                       pos += xprintf("%-3d", xf->xf_fd);
-                       displaysock(s, pos);
+                               printf("%-*s", cw.user, pwd->pw_name);
+                       printf(" %-*.*s", cw.command, cw.command,
+                               getprocname(xf->xf_pid));
+                       printf(" %*lu", cw.pid, (u_long)xf->xf_pid);
+                       printf(" %*d", cw.fd, xf->xf_fd);
+                       display_sock(s, &cw, buf, bufsize);
                }
        }
        if (opt_j >= 0)
@@ -1409,19 +1566,20 @@ display(void)
        SLIST_FOREACH(s, &nosocks, socket_list) {
                if (!check_ports(s))
                        continue;
-               pos = xprintf("%-8s %-10s %-5s %-3s",
-                   "?", "?", "?", "?");
-               displaysock(s, pos);
+               printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??",
+                       cw.pid, "??", cw.fd, "??");
+               display_sock(s, &cw, buf, bufsize);
        }
        RB_FOREACH(s, socks_t, &socks) {
                if (s->shown)
                        continue;
                if (!check_ports(s))
                        continue;
-               pos = xprintf("%-8s %-10s %-5s %-3s",
-                   "?", "?", "?", "?");
-               displaysock(s, pos);
+               printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??",
+                       cw.pid, "??", cw.fd, "??");
+               display_sock(s, &cw, buf, bufsize);
        }
+       free(buf);
 }
 
 static int
@@ -1484,7 +1642,7 @@ static void
 usage(void)
 {
        errx(1,
-    "usage: sockstat [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P 
protocols]");
+    "usage: sockstat [-46ACcfIiLlnqSsUuv] [-j jid] [-p ports] [-P protocols]");
 }
 
 int
@@ -1563,7 +1721,7 @@ main(int argc, char *argv[])
                        ++opt_v;
                        break;
                case 'w':
-                       opt_w = true;
+                       /* left for backward compatibility. */
                        break;
                default:
                        usage();

Reply via email to