bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

New option for who.c


From: Bill Crowell, N4HPG
Subject: New option for who.c
Date: Sun, 8 Oct 2006 13:58:17 -0400
User-agent: KMail/1.9.1

Option flags: -n, --ip_addr

Function: Return the IP address of the user by reading utmp. Return value in 
ipv4 or ipv6 formats based upon the type of address stored. Disable DNS 
lookup.

w010 ~ # who -n -l
root     :0       Oct  8 13:52 [0.0.0.0]
root     pts/0    Oct  8 13:53 [0.0.0.0] (:0)
root     pts/1    Oct  8 17:42 [10.2.10.1] (s001.site2.cs.lan)

The IP address is unconditionally returned from the data in utmp. This 
provides a security and functionality mechanism without needing to 
reverse-resolve the DNS. Since the connection has already been made, the 
resolver does not need to spend the time to return the IP address.

The -n option is syntactically correct with other uses of -n such as route.

The return values are enclosed in [] to differentiate from the cananonical 
name that is enclosed in (). This is especially important when the resolver 
is unable to do a lookup and the -l option returns the IP address.

The return value of [0.0.0.0] indicates that there is NO information in the 
utmp for this connection as a positive indicator. This catches conditions 
with some telnet/login combinations that do not properly update utmp.

The most common use for me is as follows:

w010 ~ # who am i -n
w010.site2.cs.lan!root     pts/1    Oct  8 17:42 [10.2.10.1]

I use the IP address for distributed processing applications where the users 
lan address is needed by the application software.

*** Diff ***

w203 src # diff -u who.c.orig who.c
--- who.c.orig  2006-10-08 13:35:34.000000000 -0400
+++ who.c       2006-10-08 13:57:35.000000000 -0400
@@ -16,6 +16,7 @@
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

 /* Written by jla; revised by djm; revised again by mstone */
+/* Revised by Bill Crowell & Mike Isely to return IP address from utmp (-n)*/

 /* Output format:
    name [state] line time [activity] [pid] [comment] [exit]
@@ -155,6 +156,9 @@
 static char const *time_format;
 static int time_format_width;

+/* If true, display the IPv4 address of the user rather than the
+   hostname or resolved hostname of the user */
+static bool use_ipaddr;
 /* for long options with no corresponding short option, use enum */
 enum
 {
@@ -178,6 +182,7 @@
   {"time", no_argument, NULL, 't'},
   {"users", no_argument, NULL, 'u'},
   {"writable", no_argument, NULL, 'T'},
+  {"ipaddr", no_argument, NULL, 'n'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -416,6 +421,59 @@
        }
       *hoststr = '\0';
     }
+if (use_ipaddr)
+    {
+       char buf[100];
+       unsigned int len1,len2,spc;
+       buf[0] = '[';
+       len2 = 1;
+       if (utmp_ent->ut_addr_v6[1] ||
+           utmp_ent->ut_addr_v6[2] ||
+           utmp_ent->ut_addr_v6[3])
+         {
+             unsigned int idx;
+             unsigned short v;
+             /* Print IPV6 style */
+             for (idx = 0; idx < 8; idx++) {
+                 v = (utmp_ent->ut_addr_v6[(7-idx) >> 1]) >>
+                     (((7-idx) & 1) ? 0 : 16);
+                 v = (v << 8) | (v >> 8);
+                 if (idx)
+                   {
+                       buf[len2] = ':';
+                       len2++;
+                   }
+                 if (v)
+                   {
+                     sprintf(buf+len2,"%x",v);
+                     len2 += strlen(buf+len2);
+                   }
+             }
+         }
+       else
+         {
+             /* Print IPV4 style */
+             sprintf(buf+len2,"%u.%u.%u.%u",
+                     utmp_ent->ut_addr_v6[0] & 0xffu,
+                     (utmp_ent->ut_addr_v6[0] >> 8) & 0xffu,
+                     (utmp_ent->ut_addr_v6[0] >> 16) & 0xffu,
+                     (utmp_ent->ut_addr_v6[0] >> 24) & 0xffu);
+             len2 += strlen(buf+len2);
+         }
+       buf[len2] = ']';
+       len2++;
+       len1 = hoststr ? strlen(hoststr) : 0;
+       spc = len1 ? 1 : 0;
+       if (hostlen < len1+len2+spc+1)
+         {
+             hostlen = len1+len2+spc+1;
+             hoststr = xrealloc(hoststr,len1+len2+spc+1);
+         }
+       if (spc) hoststr[len1] = ' ';
+       len1++;
+       memcpy(hoststr+len1,buf,len2);
+       hoststr[len1+len2] = 0;
+    }
 #endif

   print_line (sizeof UT_USER (utmp_ent), UT_USER (utmp_ent), mesg,
@@ -642,6 +700,7 @@
       fputs (_("\
       --lookup      attempt to canonicalize hostnames via DNS\n\
   -m                only hostname and user associated with stdin\n\
+  -n, --ipaddr      display IP address of hostname from utmp without DNS\n\
   -p, --process     print active processes spawned by init\n\
 "), stdout);
       fputs (_("\
@@ -682,7 +741,7 @@

   atexit (close_stdout);

-  while ((optc = getopt_long (argc, argv, "abdilmpqrstuwHT", longopts, NULL))
+  while ((optc = getopt_long (argc, argv, "abdilmnpqrstuwHT", longopts, 
NULL))
         != -1)
     {
       switch (optc)
@@ -727,6 +786,11 @@
          my_line_only = true;
          break;

+       case 'n':
+         use_ipaddr = true;
+         do_lookup = false;
+         break;
+
        case 'p':
          need_initspawn = true;
          assumptions = false;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]