[comp.bugs.4bsd] BSD4.3 finger is Berkley dependent. +FIX

thompson@dalcs.UUCP (09/25/87)

	I got rid of the Berkley-isms from finger quite a while ago,
    but in doing so all I did was add Dalhousie-isms, The following
    are the changes necessary to make your 4.3bsd finger (these may
    work for other flavors of finger but I haven't tried them) site
    independent. This is done by using two data-files:
	/usr/lib/finger.abbrev and /usr/lib/finger.phones

	Included are our versions of these files also the changes
    necessary for finger, passwd (i.e. chfn), passwd.1, and finger.1
    In addition to the above changes I've hopefully improved the
    output of finger, and documented a few of the previously
    undocumented features of finger.

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	finger.1.diffs
#	finger.abbrev
#	finger.c.diffs
#	finger.phones
#	passwd.1.diffs
#	passwd.c.diffs
# This archive created: Fri Sep 25 14:03:50 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'finger.1.diffs'" '(3222 characters)'
if test -f 'finger.1.diffs'
then
	echo shar: over-writing existing file "'finger.1.diffs'"
fi
sed 's/^X//' << \SHAR_EOF > 'finger.1.diffs'
XRCS file: RCS/finger.1,v
Xretrieving revision 1.1
Xdiff -b -c -r1.1 finger.1
X*** /tmp/,RCSt1021674	Wed Sep 23 14:19:38 1987
X--- finger.1	Wed Sep 23 14:11:11 1987
X***************
X*** 44,62 ****
X  .I Finger
X  options include:
X  .TP
X! .B \-m
X! Match arguments only on user name.
X  .TP
X  .B \-l
X  Force long output format.
X  .TP
X  .B \-p
X  Suppress printing of the
X  .I \&.plan
X  files
X  .TP
X  .B \-s
X  Force short output format.
X  .SH FILES
X  .ta 2i
X  /etc/utmp	who file
X--- 44,105 ----
X  .I Finger
X  options include:
X  .TP
X! .B \-b
X! Briefens long format outputs by excluding the line with home directory
X! and shell on it.
X  .TP
X+ .B \-f
X+ Suppress printing of the headers for short and quick outputs.
X+ .TP
X+ .B \-h
X+ Suppress printing of the
X+ .I \&.project
X+ files
X+ .TP
X+ .B \-i
X+ Quick list of users with idle times.
X+ .TP
X  .B \-l
X  Force long output format.
X  .TP
X+ .B \-m
X+ Match arguments only on user name.
X+ .TP
X  .B \-p
X  Suppress printing of the
X  .I \&.plan
X  files
X  .TP
X+ .B \-q
X+ quick list of users, (similar to who).
X+ .TP
X  .B \-s
X  Force short output format.
X+ .TP
X+ .B \-w
X+ Narrows short output format.
X+ .TP
X+ .B /usr/lib/finger.abbrev
X+ contains the abbreviations for office locations, the format for this
X+ file is a 1 character abbreviation, followed by a single character separator
X+ (usually a tab) followed by the expansion for the abbreviation. If the last
X+ character of the office field matches a one character abbreviation then the
X+ expansion is substituted. This file is also used by chfn to compress office
X+ locations, so alternate ways of specifing the same Office may be listed
X+ following the one that finger will use.
X+ .TP
X+ .B /usr/lib/finger.phones
X+ contains the templates for phone numbers based on the number of digits
X+ given. The format for this file is one expansion per line
X+ for phone numbers, in the expansion a `#' means copy the next
X+ available digit, (e.g. given the line `424-####' in
X+ /usr/lib/finger.phones and the phone number 6501 the expansion would
X+ be `424-6501'). This file is also used by chfn to compress phone numbers,
X+ so alternate templates may be listed after the first to aid in this compression
X+ (e.g. `424-6501' may also be written as `(902)424-6501' or `902-424-6501'
X+ so you might have in your file `424-####', `(902)424-####', and `902-424-####',
X+ in which case all forms of `424-6501' would be listed in /etc/passwd as
X+ `6501', and would be expanded to `424-6501').
X  .SH FILES
X  .ta 2i
X  /etc/utmp	who file
X***************
X*** 68,73 ****
X--- 111,120 ----
X  ~/.plan	plans
X  .br
X  ~/.project	projects
X+ .br
X+ /usr/lib/finger.abbrev	abbreviations for office locations.
X+ .br
X+ /usr/lib/finger.phones	phone number formats based on number of digits given.
X  .SH "SEE ALSO"
X  chfn(1), w(1), who(1)
X  .SH AUTHOR
X***************
X*** 76,86 ****
X  Only the first line of the
X  .I .project
X  file is printed.
X- .PP
X- The encoding of the gcos field is UCB dependent \- it knows that an office
X- `197MC' is `197M Cory Hall', and that `529BE' is `529B Evans Hall'.
X- It also knows that a four digit office phone number should have a ``x2-''
X- prepended.
X  .PP
X  There is no way to pass arguments to the remote machine as
X  .I finger
X--- 123,128 ----
SHAR_EOF
if test 3222 -ne "`wc -c 'finger.1.diffs'`"
then
	echo shar: error transmitting "'finger.1.diffs'" '(should have been 3222 characters)'
fi
echo shar: extracting "'finger.abbrev'" '(295 characters)'
if test -f 'finger.abbrev'
then
	echo shar: over-writing existing file "'finger.abbrev'"
fi
sed 's/^X//' << \SHAR_EOF > 'finger.abbrev'
XA	 A.M.I.
XA	 AMI
XB	 Business
XC	 Chase
XC	 M.S.&C.S.
XC	 MS&CS
XC	 MSCS
XD	 D.R.E.A.
XD	 DREA
XF	 Fenwick
XH	 Howe Hall
XH	 Howe
XK	 Killam
XL	 L.S.C.
XL	 LSC
XM	 M.St.V.U.
XM	 M.S.V.U.
XM	 MSVU
XM	 Mount
XO	 B.I.O.
XO	 BIO
XP	 A&A
XP	 Arts & Admin
XS	 Shirreff
XS	 Shirreff Hall
XT	 T.U.N.S.
XT	 TUNS
XZ	 S.M.U.
XZ	 SMU
SHAR_EOF
if test 295 -ne "`wc -c 'finger.abbrev'`"
then
	echo shar: error transmitting "'finger.abbrev'" '(should have been 295 characters)'
fi
echo shar: extracting "'finger.c.diffs'" '(8824 characters)'
if test -f 'finger.c.diffs'
then
	echo shar: over-writing existing file "'finger.c.diffs'"
fi
sed 's/^X//' << \SHAR_EOF > 'finger.c.diffs'
XRCS file: RCS/finger.c,v
Xretrieving revision 1.1
Xdiff -b -c -r1.1 finger.c
X*** /tmp/,RCSt1020512	Thu Sep 24 15:30:16 1987
X--- finger.c	Thu Sep 24 15:28:21 1987
X***************
X*** 68,75 ****
X  #define ASTERISK	'*'		/* ignore this in real name */
X  #define COMMA		','		/* separator in pw_gecos field */
X  #define COMMAND		'-'		/* command line flag char */
X- #define CORY		'C'		/* cory hall office */
X- #define EVANS		'E'		/* evans hall office */
X  #define SAMENAME	'&'		/* repeat login name in real name */
X  #define TALKABLE	0220		/* tty is writable if 220 mode */
X  
X--- 68,73 ----
X***************
X*** 96,105 ****
X--- 94,122 ----
X  	struct person *link;		/* link to next person */
X  };
X  
X+ #define EX_MAX	29
X+ 
X+ struct abbrev {
X+     char    abbreve;
X+     char    expand[EX_MAX];
X+     int	    len;
X+ } *abbrevs;
X+ 
X+ #define PH_MAX 30
X+ #define COPY_CHAR	'#'		/* copy digit from given phone number
X+ 					   to template */
X+ 
X+ struct phone {
X+     int	    len;
X+     char    expand[PH_MAX];
X+ } *phones;
X+ 
X  char LASTLOG[] = "/usr/adm/lastlog";	/* last login info */
X  char USERLOG[] = "/etc/utmp";		/* who is logged in */
X  char PLAN[] = "/.plan";			/* what plan file is */
X  char PROJ[] = "/.project";		/* what project file */
X+ char ABBREV[] = "/usr/lib/finger.abbrev";/* Abbrevs for Office locations */
X+ char PHONES[] = "/usr/lib/finger.phones";/* what to do with phone numbers */
X  	
X  int unbrief = 1;			/* -b option default */
X  int header = 1;				/* -f option default */
X***************
X*** 489,494 ****
X--- 506,512 ----
X  {
X  	char *p;
X  	char dialup;
X+ 	int i;
X  
X  	if (pers->pwd == 0) {
X  		printf("%-15s       ???\n", pers->name);
X***************
X*** 497,504 ****
X  	printf("%-*s", NMAX, pers->pwd->pw_name);
X  	dialup = 0;
X  	if (wide) {
X! 		if (pers->realname)
X  			printf(" %-20.20s", pers->realname);
X  		else
X  			printf("        ???          ");
X  	}
X--- 515,526 ----
X  	printf("%-*s", NMAX, pers->pwd->pw_name);
X  	dialup = 0;
X  	if (wide) {
X! 	    if (pers->realname) {
X! 		if (strlen(pers->realname) > 20)
X! 		  for (i=17; i <= 19; i++)
X! 		    pers->realname[i] = '.';
X  		printf(" %-20.20s", pers->realname);
X+ 	    }
X  	    else
X  	      printf("        ???          ");
X  	}
X***************
X*** 528,543 ****
X  	else
X  		printf(" <%-12.12s>", p + 4);
X  	if (dialup && pers->homephone)
X! 		printf(" %20s", pers->homephone);
X  	else {
X  		if (pers->office)
X! 			printf(" %-11.11s", pers->office);
X! 		else if (pers->officephone || pers->homephone)
X! 			printf("            ");
X  		if (pers->officephone)
X  			printf(" %s", pers->officephone);
X  		else if (pers->homephone)
X! 			printf(" %s", pers->homephone);
X  	}
X  	putchar('\n');
X  }
X--- 550,567 ----
X  	else
X  		printf(" <%-12.12s>", p + 4);
X  	if (dialup && pers->homephone)
X! 		printf(" Home Phone -> %8s", pers->homephone);
X  	else {
X  		if (pers->office)
X! 			printf(" %-13.13s", pers->office);
X! 		else if (pers->officephone)
X! 		  	printf(" Office Ph. ->");
X! 		else if (pers->homephone)
X! 			printf(" Home Phone ->");
X  		if (pers->officephone)
X  			printf(" %s", pers->officephone);
X  		else if (pers->homephone)
X! 			printf(" %8s", pers->homephone);
X  	}
X  	putchar('\n');
X  }
X***************
X*** 562,568 ****
X  	if (pers->realname)
X  		printf("In real life: %s", pers->realname);
X  	if (pers->office) {
X! 		printf("\nOffice: %-.11s", pers->office);
X  		if (pers->officephone) {
X  			printf(", %s", pers->officephone);
X  			if (pers->homephone)
X--- 586,592 ----
X  	if (pers->realname)
X  		printf("In real life: %s", pers->realname);
X  	if (pers->office) {
X! 		printf("\nOffice: %-.13s", pers->office);
X  		if (pers->officephone) {
X  			printf(", %s", pers->officephone);
X  			if (pers->homephone)
X***************
X*** 619,627 ****
X  	putchar('\n');
X  }
X  
X  /*
X!  *  very hacky section of code to format phone numbers.  filled with
X!  *  magic constants like 4, 7 and 10.
X   */
X  char *
X  phone(s, len, alldigits)
X--- 643,677 ----
X  	putchar('\n');
X  }
X  
X+ void get_phones()
X+ {
X+     FILE *pf;
X+     char buf[BUFSIZ];
X+     int pp = 0;
X+     char *cp;
X+ 
X+     phones = (struct phone *) malloc (sizeof (struct phone));
X+     phones[pp].len = 0;
X+     phones[pp].expand[0] = '\0';
X+     if ((pf = fopen (PHONES, "r")) == NULL) {
X+ 	return;
X+     }
X+     while (fgets(buf, BUFSIZ, pf)) {
X+ 	phones[pp].len = count_hash(buf);
X+ 	if (!phones[pp].len)
X+ 	  continue;
X+ 	(void) strncpy (phones[pp].expand, buf, PH_MAX);
X+ 	if (phones[pp].expand[strlen(phones[pp].expand) - 1] == '\n')
X+ 	  phones[pp].expand[strlen(phones[pp].expand) - 1] = '\0';
X+ 	phones = (struct phone *) realloc (phones, sizeof (struct phone) * (++pp + 1));
X+ 	phones[pp].len = 0;
X+ 	phones[pp].expand[0] = '\0';
X+     }
X+     (void) fclose (pf);
X+ }
X+ 
X  /*
X!  *  format phone numbers.
X   */
X  char *
X  phone(s, len, alldigits)
X***************
X*** 629,683 ****
X  	int len;
X  	char alldigits;
X  {
X! 	char fonebuf[15];
X  	register char *p = fonebuf;
X  	register i;
X  
X  	if (!alldigits)
X  		return (strcpy(malloc(len + 1), s));
X! 	switch (len) {
X! 	case 4:
X! 		*p++ = ' ';
X! 		*p++ = 'x';
X! 		*p++ = '2';
X! 		*p++ = '-';
X! 		for (i = 0; i < 4; i++)
X  			*p++ = *s++;
X  		break;
X- 	case 5:
X- 		*p++ = ' ';
X- 		*p++ = 'x';
X- 		*p++ = *s++;
X- 		*p++ = '-';
X- 		for (i = 0; i < 4; i++)
X- 			*p++ = *s++;
X- 		break;
X- 	case 7:
X- 		for (i = 0; i < 3; i++)
X- 			*p++ = *s++;
X- 		*p++ = '-';
X- 		for (i = 0; i < 4; i++)
X- 			*p++ = *s++;
X- 		break;
X- 	case 10:
X- 		for (i = 0; i < 3; i++)
X- 			*p++ = *s++;
X- 		*p++ = '-';
X- 		for (i = 0; i < 3; i++)
X- 			*p++ = *s++;
X- 		*p++ = '-';
X- 		for (i = 0; i < 4; i++)
X- 			*p++ = *s++;
X- 		break;
X- 	case 0:
X- 		return 0;
X- 	default:
X- 		return (strcpy(malloc(len + 1), s));
X  	}
X  	*p++ = 0;
X  	return (strcpy(malloc(p - fonebuf), fonebuf));
X  }
X  
X  /*
X   * decode the information in the gecos field of /etc/passwd
X   */
X--- 679,737 ----
X  	int len;
X  	char alldigits;
X  {
X! 	char fonebuf[PH_MAX];
X  	register char *p = fonebuf;
X  	register i;
X+ 	register char *cp;
X+ 	static int has_phones = 0;
X+ 	struct phone *pp;
X  
X  	if (!alldigits)
X  	  return (strcpy(malloc(len + 1), s));
X! 	if (!len)
X! 	  return 0;
X! 	if (!has_phones) {
X! 	    get_phones();
X! 	    has_phones = 1;
X! 	}
X! 	for (pp = phones; pp->len; pp++)
X! 	  if (len == pp->len) {
X! 	      for (cp = pp->expand; *cp; cp++)
X! 		if (*cp == COPY_CHAR)
X  		  *p++ = *s++;
X+ 		else
X+ 		  *p++ = *cp;
X  	      break;
X  	  }
X+ 	if (!pp->len)
X+ 	  return (strcpy(malloc(len + 1), s));
X  	*p++ = 0;
X  	return (strcpy(malloc(p - fonebuf), fonebuf));
X  }
X  
X+ void get_abbreves()
X+ {
X+     FILE *af;
X+     char buf[BUFSIZ];
X+     int ap = 0;
X+ 
X+     abbrevs = (struct abbrev *) malloc (sizeof (struct abbrev));
X+     abbrevs[ap].abbreve = '\0';
X+     if ((af = fopen (ABBREV, "r")) == NULL) {
X+ 	return;
X+     }
X+     while (fgets(buf, BUFSIZ, af)) {
X+ 	abbrevs[ap].abbreve = buf[0];
X+ 	(void) strncpy (abbrevs[ap].expand, &buf[2], EX_MAX);
X+ 	abbrevs[ap].len = strlen(abbrevs[ap].expand);
X+ 	if (abbrevs[ap].expand[abbrevs[ap].len - 1] == '\n')
X+ 	  abbrevs[ap].expand[--abbrevs[ap].len] = '\0';
X+ 	abbrevs = (struct abbrev *) realloc (abbrevs, sizeof (struct abbrev) * (++ap + 1));
X+ 	abbrevs[ap].abbreve = '\0';
X+     }
X+     (void) fclose (af);
X+ }
X+ 
X  /*
X   * decode the information in the gecos field of /etc/passwd
X   */
X***************
X*** 689,694 ****
X--- 743,750 ----
X  	int alldigits;
X  	int hasspace;
X  	int len;
X+ 	static int has_abbreves = 0;
X+ 	struct abbrev *ap;
X  
X  	pers->realname = 0;
X  	pers->office = 0;
X***************
X*** 723,729 ****
X  			*bp = *gp++;
X  			if (*bp == ' ')
X  				hasspace = 1;
X- 			/* leave 5 for Cory and Evans expansion */
X  			if (bp < buffer + sizeof buffer - 6)
X  				bp++;
X  		}
X--- 779,784 ----
X***************
X*** 732,745 ****
X  		bp--;			/* point to last character */
X  		if (hasspace || len == 0)
X  			len++;
X! 		else if (*bp == CORY) {
X! 			strcpy(bp, " Cory");
X! 			len += 5;
X! 		} else if (*bp == EVANS) {
X! 			strcpy(bp, " Evans");
X! 			len += 6;
X! 		} else
X  			len++;
X  		if (len > 1)
X  			pers->office = strcpy(malloc(len), buffer);
X  	}
X--- 787,806 ----
X  		bp--;			/* point to last character */
X  		if (hasspace || len == 0)
X  			len++;
X! 		else {
X! 		    if (!has_abbreves) {
X! 			get_abbreves();
X! 			has_abbreves = 1;
X! 		    }
X! 		    for (ap = abbrevs; ap->abbreve; ap++)
X! 		      if (*bp == ap->abbreve) {
X! 			  strcpy(bp, ap->expand);
X! 			  len += ap->len;
X! 			  break;
X! 		      }
X! 		    if (!ap->abbreve)
X  		      len++;
X+ 		}
X  		if (len > 1)
X  			pers->office = strcpy(malloc(len), buffer);
X  	}
X***************
X*** 1077,1080 ****
X--- 1138,1155 ----
X  		putchar('\n');
X  	(void)fclose(f);
X  	return (1);
X+ }
X+ 
X+ int count_hash(s)
X+ char *s;
X+ {
X+     int count = 0;
X+     register char *p = s;
X+ 
X+     while (*p) {
X+ 	if (*p == COPY_CHAR)
X+ 	  count++;
X+ 	p++;
X+     }
X+     return count;
X  }
SHAR_EOF
if test 8824 -ne "`wc -c 'finger.c.diffs'`"
then
	echo shar: error transmitting "'finger.c.diffs'" '(should have been 8824 characters)'
fi
echo shar: extracting "'finger.phones'" '(142 characters)'
if test -f 'finger.phones'
then
	echo shar: over-writing existing file "'finger.phones'"
fi
sed 's/^X//' << \SHAR_EOF > 'finger.phones'
X424-####
X(902)424-####
X902-424-####
X1-902-424-####
X###-####
X(902)###-####
X902-###-####
X#-###-####
X1-902-###-####
X(###)###-####
X1-###-###-####
SHAR_EOF
if test 142 -ne "`wc -c 'finger.phones'`"
then
	echo shar: error transmitting "'finger.phones'" '(should have been 142 characters)'
fi
echo shar: extracting "'passwd.1.diffs'" '(1070 characters)'
if test -f 'passwd.1.diffs'
then
	echo shar: over-writing existing file "'passwd.1.diffs'"
fi
sed 's/^X//' << \SHAR_EOF > 'passwd.1.diffs'
XRCS file: RCS/passwd.1,v
Xretrieving revision 1.1
Xdiff -b -c -r1.1 passwd.1
X*** /tmp/,RCSt1021667	Wed Sep 23 14:19:12 1987
X--- passwd.1	Tue Sep 22 15:29:01 1987
X***************
X*** 85,91 ****
X  .sp
X  .PP
X  .I Passwd
X! allows phone numbers to be entered with or without hyphens.
X  It is a good idea to run
X  .I finger
X  after changing the GECOS information
X--- 85,94 ----
X  .sp
X  .PP
X  .I Passwd
X! allows phone numbers to be entered with or without hyphens,
X! hyphens are stripped and the number entered is compared with the
X! templates in /usr/lib/finger.phones and if a match is made only then
X! only the necessary digits are kept.
X  It is a good idea to run
X  .I finger
X  after changing the GECOS information
X***************
X*** 97,102 ****
X--- 100,109 ----
X  /etc/passwd	The file containing all of this information
X  .br
X  /etc/shells	The list of approved shells
X+ .br
X+ /usr/lib/finger.abbrev	The list of valid office abbreviations.
X+ .br
X+ /usr/lib/finger.phones	The list of phone-number expansions.
X  .SH "SEE ALSO"
X  login(1), finger(1), passwd(5), crypt(3)
X  .br
SHAR_EOF
if test 1070 -ne "`wc -c 'passwd.1.diffs'`"
then
	echo shar: error transmitting "'passwd.1.diffs'" '(should have been 1070 characters)'
fi
echo shar: extracting "'passwd.c.diffs'" '(7964 characters)'
if test -f 'passwd.c.diffs'
then
	echo shar: over-writing existing file "'passwd.c.diffs'"
fi
sed 's/^X//' << \SHAR_EOF > 'passwd.c.diffs'
XRCS file: RCS/passwd.c,v
Xretrieving revision 1.1
Xdiff -b -c -r1.1 passwd.c
X*** /tmp/,RCSt1021655	Wed Sep 23 14:18:43 1987
X--- passwd.c	Wed Sep 23 14:17:34 1987
X***************
X*** 38,43 ****
X--- 38,46 ----
X   * but too many programs know that it is /bin/sh.
X   */
X  #define DEFSHELL "/bin/sh"
X+ #define ABBREV "/usr/lib/finger.abbrev"
X+ #define PHONES "/usr/lib/finger.phones"
X+ #define COPY_CHAR '#'
X  
X  char	temp[] = "/etc/ptmp";
X  char	passwd[] = "/etc/passwd";
X***************
X*** 418,423 ****
X--- 424,432 ----
X  	char in_str[BUFSIZ];
X  	struct default_values *defaults, *get_defaults();
X  	static char answer[4*BUFSIZ];
X+ 	FILE *af, *pf;
X+ 	char buf[BUFSIZ], prev_ch;
X+ 	int prev_num;
X  
X  	answer[0] = '\0';
X  	defaults = get_defaults(pwd->pw_gecos);
X***************
X*** 437,444 ****
X  	/*
X  	 * Get room number.
X  	 */
X  	do {
X! 		printf("Room number (Exs: 597E or 197C) [%s]: ",
X  			defaults->office_num);
X  		(void) fgets(in_str, BUFSIZ, stdin);
X  		if (special_case(in_str, defaults->office_num))
X--- 446,466 ----
X  	/*
X  	 * Get room number.
X  	 */
X+ 	if ((af = fopen (ABBREV, "r")) != NULL) {
X+ 	    printf ("Enter your room number. Any of the following single\n");
X+ 	    printf ("character abbreviations, may be used as the last\n");
X+ 	    printf ("character of the room number.");
X+ 	    printf ("\tAbbrev\tExpansion\n\t======\t=========\n");
X+ 	    prev_ch = '\0';
X+ 	    while (fgets(buf, BUFSIZ, af))
X+ 	      if (buf[0] != prev_ch) {
X+ 		  printf ("\t%s", buf);
X+ 		  prev_ch = buf[0];
X+ 	      }
X+ 	    (void) close (af);
X+ 	}
X  	do {
X! 		printf("Room number [%s]: ",
X  			defaults->office_num);
X  		(void) fgets(in_str, BUFSIZ, stdin);
X  		if (special_case(in_str, defaults->office_num))
X***************
X*** 449,461 ****
X  	 * Get office phone number.
X  	 * Remove hyphens.
X  	 */
X  	do {
X! 		printf("Office Phone (Ex: 6426000) [%s]: ",
X  			defaults->office_phone);
X  		(void) fgets(in_str, BUFSIZ, stdin);
X  		if (special_case(in_str, defaults->office_phone))
X  			break;
X! 		remove_hyphens(in_str);
X  	} while (illegal_input(in_str) || not_all_digits(in_str));
X  	(void) strcat(strcat(answer, ","), in_str);
X  	/*
X--- 471,498 ----
X  	 * Get office phone number.
X  	 * Remove hyphens.
X  	 */
X+ 	if ((pf = fopen (PHONES, "r")) != NULL) {
X+ 	    printf ("Enter your phone numbers, if you give a phone number\n");
X+ 	    printf ("with a number of digits equal to one of the following\n");
X+ 	    printf ("lengths (hyphens are ignored, any other non-digit will\n");
X+ 	    printf ("inhibit expansion), it will be expanded to the\n");
X+ 	    printf ("corresponding expansion.\n");
X+ 	    printf ("\tDigits\tExpansion\n\t======\t=========\n");
X+ 	    prev_num = -1;
X+ 	    while (fgets(buf, BUFSIZ, pf)) {
X+ 		if (prev_num == count_hash(buf))
X+ 		  continue;
X+ 		printf ("\t%d\t%s", prev_num = count_hash(buf), buf);
X+ 	    }
X+ 	    (void) close (pf);
X+ 	}
X  	do {
X! 		printf("Office Phone [%s]: ",
X  			defaults->office_phone);
X  		(void) fgets(in_str, BUFSIZ, stdin);
X  		if (special_case(in_str, defaults->office_phone))
X  			break;
X! 		minimize_phone(in_str);
X  	} while (illegal_input(in_str) || not_all_digits(in_str));
X  	(void) strcat(strcat(answer, ","), in_str);
X  	/*
X***************
X*** 463,473 ****
X  	 * Remove hyphens if present.
X  	 */
X  	do {
X! 		printf("Home Phone (Ex: 9875432) [%s]: ", defaults->home_phone);
X  		(void) fgets(in_str, BUFSIZ, stdin);
X  		if (special_case(in_str, defaults->home_phone))
X  			break;
X! 		remove_hyphens(in_str);
X  	} while (illegal_input(in_str) || not_all_digits(in_str));
X  	(void) strcat(strcat(answer, ","), in_str);
X  	if (strcmp(answer, pwd->pw_gecos) == 0) {
X--- 500,510 ----
X  	 * Remove hyphens if present.
X  	 */
X  	do {
X! 		printf("Home Phone [%s]: ", defaults->home_phone);
X  		(void) fgets(in_str, BUFSIZ, stdin);
X  		if (special_case(in_str, defaults->home_phone))
X  		  break;
X! 		minimize_phone(in_str);
X  	} while (illegal_input(in_str) || not_all_digits(in_str));
X  	(void) strcat(strcat(answer, ","), in_str);
X  	if (strcmp(answer, pwd->pw_gecos) == 0) {
X***************
X*** 554,595 ****
X  }
X  
X  /*
X-  * Deal with Berkeley buildings.  Abbreviating Cory to C and Evans to E.
X-  * Correction changes "str".
X-  *
X   * Returns 1 if incorrect room format.
X   * 
X   * Note: this function assumes that the newline has been removed from str.
X   */
X  illegal_building(str)
X! 	register char *str;
X  {
X  	int length = strlen(str);
X  	register char *ptr;
X  
X! 	/*
X! 	 * If the string is [Ee]vans or [Cc]ory or ends in
X! 	 * [ \t0-9][Ee]vans or [ \t0-9M][Cc]ory, then contract the name
X! 	 * into 'E' or 'C', as the case may be, and delete leading blanks.
X! 	 */
X! 	if (length >= 5 && strcmp(ptr = str + length - 4, "vans") == 0 &&
X! 	    (*--ptr == 'e' || *ptr == 'E') &&
X! 	    (--ptr < str || isspace(*ptr) || isdigit(*ptr))) {
X! 		for (; ptr > str && isspace(*ptr); ptr--)
X! 			;
X  		ptr++;
X! 		*ptr++ = 'E';
X! 		*ptr = '\0';
X! 	} else
X! 	if (length >= 4 && strcmp(ptr = str + length - 3, "ory") == 0 &&
X! 	    (*--ptr == 'c' || *ptr == 'C') &&
X! 	    (--ptr < str || *ptr == 'M' || isspace(*ptr) || isdigit(*ptr))) {
X! 		for (; ptr > str && isspace(*ptr); ptr--)
X! 			;
X  		ptr++;
X! 		*ptr++ = 'C';
X  		*ptr = '\0';
X  	}
X  	return (0);
X  }
X  
X--- 591,657 ----
X  }
X  
X  /*
X   * Returns 1 if incorrect room format.
X   * 
X   * Note: this function assumes that the newline has been removed from str.
X   */
X  illegal_building(str)
X! register char *str;
X  {
X      int length = strlen(str);
X      register char *ptr;
X+     FILE *af;
X+     char buf[BUFSIZ];
X+     register char *cp;
X+     int buflen;
X  
X!     ptr = str;
X!     while (*ptr && isspace(*ptr)) {
X  	ptr++;
X! 	length--;
X!     }
X!     if (ptr != str)
X!       (void) strcpy (str, ptr);
X!     ptr = str + length - 1;
X!     while ((ptr > str) && isspace(*ptr)) {
X! 	*ptr-- = '\0';
X! 	length--;
X!     }
X!     if ((af = fopen (ABBREV, "r")) == NULL) {
X! 	perror (ABBREV);
X! 	return 0;
X!     }
X!     while (fgets(buf, BUFSIZ, af)) {
X! 	buflen = strlen(buf);
X! 	if (buf[buflen - 1] == '\n')
X! 	  buf[--buflen] = '\0';
X! 	if (buflen <= 2)
X! 	  continue;
X! 	buflen -= 2;
X! 	cp = &buf[2];
X! 	while (isspace(*cp) && *cp) {
X! 	    cp++;
X! 	    buflen--;
X! 	}
X! 	if (buflen <= 0)
X! 	  continue;
X! 	if (length >= buflen) {
X! 	    ptr = str + length - buflen;
X! 	    while (isupper(*ptr)?tolower(*ptr):*ptr == isupper(*cp)?tolower(*cp):*cp && *ptr) {
X  		ptr++;
X! 		cp++;
X! 	    }
X! 	    if (!*ptr) {
X! 		ptr = str + length - buflen - 1;
X! 		for (; ptr > str && isspace(*ptr); ptr--);
X! 		ptr++;
X! 		*ptr++ = buf[0];
X  		*ptr = '\0';
X+ 		break;
X  	    }
X+ 	}
X+     }
X+     (void) fclose(af);
X      return (0);
X  }
X  
X***************
X*** 684,687 ****
X--- 746,813 ----
X  	 */
X  	*str = '\0';
X  	return (1);
X+ }
X+ 
X+ int count_hash(s)
X+ char *s;
X+ {
X+     int count = 0;
X+     register char *p = s;
X+ 
X+     while (*p) {
X+ 	if (*p == COPY_CHAR)
X+ 	  count++;
X+ 	p++;
X+     }
X+     return count;
X+ }
X+ 
X+ minimize_phone(str)
X+ char *str;
X+ {
X+     FILE *pf;
X+     char buf[BUFSIZ], tmp[BUFSIZ];
X+     char match = 0;
X+     int  loc, pos;
X+ 
X+     remove_hyphens(str);
X+     if ((pf = fopen (PHONES, "r")) == NULL)
X+       return;
X+     while (fgets(buf, BUFSIZ, pf)) {
X+ 	remove_hyphens(buf);
X+ 	if (strlen(buf) != strlen(str))
X+ 	  continue;
X+ 	else
X+ 	  for (loc = 0, match = 1; buf[loc] && match; loc++)
X+ 	    if (buf[loc] == COPY_CHAR)
X+ 	      switch (str[loc]) {
X+ 	      case '0':
X+ 	      case '1':
X+ 	      case '2':
X+ 	      case '3':
X+ 	      case '4':
X+ 	      case '5':
X+ 	      case '6':
X+ 	      case '7':
X+ 	      case '8':
X+ 	      case '9':
X+ 		  break;
X+ 	      default:
X+ 		  match = 0;
X+ 		  break;
X+ 	      }
X+ 	    else if (buf[loc] != str[loc])
X+ 	      match = 0;
X+ 	if (match)
X+ 	  break;
X+     }
X+     (void) fclose (pf);
X+     if (match) {
X+ 	for (loc = 0, pos=0; buf[loc]; loc++)
X+ 	  if (buf[loc] == COPY_CHAR)
X+ 	    tmp[pos++] = str[loc];
X+ 	tmp[pos++] = '\n';
X+ 	tmp[pos] = '\0';
X+ 	strcpy (str, tmp);
X+     }
X  }
SHAR_EOF
if test 7964 -ne "`wc -c 'passwd.c.diffs'`"
then
	echo shar: error transmitting "'passwd.c.diffs'" '(should have been 7964 characters)'
fi
#	End of shell archive
exit 0
-- 
Michael A. Thompson, Dept. Math, Stats, & C.S., Dalhousie U., Halifax, N.S.
thompson@dalcs.uucp	From Bitnet or Uucp
thompson@cs.dal.cdn	From Bitnet or Cdn
thompson%dalcs.uucp@uunet.uu.net From Arpa