[comp.sources.bugs] Official patch #7 for faces v1.4

richb@sunaus.oz (Rich Burridge) (08/14/90)

/** IMPORTANT NOTE: This patch and the new file (mush.xface.patch)
 ** comes in two messages. You should save these two messages, strip off the
 ** initial header (down to and including the CUT HERE lines), and
 ** anything below (and including) the CUT HERE line at the end of each
 ** file. cat the two files together, and unpack with sh. Use Larry Wall's
 ** patch program to apply, and recompile and reinstall.
 **
 ** I apologise for this; I didn't realise the patch was going to be so
 ** big.
 **/

This is official patch #7 for faces v1.4; please apply it.
It has also been sent to comp.sources.misc for posting there, and
subsequent archiving.

Faces v1.4 was posted to comp.sources.misc about the end of June 1990,
and was already at patchlevel #5. Patch #6 can be obtained via the mail
archive server, by sending a message to rb-archive-server@Aus.Sun.COM
containing the line:

send faces patch6

Note you might need to include a valid path line in this message, in
order for the mail server to get the patch back to you. Such a line might
be:

path uunet.uu.net!hostname!username

Rich Burridge,          DOMAIN: richb@Aus.Sun.COM
Sun Microsystems.       ACSNET: richb@sunaus.sun.oz
PHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
-------------------------------------------------------------------------

Faces v1.4 patch #7 makes the following changes:

       * From Chris Steinbroner <hesh@lll-crg.llnl.gov>
         From Bob Posert <psitech.psitech!bob@uunet.UU.NET>
         Incoming mail is not always stored in /usr/spool/mail/username.
         HP-UX and Dell Unix (Interactive 386/ix) store it in
         /usr/mail/username. Another definition (SPOOLDIR), has been added
         to the Makefile. The README file has also been updated.
 
       * From Hugues Leroy <Hugues.Leroy@irisa.fr>
         From Graham Dumpleton <grahamd@otc.otca.oz.au>
         From Peter Chubb <peterc@softway.oz.au>
         From Robert Adams <adams@trim.intel.com>
         The parsefrom() function was not replacing a '\n' at the end of
         a line with '\0' before preceding.
 
       * From Michael Schmidt <michael@uni-paderborn.de>
         The faces window now accepts two more keyboard characters:
            q - to terminate the faces program.
           ^L - to refresh the faces window.
 
       * From Michael Schmidt <michael@uni-paderborn.de>
         Added support for printer monitoring with the PLP printer
         spooling system. Another definition (PLP) has been added to
         the Makefile. The README file has been updated.
 
       * From Chris Steinbroner <hesh@lll-crg.llnl.gov>
         Diffs included to allow faces to run under HP-UX.
 
       * From Robert Adams <adams@trim.intel.com>
         Changed the SYSV definition to SYSV32 because I work with both
         System V.3.2.2 and System V.4.0 from AT&T and they need different
         defines.
 
       * From Robert Adams <adams@trim.intel.com>
         Added -bg and -fg to the parameter string and modified x11.c
         to set the background and foreground colors. Currently this is
         only available with the X11 graphics driver.
 
       * From Robert Adams <adams@trim.intel.com>
         people.tab now accepts the syntax "aliascomm/alias=comm/name"
         to map a whole name (this is one of the TODO points).
         It still accepts the old syntax. As a side effect, the
         people.tab and machine.tab routines were re-written to be
         better parsers and are now forgiving of white space.
 
       * From Robert Adams <adams@trim.intel.com>
         make_iconname was rewritten to get rid of the cut and paste
         code and now is a gaggle of 'for' loops.
 
       * From Robert Adams <adams@trim.intel.com>
         From Michael Schmidt <michael@uni-paderborn.de>
         The domain name parsing code in make_iconname was not working.
         The problem was that the 'old_style' code 'goto'ed out of the
         middle of the domain breakdown loop thus defeating same.
 
       * From Robert Adams <adams@trim.intel.com>
         The code for building the name for people.tab and machine.tab was
         broken if an alternate directory ("-f") was specified (changes
         in rec.c in read_alias and read_machines).

       * From Robert Adams <adams@trim.intel.com>
         If 'host' does not appear in an RFC822 address, the code would
         assume "LOCAL".  The code has been fixed to assume 'hostname'
         instead (fix to parsefrom.c).

       * From Robert Adams <adams@trim.intel.com>
         There was a strange bug that would cause icons on the end of the
         list (after entries were deleted) to get mangled.  This usually
         showed up as the NOMAIL icon not being shown but garbage being
         shown instead.  The problem was that in 'garbage_collect', there
         was a local variable 'last' that was hidding the global variable
         of the same name and thus the global was not getting updated

       * From Pat Lashley <patl@Sun.COM>
         Added code to use the Domain Name Service to attempt to convert
         unqualified hostnames, or hostnames with partial domains to fully
         qualified domain names. Another definition (DNSLOOKUP) has been
         added to the Makefile. The README file has been updated.

       * From Pat Lashley <patl@Sun.COM>
         When no icon is found for a given user, the unknown icon may be
         displayed either with the user name, or labeled as `unknown'.
         The former case provides the most information, the latter allows
         all unknown users within a given community to be lumped into a
         single image. Another definition (NAMEUNKNOWN) has been added to
         the Makefile. The README file has been updated.

       * From Pat Lashley <patl@Sun.COM>
         Support is now included for multiple face directories. Faces
         will search for the environment variable FACEPATH, and use this
         as a list of colon separated face directories. See the manual
         page for more details.

       * Official support for X-Face lines was not included with patch #2
         to mush v7.1. Dan and Bart suggested that instead, a new file
         (mush.xface.patch) should be included with the faces distribution
         which in an unofficial patch to mush v7.1.2, to allow that X-Face
         support. The README, MANIFEST and FILES files have been updated.

       * From Rod Whitby <rwhitby@austek.oz.au>
         faces v.1.4.6 dumps core when the following message (cut down to the
         smallest case) is in my mail box. This was a case of a valid X-Face:
         being followed by a line starting with the word "X-Face ". Faces now
         searches for "X-Face:" rather than "X-Face". This really needs to be
         tightened up some more.

It introduces the following file:

       * mush.xface.patch  - unofficial patch to apply to Mush v7.1.2 to get
                             X-Face: support.

------CUT HERE------CUT HERE------CUT HERE------CUT HERE------
#! /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 to create the files:
#	mush.xface.patch
#	patch.7
# This archive created: Tue Aug 14 07:22:29 EST 1990
#
#
export PATH; PATH=/bin:$PATH
#
if [ -f mush.xface.patch ]
then
echo shar: will not over-write existing file mush.xface.patch
else
echo shar: extracting 'mush.xface.patch',     3336 characters
cat > mush.xface.patch <<'Funky_Stuff'
*** Mushrc.orig	Mon Aug  6 11:32:57 1990
--- Mushrc	Mon Aug  6 11:33:22 1990
***************
*** 29,35 ****
  set newline
  
  # When reading messages, don't bother looking at lengthy, boring headers.
! ignore message-id received via status
  
  # Since mush has csh-like history, you might find it annoying to type
  # things like "mail host\!host1\!host2\!user" from within the mush shell.
--- 29,35 ----
  set newline
  
  # When reading messages, don't bother looking at lengthy, boring headers.
! ignore message-id received via status X-Face
  
  # Since mush has csh-like history, you might find it annoying to type
  # things like "mail host\!host1\!host2\!user" from within the mush shell.
*** init.c.orig	Mon Aug  6 07:57:54 1990
--- init.c	Mon Aug  6 08:01:10 1990
***************
*** 12,20 ****
--- 12,23 ----
  #include <sys/utsname.h>
  #endif /* SYSV */
  
+ char facebuf[1024];	/* For possible compressed X-Face: image. */
+ 
  void
  init()
  {
+     FILE		*fp;
      char 		*home, *realname, *argv[4];
      extern char		*getlogin();
      char		buf[MAXPATHLEN];
***************
*** 135,140 ****
--- 138,153 ----
  	argv[0] = "hostname";
  	argv[2] = buf;
  	(void) add_option(&set_options, argv);
+     }
+ 
+     (void) sprintf(buf, "%s/.face", home);
+     if (fp = fopen(buf, "r")) {
+ 	facebuf[0] = '\0';
+ 	while (fgets(buf, BUFSIZ, fp) != NULL) {
+ 	    if (facebuf[0] != '\0')
+ 		(void) strcat(facebuf, "\t");
+ 	    (void) strcat(facebuf, buf);
+ 	}
      }
  
      init_bindings();
*** config.h-dist.orig	Mon Aug  6 11:38:03 1990
--- config.h-dist	Mon Aug  6 11:39:53 1990
***************
*** 104,110 ****
  /* #define PICKY_MAILER /**/
  
  /* Headers that will NOT be included when forwarding mail */
! #define IGNORE_ON_FWD	"status"	/* comma or space separated list */
  
  #define	MAXMSGS		1000	/* maximum number of messages we can read */
  #define HDRSIZ BUFSIZ	/* This should not be < BUFSIZ! (but can be >) */
--- 104,110 ----
  /* #define PICKY_MAILER /**/
  
  /* Headers that will NOT be included when forwarding mail */
! #define IGNORE_ON_FWD	"status,X-Face"	/* comma or space separated list */
  
  #define	MAXMSGS		1000	/* maximum number of messages we can read */
  #define HDRSIZ BUFSIZ	/* This should not be < BUFSIZ! (but can be >) */
*** mail.c.orig	Mon Aug  6 07:58:05 1990
--- mail.c	Mon Aug  6 09:02:27 1990
***************
*** 1491,1496 ****
--- 1491,1497 ----
      int i, for_editor = (fp == NULL_FILE);
      int got_date = for_editor, got_from = for_editor;
      struct options *opts;
+     extern char facebuf[];
  
      if (for_editor && hfile) {
  	i = file_to_fp(hfile, files[0], "r");
***************
*** 1654,1659 ****
--- 1655,1661 ----
  		    !lcase_strncmp(p, "bcc:", 4) ||
  		    !lcase_strncmp(p, "fcc:", 4) ||
  		    !lcase_strncmp(p, "x-mailer:", 9) ||
+ 		    !lcase_strncmp(p, "x-face:", 7) ||
  		    !lcase_strncmp(p, "status:", 7))
  		    print_hdr = FALSE;
  		else if (!lcase_strncmp(p, "date:", 5))
***************
*** 1720,1725 ****
--- 1722,1729 ----
  #ifdef PICKY_MAILER
  	}
  #endif /* PICKY_MAILER */
+ 	if (facebuf != NULL)
+ 		(void) fprintf(files[i], "X-Face: %s", facebuf);
  	(void) fprintf(files[i], "X-Mailer: %s\n", check_internal("version"));
  	(void) fprintf(files[i], "%sTo: %s\n",
  	    ison(flags, FORWARD) ? "Resent-" : "", To);
Funky_Stuff
len=`wc -c < mush.xface.patch`
if [ $len !=     3336 ] ; then
echo error: mush.xface.patch was $len bytes long, should have been     3336
fi
fi # end of overwriting check
if [ -f patch.7 ]
then
echo shar: will not over-write existing file patch.7
else
echo shar: extracting 'patch.7',   101860 characters
cat > patch.7 <<'Funky_Stuff'

------- get.c -------
*** /tmp/da09664	Tue Aug 14 07:20:14 1990
--- get.c	Wed Aug  8 17:45:12 1990
***************
*** 15,21 ****
--- 15,25 ----
   */
  
  #include <stdio.h>
+ #ifdef SYSV32 || hpux
+ #include <string.h>
+ #else
  #include <strings.h>
+ #endif /* SYSV32 || hpux */
  #include <pwd.h>
  #include <ctype.h>
  #include "faces.h"
***************
*** 136,143 ****
--- 140,154 ----
  int argc ;
  char *argv[] ;
  {
+   char *faceenv ;
    char next[MAXLINE] ;    /* The next command line parameter. */
+   char *pptr ;
+   int i ;
  
+   faceenv = getenv("FACEPATH") ;
+   if (faceenv) STRCPY(facedirs, faceenv) ;
+   else facedirs[0] = (char) NULL ;
+ 
    INC ;
    while (argc > 0)
      {
***************
*** 159,165 ****
                         break ;
              case 'a' : mtype = MONALL ;    /* Monitor all of the spoolfile. */
                         break ;
!             case 'b' : INC ;               /* Alternate background pattern. */
                         getparam(bgicon, argv, "-b needs background icon") ;
                         break ;
              case 'c' : INC ;               /* Number of columns. */
--- 170,182 ----
                         break ;
              case 'a' : mtype = MONALL ;    /* Monitor all of the spoolfile. */
                         break ;
!             case 'b' : if (argv[0][2] == 'g')
!                          {
!                            INC ;           /* Background color. */
!                            getparam(bgcolor, argv, "-bg specifies background color") ;
!                            break ;
!                          }
!                        INC ;               /* Alternate background pattern. */
                         getparam(bgicon, argv, "-b needs background icon") ;
                         break ;
              case 'c' : INC ;               /* Number of columns. */
***************
*** 177,184 ****
                         INC ;
                         getparam(userprog, argv, "-e needs user program") ;
                         break ;
!             case 'f' : INC ;               /* New directory for face icons. */
!                        getparam(facedir, argv, "-f needs face directory") ;
                         break ;
              case 'g' : INC ;               /* X11 geometry information. */
                         getparam(geometry, argv,
--- 194,207 ----
                         INC ;
                         getparam(userprog, argv, "-e needs user program") ;
                         break ;
!             case 'f' : if (argv[0][2] == 'g')
!                          {
!                            INC ;           /* Background color. */
!                            getparam(fgcolor, argv, "-fg specifies foreground color") ;
!                            break ;
!                          }
!                        INC ;               /* New directory for face icons. */
!                        getparam(facedirs, argv, "-f needs face directory path") ;
                         break ;
              case 'g' : INC ;               /* X11 geometry information. */
                         getparam(geometry, argv,
***************
*** 276,281 ****
--- 299,324 ----
            }
        INC ;
      }
+ 
+ /* Parse the face path from the parameter line... */
+ 
+   for (i = 0, pptr = facedirs; pptr && (i <= MAXPATHS); i++)
+     {
+       if ((*pptr == ':') || (*pptr == (char) NULL))
+         {
+ 
+ /* Null entry in face path means insert compiled-in default. */
+ 
+           facepath[i] = FACEDIR ;
+           if (*(pptr++) == (char) NULL) break ;
+         }
+       else
+         {
+           facepath[i] = pptr ;
+           pptr = index(pptr, ':') ;
+           if (pptr) *(pptr++) = (char) NULL ;
+         }
+     }
  }
  
  
***************
*** 492,498 ****
  usage()      /* Print faces usage message. */
  {
    FPRINTF(stderr, "Usage: %s [-MH] [-P printer] [-Wi] [-Wp x y] ", progname) ;
!   FPRINTF(stderr, "[-WP x y] [-b background] [-d display] [-f facedir] ") ;
    FPRINTF(stderr, "[-g geometry] [-i] [-n] [-p period] [-s spoolfile] [-u] ") ;
    FPRINTF(stderr, "[-t] [-v]\n") ;
  }
--- 535,542 ----
  usage()      /* Print faces usage message. */
  {
    FPRINTF(stderr, "Usage: %s [-MH] [-P printer] [-Wi] [-Wp x y] ", progname) ;
!   FPRINTF(stderr, "[-WP x y] [-b background] [-bg background_color] ") ;
!   FPRINTF(stderr, "[-d display] [-f facepath] [-fg foreground_color] ") ;
    FPRINTF(stderr, "[-g geometry] [-i] [-n] [-p period] [-s spoolfile] [-u] ") ;
    FPRINTF(stderr, "[-t] [-v]\n") ;
  }

------- main.c -------
*** /tmp/da09667	Tue Aug 14 07:20:15 1990
--- main.c	Sat Aug  4 23:35:02 1990
***************
*** 17,31 ****
   */
  
  #include <stdio.h>
! #ifdef SYSV
  #include <string.h>
  #else
  #include <strings.h>
! #endif /*SYSV*/
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <netdb.h>
  
  #ifdef NISLOOKUP
  #include <rpcsvc/ypclnt.h>
  #endif /*NISLOOKUP*/
--- 17,37 ----
   */
  
  #include <stdio.h>
! #ifdef SYSV32 || hpux
  #include <string.h>
  #else
  #include <strings.h>
! #endif /* SYSV32 || hpux */
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <netdb.h>
+ #include <ctype.h>
  
+ #ifdef DNSLOOKUP
+ #include <sys/socket.h>
+ #include <netdb.h>
+ #endif /*DNSLOOKUP*/
+ 
  #ifdef NISLOOKUP
  #include <rpcsvc/ypclnt.h>
  #endif /*NISLOOKUP*/
***************
*** 72,77 ****
--- 78,84 ----
  enum gr_type gtype ;                /* Which graphics system is being used. */
  enum mon_type mtype = MONNEW ;      /* Type of monitoring operation to do. */
  
+ char bgcolor[MAXLINE] ;          /* X11 background color. */
  char bgicon[MAXLINE] ;           /* Alternate background pattern. */
  char community[MAXLINE] ;        /* Community name ("real" host name). */
  char defdir[MAXLINE] ;           /* The default face directory. */
***************
*** 81,87 ****
  char face_host[MAXLINE] ;   /* Pointer to host name from the "From" line. */
  char face_ts[MAXLINE] ;     /* Pointer to time stamp from the "From" line. */
  char face_user[MAXLINE] ;   /* Pointer to user name from the "From" line. */
! char facedir[MAXLINE] ;          /* Alternate face image directory. */
  char fname[MAXTYPES][MAXLINE] ;  /* Array of various face name types. */
  char geometry[MAXLINE] ;         /* X11 geometry information. */
  char hostcommunity[MAXLINE] ;    /* The community of the host machine */
--- 88,96 ----
  char face_host[MAXLINE] ;   /* Pointer to host name from the "From" line. */
  char face_ts[MAXLINE] ;     /* Pointer to time stamp from the "From" line. */
  char face_user[MAXLINE] ;   /* Pointer to user name from the "From" line. */
! char facedirs[MAXLINE] ;    /* Colon separated list of face directories. */
! char *facepath[MAXPATHS+1] ;     /* Array of face image directories. */
! char fgcolor[MAXLINE] ;          /* X11 foreground color. */
  char fname[MAXTYPES][MAXLINE] ;  /* Array of various face name types. */
  char geometry[MAXLINE] ;         /* X11 geometry information. */
  char hostcommunity[MAXLINE] ;    /* The community of the host machine */
***************
*** 93,98 ****
--- 102,108 ----
  char peopfile[MAXLINE] ;    /* Name of the people/username file. */
  char printer[MAXLINE] ;     /* Printer name to monitor. */
  char progname[MAXLINE] ;    /* Name of this program. */
+ char realcomm[MAXLINE] ;    /* Real community for this user. */
  char realname[MAXLINE] ;    /* Real username for this user. */
  char spoolfile[MAXLINE] ;   /* Full pathname of users current mail. */
  char update_alias[MAXLINE] ;   /* Name of mail alias for database updates. */
***************
*** 137,142 ****
--- 147,153 ----
  int period = 60 ;   /* Period in seconds for new mail check. */
  int posspec = 0 ;   /* Set if -Wp or -g option is present (for X11) */
  int row ;           /* Row number for next icon. */
+ int toclear = 0 ;   /* Set if faces memory area needs clearing. */
  int update = 0 ;    /* If set, send mail to update faces database. */
  int width ;         /* Width in pixels of faces display. */
  int wx = 0 ;        /* Initial X position of the window. */
***************
*** 220,230 ****
   */
  
    {
!     struct hostent *hp ;
      char hostname[MAXLINE] ;
  
      GETHOSTNAME(hostname, MAXLINE) ;
!     hp = gethostbyname (hostname) ;
      if (hp != NULL) STRCPY(hostname, hp->h_name) ;
      h_to_c(hostname, hostcommunity) ;
    }
--- 231,243 ----
   */
  
    {
!     struct hostent *hp = NULL ;
      char hostname[MAXLINE] ;
  
      GETHOSTNAME(hostname, MAXLINE) ;
! #ifndef SYSV32
!     hp = gethostbyname(hostname) ;
! #endif /*SYSV32*/
      if (hp != NULL) STRCPY(hostname, hp->h_name) ;
      h_to_c(hostname, hostcommunity) ;
    }
***************
*** 233,241 ****
    {
      struct machinfo *temp ;
  
!     yp_get_default_domain (&hostdomain) ;
      STRCPY(domaincommunity, hostdomain) ;
  
  /*  We can't call h_to_c() to setup the default because it expects
   *  it to be set already; so we grovel through the machine/community
   *  association list directly.
--- 246,257 ----
    {
      struct machinfo *temp ;
  
!     yp_get_default_domain(&hostdomain) ;
      STRCPY(domaincommunity, hostdomain) ;
  
+     IF_DEBUG( FPRINTF(stderr, "main: NIS community is `%s`\n",
+                       domaincommunity) ) ;
+ 
  /*  We can't call h_to_c() to setup the default because it expects
   *  it to be set already; so we grovel through the machine/community
   *  association list directly.
***************
*** 242,253 ****
   */
  
      for (temp = machines; temp != NULL; temp = temp->next)
!       if (strcmp(temp->machine, domaincommunity) == 0)
!         {
!           STRCPY(domaincommunity, temp->community) ;
!           break ;
!         }
  
      IF_DEBUG( FPRINTF(stderr, "main: domain community is `%s`\n",
                        domaincommunity) ; )
    }
--- 258,273 ----
   */
  
      for (temp = machines; temp != NULL; temp = temp->next)
!      if (!strcmp(temp->machine, domaincommunity))
!        {
!          char *str ;
  
+          STRCPY(domaincommunity, temp->community) ;
+          for (str = community;  *str;  str++)
+            if (isascii(*str) && isupper(*str)) *str = tolower(*str) ;
+          break ;
+        }
+ 
      IF_DEBUG( FPRINTF(stderr, "main: domain community is `%s`\n",
                        domaincommunity) ; )
    }
***************
*** 260,273 ****
  }
  
  
! a_to_u(community, user, realname)    /* Turn possible alias into username. */
! char *community, *user, *realname ;
  {
    struct comminfo *ctemp ;
    struct peopinfo *ptemp ;
  
!   STRCPY(realname, user) ;      /* In case alias not found. */
!   ctemp = communities ;         /* Point to chain of communities. */
    while (ctemp != NULL)
      if (!strcmp(ctemp->community, community))
        {
--- 280,296 ----
  }
  
  
! /* Turn possible alias into username. */
! 
! a_to_u(community, user, realcomm, realname)
! char *community, *user, *realcomm, *realname ;
  {
    struct comminfo *ctemp ;
    struct peopinfo *ptemp ;
  
!   STRCPY(realname, user) ;         /* In case alias not found. */
!   STRCPY(realcomm, community) ;    /* In case alias not found. */
!   ctemp = communities ;            /* Point to chain of communities. */
    while (ctemp != NULL)
      if (!strcmp(ctemp->community, community))
        {
***************
*** 276,281 ****
--- 299,305 ----
            if (!strcmp(ptemp->alias, user))
              {
                STRCPY(realname, ptemp->username) ;
+               STRCPY(realcomm, ptemp->community) ;
                return ;
              }
            else ptemp = ptemp->next ;
***************
*** 287,295 ****
  
  initialise()
  {
!   STRCPY(facedir, "") ;       /* No alternate face directory by default. */
    STRCPY(display, "") ;       /* X11 display type. */
    STRCPY(geometry, "") ;      /* X11 geometry information. */
  
  #ifdef FBMONTYPE
    mtype = FBMONTYPE ;         /* Type of monitoring to do. */
--- 311,325 ----
  
  initialise()
  {
!   int i ;
! 
!   facepath[0] = FACEDIR ;    /* Default path is single built-in directory. */
!   for (i = 1;  i <= MAXPATHS;  i++) facepath[i] = (char *) NULL ;
! 
    STRCPY(display, "") ;       /* X11 display type. */
    STRCPY(geometry, "") ;      /* X11 geometry information. */
+   STRCPY(fgcolor, "") ;       /* X11 foreground information. */
+   STRCPY(bgcolor, "") ;       /* X11 background information. */
  
  #ifdef FBMONTYPE
    mtype = FBMONTYPE ;         /* Type of monitoring to do. */
***************
*** 301,315 ****
    STRCPY(bgicon, "") ;                  /* Default is to use root gray. */
  #endif /*BACKGROUND*/
  
- #ifdef FACEDIR
-   STRCPY(defdir, FACEDIR) ;            /* Different directory for face icons. */
- #else
-   STRCPY(defdir,"/usr/local/faces") ;  /* Directory for face icons. */
- #endif /*FACEDIR*/
- 
-   SPRINTF(machfile, "%s/%s", defdir, MACHINETAB) ;
-   SPRINTF(peopfile, "%s/%s", defdir, PEOPLETAB) ;
- 
  #ifdef INVERT
    invert = 1 ;               /* Display in reverse video. */
  #endif /*INVERT*/
--- 331,336 ----
***************
*** 329,335 ****
--- 350,360 ----
    else
      {
        username = getname() ;     /* Get users name from passwd entry. */
+ #ifdef SPOOLDIR
+       SPRINTF(spoolfile, "%s/%s", SPOOLDIR, username) ;
+ #else
        SPRINTF(spoolfile, "/usr/spool/mail/%s", username) ;
+ #endif /*SPOOLDIR*/
      }
  #endif /*SPOOLFILE*/
  
***************
*** 380,385 ****
--- 405,442 ----
          return ;
        }
  
+ #ifdef DNSLOOKUP
+   {
+     char *str ;
+     struct hostent *found = gethostbyname(community) ;
+  
+     if (found)
+       {
+          IF_DEBUG( FPRINTF(stderr, "DNSLOOKUP found %s as %s\n",
+                            community, found->h_name) ) ;
+          STRCPY(community, found->h_name) ;
+ 
+          for (str = community;  *str;  str++)
+            if (isascii(*str) && isupper(*str)) *str = tolower(*str) ;
+        
+ /* Grovel through the machine/community association list again
+  * to allow domains to be aliases.
+  */
+ 
+          for (temp = machines; temp != NULL; temp = temp->next)
+            if (!strcmp(temp->machine, community))
+              {
+                STRCPY(community, temp->community) ;
+                IF_DEBUG( FPRINTF(stderr,
+                          "h_to_c(): machine `%s` found in community '%s'\n",
+                          temp->machine, community) ; )
+                return ;
+              }
+          return ;
+       }
+   }
+ #endif /*DNSLOOKUP*/
+ 
  #ifdef NISLOOKUP
  
  /*  yp_match() returns zero on success. We will treat any failure as
***************
*** 389,412 ****
    yp_err = yp_match(hostdomain, "hosts.byname",
                      host, strlen(host), &hostinfo, &len) ;
  
-   if (yp_err == 0)
-     {
- 
  /* We aren't interested in the value returned, only whether the key
   * was found...
   */
  
        STRCPY(community, domaincommunity) ;
!       IF_DEBUG( FPRINTF(stderr, "NISlookup: found %s\n", host) ; )
      }
!   IF_DEBUG( else FPRINTF(stderr, "NISlookup: Error %d\n", yp_err) ; )
!   IF_DEBUG( FPRINTF(stderr, "h_to_c(): community = '%s'\n", community) ; )
  #endif /*NISLOOKUP*/
  }
  
  
! make_iconname(facedir, community, user)    /* Construct the icon name. */
! char *facedir, *community, *user ;
  {
  
  /*  Sets up community and user based on the first successful
--- 446,478 ----
    yp_err = yp_match(hostdomain, "hosts.byname",
                      host, strlen(host), &hostinfo, &len) ;
  
  /* We aren't interested in the value returned, only whether the key
   * was found...
   */
  
+   if (yp_err == 0)
+     {
+       char *str ;
+ 
        STRCPY(community, domaincommunity) ;
!       for (str = community;  *str;  str++)
!         if (isascii(*str) && isupper(*str)) *str = tolower(*str) ;
!  
! /* Don't bother checking for domaincommunity in the machines
!  * alias list - that should have been done when the variable
!  * was initialized.
!  */
!  
!       IF_DEBUG( FPRINTF(stderr, "NISlookup: found %s\n", host) ) ;
      }
!   IF_DEBUG( else FPRINTF(stderr, "NISlookup: Error %d\n", yp_err) ) ;
!   IF_DEBUG( FPRINTF(stderr, "h_to_c(): community = '%s'\n", community) ) ;
  #endif /*NISLOOKUP*/
  }
  
  
! make_iconname(facepath, community, user)    /* Construct the icon name. */
! char *facepath[MAXPATHS+1], *community, *user ;
  {
  
  /*  Sets up community and user based on the first successful
***************
*** 417,647 ****
   *  $(FACEDIR)/community/unknown/[face.ps, sun.icon, 48x48x1, face.xbm]
   *  $(FACEDIR)/misc./unknown/[face.ps, sun.icon, 48x48x1, face.xbm]
   *
!  *  Firstly a check is made for the "old" style; first in a possible
!  *  alternate face directory, then in the default directory. This is
!  *  where the username is not a directory but the ikon in 48x48x1
!  *  format.
   *
   *  If none of these are found, the "blank face" is returned.
   */
  
!   char *cptr ;
!   int i ;
  
    old_style = 0 ;     /* Reset before checking this face. */
  
    IF_DEBUG( FPRINTF(stderr, "make_iconname: %s[%s] ", community, user) ; )
    
!   if (strlen(facedir))
!     for (cptr = community; cptr != NULL; cptr = index(cptr, '.'))
!       for (i = -1; i < maxtypes; i++)
!         {
!           if (*cptr == '.') cptr++ ;
!           if (i < 0)
!             {
!               SPRINTF(iconname, "%s/%s/%s", facedir, cptr, user) ;
!               if (stat(iconname, &buf) == -1) goto mi1 ;
!               if ((buf.st_mode & S_IFMT) == S_IFREG)
!                 {
!                   old_style = 1 ;
!                   IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
!                   return 1 ;
!                 }
!             }
!           else
!             {
!               SPRINTF(iconname, "%s/%s/%s/%s", facedir, cptr, user, fname[i]) ;
!               if (stat(iconname, &buf) != -1)
!                 {
!                   IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
!                   return 1 ;
!                 }
!             }
!         }
! 
! mi1:
!   for (cptr = community; cptr != NULL; cptr = index(cptr, '.'))
!     for (i = -1; i < maxtypes; i++)
!       {
!         if (*cptr == '.') cptr++ ;
!         if (i < 0)
            {
!             SPRINTF(iconname, "%s/%s/%s", defdir, cptr, user) ;
!             if (stat(iconname, &buf) == -1) goto mi2 ;
!             if ((buf.st_mode & S_IFMT) == S_IFREG)
!               {    
!                 IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
!                 old_style = 1 ;
!                 return 1 ;
!               }
!           } 
!         else
!           {
!             SPRINTF(iconname, "%s/%s/%s/%s", defdir, cptr, user, fname[i]) ;
              if (stat(iconname, &buf) != -1)
-               {
-                 IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-                 return 1 ;
-               }
-           }
-       }
-  
- mi2:
-   if (strlen(facedir))
-     for (i = -1; i < maxtypes; i++)
-       if (i < 0)
-         {
-           SPRINTF(iconname, "%s/misc./%s", facedir, user) ;
-           if (stat(iconname, &buf) == -1) goto mi3 ;
-           if ((buf.st_mode & S_IFMT) == S_IFREG)
-             {
-               IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-               old_style = 1 ;
-               return 1 ;
-             }
-         }    
-       else
-         { 
-           SPRINTF(iconname, "%s/misc./%s/%s", facedir, user, fname[i]) ;
-           if (stat(iconname, &buf) != -1)
-             {
-               if (!x_face) STRCPY(community, "misc.") ;
-               IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-               return 1 ;
-             }
-         }
- 
- mi3:
-   for (i = -1; i < maxtypes; i++)
-     if (i < 0)
-       {
-         SPRINTF(iconname, "%s/misc./%s", defdir, user) ;
-         if (stat(iconname, &buf) == -1) goto mi4 ;
-         if ((buf.st_mode & S_IFMT) == S_IFREG)
-           {
-             IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-             old_style = 1 ;
-             return 1 ;
-           }
-       }    
-     else
-       {
-         SPRINTF(iconname, "%s/misc./%s/%s", defdir, user, fname[i]) ;
-         if (stat(iconname, &buf) != -1)
-           {
-             IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-             if (!x_face) STRCPY(community, "misc.") ;
-             return 1 ;
-           }
-       }
-  
- mi4:
-   if (strlen(facedir))
-     for (cptr = community; cptr != NULL; cptr = index(cptr, '.'))
-       for (i = -1; i < maxtypes; i++)
-         {
-           if (*cptr == '.') cptr++ ;
-           if (i < 0)
-             {
-               SPRINTF(iconname, "%s/%s/unknown", facedir, cptr) ;
-               if (stat(iconname, &buf) == -1) goto mi5 ;
                if ((buf.st_mode & S_IFMT) == S_IFREG)
-                 {    
-                   IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-                   old_style = 1 ;
-                   return 1 ;
-                 }
-             } 
-           else
-             {
-               SPRINTF(iconname, "%s/%s/unknown/%s", facedir, cptr, fname[i]) ;
-               if (stat(iconname, &buf) != -1)
                  {
                    IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-                   if (mtype == MONALL && !x_face) STRCPY(user, "unknown") ;
                    return 1 ;
                  }
!             }
!         }
! 
! mi5:
!   for (cptr = community; cptr != NULL; cptr = index(cptr, '.'))
!     for (i = -1; i < maxtypes; i++)
!       {
!         if (*cptr == '.') cptr++ ;
!         if (i < 0)
!           {
!             SPRINTF(iconname, "%s/%s/unknown", defdir, cptr) ;
!             if (stat(iconname, &buf) == -1) goto mi6 ;
!             if ((buf.st_mode & S_IFMT) == S_IFREG)
!               {    
!                 IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
!                 old_style = 1 ;
!                 return 1 ;
!               }
!           } 
!         else
!           {
!             SPRINTF(iconname, "%s/%s/unknown/%s", defdir, cptr, fname[i]) ;
!             if (stat(iconname, &buf) != -1)
                {
!                 IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
!                 if (mtype == MONALL && !x_face) STRCPY(user, "unknown") ;
!                 return 1 ;
                }
            }
-       }
- 
- mi6:
-   if (strlen(facedir))
-     for (i = -1; i < maxtypes; i++)
-       if (i < 0)
-         {
-           SPRINTF(iconname, "%s/misc./unknown", facedir) ;
-           if (stat(iconname, &buf) == -1) goto mi7 ;
-           if ((buf.st_mode & S_IFMT) == S_IFREG)
-             {
-               IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-               old_style = 1 ;
-               return 1 ;
-             }
-         }    
-       else
-         {
-           SPRINTF(iconname, "%s/misc./unknown/%s", facedir, fname[i]) ;
-           if (stat(iconname, &buf) != -1)
-             {
-               IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-               if (!x_face) STRCPY(community, "misc.") ;
-               if (mtype == MONALL && !x_face) STRCPY(user, "unknown") ;
-               return 1 ;
-             }
-         }
- 
- mi7:
-   for (i = -1; i < maxtypes; i++)
-     if (i < 0)
-       {
-         SPRINTF(iconname, "%s/misc./unknown", defdir) ;
-         if (stat(iconname, &buf) == -1) return 0 ;
-         if ((buf.st_mode & S_IFMT) == S_IFREG)
-           {
-             IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-             old_style = 1 ;
-             return 1 ;
-           }  
-       }    
-     else
-       {
-         SPRINTF(iconname, "%s/misc./unknown/%s", defdir, fname[i]) ;
-         if (stat(iconname, &buf) != -1)
-           {
-             IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
-             if (!x_face) STRCPY(community, "misc.") ;
-             if (mtype == MONALL && !x_face) STRCPY(user, "unknown") ;
-             return 1 ;
-           }
-       }
  
  /* Face icon not found, so the "blank face" should be used. */
  
--- 483,538 ----
   *  $(FACEDIR)/community/unknown/[face.ps, sun.icon, 48x48x1, face.xbm]
   *  $(FACEDIR)/misc./unknown/[face.ps, sun.icon, 48x48x1, face.xbm]
   *
!  *  Firstly a check is made for the "old" style. This is where the username
!  *  is not a directory but the ikon in 48x48x1 format. $(FACEDIR) is
!  *  replaced by all the face directories given.
   *
   *  If none of these are found, the "blank face" is returned.
   */
  
!   char *cptr, *icomm[3], *iuser[3] ;
!   int i, ic, id, iu ;
  
+   icomm[0] = community ;
+   icomm[1] = "misc." ;
+   icomm[2] = "" ;
+ 
+   iuser[0] = user ;
+   iuser[1] = "unknown" ;
+   iuser[2] = "" ;
+ 
    old_style = 0 ;     /* Reset before checking this face. */
  
    IF_DEBUG( FPRINTF(stderr, "make_iconname: %s[%s] ", community, user) ; )
    
!   for (id = 0; strlen(facepath[id]) != 0; id++)
!     for (iu = 0; strlen(iuser[iu]) != 0; iu++)
!       for (ic = 0; strlen(icomm[ic]) != 0; ic++)
!         for (cptr = icomm[ic]; cptr != NULL; cptr = index(cptr, '.'))
            {
!             SPRINTF(iconname, "%s/%s/%s", facepath[id], cptr, iuser[iu]) ;
              if (stat(iconname, &buf) != -1)
                if ((buf.st_mode & S_IFMT) == S_IFREG)
                  {
+                   old_style = 1 ;
                    IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
                    return 1 ;
                  }
!             for (i = 0; i < maxtypes; i++)
                {
!                 if (*cptr == '.') cptr++ ;
!                 SPRINTF(iconname, "%s/%s/%s/%s", 
!                         facepath[id], cptr, iuser[iu], fname[i]) ;
!                 if (stat(iconname, &buf) != -1)
!                   {
!                     IF_DEBUG( FPRINTF(stderr, "found as %s\n", iconname) ; )
! #ifdef NAMEUNKNOWN
!                     if (EQUAL(iser[iu], "unknown")) STRCPY(user, "unknown") ;
! #endif /*NAMEUNKNOWN*/
!                     return 1 ;
!                   }
                }
            }
  
  /* Face icon not found, so the "blank face" should be used. */
  

------- mon.c -------
*** /tmp/da09670	Tue Aug 14 07:20:16 1990
--- mon.c	Tue Aug 14 06:58:10 1990
***************
*** 15,25 ****
   */
  
  #include <stdio.h>
! #ifdef SYSV
  #include <string.h>
  #else
  #include <strings.h>
! #endif /*SYSV*/
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/time.h>
--- 15,25 ----
   */
  
  #include <stdio.h>
! #ifdef SYSV32 || hpux
  #include <string.h>
  #else
  #include <strings.h>
! #endif /* SYSV32 || hpux */
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/time.h>
***************
*** 130,135 ****
--- 130,155 ----
  }
  
  
+ do_key(val)            /* Handle various keyboard options. */
+ int val ;
+ {
+   switch (val)
+     {
+       case KEY_CLEAR   : if (mtype == MONNEW)
+                            {
+                              repl_image(DISP_NAME,  CUROFF, width, height) ;
+                              repl_image(DISP_OTHER, CUROFF, width, height) ;
+                              toclear = 1 ;
+                              do_check() ;
+                            }
+                          break ;
+       case KEY_REFRESH : draw_screen(wdtype) ;
+                          break ;
+       case KEY_QUIT    : exit(0) ;
+     }
+ }
+ 
+ 
  do_mail(mtype)              /* Monitor a mail file for new or all mail. */
  enum mon_type mtype ;
  {        
***************
*** 184,192 ****
            if (froms_found) process_info() ;  /* Process previous mail. */
            process_from() ;                   /* Save new from details. */
          }
!       else if (EQUAL(line, "From:"))  process_from() ;
!       else if (EQUAL(line, "X-Face")) process_face() ;
!       else if (doing_xface)           process_face() ;
      }
    FCLOSE(fp) ;
  
--- 204,212 ----
            if (froms_found) process_info() ;  /* Process previous mail. */
            process_from() ;                   /* Save new from details. */
          }
!       else if (EQUAL(line, "From:"))   process_from() ;
!       else if (EQUAL(line, "X-Face:")) process_face() ;
!       else if (doing_xface)            process_face() ;
      }
    FCLOSE(fp) ;
  
***************
*** 216,221 ****
--- 236,243 ----
        return ;
      }
    column = row = 0 ;          /* Start in top left corner of pixrect. */
+ 
+ #ifndef PLP
    FGETS(nextline, MAXLINE, fp) ;
    if (EQUAL(nextline, "no entries"))
      {
***************
*** 230,245 ****
        text(DISP_ALL, LEFT, printer) ;      /* Output printer name. */
      }
    else
      {
        FGETS(nextline, MAXLINE, fp) ;    /* Skip the next line. */
        while (fgets(nextline, MAXLINE, fp) != NULL)
          {
            SSCANF(&nextline[7], "%s", owner) ;
            SSCANF(&nextline[60], "%d", &size) ;
            h_to_c("", community) ;
!           found = make_iconname(facedir, community, owner) ;
            add_record("", owner, "", size) ;
          }
        make_pixrect(noicons) ;
        this = recs ;
        while (this != NULL)
--- 252,302 ----
        text(DISP_ALL, LEFT, printer) ;      /* Output printer name. */
      }
    else
+ #endif /*PLP*/
      {
        FGETS(nextline, MAXLINE, fp) ;    /* Skip the next line. */
        while (fgets(nextline, MAXLINE, fp) != NULL)
          {
+ #ifdef PLP
+           if ((nextline[0] == '\n')             ||
+               (EQUAL(nextline, "  work done"))  ||
+               (EQUAL(nextline, "  processing")) ||
+               (EQUAL(nextline, "Printer "))     ||
+               (EQUAL(nextline, "Remote printer "))) continue ;
+ 
+           if ((EQUAL(nextline, "  Printer Error: may need attention!")) ||
+               (EQUAL(nextline, "Remote connect to "))) /* for the time being */
+             {
+               make_pixrect(1) ;                 /* Just the "no paper" icon. */
+               add_face(DISP_ALL, NOPAPER, "") ; /* Set to "no paper" icon. */
+               text(DISP_ALL, LEFT, printer) ;   /* Output printer name. */
+               PCLOSE(fp) ;
+               show_display() ;
+               return ;
+ 	    }
+ #endif /*PLP*/
            SSCANF(&nextline[7], "%s", owner) ;
+ #ifdef PLP
+           if (EQUAL(owner, "Owner")) continue ;
+           SSCANF(&nextline[59], "%d", &size) ;
+ #else
            SSCANF(&nextline[60], "%d", &size) ;
+ #endif /*PLP*/
            h_to_c("", community) ;
!           found = make_iconname(facepath, community, owner) ;
            add_record("", owner, "", size) ;
          }
+ #ifdef PLP
+       if (recs == NULL)
+         {
+           make_pixrect(1) ;                    /* Just the "no print" icon. */
+           add_face(DISP_ALL, NOPRINT, "") ;    /* Set to "no print" icon. */
+           text(DISP_ALL, LEFT, printer) ;      /* Output printer name. */
+           PCLOSE(fp) ;
+           show_display() ;
+           return ;
+ 	}
+ #endif /*PLP*/
        make_pixrect(noicons) ;
        this = recs ;
        while (this != NULL)
***************
*** 319,326 ****
              EQUAL(user, "NOPRINT") || EQUAL(user, "NOUSERS")))
          {
            h_to_c(host, community) ;   /* Turn hostname into community name. */
!           a_to_u(community, user, realname) ;
!           found = make_iconname(facedir, community, realname) ;
          }
             if (EQUAL(user, "NOMAIL"))  ftype = NOMAIL ;
        else if (EQUAL(user, "NOPAPER")) ftype = NOPAPER ;
--- 376,383 ----
              EQUAL(user, "NOPRINT") || EQUAL(user, "NOUSERS")))
          {
            h_to_c(host, community) ;   /* Turn hostname into community name. */
!           a_to_u(community, user, realcomm, realname) ;
!           found = make_iconname(facepath, realcomm, realname) ;
          }
             if (EQUAL(user, "NOMAIL"))  ftype = NOMAIL ;
        else if (EQUAL(user, "NOPAPER")) ftype = NOPAPER ;
***************
*** 360,366 ****
        SSCANF(&nextline[0], "%s", username) ;
        SSCANF(&nextline[38], "%s", ts) ;
        h_to_c("", community) ;
!       found = make_iconname(facedir, community, username) ;
        add_record("", username, ts, 0) ;
      }
    if (!noicons)
--- 417,423 ----
        SSCANF(&nextline[0], "%s", username) ;
        SSCANF(&nextline[38], "%s", ts) ;
        h_to_c("", community) ;
!       found = make_iconname(facepath, community, username) ;
        add_record("", username, ts, 0) ;
      }
    if (!noicons)
***************
*** 557,576 ****
    struct recinfo *crec ;    /* Pointer to current mail record for updating. */
  
    h_to_c(face_host, community) ;    /* Turn hostname into community name. */
!   a_to_u(community, face_user, realname) ;
    if (mtype == MONNEW)
      {
        if (x_face)
          {
-           SPRINTF(iconname, "%s/%s/%s/48x48x1",
-                   strlen(facedir) ? facedir : defdir, community, realname) ;
            add_face(DISP_ALL, XFACE, iconname) ;
            if (update) do_face_update(iconname, face_buf) ;
          }
        else
          {
!           if (!(found = make_iconname(facedir, community, realname)))
!             add_face(DISP_ALL, NOFACE, (char *) NULL) ;
            else add_face(DISP_ALL, ORDINARY, iconname) ;
          }
  
--- 614,635 ----
    struct recinfo *crec ;    /* Pointer to current mail record for updating. */
  
    h_to_c(face_host, community) ;    /* Turn hostname into community name. */
!   a_to_u(community, face_user, realcomm, realname) ;
! 
!   found = make_iconname (facepath, community, realname) ;
!   if (x_face && !found)
!     SPRINTF(iconname, "%s/%s/%s/48x48x1", facepath[0], community, realname) ;
! 
    if (mtype == MONNEW)
      {
        if (x_face)
          {
            add_face(DISP_ALL, XFACE, iconname) ;
            if (update) do_face_update(iconname, face_buf) ;
          }
        else
          {
!           if (!found) add_face(DISP_ALL, NOFACE, (char *) NULL) ;
            else add_face(DISP_ALL, ORDINARY, iconname) ;
          }
  
***************
*** 584,600 ****
      }
    else
      {
!       found = make_iconname(facedir, community, realname) ;
!       if (x_face)
!         SPRINTF(iconname, "%s/%s/%s/48x48x1",
!                 strlen(facedir) ? facedir : defdir, community, realname) ;
!       if ((crec = rec_exists(community, realname)) != NULL)
          {
            STRCPY(crec->ts, face_ts) ;
            if (!crec->total) noicons++ ;
            crec->total++ ;
          }
!       else add_record(community, realname, face_ts, 0) ;
      }
    fromc_found = froms_found = x_face = 0 ;  /* Reset for the next message. */
  }
--- 643,655 ----
      }
    else
      {
!       if ((crec = rec_exists(realcomm, realname)) != NULL)
          {
            STRCPY(crec->ts, face_ts) ;
            if (!crec->total) noicons++ ;
            crec->total++ ;
          }
!       else add_record(realcomm, realname, face_ts, 0) ;
      }
    fromc_found = froms_found = x_face = 0 ;  /* Reset for the next message. */
  }

------- rec.c -------
*** /tmp/da09673	Tue Aug 14 07:20:17 1990
--- rec.c	Wed Aug  8 18:02:52 1990
***************
*** 15,25 ****
   */
  
  #include <stdio.h>
! #ifdef SYSV
  #include <string.h>
  #else
  #include <strings.h>
! #endif /*SYSV*/
  #include "faces.h"
  #include "extern.h"
  
--- 15,25 ----
   */
  
  #include <stdio.h>
! #ifdef SYSV32 || hpux
  #include <string.h>
  #else
  #include <strings.h>
! #endif /* SYSV32 || hpux */
  #include "faces.h"
  #include "extern.h"
  
***************
*** 36,44 ****
  }
  
  
! add_alias(crec, username, alias)  /* Add new alias to hostnames' list. */
  struct comminfo *crec ;
! char *username, *alias ;
  {
    struct peopinfo *cptemp, *ptemp ;
  
--- 36,46 ----
  }
  
  
! /* Add new alias to hostnames' list. */
! 
! add_alias(crec, username, realcomm, alias)
  struct comminfo *crec ;
! char *username, *realcomm, *alias ;
  {
    struct peopinfo *cptemp, *ptemp ;
  
***************
*** 47,52 ****
--- 49,56 ----
    STRCPY(ptemp->alias, alias) ;
    ptemp->username = (char *) Malloc(strlen(username)+1) ;
    STRCPY(ptemp->username, username) ;
+   ptemp->community = (char *) Malloc(strlen(realcomm)+1) ;
+   STRCPY(ptemp->community, realcomm) ;
    ptemp->next = NULL ;
  
    if (crec->people == NULL) crec->people = ptemp ;
***************
*** 82,87 ****
--- 86,94 ----
        mlast->next = temp ;     /* Add record to existing chain. */
        mlast = temp ;           /* Point to end of chain. */
      }
+ 
+   IF_DEBUG( FPRINTF(stderr, "add_machine: Added %s ==> %s\n",
+                     temp->machine, temp->community) ) ;
  }
  
  
***************
*** 141,163 ****
  }
  
  
! check_comm(hostname, username, alias)  /* Check community list. */
! char *hostname, *username, *alias ;
  {
    struct comminfo *ctemp ;
   
    ctemp = communities ;      /* Try and find machine record for hostname. */
    while (ctemp != NULL)
!     if (!strcmp(ctemp->community, hostname))
        {  
!         add_alias(ctemp, username, alias) ;
          return ;
        }  
      else ctemp = ctemp->next ;
   
    ctemp = (struct comminfo *) LINT_CAST(Malloc(sizeof(struct comminfo))) ;
!   ctemp->community = (char *) Malloc(strlen(hostname)+1) ;
!   STRCPY(ctemp->community, hostname) ; 
    ctemp->people = NULL ; 
    ctemp->next = NULL ; 
   
--- 148,172 ----
  }
  
  
! /* Check community list. */
! 
! check_comm(hostname, username, aliascomm, alias)
! char *hostname, *username, *aliascomm, *alias ;
  {
    struct comminfo *ctemp ;
   
    ctemp = communities ;      /* Try and find machine record for hostname. */
    while (ctemp != NULL)
!     if (!strcmp(ctemp->community, aliascomm))
        {  
!         add_alias(ctemp, username, hostname, alias) ;
          return ;
        }  
      else ctemp = ctemp->next ;
   
    ctemp = (struct comminfo *) LINT_CAST(Malloc(sizeof(struct comminfo))) ;
!   ctemp->community = (char *) Malloc(strlen(aliascomm)+1) ;
!   STRCPY(ctemp->community, aliascomm) ; 
    ctemp->people = NULL ; 
    ctemp->next = NULL ; 
   
***************
*** 167,173 ****
        clast->next = ctemp ;   /* Add record to existing chain. */
        clast = ctemp ;         /* Point to end of chain. */
      }
!   add_alias(ctemp, username, alias) ;
  }
  
  
--- 176,182 ----
        clast->next = ctemp ;   /* Add record to existing chain. */
        clast = ctemp ;         /* Point to end of chain. */
      }
!   add_alias(ctemp, username, hostname, alias) ;
  }
  
  
***************
*** 175,181 ****
  
  garbage_collect()
  {
!   struct recinfo *last, *this, *next ;
  
    last = NULL ;
    this = recs ;
--- 184,190 ----
  
  garbage_collect()
  {
!   struct recinfo *this, *next ;
  
    last = NULL ;
    this = recs ;
***************
*** 198,242 ****
  }
  
  
  read_aliases()     /* Setup the hostname aliases subchains. */
  {
    char alias[MAXLINE] ;      /* Alias for this community/username. */
    char hostname[MAXLINE] ;   /* This records' hostname. */
    char username[MAXLINE] ;   /* This records real username. */
    char *ptr1, *ptr2 ;
    FILE *fd ;
  
!   if (strlen(facedir)) SPRINTF(peopfile, "%s/PEOPLETAB", facedir) ;
!   if ((fd = fopen(peopfile, "r")) == NULL)   /* Open people file. */
      {
!       if (strlen(facedir))
          {
!           SPRINTF(peopfile, "%s/machine.tab", defdir) ;
!           fd = fopen(peopfile, "r") ;
          }
!       if (fd == NULL)
!         {
!           FPRINTF(stderr,"%s: cannot open %s\n", progname, peopfile) ;
!           return ;
!         }
      }
-   while (fgets(nextline, MAXLINE, fd) != NULL)
-     {
-       if (nextline[0] == '\n' || nextline[0] == '#') continue ;
-       ptr1 = index(nextline, '/') ;
-       if (((int) (ptr1-nextline)) <= 0) continue ;  /* Ignore if no length. */
-       STRNCPY(hostname, nextline, (int) (ptr1-nextline)) ;
-       hostname[(int) (ptr1-nextline)] = '\0' ;
-       ptr2 = index(nextline, '=') ;
-       if (((int) (ptr2-ptr1-1)) <= 0) continue ;    /* Ignore if no length. */
-       STRNCPY(alias, ptr1+1, (int) (ptr2-ptr1-1)) ;
-       alias[(int) (ptr2-ptr1-1)] = '\0' ;
-       if ((strlen(ptr2)-2) <= 0) continue ;         /* Ignore if no length. */
-       STRNCPY(username, ptr2+1, strlen(ptr2)-2) ;
-       username[strlen(ptr2)-2] = '\0' ;
-       check_comm(hostname, username, alias) ;
-     }
-   FCLOSE(fd) ;
  }
  
  
--- 207,273 ----
  }
  
  
+ #define  MAXTOKENLEN  100
+ static char ptoken[MAXTOKENLEN] ;
+ 
+ char *
+ get_token(pntr)
+ char *pntr ;
+ {
+   int i = 0 ;
+ 
+   while (*pntr=='\t' || *pntr == ' ') pntr++ ;
+   while ((i < MAXTOKENLEN) && (!strchr("/= \t#",*pntr)))
+     ptoken[i++] = *(pntr++) ;
+   while (*pntr=='\t' || *pntr == ' ') pntr++ ;
+   ptoken[i] = '\0' ;
+   return(pntr) ;
+ }
+ 
+ 
  read_aliases()     /* Setup the hostname aliases subchains. */
  {
    char alias[MAXLINE] ;      /* Alias for this community/username. */
+   char aliascomm[MAXLINE] ;  /* Alias for this community/username. */
    char hostname[MAXLINE] ;   /* This records' hostname. */
    char username[MAXLINE] ;   /* This records real username. */
    char *ptr1, *ptr2 ;
+   int i ;
    FILE *fd ;
  
!   for (i = 0; facepath[i] != NULL; i++)
      {
!       SPRINTF(peopfile, "%s/%s", facepath[i], PEOPLETAB) ;
!       if ((fd = fopen(peopfile, "r")) == NULL) continue ;
! 
!       while (fgets(nextline, MAXLINE, fd) != NULL)
          {
!           if (nextline[0] == '\n' || nextline[0] == '#') continue ;
!           nextline[strlen(nextline)-1] = '\0' ;
!           ptr1 = get_token(nextline) ;
!           if (!strlen(ptoken) || *ptr1 != '/') continue ;
!           STRCPY(aliascomm, ptoken) ;
!           ptr1 = get_token(++ptr1) ;
!           if (!strlen(ptoken) || *ptr1 != '=') continue ;
!           STRCPY(alias, ptoken) ;
!           ptr1 = get_token(++ptr1) ;
!           if (!strlen(ptoken)) continue ;
!           if (*ptr1 == '/')
!             {
!               STRCPY(hostname, ptoken) ;
!               ptr1 = get_token(++ptr1) ;
!               if (!strlen(ptoken)) continue ;
!               STRCPY(username, ptoken) ;
!             }
!           else
!             {
!               STRCPY(hostname, aliascomm) ;
!               STRCPY(username, ptoken) ;
!             }
!          check_comm(hostname, username, aliascomm, alias) ;
          }
!       FCLOSE(fd) ;
      }
  }
  
  
***************
*** 245,279 ****
    char community[MAXLINE] ;   /* This records' community. */
    char machine[MAXLINE] ;     /* This records' machine name. */
    char *ptr ;
    FILE *fd ;
  
!   if (strlen(facedir)) SPRINTF(machfile, "%s/MACHINETAB", facedir) ;
!   if ((fd = fopen(machfile, "r")) == NULL)   /* Open machine file. */
      {
!       if (strlen(facedir))
          {
!           SPRINTF(machfile, "%s/machine.tab", defdir) ;
!           fd = fopen(machfile, "r") ;
          }
!       if (fd == NULL)
!         {
!           FPRINTF(stderr,"%s: cannot open %s\n", progname, machfile) ;
!           return ;
!         }
      }
-   while (fgets(nextline, MAXLINE, fd) != NULL)
-     {
-       if (nextline[0] == '\n' || nextline[0] == '#') continue ;
-       ptr = index(nextline, '=') ;
-       if (((int) (ptr-nextline)) <= 0) continue ;  /* Ignore if no length. */
-       STRNCPY(machine, nextline, (int) (ptr-nextline)) ;
-       machine[(int) (ptr-nextline)] = '\0' ;
-       if (strlen(ptr)-2 <= 0) continue ;           /* Ignore if no length. */
-       STRNCPY(community, ptr+1, strlen(ptr)-2) ;
-       community[strlen(ptr)-2] = '\0' ;
-       add_machine(machine, community) ;
-     }
-   FCLOSE(fd) ;
  }
  
  
--- 276,303 ----
    char community[MAXLINE] ;   /* This records' community. */
    char machine[MAXLINE] ;     /* This records' machine name. */
    char *ptr ;
+   int i ;
    FILE *fd ;
  
!   for (i = 0; facepath[i] != NULL; i++)
      {
!       SPRINTF(machfile, "%s/%s", facepath[i], MACHINETAB) ;
!       if ((fd = fopen(machfile, "r")) == NULL) continue ;
! 
!       while (fgets(nextline, MAXLINE, fd) != NULL)
          {
!           if (nextline[0] == '\n' || nextline[0] == '#') continue ;
!           nextline[strlen(nextline)-1] = '\0' ;
!           ptr = get_token(nextline) ;
!           if (!strlen(ptoken) || *ptr != '=') continue ;
!           STRCPY(machine, ptoken) ;
!           ptr = get_token(++ptr) ;
!           if (!strlen(ptoken)) continue ;
!           STRCPY(community, ptoken) ;
!           add_machine(machine, community) ;
          }
!       FCLOSE(fd) ;
      }
  }
  
  

------CUT HERE------CUT HERE------CUT HERE------CUT HERE------

Rich Burridge,          DOMAIN: richb@Aus.Sun.COM
Sun Microsystems.       ACSNET: richb@sunaus.sun.oz
PHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb

richb@sunaus.oz (Rich Burridge) (08/14/90)

Official patch #7 for faces v1.4 (part 2 of 2).

/** IMPORTANT NOTE: This patch and the new file (mush.xface.patch)
 ** comes in two messages. You should save these two messages, strip off the
 ** initial header (down to and including the CUT HERE lines), and
 ** anything below (and including) the CUT HERE line at the end of each
 ** file. cat the two files together, and unpack with sh. Use Larry Wall's
 ** patch program to apply, and recompile and reinstall.
 **
 ** I apologise for this; I didn't realise the patch was going to be so
 ** big.
 **/

------CUT HERE------CUT HERE------CUT HERE------CUT HERE------
------- sunview.c -------
*** /tmp/da09676	Tue Aug 14 07:20:18 1990
--- sunview.c	Sat Aug  4 03:28:47 1990
***************
*** 56,62 ****
  } ;
  
  Pixwin *fpw, *pw ;
- int toclear ;                 /* Set if faces icon needs clearing. */
  int ffd ;                     /* File descriptor of faces frame. */
  
  
--- 56,61 ----
***************
*** 65,79 ****
  enum icon_type itype ;
  int row, column ;
  {
!   switch ((int) mtype)
!     {
!       case MONNEW : PR_ROP(pr[(int) dtype], imagewidth, 0,
!                            (maxcols-1)*imagewidth, imageheight, PIX_SRC,
!                            pr[(int) dtype], 0, 0) ;
!       default     : PR_ROP(pr[(int) dtype], column*imagewidth, row*imageheight,
!                            imagewidth, imageheight, PIX_SRC,
!                            images[(int) itype], 0, 0) ;
!     }
  }
  
  
--- 64,75 ----
  enum icon_type itype ;
  int row, column ;
  {
!   if (mtype == MONNEW)
!     PR_ROP(pr[(int) dtype], imagewidth, 0, (maxcols-1)*imagewidth,
!            imageheight, PIX_SRC, pr[(int) dtype], 0, 0) ;
! 
!   PR_ROP(pr[(int) dtype], column*imagewidth, row*imageheight,
!          imagewidth, imageheight, PIX_SRC, images[(int) itype], 0, 0) ;
  }
  
  
***************
*** 111,125 ****
    if (event_is_down(event) && nextc == MS_LEFT)
      {
        wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
!       PW_ROP(pw, 0, 0, width, height, PIX_SRC, pr[(int) wdtype], 0, 0) ;
      }
!   if (mtype == MONNEW && event_is_ascii(event) && nextc == DEL)
!     {
!       repl_image(DISP_NAME,  CUROFF, width, height) ;
!       repl_image(DISP_OTHER, CUROFF, width, height) ;
!       toclear = 1 ;
!       do_check() ;
!     }
    else window_default_event_proc(canvas, event, arg) ;
  }
  
--- 107,115 ----
    if (event_is_down(event) && nextc == MS_LEFT)
      {
        wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
!       draw_screen(wdtype) ;
      }
!   if (event_is_ascii(event)) do_key(nextc) ;
    else window_default_event_proc(canvas, event, arg) ;
  }
  
***************
*** 169,174 ****
--- 159,171 ----
  }
  
  
+ draw_screen(wdtype)
+ enum disp_type wdtype ;
+ {
+   PW_ROP(pw, 0, 0, width, height, PIX_SRC, pr[(int) wdtype], 0, 0) ;
+ }
+ 
+ 
  init_font()
  {
    sfont = pf_open(FONT) ;
***************
*** 206,212 ****
    gtype = SVIEW ;
    pr[(int) DISP_NAME] = pr[(int) DISP_OTHER] = NULL ;
    old_pr[(int) DISP_NAME] = old_pr[(int) DISP_OTHER] = NULL ;
-   toclear = 0 ;
    return 0 ;
  }
  
--- 203,208 ----
***************
*** 288,294 ****
  Pixwin *pw ;
  Rectlist *repaint_area ;
  {
!   PW_ROP(pw, 0, 0, width, height, PIX_SRC, pr[(int) wdtype], 0, 0) ;
  }
  
  
--- 284,290 ----
  Pixwin *pw ;
  Rectlist *repaint_area ;
  {
!   draw_screen(wdtype) ;
  }
  
  
***************
*** 331,337 ****
    temprect->r_height = height + 10 ;
    temprect->r_width = width + 10 ;
    WINDOW_SET(frame, FRAME_OPEN_RECT, temprect, 0) ;
!   PW_ROP(pw, 0, 0, width, height, PIX_SRC, pr[(int) wdtype], 0, 0) ;
  
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr[(int) DISP_NAME])    PR_DESTROY(old_pr[(int) DISP_NAME]) ;
--- 327,333 ----
    temprect->r_height = height + 10 ;
    temprect->r_width = width + 10 ;
    WINDOW_SET(frame, FRAME_OPEN_RECT, temprect, 0) ;
!   draw_screen(wdtype) ;
  
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr[(int) DISP_NAME])    PR_DESTROY(old_pr[(int) DISP_NAME]) ;

------- extern.h -------
*** /tmp/da09679	Tue Aug 14 07:20:18 1990
--- extern.h	Wed Aug  8 17:45:02 1990
***************
*** 33,38 ****
--- 33,39 ----
  extern enum gr_type gtype ;  /* Indicates what graphics system is being used. */
  extern enum mon_type mtype ; /* What type of monitoring we should do. */
  
+ extern char bgcolor[] ;    /* X11 background color. */
  extern char bgicon[] ;     /* Alternate background pattern. */
  extern char community[] ;  /* Community name ("real" host name). */
  extern char defdir[] ;     /* The default face directory. */
***************
*** 41,47 ****
  extern char face_host[] ;  /* Pointer to host name from the "From" line. */
  extern char face_ts[] ;    /* Pointer to time stamp from the "From" line. */
  extern char face_user[] ;  /* Pointer to user name from the "From" line. */
! extern char facedir[] ;    /* Alternate face image directory. */
  extern char fname[MAXTYPES][MAXLINE] ;  /* Array of various face name types. */
  extern char geometry[] ;   /* X11 geometry information. */
  extern char hostname[] ;   /* Machine name to monitor. */
--- 42,50 ----
  extern char face_host[] ;  /* Pointer to host name from the "From" line. */
  extern char face_ts[] ;    /* Pointer to time stamp from the "From" line. */
  extern char face_user[] ;  /* Pointer to user name from the "From" line. */
! extern char facedirs[] ;   /* Colon separated list of face directories. */
! extern char *facepath[] ;  /* Array of face image directories. */
! extern char fgcolor[] ;                 /* X11 foreground color. */
  extern char fname[MAXTYPES][MAXLINE] ;  /* Array of various face name types. */
  extern char geometry[] ;   /* X11 geometry information. */
  extern char hostname[] ;   /* Machine name to monitor. */
***************
*** 52,57 ****
--- 55,61 ----
  extern char peopfile[] ;   /* Name of the people/username file. */
  extern char printer[] ;    /* Printer name to monitor. */
  extern char progname[] ;   /* Name of this program. */
+ extern char realcomm[] ;   /* Real community for this user. */
  extern char realname[] ;   /* Real username for this user. */
  extern char revtable[] ;   /* Table for reversing the bits in a byte. */
  extern char spoolfile[] ;  /* Full pathname of users current mail. */
***************
*** 88,93 ****
--- 92,98 ----
  extern int period ;        /* Period in seconds for checking new mail. */
  extern int posspec ;       /* Set if -Wp or -g option is present (for X11) */
  extern int row ;           /* Row number for next icon. */
+ extern int toclear ;       /* Set if faces memory area needs clearing. */
  extern int update ;        /* If set, send mail to update faces database. */
  extern int width ;         /* Width in pixels of faces display. */
  extern int wx ;            /* Initial X position of the window. */

------- faces.h -------
*** /tmp/da09682	Tue Aug 14 07:20:19 1990
--- faces.h	Sat Aug  4 22:38:31 1990
***************
*** 14,19 ****
--- 14,34 ----
   *  reported to me then an attempt will be made to fix them.
   */
  
+ #ifndef FALSE
+ #define  FALSE  (0 == 1)
+ #define  TRUE   (0 == 0)
+ #endif /*FALSE*/
+ 
+ /* If your compiler can handle inline functions, define INLINE as `inline',
+  * otherwise define it as `'.
+  */
+ 
+ #ifdef __GNU_CC__
+ #define  INLINE  inline
+ #else
+ #define  INLINE
+ #endif /*__GNU_CC__*/
+ 
  #ifdef DEBUG
  #define  IF_DEBUG(stmt)  stmt
  #else
***************
*** 20,25 ****
--- 35,44 ----
  #define  IF_DEBUG(stmt)
  #endif /*DEBUG*/
  
+ #ifndef FACEDIR
+ #define  FACEDIR  "/usr/local/faces"
+ #endif /*FACEDIR*/
+ 
  #define  FCLOSE        (void) fclose      /* To make lint happy. */
  #define  FFLUSH        (void) fflush
  #define  FGETS         (void) fgets
***************
*** 74,81 ****
  #define  PAINTED         101  /* Canvas/Icon needs repainting. */
  #define  LEFTDOWN        102  /* Left mouse button has been pressed. */
  
  #define  BLITHEIGHT      48       /* Maximum number of lines in a blit icon. */
- #define  DEL             '\177'   /* Clear faces display. */
  #define  EQUAL(str,val)  !strncmp(str,val,strlen(val))
  #define  ICONHEIGHT      64   /* Default height of individual face icons. */
  #define  ICONWIDTH       64   /* Default width of individual face icons. */
--- 93,104 ----
  #define  PAINTED         101  /* Canvas/Icon needs repainting. */
  #define  LEFTDOWN        102  /* Left mouse button has been pressed. */
  
+ /* Keyboard actions. */
+ #define  KEY_CLEAR       '\177'   /* Clear faces display. */
+ #define  KEY_REFRESH     '\014'   /* Refresh faces display. */
+ #define  KEY_QUIT        'q'      /* Terminate faces display. */
+ 
  #define  BLITHEIGHT      48       /* Maximum number of lines in a blit icon. */
  #define  EQUAL(str,val)  !strncmp(str,val,strlen(val))
  #define  ICONHEIGHT      64   /* Default height of individual face icons. */
  #define  ICONWIDTH       64   /* Default width of individual face icons. */
***************
*** 94,101 ****
  
  #ifndef  MAXLINE
  #define  MAXLINE         200  /* Maximum length for character strings. */
! #endif   MAXLINE
  
  #define  MAXTYPES        4    /* Maximum number of different face types. */
  #define  NO_PER_ROW      10   /* Default number of faces per row. */
  
--- 117,128 ----
  
  #ifndef  MAXLINE
  #define  MAXLINE         200  /* Maximum length for character strings. */
! #endif /*MAXLINE*/
  
+ #ifndef  MAXPATHS
+ #define	 MAXPATHS        10   /* Maximum number of dirs in FACEPATH list */
+ #endif /*MAXPATHS*/
+ 
  #define  MAXTYPES        4    /* Maximum number of different face types. */
  #define  NO_PER_ROW      10   /* Default number of faces per row. */
  
***************
*** 104,112 ****
  #define  rindex       strrchr
  #endif /*NOINDEX*/
  
! char *getenv(), *malloc(), *sprintf() ;
  void endpwent() ;
  FILE *popen() ;
  
  /*  Various programs that are used by faces.
   *  You might need to change these on some machines.
--- 131,146 ----
  #define  rindex       strrchr
  #endif /*NOINDEX*/
  
! #ifndef SYSV32
! char *getenv(), *malloc() ;
! #ifdef hpux
! int sprintf() ;
! #else
! char *sprintf() ;
! #endif /*hpux*/
  void endpwent() ;
  FILE *popen() ;
+ #endif /*SYSV32*/
  
  /*  Various programs that are used by faces.
   *  You might need to change these on some machines.
***************
*** 144,149 ****
--- 178,184 ----
  struct peopinfo                 /* Username/alias record. */
    {
      char *alias ;               /* Alias for this user. */
+     char *community ;           /* Real community. */
      char *username ;            /* Real username. */
      struct peopinfo *next ;     /* Pointer to next record. */
    } ;

------- patchlevel.h -------
*** /tmp/da09685	Tue Aug 14 07:20:20 1990
--- patchlevel.h	Fri Aug  3 12:04:40 1990
***************
*** 14,17 ****
   *  reported to me then an attempt will be made to fix them.
   */
  
! #define  PATCHLEVEL  6
--- 14,17 ----
   *  reported to me then an attempt will be made to fix them.
   */
  
! #define  PATCHLEVEL  7

------- README -------
*** /tmp/da09688	Tue Aug 14 07:20:21 1990
--- README	Tue Aug 14 07:19:51 1990
***************
*** 101,106 ****
--- 101,107 ----
  These are:
  
  BACKGROUND    - alternate background icon pattern.
+ DNSLOOKUP     - use DNS (Domain Name Service) to try to convert hostnames.
  DONTSHOWNO    - don't show number of message on face image.
  DONTSHOWTIME  - don't show timestamp on face image.
  DONTSHOWUSER  - don't show username on face image.
***************
*** 107,112 ****
--- 108,114 ----
  FACEDIR       - alternate face database directory.
  FMONTYPE      - default monitoring type.
  INVERT        - inverse video.
+ NAMEUNKNOWN   - clump all unknown users together per community.
  NEWSINCDIR    - NeWS only: location of the NeWS #include files.
  NEWSLIBDIR    - NeWS only: location of the NeWS libraries.
  NISLOOKUP     - uncomment to use Sun NIS (formerly YP) to look for hosts.
***************
*** 113,120 ****
--- 115,124 ----
  NODOMAINS     - uncomment if you don't want full host domain names.
  NOINDEX       - uncomment if you don't have the index() function.
  PERIOD        - alternate period in seconds before recheck.
+ PLP           - uncomment if you are running PLP and monitoring printers.
  REVORDER      - byte reversal for little-endian machines.
  SELTYPE       - uncomment for old select(2) calls.
+ SPOOLDIR      - alternate directory for spoolfiles.
  SPOOLFILE     - alternate default spoolfile to monitor.
  SYSV          - uncomment if you are running Unix System V.
  TTEXT         - SunView only: uncomment on SunOS v3.x systems.
***************
*** 208,216 ****
  
      X-Face: `cat $HOME/.face`
  
! In v7.1.2 (version 7.1 - patchlevel #2), the Mush mail program will look for
! the existence of a .face file (in the above format) in the users home
! directory, and generate a similar header.
  
  For users of other mailers, it is suggested that the X-Face: line[s] be
  added to your .signature file. Note that in this case, the initial line
--- 212,221 ----
  
      X-Face: `cat $HOME/.face`
  
! Included with this faces distribution, is an unofficial patch to mush v7.1.2
! to allow for X-Face support. The Mush mail program will look for the
! existence of a .face file (in the above format) in the users home directory,
! and generate a similar header.
  
  For users of other mailers, it is suggested that the X-Face: line[s] be
  added to your .signature file. Note that in this case, the initial line
***************
*** 261,268 ****
  
  Hal Stern for the face_update shell script.
  
! Dan Heller and Bart Schaefer for adding support for .face files in
! their latest patch to v7.1 of the mush mailer.
  
  Guy Harris for the basis of the previous manual page.
  
--- 266,273 ----
  
  Hal Stern for the face_update shell script.
  
! Dan Heller and Bart Schaefer for suggesting what should be in the unofficial
! patch to mush v7.1.2 to support X-Face lines.
  
  Guy Harris for the basis of the previous manual page.
  
***************
*** 294,301 ****
  Also thanks to Jeremy Cook, John Machin, Neil Crellin, Mark Andrews, Sjoerd
  Mullender, Cameron Humphries, Rick Gunderson, Rich McAllister, Hakon Lie,
  John Fong, Chris Maltby, Darryl K. Ramm, Steve Piette, Tony Landells, Pat
! Lashley, Dave Glowacki, Chris Steinbroner and Steven M. Miller for various
! bug reports, fixes and suggestions for improvement.
  
  
  ----------------------------------------------------------------------------
--- 299,307 ----
  Also thanks to Jeremy Cook, John Machin, Neil Crellin, Mark Andrews, Sjoerd
  Mullender, Cameron Humphries, Rick Gunderson, Rich McAllister, Hakon Lie,
  John Fong, Chris Maltby, Darryl K. Ramm, Steve Piette, Tony Landells, Pat
! Lashley, Dave Glowacki, Chris Steinbroner, Steven M. Miller, Bob Posert,
! Hugues Leroy, Graham Dumpleton, Michael Schmidt, Robert Adams and Rod
! Whitby for various bug reports, fixes and suggestions for improvement.
  
  
  ----------------------------------------------------------------------------

------- faces.1 -------
*** /tmp/da09691	Tue Aug 14 07:20:22 1990
--- faces.1	Sat Aug  4 20:35:14 1990
***************
*** 201,210 ****
  face images. The format of these input records is described in a previous
  section.
  .TP
! .BI \-f " facedir"
! If specified, then this directory is searched first for face images. If
! they are not found, then the default face directory will be searched.
! The default face directory is
  .BR /usr/local/faces .
  .TP
  .BI \-g " geometry"
--- 201,213 ----
  face images. The format of these input records is described in a previous
  section.
  .TP
! .BI \-f " facepath"
! If specified, this is a colon-separated list of paths to be searched for
! face images.  A null entry in the path will be replaced by the compiled
! in default face directory.  If not specified, the directories specified
! by the FACEPATH environment variable will be used.  If there is no FACEPATH
! environment variable, the default face directory will be searched.
! The default face directory is normally
  .BR /usr/local/faces .
  .TP
  .BI \-g " geometry"
***************
*** 292,311 ****
  Blit icon.
  .PP
  To access the face for the mail name
! .I machine!uid
! take the result of the first successful open from the following list of files:
  .RS 6
! /usr/local/faces/machine/uid/iconname
  .br
! /usr/local/faces/misc./uid/iconname
  .br
! /usr/local/faces/machine/unknown/iconname
  .br
! /usr/local/faces/misc./unknown/iconname
  .RE
  If the
  .B -f
! argument is specified the given directory is searched before
  .IR /usr/local/faces .
  The iconname above, consists of the following choices, in the given order:
  .TS
--- 295,323 ----
  Blit icon.
  .PP
  To access the face for the mail name
! .I machine.dom.ain!uid
! take the result of the first successful open from the following list of files
! (where $DIR represents iteration over the list of directories in FACEPATH):
  .RS 6
! $DIR/machine.dom.ain/uid/iconname
  .br
! $DIR/dom.ain/uid/iconname
  .br
! $DIR/ain/uid/iconname
  .br
! $DIR/misc./uid/iconname
! .br
! $DIR/machine.dom.ain/unknown/iconname
! .br
! $DIR/dom.ain/unknown/iconname
! .br
! $DIR/ain/unknown/iconname
! .br
! $DIR/misc./unknown/iconname
  .RE
  If the
  .B -f
! argument is specified the given directory is searched instead of
  .IR /usr/local/faces .
  The iconname above, consists of the following choices, in the given order:
  .TS
***************
*** 344,351 ****
  .I stard
  in community
  .I sunaus.
! The people table associates a community/alias pair, with a real username.
  .RS 6
  sunaus/rburridge=richb
  .RE
  causes the alias
--- 356,372 ----
  .I stard
  in community
  .I sunaus.
! The machine table may be used to alias entire communities; the line
  .RS 6
+ wseng.sun.com=eng.sun.com
+ .RE
+ will cause the
+ .I wseng.sun.com
+ domain to be mapped to the
+ .I eng.sun.com
+ community. The people table associates a community/alias pair, with a
+ real username.
+ .RS 6
  sunaus/rburridge=richb
  .RE
  causes the alias
***************
*** 431,436 ****
--- 452,475 ----
  .TP
  .B /usr/local/faces/machine.tab
  machine/community equivalences
+ .SH ENVIRONMENT VARIABLES
+ .TP 15
+ .B DISPLAY
+ The X11 server to be used by the XView or X11 faces program to display
+ the face icons on.
+ .TP
+ .B FACEPATH
+ A colon separated list of directory paths to search for machine/user
+ face icons.
+ .TP
+ .B HOME
+ The home directory of the current user.  Used to locate the .mailrc file.
+ .TP
+ .B MAIL
+ The complete pathname of the mail spool file to monitor.
+ .TP
+ .B WINDOW_PARENT
+ Used to verify that the program is executing under a valid SunView environment.
  .SH HISTORY
  .I faces
  is based on the Bell Labs Edition 8 program

------- Makefile -------
*** /tmp/da09694	Tue Aug 14 07:20:23 1990
--- Makefile	Tue Aug 14 06:59:01 1990
***************
*** 29,34 ****
--- 29,50 ----
  #
  #BACKGROUND       = -DBACKGROUND=\"\"
  #------------------------------------------------------------------------
+ #  Uncomment the following two lines to use the Domain Name Service to 
+ #  attempt to convert unqualified hostnames, or hostnames with partial
+ #  domains to fully qualified domain names.
+ #
+ #  When used with NISLOOKUP, DNSLOOKUP will take precedance.
+ #
+ #  NOTE that the domain name returned by DNS will be converted to lower
+ #  case before attempting a machines.tab match, or constructing an icon
+ #  file name.
+ #
+ #  NOTE that for this to work you must have at least a minimal
+ #  /etc/resolv.conf file containing a valid nameserver entry.
+ #
+ #DNSLOOKUP	= -DDNSLOOKUP
+ #DNSLIB		= -lresolv
+ #------------------------------------------------------------------------
  #  If you do not want to show the number of messages on the face icon,
  #  then uncomment the next line.
  # 
***************
*** 46,52 ****
  #------------------------------------------------------------------------
  #  By default, faces looks for the face images in /usr/local/faces. If
  #  you wish to specify an alternate location, then these two lines should
! #  be uncommented and set appropriately.
  #               
  FACEDIR           = /usr/local/faces
  CFACEDIR	= -DFACEDIR=\"$(FACEDIR)\"
--- 62,69 ----
  #------------------------------------------------------------------------
  #  By default, faces looks for the face images in /usr/local/faces. If
  #  you wish to specify an alternate location, then these two lines should
! #  be uncommented and set appropriately. Note that the value must be
! #  a single directory name, not a colon separated list of paths.
  #               
  FACEDIR           = /usr/local/faces
  CFACEDIR	= -DFACEDIR=\"$(FACEDIR)\"
***************
*** 66,71 ****
--- 83,96 ----
  #
  #INVERT           = -DINVERT
  #------------------------------------------------------------------------
+ #  When no icon is found for a given user, the unknown icon may be displayed
+ #  either with the user name, or labeled as `unknown'.  The former case
+ #  provides the most information, the latter allows all unknown users
+ #  within a given community to be lumped into a single image.  To select
+ #  the latter case uncomment the following line.
+ #
+ #NAMEUNKNOWN	= -DNAMEUNKNOWN
+ #------------------------------------------------------------------------
  #  If you are compiling the NeWS version, then the following two lines
  #  should be uncommented, and set appropriately.
  #
***************
*** 72,81 ****
  #NEWSINCDIR	= -I$(OPENWINHOME)/include
  #NEWSLIBDIR	= -L$(OPENWINHOME)/lib
  #------------------------------------------------------------------------
! #  Uncomment the following two lines to use the Sun Network Information
  #  Services (NIS, formerly YP) to look for hosts which do not explicitly
! #  appear in the machines.tab file.
  #
  #NISLOOKUP	= -DNISLOOKUP
  #------------------------------------------------------------------------
  #  If you don't want faces to use full domain names for extracting face
--- 97,110 ----
  #NEWSINCDIR	= -I$(OPENWINHOME)/include
  #NEWSLIBDIR	= -L$(OPENWINHOME)/lib
  #------------------------------------------------------------------------
! #  Uncomment the following line to use the Sun Network Information
  #  Services (NIS, formerly YP) to look for hosts which do not explicitly
! #  appear in the machines.tab file. When used with DNSLOOKUP, DNSLOOKUP
! #  takes precedance.
  #
+ #  Note that the domain name will be converted to lower case before
+ #  attempting to match in the machines file, or create an icon filename.
+ #
  #NISLOOKUP	= -DNISLOOKUP
  #------------------------------------------------------------------------
  #  If you don't want faces to use full domain names for extracting face
***************
*** 97,102 ****
--- 126,137 ----
  #
  #PERIOD           = -DPERIOD=30
  #------------------------------------------------------------------------
+ #  By default, faces will examine printer queues a la Berkeley Style.
+ #  Alternatively, if you have the PLP printer spooling system running, then
+ #  uncomment the next line.
+ #
+ #PLP              = -DPLP
+ #-------------------------------------------------------------------------
  #  Faces is designed to work on a big-endian machine by default. If you
  #  are compiling for a little-endian machine (such as the Sun 386i), then
  #  you need to uncomment the following line.
***************
*** 109,114 ****
--- 144,154 ----
  #
  #SELTYPE        = -DNO_43SELECT
  #------------------------------------------------------------------------
+ #  If the pending mail for users is in a different directory than
+ #  /usr/spool/mail, uncomment the following and set appropriately.
+ #
+ #SPOOLDIR	= -DSPOOLDIR=\"/usr/mail\"
+ #------------------------------------------------------------------------
  #  If faces is setup to monitor mail, then the name of the default
  #  spoolfile is /usr/spool/mail/username. An alternative spoolfile name
  #  can be given by uncommenting the following line and setting
***************
*** 119,125 ****
  #  If you are running on a Unix System V machine, then you should uncomment
  #  the next definition.
  #
! #SYSV		= -DSYSV
  #--------------------------------------------------------------------------
  #  If you are running SunOS v3.x, then pr_ttext doesn't exist, and
  #  you must uncomment this definition.
--- 159,165 ----
  #  If you are running on a Unix System V machine, then you should uncomment
  #  the next definition.
  #
! #SYSV		= -DSYSV32
  #--------------------------------------------------------------------------
  #  If you are running SunOS v3.x, then pr_ttext doesn't exist, and
  #  you must uncomment this definition.
***************
*** 173,183 ****
  #
  #  Compilation flags and standard macro definitions.
  #
! CDEFS		= $(BACKGROUND) $(DONTSHOWNO) $(DONTSHOWTIME) \
  		  $(DONTSHOWUSER) $(CFACEDIR) $(FMONTYPE) $(INVERT) \
! 		  $(NEWSINCDIR) $(NISLOOKUP) $(NODOMAINS) $(NOINDEX) \
! 		  $(PERIOD) $(REVORDER) $(SELTYPE) $(SPOOLFILE) $(SYSV) \
! 		  $(TTEXT) $(UPDATE) $(X11INCDIR) $(XVIEWINCDIR) $(DEBUG)
  CCOMP		= -g
  CFLAGS		= $(CCOMP) $(CDEFS)
  #
--- 213,224 ----
  #
  #  Compilation flags and standard macro definitions.
  #
! CDEFS		= $(BACKGROUND) $(DNSLOOKUP) $(DONTSHOWNO) $(DONTSHOWTIME) \
  		  $(DONTSHOWUSER) $(CFACEDIR) $(FMONTYPE) $(INVERT) \
! 		  $(NAMEUNKNOWN) $(NEWSINCDIR) $(NISLOOKUP) $(NODOMAINS) \
! 		  $(NOINDEX) $(PERIOD) $(PLP) $(REVORDER) $(SELTYPE) \
! 		  $(SPOOLDIR) $(SPOOLFILE) $(SYSV) $(TTEXT) $(UPDATE) \
! 		  $(X11INCDIR) $(XVIEWINCDIR) $(DEBUG)
  CCOMP		= -g
  CFLAGS		= $(CCOMP) $(CDEFS)
  #
***************
*** 190,196 ****
  
  STDSRCS		= get.c main.c mon.c parsefrom.c rec.c
  STDOBJS		= get.o main.o mon.o parsefrom.o rec.o
! STDLIBS		= compface/libcompface.a
  
  COMPFACE	= compface
  FACES		= facedir
--- 231,237 ----
  
  STDSRCS		= get.c main.c mon.c parsefrom.c rec.c
  STDOBJS		= get.o main.o mon.o parsefrom.o rec.o
! STDLIBS		= compface/libcompface.a $(DNSLIB)
  
  COMPFACE	= compface
  FACES		= facedir
***************
*** 206,217 ****
  SFILES2		= get.c parsefrom.c news.c sunview.c
  SFILES3		= xview.c x11.c $(HDRS)
  SFILES4		= CHANGES README TODO MANIFEST FILES Makefile
! SFILES5		= faces.1 face_update.1 faces_cps.cps face_update $(IMAGES)
  SFILES6		= $(FACES) $(FILTERS)
  SFILES7		= $(COMPFACE)
  
  NEWSLIBS	= $(NEWSLIBDIR) -lcps
  SVIEWLIBS	= -lsuntool -lsunwindow -lpixrect
  X11LIBS		= $(X11LIBDIR) -lX11
  XVIEWLIBS	= $(XVIEWLIBDIR) -lxview -lolgx -lX11
  
--- 247,266 ----
  SFILES2		= get.c parsefrom.c news.c sunview.c
  SFILES3		= xview.c x11.c $(HDRS)
  SFILES4		= CHANGES README TODO MANIFEST FILES Makefile
! SFILES5		= faces.1 face_update.1 faces_cps.cps face_update \
! 		  mush.xface.patch $(IMAGES)
  SFILES6		= $(FACES) $(FILTERS)
  SFILES7		= $(COMPFACE)
  
  NEWSLIBS	= $(NEWSLIBDIR) -lcps
  SVIEWLIBS	= -lsuntool -lsunwindow -lpixrect
+ #
+ #  The following definition can vary. Here are a few examples:
+ #
+ #  Sun/MIT X11R4:                  $(X11LIBDIR) -lX11
+ #  Dell Unix (Interactive 386/ix): $(X11LIBDIR) -lX11 -linet
+ #  AT&T's XWIN:                    $(X11LIBDIR) -lX11_s -lc_s -lnsl_s -lpt
+ #
  X11LIBS		= $(X11LIBDIR) -lX11
  XVIEWLIBS	= $(XVIEWLIBDIR) -lxview -lolgx -lX11
  

------- MANIFEST -------
*** /tmp/da09697	Tue Aug 14 07:20:23 1990
--- MANIFEST	Mon Aug  6 11:52:08 1990
***************
*** 11,16 ****
--- 11,17 ----
  Makefile                               |    4
  faces.1                                |    5
  face_update.1                          |    5
+ mush.xface.patch                       |    5
  face_update                            |    4
  main.c                                 |    1
  get.c                                  |    2

------- x11.c -------
*** /tmp/da09700	Tue Aug 14 07:20:24 1990
--- x11.c	Sat Aug  4 16:58:48 1990
***************
*** 62,68 ****
  
  unsigned long gc_mask ;
  int screen ;
- int toclear ;                /* Set if faces icon needs clearing. */
  int xfd ;                    /* File descriptor for X11 server connection. */
  unsigned int depth ;
  long backgnd, foregnd ;
--- 62,67 ----
***************
*** 76,81 ****
--- 75,81 ----
    if (mtype == MONNEW)
      XCopyArea(dpy, pr[(int) dtype], pr[(int) dtype], gc, 0, 0,
                (maxcols-1)*imagewidth, imageheight, imagewidth, 0) ;
+ 
    XCopyArea(dpy, images[(int) itype], pr[(int) dtype], gc, 0, 0,
              imagewidth, imageheight, column*imagewidth, row*imageheight) ;
  }
***************
*** 89,95 ****
--- 89,99 ----
    while (beeps > 0)
      {
        XBell(dpy, 56) ;
+ #ifndef SYSV32
        SELECT(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &btime) ;
+ #else
+       sleep(1) ;
+ #endif /*SYSV32*/
        beeps-- ;
      }
    while (flashes > 0)
***************
*** 148,153 ****
--- 152,167 ----
  }
  
  
+ draw_screen(wdtype)
+ enum disp_type wdtype ;
+ {
+   XCopyArea(dpy, pr[(int) wdtype], frame[F_WINDOW], gc, 0, 0,
+             (unsigned int) width, (unsigned int) height, 0, 0) ;
+   XCopyArea(dpy, pr[(int) DISP_ICON], frame[F_ICON], gc, 0, 0,
+             (unsigned int) width, (unsigned int) height, 0, 0) ;
+ }
+ 
+ 
  init_font()
  {
    if ((sfont = XLoadQueryFont(dpy, FONT)) == NULL)
***************
*** 167,172 ****
--- 181,188 ----
    char *def_geom ;
    int i, j ;
    unsigned short buf[256] ;
+   Colormap cmap ;
+   XColor selcolor ;
  
    if ((dpy = XOpenDisplay(display)) == NULL)
      {
***************
*** 189,196 ****
        (def_geom = XGetDefault(dpy, progname, "Geometry")) != NULL)
      STRCPY(geometry, def_geom) ;
  
!   foregnd = BlackPixel(dpy, screen) ;
!   backgnd = WhitePixel(dpy, screen) ;
    depth = DefaultDepth(dpy, screen) ;
  
    init_font() ;
--- 205,227 ----
        (def_geom = XGetDefault(dpy, progname, "Geometry")) != NULL)
      STRCPY(geometry, def_geom) ;
  
!   cmap = DefaultColormap(dpy, screen) ;
!   if (strlen(fgcolor) == 0 || XDefaultDepth(dpy, screen) <= 2)
!     foregnd = BlackPixel(dpy, screen) ;
!   else
!     {
!       XParseColor(dpy, cmap, fgcolor, &selcolor) ;
!       XAllocColor(dpy, cmap, &selcolor) ;
!       foregnd = selcolor.pixel ;
!     }
!   if (strlen(bgcolor) == 0 || XDefaultDepth(dpy, screen) <= 2)
!     backgnd = WhitePixel(dpy, screen) ;
!   else
!     {
!       XParseColor(dpy, cmap, bgcolor, &selcolor) ;
!       XAllocColor(dpy, cmap, &selcolor) ;
!       backgnd = selcolor.pixel ;
!     }
    depth = DefaultDepth(dpy, screen) ;
  
    init_font() ;
***************
*** 224,230 ****
    gtype = X11 ;
    pr[(int) DISP_NAME] = pr[(int) DISP_OTHER] = NULL ;
    old_pr[(int) DISP_NAME] = old_pr[(int) DISP_OTHER] = NULL ;
-   toclear = 0 ;
    return(0) ;
  }
  
--- 255,260 ----
***************
*** 408,420 ****
        first_time = 0 ;
      }
  
-   XCopyArea(dpy, pr[(int) DISP_ICON], frame[F_ICON], gc, 0, 0,
-             (unsigned int) width, (unsigned int) height, 0, 0) ;
- 
    XResizeWindow(dpy, frame[F_WINDOW],
                  (unsigned int) width, (unsigned int) height) ;
!   XCopyArea(dpy, pr[(int) wdtype], frame[F_WINDOW], gc, 0, 0,
!             (unsigned int) width, (unsigned int) height, 0, 0) ;
   
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr[(int) DISP_NAME])  XFreePixmap(dpy, old_pr[(int) DISP_NAME]) ;
--- 438,446 ----
        first_time = 0 ;
      }
  
    XResizeWindow(dpy, frame[F_WINDOW],
                  (unsigned int) width, (unsigned int) height) ;
!   draw_screen(wdtype) ;
   
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr[(int) DISP_NAME])  XFreePixmap(dpy, old_pr[(int) DISP_NAME]) ;
***************
*** 439,444 ****
--- 465,471 ----
    for (;;)
      {
        readmask = fullmask ;
+ #ifndef SYSV32
  #ifdef NO_43SELECT
        SELECT(32, &readmask, 0, 0, &tval) ;
        if (readmask && (1 << xfd))
***************
*** 446,451 ****
--- 473,491 ----
        SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &tval) ;
        if (FD_ISSET(xfd, &readmask))
  #endif /*NO_43SELECT*/
+ #else
+         {
+           int contr = 0 ;       /* System 5.3.2.2 doesn't have a select */
+ 
+           sleep(1) ;
+           while ((XPending(dpy) == 0) && (contr < period))
+             {
+               sleep(5) ;
+               contr += 5 ;
+             }
+         }
+       if (XPending(dpy))
+ #endif /*SYSV32*/
          do
            {
              XNextEvent(dpy, &event) ;
***************
*** 465,476 ****
              else if (event.type == Expose && event.xexpose.count == 0)
                {
                  while (XCheckTypedEvent(dpy, Expose, &event)) /* do nothing. */ ;
!                 XCopyArea(dpy, pr[(int) wdtype],
!                           frame[F_WINDOW], gc, 0, 0,
!                           (unsigned int) width, (unsigned int) height, 0, 0) ;
!                 XCopyArea(dpy, pr[(int) DISP_ICON],
!                           frame[F_ICON], gc, 0, 0,
!                           (unsigned int) width, (unsigned int) height, 0, 0) ;
                }
  
  /* ButtonPress. */
--- 505,511 ----
              else if (event.type == Expose && event.xexpose.count == 0)
                {
                  while (XCheckTypedEvent(dpy, Expose, &event)) /* do nothing. */ ;
!                 draw_screen(wdtype) ;
                }
  
  /* ButtonPress. */
***************
*** 479,503 ****
                       event.xbutton.button == Button1)
                {
                  wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
!                 XCopyArea(dpy, pr[(int) wdtype],
!                           frame[F_WINDOW], gc, 0, 0,
!                           (unsigned int) width, (unsigned int) height, 0, 0) ;
                }
  
  /* KeyPress. */
  
!             else if (mtype == MONNEW && event.type == KeyPress)
                {
                  key_event = (XKeyPressedEvent *) &event ;
                  (void) XLookupString(key_event, chs, 1, (KeySym *) NULL,
                                       (XComposeStatus *) NULL) ;
!                 if (chs[0] == DEL)
!                   {
!                     repl_image(DISP_NAME,  CUROFF, width, height) ;
!                     repl_image(DISP_OTHER, CUROFF, width, height) ;
!                     toclear = 1 ;
!                     do_check() ;
!                   }
                }
            }
          while (XPending(dpy)) ;
--- 514,530 ----
                       event.xbutton.button == Button1)
                {
                  wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
!                 draw_screen(wdtype) ;
                }
  
  /* KeyPress. */
  
!             else if (event.type == KeyPress)
                {
                  key_event = (XKeyPressedEvent *) &event ;
                  (void) XLookupString(key_event, chs, 1, (KeySym *) NULL,
                                       (XComposeStatus *) NULL) ;
!                 do_key(chs[0]) ;
                }
            }
          while (XPending(dpy)) ;

------- TODO -------
*** /tmp/da09703	Tue Aug 14 07:20:25 1990
--- TODO	Tue Aug 14 06:47:04 1990
***************
*** 3,18 ****
     seem to work at all, and of course its the wrong way round
     for the uk anyway.
  
! 2/ Alias file people.tab should be capable of understanding:
!    sunaus/richb=sun/rburridge
!    or some such format.
! 
! 3/ From Ian Donaldson <rcodi@melomys.co.rmit.oz>
     Is it possible to have the faces cleared automatically once the
     mail has been read?  I'm clearing by clicking on the window at
     the moment.
  
! 4/ From Pat Lashley <patl@Sun.COM>
     Have you given any thought to how to support multiple windowing systems at
     execution time?  I am currently using the sun386i version of architecture
     independant /vol trees to make locally installed programs available
--- 3,14 ----
     seem to work at all, and of course its the wrong way round
     for the uk anyway.
  
! 2/ From Ian Donaldson <rcodi@melomys.co.rmit.oz>
     Is it possible to have the faces cleared automatically once the
     mail has been read?  I'm clearing by clicking on the window at
     the moment.
  
! 3/ From Pat Lashley <patl@Sun.COM>
     Have you given any thought to how to support multiple windowing systems at
     execution time?  I am currently using the sun386i version of architecture
     independant /vol trees to make locally installed programs available
***************
*** 23,58 ****
     windowing system is in use, and envoke the appropriate binary. The difficulty
     is in how to determine which system is in use.
  
! 5/ From: Chris Orgill, cho%cs.aber.ac.uk@uunet.uu.net
     How about allowing the Sunview version to use arbitrary size Sun icons ?
  
! 6/ From Lindsay F. Marshall <Lindsay.Marshall%newcastle.ac.uk@munnari.oz>
     There is a byte-order assumption somewhere that screws up
     any X bitmaps read in from a file - why dont you use the
     procedure provided by the system rather than writing your
     own?? That copes with the problems correctly.
  
! 7/ The NeWS version needs to be finished.
     Remaining problems are:
  
      (a) There are two warnings on compiling news.c, due to FILE operations
          being performed on PSFILE variables.
  
!     (b) The new input functionality (click left mouse and Del) has to be
!         added in.
  
! 8/ With the XView version, add a Properties pinup window which would
     allow you to change the various monitoring options on the fly.
  
! 9/ Add in audio capabilities.
  
! 10/ From Pat Lashley <patl@Sun.COM>
!     There is no reason that FaceSaver images couldn't be parsed by faces and
!     sent to NeWS with the appropriate transformation matrix to squeeze it down
!     to icon size.  Let the NeWS PostScript interpreter do the bit
!     compression/dithering.
  
! 11/ If an X-Face is found inside a piece of mail that has been forwarded
      inside another mail item, and the -U option is set, then it is possible
      to update the wrong face in the faces database. The only clean solution
      to this, is if faces only recognises X-Face lines in the mail header.
--- 19,54 ----
     windowing system is in use, and envoke the appropriate binary. The difficulty
     is in how to determine which system is in use.
  
! 4/ From: Chris Orgill, cho%cs.aber.ac.uk@uunet.uu.net
     How about allowing the Sunview version to use arbitrary size Sun icons ?
  
! 5/ From Lindsay F. Marshall <Lindsay.Marshall%newcastle.ac.uk@munnari.oz>
     There is a byte-order assumption somewhere that screws up
     any X bitmaps read in from a file - why dont you use the
     procedure provided by the system rather than writing your
     own?? That copes with the problems correctly.
  
! 6/ The NeWS version needs to be finished.
     Remaining problems are:
  
      (a) There are two warnings on compiling news.c, due to FILE operations
          being performed on PSFILE variables.
  
!     (b) The new input functionality (click left mouse, Del, ^L and q) has
!         to be added in.
  
! 7/ With the XView version, add a Properties pinup window which would
     allow you to change the various monitoring options on the fly.
  
! 8/ Add in audio capabilities.
  
! 9/ From Pat Lashley <patl@Sun.COM>
!    There is no reason that FaceSaver images couldn't be parsed by faces and
!    sent to NeWS with the appropriate transformation matrix to squeeze it down
!    to icon size.  Let the NeWS PostScript interpreter do the bit
!    compression/dithering.
  
! 10/ If an X-Face is found inside a piece of mail that has been forwarded
      inside another mail item, and the -U option is set, then it is possible
      to update the wrong face in the faces database. The only clean solution
      to this, is if faces only recognises X-Face lines in the mail header.
***************
*** 62,68 ****
      resolved by a flag which would restrict X-Face: recognition to the header
      or the first non-blank line of the body.
  
! 12/ From Pat Lashley <patl@Sun.COM>
      An entry of the form `+domainname=community' in the machines.tab file to
      indicate that if a hostname is found without domain specifier, and it
      doesn't match any other machines.tab entry, and YP (oops, NIS) access to
--- 58,64 ----
      resolved by a flag which would restrict X-Face: recognition to the header
      or the first non-blank line of the body.
  
! 11/ From Pat Lashley <patl@Sun.COM>
      An entry of the form `+domainname=community' in the machines.tab file to
      indicate that if a hostname is found without domain specifier, and it
      doesn't match any other machines.tab entry, and YP (oops, NIS) access to
***************
*** 71,109 ****
      indicates that the current NIS domain should be used.  This should
      probably be enabled by a compile-time option for those who don't run NIS.
  
! 13/ From Pat Lashley <patl@Sun.COM>
      An option to display unknown users individually with the username,
      instead of clustered under a single `unknown' user.  Really hot would be
      some way to specify this on a per-community basis...
  
! 14/ From Pat Lashley <patl@Sun.COM>
      Multiple face directory hierarchies. I.e:
      `-f $HOME/facedir -f /import/group/facedir -f /import/global/facedir ...'
      The order of specification would indicate the search order.
  
! 15/ From Pat Lashley <patl@Sun.COM>
      Accept SIGHUP as an indication that various internal databases should be
      updated from the files (i.e. machines.tab), and that the display should be
      immediatly updated to reflect current state instead of waiting for the
      polling period to end.
  
! 16/ From Pat Lashley <patl@Sun.COM>
      Accept SIGALRM as an indication that the current polling period should be
      immediatly terminated, and the display updated.
  
! 17/ From Pat Lashley <patl@Sun.COM>
      More internal comments and a general design document.
  
! 18/ Provide a template of what each of the independent graphics routine do,
      to aid porting to new graphics environments.
  
! 19/ Add an option to disable flashing and beeping when new mail arrives.
  
! 20/ From Pat Lashley <patl@Sun.COM>
      Change window header to show what is being monitored (mail, lp1, users,
      etc.)
  
! 21/ From Pat Lashley <patl@Sun.COM>
      A mixed-mode version which would use xview for the basic windowing and
      property sheets; but use NeWS for the rendering. It is, of course,
      dependant upon having the X/NeWS server, but there may be some way to
--- 67,105 ----
      indicates that the current NIS domain should be used.  This should
      probably be enabled by a compile-time option for those who don't run NIS.
  
! 12/ From Pat Lashley <patl@Sun.COM>
      An option to display unknown users individually with the username,
      instead of clustered under a single `unknown' user.  Really hot would be
      some way to specify this on a per-community basis...
  
! 13/ From Pat Lashley <patl@Sun.COM>
      Multiple face directory hierarchies. I.e:
      `-f $HOME/facedir -f /import/group/facedir -f /import/global/facedir ...'
      The order of specification would indicate the search order.
  
! 14/ From Pat Lashley <patl@Sun.COM>
      Accept SIGHUP as an indication that various internal databases should be
      updated from the files (i.e. machines.tab), and that the display should be
      immediatly updated to reflect current state instead of waiting for the
      polling period to end.
  
! 15/ From Pat Lashley <patl@Sun.COM>
      Accept SIGALRM as an indication that the current polling period should be
      immediatly terminated, and the display updated.
  
! 16/ From Pat Lashley <patl@Sun.COM>
      More internal comments and a general design document.
  
! 17/ Provide a template of what each of the independent graphics routine do,
      to aid porting to new graphics environments.
  
! 18/ Add an option to disable flashing and beeping when new mail arrives.
  
! 19/ From Pat Lashley <patl@Sun.COM>
      Change window header to show what is being monitored (mail, lp1, users,
      etc.)
  
! 20/ From Pat Lashley <patl@Sun.COM>
      A mixed-mode version which would use xview for the basic windowing and
      property sheets; but use NeWS for the rendering. It is, of course,
      dependant upon having the X/NeWS server, but there may be some way to
***************
*** 110,127 ****
      determine at run-time whether the NeWS operations are available, or
      whether to stick to XView/X11 mechanisms.
  
! 22/ From Steven M. Miller <miller@SCTC.COM>
      I would like to use -iconic to specify iconic mode for X. This would
      require change -i to -I for inverse in get.c and having -i to set iconic=1.
  
! 23/ From Steven M. Miller <miller@SCTC.COM>
      Under X, when faces is started up in iconic mode nothing is displayed in
      the icon until the icon is clicked on and opened and then closed again.
  
! 24/ From Kee Hinckley <nazgul@alphalpha.com>
      Any possibility of changing that header to an RFC1154 (I think that's
      the number) conformant form?  Namely an encoding field in the
      header (presumbably with a new name for the faces format, or using
      one of the existing ones (G3Fax uuencode would probably be good)).
  
! 25/ Optimise.
--- 106,146 ----
      determine at run-time whether the NeWS operations are available, or
      whether to stick to XView/X11 mechanisms.
  
! 21/ From Steven M. Miller <miller@SCTC.COM>
      I would like to use -iconic to specify iconic mode for X. This would
      require change -i to -I for inverse in get.c and having -i to set iconic=1.
  
! 22/ From Steven M. Miller <miller@SCTC.COM>
      Under X, when faces is started up in iconic mode nothing is displayed in
      the icon until the icon is clicked on and opened and then closed again.
  
! 23/ From Kee Hinckley <nazgul@alphalpha.com>
      Any possibility of changing that header to an RFC1154 (I think that's
      the number) conformant form?  Namely an encoding field in the
      header (presumbably with a new name for the faces format, or using
      one of the existing ones (G3Fax uuencode would probably be good)).
  
! 24/ From Michael Schmidt <michael@uni-paderborn.de>
!     Perhaps my configuration (SparcStation, SunOS4.0.3, X11R4, twm with
!     ForceIcons, IconManager and IconRegion) is wierd, but... The icon is
!     not placed in the IconRegion, but just at 0x0 (or 1x1, or so). Then I
!     cannot deiconify the icon by a mouse click (all other icons deiconify
!     on a left button click).
! 
! 25/ Get the SunView, XView and NeWS drivers to use the -bg and -fg color
!     options.
! 
! 26/ From Ken Wood <kwood@adl.austek.oz.au>
!     Sometimes the display gets stuck while changing from "No mail" to a
!     single face or vice-versa. xfaces just displays a plain grey window.
! 
! 27/ From Ken Wood <kwood@adl.austek.oz.au>
!     Quite often, users who don't have a face file are shown as "unknown"
!     with the unknown face, rather than putting the username with the unknown
!     face.
! 
! 28/ From Ken Wood <kwood@adl.austek.oz.au>
!     Do you have any plans to get xfaces to read geometry etc from the
!     database ?
! 
! 29/ Optimise.

------- xview.c -------
*** /tmp/da09706	Tue Aug 14 07:20:26 1990
--- xview.c	Sat Aug  4 03:31:06 1990
***************
*** 58,64 ****
  XFontStruct *sfont ;
  XGCValues gc_val ;            /* Used to setup graphics context values. */
  int screen ;                  /* Default graphics display screen. */
- int toclear ;                 /* Set if faces icon needs clearing. */
  unsigned int depth ;
  unsigned long backgnd ;       /* Default background color. */
  unsigned long foregnd ;       /* Default foreground color. */
--- 58,63 ----
***************
*** 102,117 ****
    if (event_is_down(event) && nextc == MS_LEFT)
      {
        wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
!       XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
!                 width, height, 0, 0) ;
      }
!   else if (mtype == MONNEW && event_is_ascii(event) && nextc == DEL)
!     {
!       repl_image(DISP_NAME,  CUROFF, width, height) ;
!       repl_image(DISP_OTHER, CUROFF, width, height) ;
!       toclear = 1 ;
!       do_check() ;
!     }
  }
  
  
--- 101,109 ----
    if (event_is_down(event) && nextc == MS_LEFT)
      {
        wdtype = (wdtype == DISP_NAME) ? DISP_OTHER : DISP_NAME ;
!       draw_screen(wdtype) ;
      }
!   else if (event_is_ascii(event)) do_key(nextc) ;
  }
  
  
***************
*** 160,165 ****
--- 152,165 ----
  }
  
  
+ draw_screen(wdtype)
+ enum disp_type wdtype ;
+ {
+   XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
+             width, height, 0, 0) ;
+ }
+ 
+ 
  static Notify_value
  frame_interpose(frame, event, arg, type)
  Frame frame ;
***************
*** 244,250 ****
    gtype = XVIEW ;
    pr[(int) DISP_NAME] = pr[(int) DISP_OTHER] = NULL ;
    old_pr[(int) DISP_NAME] = old_pr[(int) DISP_OTHER] = NULL ;
-   toclear = 0 ;
    return 0 ;
  }
  
--- 244,249 ----
***************
*** 334,341 ****
  Xv_Window window ;
  Rectlist *repaint_area ;
  {
!   XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
!             (unsigned int) width, (unsigned int) height, 0, 0) ;
  }
  
  
--- 333,339 ----
  Xv_Window window ;
  Rectlist *repaint_area ;
  {
!   draw_screen(wdtype) ;
  }
  
  
***************
*** 374,382 ****
    temprect->r_height = height ;
    temprect->r_width = width ;
    XV_SET(frame, FRAME_OPEN_RECT, temprect, 0) ;
! 
!   XCopyArea(dpy, pr[(int) wdtype], xid[F_WINDOW], gc, 0, 0,
!             (unsigned int) width, (unsigned int) height, 0, 0) ;
  
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr[(int) DISP_NAME])  XFreePixmap(dpy, old_pr[(int) DISP_NAME]) ;
--- 372,378 ----
    temprect->r_height = height ;
    temprect->r_width = width ;
    XV_SET(frame, FRAME_OPEN_RECT, temprect, 0) ;
!   draw_screen(wdtype) ;
  
    if (newmail) beep_flash(beeps, flashes) ;
    if (old_pr[(int) DISP_NAME])  XFreePixmap(dpy, old_pr[(int) DISP_NAME]) ;

------- CHANGES -------
*** /tmp/da09709	Tue Aug 14 07:20:26 1990
--- CHANGES	Tue Aug 14 06:57:13 1990
***************
*** 181,183 ****
--- 181,290 ----
         * From Chris Steinbroner <hesh@lll-crg.llnl.gov>
           ikon2icon in the filters directory uses index(), so you have to do
           the NOINDEX define stuff there too.
+ 
+ v1.4 - patchlevel 7 - 6th August 1990.
+ 
+        * From Chris Steinbroner <hesh@lll-crg.llnl.gov>
+          From Bob Posert <psitech.psitech!bob@uunet.UU.NET>
+          Incoming mail is not always stored in /usr/spool/mail/username.
+          HP-UX and Dell Unix (Interactive 386/ix) store it in
+          /usr/mail/username. Another definition (SPOOLDIR), has been added
+          to the Makefile. The README file has also been updated.
+ 
+        * From Hugues Leroy <Hugues.Leroy@irisa.fr>
+          From Graham Dumpleton <grahamd@otc.otca.oz.au>
+          From Peter Chubb <peterc@softway.oz.au>
+          From Robert Adams <adams@trim.intel.com>
+          The parsefrom() function was not replacing a '\n' at the end of
+          a line with '\0' before preceding.
+ 
+        * From Michael Schmidt <michael@uni-paderborn.de>
+          The faces window now accepts two more keyboard characters:
+             q - to terminate the faces program.
+            ^L - to refresh the faces window.
+ 
+        * From Michael Schmidt <michael@uni-paderborn.de>
+          Added support for printer monitoring with the PLP printer
+          spooling system. Another definition (PLP) has been added to
+          the Makefile. The README file has been updated.
+ 
+        * From Chris Steinbroner <hesh@lll-crg.llnl.gov>
+          Diffs included to allow faces to run under HP-UX.
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          Changed the SYSV definition to SYSV32 because I work with both
+ 	 System V.3.2.2 and System V.4.0 from AT&T and they need different
+          defines.
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          Added -bg and -fg to the parameter string and modified x11.c
+ 	 to set the background and foreground colors. Currently this is
+          only available with the X11 graphics driver.
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          people.tab now accepts the syntax "aliascomm/alias=comm/name"
+          to map a whole name (this is one of the TODO points).
+          It still accepts the old syntax. As a side effect, the
+          people.tab and machine.tab routines were re-written to be
+          better parsers and are now forgiving of white space.
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          make_iconname was rewritten to get rid of the cut and paste
+          code and now is a gaggle of 'for' loops.
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          From Michael Schmidt <michael@uni-paderborn.de>
+          The domain name parsing code in make_iconname was not working.
+          The problem was that the 'old_style' code 'goto'ed out of the
+          middle of the domain breakdown loop thus defeating same.
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          The code for building the name for people.tab and machine.tab was
+          broken if an alternate directory ("-f") was specified (changes
+          in rec.c in read_alias and read_machines).
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          If 'host' does not appear in an RFC822 address, the code would
+          assume "LOCAL".  The code has been fixed to assume 'hostname'
+          instead (fix to parsefrom.c).
+ 
+        * From Robert Adams <adams@trim.intel.com>
+          There was a strange bug that would cause icons on the end of the
+          list (after entries were deleted) to get mangled.  This usually
+          showed up as the NOMAIL icon not being shown but garbage being
+          shown instead.  The problem was that in 'garbage_collect', there
+          was a local variable 'last' that was hidding the global variable
+          of the same name and thus the global was not getting updated
+ 
+        * From Pat Lashley <patl@Sun.COM>
+          Added code to use the Domain Name Service to attempt to convert
+          unqualified hostnames, or hostnames with partial domains to fully
+          qualified domain names. Another definition (DNSLOOKUP) has been
+          added to the Makefile. The README file has been updated.
+ 
+        * From Pat Lashley <patl@Sun.COM>
+          When no icon is found for a given user, the unknown icon may be
+          displayed either with the user name, or labeled as `unknown'.
+          The former case provides the most information, the latter allows
+          all unknown users within a given community to be lumped into a
+          single image. Another definition (NAMEUNKNOWN) has been added to
+          the Makefile. The README file has been updated.
+ 
+        * From Pat Lashley <patl@Sun.COM>
+          Support is now included for multiple face directories. Faces
+          will search for the environment variable FACEPATH, and use this
+          as a list of colon separated face directories. See the manual
+          page for more details.
+ 
+        * Official support for X-Face lines was not included with patch #2
+          to mush v7.1. Dan and Bart suggested that instead, a new file
+          (mush.xface.patch) should be included with the faces distribution
+          which in an unofficial patch to mush v7.1.2, to allow that X-Face
+          support. The README, MANIFEST and FILES files have been updated.
+ 
+        * From Rod Whitby <rwhitby@austek.oz.au>
+          faces v.1.4.6 dumps core when the following message (cut down to the
+          smallest case) is in my mail box. This was a case of a valid X-Face:
+          being followed by a line starting with the word "X-Face ". Faces now
+          searches for "X-Face:" rather than "X-Face". This really needs to be
+          tightened up some more.

------- FILES -------
*** /tmp/da09712	Tue Aug 14 07:20:27 1990
--- FILES	Mon Aug  6 11:54:02 1990
***************
*** 12,17 ****
--- 12,18 ----
  faces.1         - the faces manual page (tbl + troff/nroff -man format).
  face_update     - shell script to automatically update the faces database.
  face_update.1   - the face_update manual page (troff/nroff -man format)
+ mush.xface.patch - unofficial patch to mush v7.1.2 to support X-Face lines.
  
  main.c          - STANDARD SOURCE FILES: includes declarations and main().
  get.c           - routines to get information, objects, icons etc..

------- parsefrom.c -------
*** /tmp/da09715	Tue Aug 14 07:20:28 1990
--- parsefrom.c	Sat Aug  4 19:18:57 1990
***************
*** 15,26 ****
   */
  
  #include <stdio.h>
! #ifdef SYSV
  #include <string.h>
  #else
  #include <strings.h>
! #endif /*SYSV*/
  #include "faces.h"
  
  
  int
--- 15,27 ----
   */
  
  #include <stdio.h>
! #ifdef SYSV32 || hpux
  #include <string.h>
  #else
  #include <strings.h>
! #endif /* SYSV32 || hpux */
  #include "faces.h"
+ #include "extern.h"
  
  
  int
***************
*** 94,104 ****
  		user = p;
  	}
  	if (host == NULL)
! 		host = "LOCAL";
  #ifdef	NODOMAINS
  	else if ((p = index(host, '.')) != NULL)
  		*p = '\0';
  #endif	/* NODOMAINS */
  	*hostp = host;
  	*userp = user;
  	return 1;
--- 95,107 ----
  		user = p;
  	}
  	if (host == NULL)
! 		host = hostname;
  #ifdef	NODOMAINS
  	else if ((p = index(host, '.')) != NULL)
  		*p = '\0';
  #endif	/* NODOMAINS */
+ 	if ((p = index(host, '\n')) != NULL)
+ 		*p = '\0';
  	*hostp = host;
  	*userp = user;
  	return 1;
Funky_Stuff
len=`wc -c < patch.7`
if [ $len !=   101860 ] ; then
echo error: patch.7 was $len bytes long, should have been   101860
fi
fi # end of overwriting check
------CUT HERE------CUT HERE------CUT HERE------CUT HERE------

Rich Burridge,          DOMAIN: richb@Aus.Sun.COM
Sun Microsystems.       ACSNET: richb@sunaus.sun.oz
PHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb