]> granicus.if.org Git - procps-ng/commitdiff
Rework of the -i feature
authorJaromir Capik <jcapik@redhat.com>
Wed, 20 Jun 2012 12:19:14 +0000 (22:19 +1000)
committerCraig Small <csmall@enc.com.au>
Wed, 20 Jun 2012 12:19:14 +0000 (22:19 +1000)
This version detects IPv6 address in the host field
and also IPv6 link interface separated by % sign.
It also handles unprintable characters and spaces better
than the previous one.

Signed-off-by: Craig Small <csmall@enc.com.au>
w.c

diff --git a/w.c b/w.c
index 43e941a55001187e42c8ceec1a8e7f718e6dbe2e..2e79980d43edfcc203827fcb71eae6523a142680 100644 (file)
--- a/w.c
+++ b/w.c
@@ -103,35 +103,67 @@ static void print_host(const char *restrict host, int len, const int fromlen)
 }
 
 
-/* This routine prints the display part of the host */
-static void print_display(const char *restrict host, int len, int restlen)
+/* This routine prints the display part of the host or IPv6 link address interface */
+static void print_display_or_interface(const char *restrict host, int len, int restlen)
 {
-       char *disp;
+       char *disp,*tmp;
 
-       if (restlen <= 0) return; /* not enough space for the display */
+       if (restlen <= 0) return; /* not enough space for printing anything */
 
-       /* search for the display (collon) */
+       /* search for a collon (might be a display) */
        disp = (char *)host;
-       while ( (disp < (host + len)) && (*disp != ':') && (*disp != '\0') ) disp++;
+       while ( (disp < (host + len)) && (*disp != ':') && isprint(*disp) ) disp++;
 
-       /* number of chars till the end of the input field */
-       len -= (disp - host);
+       /* colon found */
+       if (*disp == ':') {
+               /* detect multiple colons -> IPv6 in the host (not a display) */
+               tmp = disp+1;
+               while ( (tmp < (host + len)) && (*tmp != ':') && isprint(*tmp) ) tmp++;
 
-       /* if it is still longer than the rest of the output field, then cut it */
-       if (len > restlen) len = restlen;
+               if (*tmp != ':') { /* multiple colons not found - it's a display */
 
-       /* display found, print it */
-       if (*disp == ':') {
-               while ((len > 0) && (*disp != '\0')) {
-                       len--; restlen--;
-                       /* print only if printable and non-space */
-                       if (isprint(*host) && *host != ' ') {
+                       /* number of chars till the end of the input field */
+                       len -= (disp - host);
+
+                       /* if it is still longer than the rest of the output field, then cut it */
+                       if (len > restlen) len = restlen;
+
+                       /* print the display */
+                       while ((len > 0) && isprint(*disp) && (*disp != ' ')) {
+                               len--; restlen--;
                                fputc(*disp, stdout);
                                disp++;
-                       } else { /* space or nonprintable - replace with dash and stop printing */
+                       }
+
+                       if ((len > 0) && (*disp != '\0')) { /* space or nonprintable found - replace with dash and stop printing */
+                               restlen--;
                                fputc('-', stdout);
-                               break;
                        }
+               } else { /* multiple colons found - it's an IPv6 address */
+                       
+                       /* search for % (interface separator in case of IPv6 link address) */
+                       while ( (tmp < (host + len)) && (*tmp != '%') && isprint(*tmp) ) tmp++;
+
+                       if (*tmp == '%') { /* interface separator found */
+                               
+                               /* number of chars till the end of the input field */
+                               len -= (tmp - host);
+
+                               /* if it is still longer than the rest of the output field, then cut it */
+                               if (len > restlen) len = restlen;
+
+                               /* print the interface */
+                               while ((len > 0) && isprint(*tmp) && (*tmp != ' ')) {
+                                       len--; restlen--;
+                                       fputc(*tmp, stdout);
+                                       tmp++;
+                               }
+                               if ((len > 0) && (*tmp != '\0')) {  /* space or nonprintable found - replace with dash and stop printing */
+                                       restlen--;
+                                       fputc('-', stdout);
+                               }
+                       }
+
                }
        }
 
@@ -177,8 +209,8 @@ static void print_from(const utmp_t *restrict const u, const int ip_addresses, c
                len = strlen(buf);
                if (len) { /* IP address is non-empty, print it (and concatenate with display, if present) */
                        fputs(buf, stdout);
-                       /* show the display part of the host, if present */
-                       print_display(u->ut_host, UT_HOSTSIZE, fromlen - len);
+                       /* show the display part of the host or IPv6 link addr. interface, if present */
+                       print_display_or_interface(u->ut_host, UT_HOSTSIZE, fromlen - len);
                } else { /* IP address is empty, print the host instead */
                        print_host(u->ut_host, UT_HOSTSIZE, fromlen);
                }