[comp.windows.x] Another way to fix multiple wall messages

dce@stan.UUCP (David Elliott) (04/04/89)

Well, I sent this to comp.sys.sun, but never saw it posted, so I'll
post it here.

This patch is for the SunOS 4.0 /bin/wall.  It changes wall so that it
only sends a message to each unique user/remote hostname pair.  It is
fairly loose about remote hostnames.  An empty field is replaced by the
local hostname,  a field of the form ".*:.*" has the : and trailing
text removed, and a field beginning with "unix:" is replaced by the
local hostname.

*** wall.c.orig	Thu Mar 23 19:38:53 1989
--- wall.c	Thu Mar 16 11:23:25 1989
***************
*** 29,38 ****
  #include <fcntl.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  
  #define IGNOREUSER	"sleeper"
  
! char	hostname[32];
  char	mesg[3000];
  int		msize,sline;
  struct	utmp *utmp;
--- 29,39 ----
  #include <fcntl.h>
  #include <sys/types.h>
  #include <sys/stat.h>
+ #include <sys/param.h>
  
  #define IGNOREUSER	"sleeper"
  
! char	hostname[MAXHOSTNAMELEN + 1];
  char	mesg[3000];
  int		msize,sline;
  struct	utmp *utmp;
***************
*** 116,123 ****
  		/*
  		 * if (-a option OR remote OR NOT tty[pqr]), send the message
  		 */
! 		if (aflag || !nonuser(*p))
  			sendmes(p->ut_line);
  	}
  	exit(0);
  }
--- 117,129 ----
  		/*
  		 * if (-a option OR remote OR NOT tty[pqr]), send the message
  		 */
! 		if (aflag) {
  			sendmes(p->ut_line);
+ 		} else {
+ 			if (!already(p) && !nonuser(*p)) {
+ 				sendmes(p->ut_line);
+ 			}
+ 		}
  	}
  	exit(0);
  }
***************
*** 166,169 ****
--- 172,255 ----
  	}
  	(void) write(f, mesg, msize);
  	exit(0);
+ }
+ 
+ /*
+  * already() returns a 1 if the named user/machine pair has already
+  * been sent the message.
+  */
+ 
+ struct cacheut {
+ 	char cu_name[16];
+ 	char cu_host[MAXHOSTNAMELEN + 1];
+ 	struct cacheut *next;
+ };
+ 
+ struct cacheut *UtHead;
+ 
+ already(ut)
+ 	struct utmp *ut;
+ {
+ 	register struct cacheut *cur;
+ 	char userhost[MAXHOSTNAMELEN + 1];
+ 
+ 	gethost(ut->ut_host, userhost);
+ 
+ 	cur = UtHead;
+ 	while (cur) {
+ #ifdef DEBUG
+ 	printf("Comparing <%s, %s(%s)> to <%s, %s>\n", ut->ut_name,
+ 	ut->ut_host, userhost, cur->cu_name, cur->cu_host);
+ #endif
+ 		if (strcmp(cur->cu_name, ut->ut_name) == 0 &&
+ 		    strcmp(cur->cu_host, userhost) == 0) {
+ #ifdef DEBUG
+ 			printf("Match\n");
+ #endif
+ 			return 1;
+ 		}
+ 		cur = cur->next;
+ 	}
+ 
+ 	cur = (struct cacheut *)malloc(sizeof (struct cacheut));
+ 	if (cur == NULL) {
+ 		fprintf(stderr, "wall: Out of memory\n");
+ 		exit(1);
+ 	}
+ 	strcpy (cur->cu_name, ut->ut_name);
+ 	strcpy (cur->cu_host, userhost);
+ 
+ 	if (UtHead) {
+ 		cur->next = UtHead;
+ 	} else {
+ 		cur->next = NULL;
+ 	}
+ 	UtHead = cur;
+ 
+ 	return 0;
+ }
+ 
+ gethost(src, dest)
+ 	char *src;
+ 	char *dest;
+ {
+ 
+ 	char *ind;
+ 
+ 	if (*src == '\0') {
+ 		strcpy(dest, hostname);
+ 		return;
+ 	}
+ 
+ 	ind = (char *)index(src, ':');
+ 	if (ind == NULL) {
+ 		strcpy(dest, src);
+ 		return;
+ 	}
+ 	strncpy(dest, src, ind - src);
+ 	dest[ind - src] = '\0';
+ 
+ 	if (strcmp(dest, "unix") == 0) {
+ 		strcpy(dest, hostname);
+ 	}
  }
-- 
David Elliott		dce@Solbourne.COM
			...!{boulder,nbires,sun}!stan!dce