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