[comp.sys.sun] Patch to restrict wall messages

dce@ames.arc.nasa.gov (David Elliott) (04/22/89)

Enclosed is a patch to the SunOS 4.0 wall command that makes sure that
wall messages (such as those produced by shutdown) only go to one window
per person per "hostname".  An empty remote hostname is assumed to be the
local host, as is a hostname beginning with "unix:" (for local X clients).
The code also handles remote X clients.  Note that the message goes to the
first tty it finds for each user/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		...!pyramid!boulder!stan!dce
"Splish splash, I was rakin' in the cash"  -- Eno