]> granicus.if.org Git - procps-ng/commitdiff
Add -i option to w
authorJaromir Capik <jcapik@redhat.com>
Tue, 29 May 2012 12:20:36 +0000 (22:20 +1000)
committerCraig Small <csmall@enc.com.au>
Tue, 29 May 2012 12:20:36 +0000 (22:20 +1000)
w can now show IP address for the from field with the -i option

.gitignore
NEWS
w.1
w.c

index 383a8aa139c2da43ff5855f3cc11435392e27d03..67b92cbd4cacd33e3949ea15be115b2a75fc6c8f 100644 (file)
@@ -3,6 +3,7 @@
 *.so
 .deps
 .libs
+.version
 ABOUT-NLS
 aclocal.m4
 autom4te.cache
diff --git a/NEWS b/NEWS
index 32cc76dd106903ed865cef19a5c0e70b4776fd4b..29512ee4f05da06018642a770edcfb30bdda235c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 procps-ng-3.3.4
 ---------------
   * Removed ps -aux bogus message
+  * w get -i option to display IP addresses
 
 procps-ng-3.3.3
 ---------------
diff --git a/w.1 b/w.1
index 6adecfac484d6ac0fc389a019f34f5ff70253d74..5b2b2645433b9461b8f127b357273ce983b4805a 100644 (file)
--- a/w.1
+++ b/w.1
@@ -1,6 +1,6 @@
 .\"             -*-Nroff-*-
 .\"
-.TH W "1" "June 2011" "procps-ng" "User Commands"
+.TH W "1" "May 2012" "procps-ng" "User Commands"
 .SH NAME
 w \- Show who is logged on and what they are doing.
 .SH SYNOPSIS
@@ -49,6 +49,9 @@ field is shown by default.
 \fB\-\-help\fR
 Display help text and exit.
 .TP
+\fB\-\-ip\-addr\fR
+Display IP address instead of hostname for \fBfrom\fR field.
+.TP
 \fB\-V\fR, \fB\-\-version\fR
 Display version information.
 .TP
diff --git a/w.c b/w.c
index 9c54d10240865adbb8d15837c04d0bd4a473b7e5..42854b66a071a41de1e19e930cf4cb9bba0916f3 100644 (file)
--- a/w.c
+++ b/w.c
@@ -55,6 +55,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <utmp.h>
+#include <arpa/inet.h>
 
 static int ignoreuser = 0;     /* for '-u' */
 static int oldstyle = 0;       /* for '-o' */
@@ -82,7 +83,7 @@ static void print_host(const char *restrict host, int len, const int fromlen)
                len = fromlen;
        last = host + len;
        for (; host < last; host++) {
-           if (*host == '\0') break;
+               if (*host == '\0') break;
                if (isprint(*host) && *host != ' ') {
                        fputc(*host, stdout);
                        ++width;
@@ -101,6 +102,89 @@ static void print_host(const char *restrict host, int len, const int fromlen)
                fputc(' ', stdout);
 }
 
+
+/* This routine prints the display part of the host */
+static void print_display(const char *restrict host, int len, int restlen)
+{
+       char *disp;
+
+       if (restlen <= 0) return; /* not enough space for the display */
+
+       /* search for the display (collon) */
+       disp = (char *)host;
+       while ( (disp < (host + len)) && (*disp != ':') && (*disp != '\0') ) disp++;
+
+       /* 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;
+
+       /* display found, print it */
+       if (*disp == ':') {
+               while ((len > 0) && (*disp != '\0')) {
+                       len--; restlen--;
+                       /* print only if printable and non-space */
+                       if (isprint(*host) && *host != ' ') {
+                               fputc(*disp, stdout);
+                               disp++;
+                       } else { /* space or nonprintable - replace with dash and stop printing */
+                               fputc('-', stdout);
+                               break;
+                       }
+               }
+       }
+
+       /* padding with spaces */
+       while (restlen > 0) {
+               fputc(' ', stdout);
+               restlen--;
+       }
+}
+
+
+/* This routine prints either the hostname or the IP address of the remote */
+static void print_from(const utmp_t *restrict const u, const int ip_addresses, const int fromlen) {
+       char buf[fromlen + 1];
+       int len;
+       int32_t ut_addr_v6[4];      /* IP address of the remote host */
+
+       if (ip_addresses) { /* -i switch used */
+               memcpy(&ut_addr_v6, &u->ut_addr_v6, sizeof(ut_addr_v6));
+               if (IN6_IS_ADDR_V4MAPPED(&ut_addr_v6)) {
+                       /* map back */
+                       ut_addr_v6[0] = ut_addr_v6[3];
+                       ut_addr_v6[1] = 0;
+                       ut_addr_v6[2] = 0;
+                       ut_addr_v6[3] = 0;
+               }
+               if (ut_addr_v6[1] || ut_addr_v6[2] || ut_addr_v6[3]) {
+                       /* IPv6 */
+                       if (!inet_ntop(AF_INET6, &ut_addr_v6, buf, sizeof(buf))) {
+                               strcpy(buf, ""); /* invalid address, clean the buffer */
+                       }
+               } else {
+                       /* IPv4 */
+                       if (!(ut_addr_v6[0] && inet_ntop(AF_INET, &ut_addr_v6[0], buf, sizeof(buf)))) {
+                               strcpy(buf, ""); /* invalid address, clean the buffer */
+                       }
+               }
+               buf[fromlen] = '\0';
+
+               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);
+               } else { /* IP address is empty, print the host instead */
+                       print_host(u->ut_host, UT_HOSTSIZE, fromlen);
+               }
+       } else {  /* -i switch NOT used */
+               print_host(u->ut_host, UT_HOSTSIZE, fromlen);
+       }
+}
+
+
 /* compact 7 char format for time intervals (belongs in libproc?) */
 static void print_time_ival7(time_t t, int centi_sec, FILE * fout)
 {
@@ -239,7 +323,7 @@ static const proc_t *getproc(const utmp_t * restrict const u,
 }
 
 static void showinfo(utmp_t * u, int formtype, int maxcmd, int from,
-                    const int userlen, const int fromlen)
+                    const int userlen, const int fromlen, const int ip_addresses)
 {
        unsigned long long jcpu;
        int ut_pid_found;
@@ -271,7 +355,7 @@ static void showinfo(utmp_t * u, int formtype, int maxcmd, int from,
        if (formtype) {
                printf("%-*.*s%-9.8s", userlen + 1, userlen, uname, u->ut_line);
                if (from)
-                       print_host(u->ut_host, UT_HOSTSIZE, fromlen);
+                       print_from(u, ip_addresses, fromlen);
                print_logintime(u->ut_time, stdout);
                if (*u->ut_line == ':')
                        /* idle unknown for xdm logins */
@@ -291,7 +375,7 @@ static void showinfo(utmp_t * u, int formtype, int maxcmd, int from,
                printf("%-*.*s%-9.8s", userlen + 1, userlen, u->ut_user,
                       u->ut_line);
                if (from)
-                       print_host(u->ut_host, UT_HOSTSIZE, fromlen);
+                       print_from(u, ip_addresses, fromlen);
                if (*u->ut_line == ':')
                        /* idle unknown for xdm logins */
                        printf(" ?xdm? ");
@@ -320,7 +404,8 @@ static void __attribute__ ((__noreturn__))
                " -u, --no-current    ignore current process username\n"
                " -s, --short         short format\n"
                " -f, --from          show remote hostname field\n"
-               " -o, --old-style     old style output\n"), out);
+               " -o, --old-style     old style output\n"
+               " -i, --ip-addr       display IP address instead of hostname (if possible)\n"), out);
        fputs(USAGE_SEPARATOR, out);
        fputs(_("     --help     display this help and exit\n"), out);
        fputs(USAGE_VERSION, out);
@@ -334,11 +419,18 @@ int main(int argc, char **argv)
        char *user = NULL, *p;
        utmp_t *u;
        struct winsize win;
-       int header = 1, longform = 1, from = 1, maxcmd = 80, ch;
+       int ch;
+       int maxcmd = 80;
        int userlen = 8;
        int fromlen = 16;
        char *env_var;
 
+       /* switches (defaults) */
+       int header = 1;
+       int longform = 1;
+       int from = 1;
+       int ip_addresses = 0;
+
        enum {
                HELP_OPTION = CHAR_MAX + 1
        };
@@ -365,7 +457,7 @@ int main(int argc, char **argv)
 #endif
 
        while ((ch =
-               getopt_long(argc, argv, "husfoV", longopts, NULL)) != -1)
+               getopt_long(argc, argv, "husfoVi", longopts, NULL)) != -1)
                switch (ch) {
                case 'h':
                        header = 0;
@@ -388,6 +480,10 @@ int main(int argc, char **argv)
                case 'o':
                        oldstyle = 1;
                        break;
+               case 'i':
+                       ip_addresses = 1;
+                       from = 1;
+                       break;
                case HELP_OPTION:
                        usage(stdout);
                default:
@@ -458,7 +554,7 @@ int main(int argc, char **argv)
                                continue;
                        if (!strncmp(u->ut_user, user, UT_NAMESIZE))
                                showinfo(u, longform, maxcmd, from, userlen,
-                                        fromlen);
+                                        fromlen, ip_addresses);
                }
        } else {
                for (;;) {
@@ -469,7 +565,7 @@ int main(int argc, char **argv)
                                continue;
                        if (*u->ut_user)
                                showinfo(u, longform, maxcmd, from, userlen,
-                                        fromlen);
+                                        fromlen, ip_addresses);
                }
        }
        endutent();