Subject: bin/3768: finger ought to treat hostnames better
To: None <gnats-bugs@gnats.netbsd.org>
From: Eric Fischer <eric@fudge.uchicago.edu>
List: netbsd-bugs
Date: 06/20/1997 16:26:33
>Number:         3768
>Category:       bin
>Synopsis:       finger ought to treat hostnames better
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 20 14:35:01 1997
>Last-Modified:
>Originator:     Eric Fischer
>Organization:
The University of Chicago
>Release:        1.2
>Environment:
	
System: NetBSD fudge 1.2 NetBSD 1.2 (FUDGE) #7: Sun Jan 19 16:26:56 CST 1997 eric@fudge:/usr/people/eric/usrsrc/sys/arch/sparc/compile/FUDGE sparc


>Description:

In spite of the large fraction of logins that happen over the network,
finger thinks that the GECOS field office and phone number are more
informative than the network hostname someone is connected from.  When
it does give a hostname, it's typically in numeric form rather than
something human-readable.

>How-To-Repeat:

Finger @ some NetBSD machine and try to figure out where people actually
are without having to finger -l them and do nslookups to translate their
IP addresses.

>Fix:

Apply this patch, which adds hostnames to the finger -s output and
automatically calls the resolver on addresses that have been logged
numerically in wtmp.


diff -rc ../../../src/usr.bin/finger/finger.1 ./finger.1
*** ../../../src/usr.bin/finger/finger.1	Tue Jul 25 13:16:57 1995
--- ./finger.1	Mon Jun 16 10:19:35 1997
***************
*** 54,61 ****
  .Nm Finger
  displays the user's login name, real name, terminal name and write
  status (as a ``*'' before the terminal name if write permission is
! denied), idle time, login time, office location and office phone
! number.
  .Pp
  Idle time is in minutes if it is a single integer, hours and minutes
  if a ``:'' is present, or days if a ``d'' is present.
--- 54,61 ----
  .Nm Finger
  displays the user's login name, real name, terminal name and write
  status (as a ``*'' before the terminal name if write permission is
! denied), idle time, login time, office location, office phone
! number, and, if the login is over the network, remote location.
  .Pp
  Idle time is in minutes if it is a single integer, hours and minutes
  if a ``:'' is present, or days if a ``d'' is present.
Only in .: finger.cat1
Only in .: finger.o
diff -rc ../../../src/usr.bin/finger/lprint.c ./lprint.c
*** ../../../src/usr.bin/finger/lprint.c	Sat Dec 24 10:33:51 1994
--- ./lprint.c	Thu Jun 12 11:40:22 1997
***************
*** 55,60 ****
--- 55,62 ----
  #define	_PATH_PLAN	".plan"
  #define	_PATH_PROJECT	".project"
  
+ extern char *iptohost __P((char *));
+ 
  lflag_print()
  {
  	extern int pplan;
***************
*** 193,201 ****
  			break;
  		}
  		if (*w->host) {
! 			if (LINE_LEN < (cpr + 6 + strlen(w->host)))
! 				(void)printf("\n   ");
! 			(void)printf(" from %s", w->host);
  		}
  		putchar('\n');
  	}
--- 195,212 ----
  			break;
  		}
  		if (*w->host) {
! 			char *s = iptohost (w->host);
! 
! 			if (s == w->host) {
! 				if (LINE_LEN < (cpr + 6 + strlen(w->host)))
! 					(void)printf("\n   ");
! 				(void)printf(" from %s", w->host);
! 			} else {
! 				if (LINE_LEN < (cpr + strlen(w->host) +
! 						strlen (s) + 9))
! 					(void)printf("\n   ");
! 				(void)printf(" from %s (%s)", s, w->host);
! 			}
  		}
  		putchar('\n');
  	}
Only in .: lprint.o
Only in .: net.o
diff -rc ../../../src/usr.bin/finger/sprint.c ./sprint.c
*** ../../../src/usr.bin/finger/sprint.c	Tue Oct 26 15:54:41 1993
--- ./sprint.c	Fri Jun 13 14:41:16 1997
***************
*** 43,51 ****
--- 43,54 ----
  #include <sys/time.h>
  #include <tzfile.h>
  #include <stdio.h>
+ #include <string.h>
  #include "finger.h"
  
  extern int entries;
+ extern char *iptohost __P((char *));
+ extern char *hosttrim __P((char *));
  
  sflag_print()
  {
***************
*** 56,62 ****
  	register char *p;
  	PERSON **list, **sort();
  	time_t time();
! 	char *ctime(), *prphone();
  
  	list = sort();
  	/*
--- 59,65 ----
  	register char *p;
  	PERSON **list, **sort();
  	time_t time();
! 	char *ctime(), *prphone(), *s;
  
  	list = sort();
  	/*
***************
*** 74,80 ****
  	 */
  #define	MAXREALNAME	20
  	(void)printf("%-*s %-*s %s\n", UT_NAMESIZE, "Login", MAXREALNAME,
! 	    "Name", "Tty  Idle  Login Time   Office     Office Phone");
  	for (cnt = 0; cnt < entries; ++cnt) {
  		pn = list[cnt];
  		for (w = pn->whead; w != NULL; w = w->next) {
--- 77,83 ----
  	 */
  #define	MAXREALNAME	20
  	(void)printf("%-*s %-*s %s\n", UT_NAMESIZE, "Login", MAXREALNAME,
! 	    "Name", "Tty  Idle  Login Time   Office     Phone     From");
  	for (cnt = 0; cnt < entries; ++cnt) {
  		pn = list[cnt];
  		for (w = pn->whead; w != NULL; w = w->next) {
***************
*** 104,116 ****
  				(void)printf("  %.4s", p + 20);
  			else
  				(void)printf(" %.5s", p + 11);
! office:			if (pn->office)
! 				(void)printf(" %-10.10s", pn->office);
! 			else if (pn->officephone)
! 				(void)printf(" %-10.10s", " ");
! 			if (pn->officephone)
! 				(void)printf(" %-.15s",
! 				    prphone(pn->officephone));
  			putchar('\n');
  		}
  	}
--- 107,151 ----
  				(void)printf("  %.4s", p + 20);
  			else
  				(void)printf(" %.5s", p + 11);
! office:			
! 			if (*w->host && (s = strdup(iptohost(w->host)))) {
! 				int l = strlen(hosttrim(s));
! 
! 				if (l > 14)
! 					if (pn->office && 
! 					    strlen(pn->office) + l < 24)
! 						printf(" %s %*s", pn->office,
! 						       24 - strlen(pn->office),
! 						       s);
! 					else
! 						printf(" %25.25s", s);
! 				else {
! 					if (pn->office)
! 						printf(" %-10.10s", 
! 						       pn->office);
! 					else
! 						printf(" %-10.10s", "");
! 
! 					if (pn->officephone &&
! 					    strlen(pn->officephone) + l < 13)
! 						printf (" %s %*s",
! 							pn->officephone,
! 							13 - strlen
! 							(pn->officephone), s);
! 					else
! 						printf(" %14.14s", s);
! 				}
! 
! 				free (s);
! 			} else {
! 				if (pn->office)
! 					(void)printf(" %-10.10s", pn->office);
! 				else if (pn->officephone)
! 					(void)printf(" %-10.10s", " ");
! 				if (pn->officephone)
! 					(void)printf(" %-.15s",
! 					    prphone(pn->officephone));
! 			}
  			putchar('\n');
  		}
  	}
Only in .: sprint.c.works
Only in .: sprint.o
diff -rc ../../../src/usr.bin/finger/util.c ./util.c
*** ../../../src/usr.bin/finger/util.c	Tue Sep 26 20:10:48 1995
--- ./util.c	Fri Jun 20 13:04:12 1997
***************
*** 42,53 ****
--- 42,55 ----
  #include <sys/param.h>
  #include <sys/stat.h>
  #include <sys/file.h>
+ #include <sys/socket.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <ctype.h>
  #include <string.h>
  #include <paths.h>
  #include <errno.h>
+ #include <netdb.h>
  #include "finger.h"
  
  find_idle_and_ttywrite(w)
***************
*** 351,354 ****
--- 353,418 ----
  	*p++ = *num++;
  	*p = '\0';
  	return(pbuf);
+ }
+ 
+ /*
+  * Trim off as many trailing components of the remote hostname as are the
+  * same as our own, to save space for phone and room numbers.
+  */
+ 
+ char *
+ hosttrim (char *s)
+ {
+ 	static char *ourhost = NULL;
+ 	int hl, sl, i;
+ 
+ 	if (ourhost == NULL) {
+ 		char h[MAXHOSTNAMELEN + 1];
+ 		struct hostent *he;
+ 
+ 		if (gethostname(h, MAXHOSTNAMELEN) != 0)
+ 			return s;
+ 
+ 		h[MAXHOSTNAMELEN] = '\0';
+ 
+ 		if ((he = gethostbyname(h)) == NULL)
+ 			return s;
+ 		if ((ourhost = strdup(he->h_name)) == NULL)
+ 			return s;
+ 	}
+ 
+ 	hl = strlen(ourhost);
+ 	sl = strlen(s);
+ 
+ 	for (i = 1; i < hl && i < sl; i++) {
+ 		if (ourhost[hl - i] != s[sl - i])
+ 			break;
+ 		if (ourhost[hl - i] == '.')
+ 			s[sl - i] = '\0';
+ 	}
+ 
+ 	return s;
+ }
+ 
+ /*
+  * If the host has been recorded as a numeric IP address instead of a name to
+  * make it fit in UT_HOSTSIZE, convert it back to a name for the benefit of
+  * human beings.
+  */
+ 
+ char *
+ iptohost (char *s)
+ {
+ 	long addr;
+ 	struct hostent *he;
+ 
+ 	/* following the example of /usr/bin/w */
+ 
+ 	if (isdigit (*s))
+ 		if ((addr = inet_addr (s)) != -1)
+ 			if ((he = gethostbyaddr ((char *) &addr,
+ 						 sizeof (addr), AF_INET)))
+ 				return he->h_name;
+ 
+ 	return s;
  }
Only in .: util.o
>Audit-Trail:
>Unformatted: