xref: /csrg-svn/usr.bin/wall/wall.c (revision 16256)
1*16256Sralph static char *sccsid = "@(#)wall.c	4.8 (Berkeley) 84/03/30";
21159Sbill /*
31159Sbill  * wall.c - Broadcast a message to all users.
41159Sbill  *
51159Sbill  * This program is not related to David Wall, whose Stanford Ph.D. thesis
61159Sbill  * is entitled "Mechanisms for Broadcast and Selective Broadcast".
71159Sbill  */
81159Sbill 
91159Sbill #include <stdio.h>
101159Sbill #include <utmp.h>
11*16256Sralph #include <errno.h>
12*16256Sralph #include <signal.h>
1313594Swnj #include <sys/time.h>
14*16256Sralph #include <fcntl.h>
15*16256Sralph 
161159Sbill #define	USERS	128
173884Sroot #define IGNOREUSER	"sleeper"
181159Sbill 
196200Sroot char	hostname[32];
201159Sbill char	mesg[3000];
211159Sbill int	msize,sline;
221159Sbill struct	utmp utmp[USERS];
231159Sbill char	*strcpy();
241159Sbill char	*strcat();
25*16256Sralph char	who[9] = "???";
263660Smark long	clock, time();
271159Sbill struct tm *localtime();
281159Sbill struct tm *localclock;
291159Sbill 
30*16256Sralph extern	errno;
31*16256Sralph 
321159Sbill main(argc, argv)
331159Sbill char *argv[];
341159Sbill {
35*16256Sralph 	register int i, c;
361159Sbill 	register struct utmp *p;
371159Sbill 	FILE *f;
381159Sbill 
396200Sroot 	gethostname(hostname, sizeof (hostname));
40*16256Sralph 	if ((f = fopen("/etc/utmp", "r")) == NULL) {
411159Sbill 		fprintf(stderr, "Cannot open /etc/utmp\n");
421159Sbill 		exit(1);
431159Sbill 	}
441159Sbill 	clock = time( 0 );
451159Sbill 	localclock = localtime( &clock );
46*16256Sralph 	sline = ttyslot();	/* 'utmp' slot no. of sender */
47*16256Sralph 	c = fread((char *)utmp, sizeof(struct utmp), USERS, f);
48*16256Sralph 	fclose(f);
49*16256Sralph 	if (sline)
50*16256Sralph 		strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
51*16256Sralph 	sprintf(mesg,
52*16256Sralph 	    "\nBroadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n"
53*16256Sralph 		, who
54*16256Sralph 		, hostname
55*16256Sralph 		, sizeof(utmp[sline].ut_line)
56*16256Sralph 		, utmp[sline].ut_line
57*16256Sralph 		, localclock -> tm_hour
58*16256Sralph 		, localclock -> tm_min
59*16256Sralph 	);
60*16256Sralph 	msize = strlen(mesg);
61*16256Sralph 	if (argc >= 2) {
621159Sbill 		/* take message from unix file instead of standard input */
63*16256Sralph 		if (freopen(argv[1], "r", stdin) == NULL) {
64*16256Sralph 			perror(argv[1]);
651159Sbill 			exit(1);
661159Sbill 		}
671159Sbill 	}
68*16256Sralph 	while ((i = getchar()) != EOF) {
69*16256Sralph 		if (i == '\n')
70*16256Sralph 			mesg[msize++] = '\r';
713176Swnj 		if (msize >= sizeof mesg) {
723176Swnj 			fprintf(stderr, "Message too long\n");
733176Swnj 			exit(1);
743176Swnj 		}
753176Swnj 		mesg[msize++] = i;
763176Swnj 	}
77*16256Sralph 	fclose(stdin);
78*16256Sralph 	for (i=0; i<c; i++) {
791159Sbill 		p = &utmp[i];
80*16256Sralph 		if (p->ut_name[0] == 0 ||
81*16256Sralph 		    strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0)
821159Sbill 			continue;
831159Sbill 		sendmes(p->ut_line);
841159Sbill 	}
851159Sbill 	exit(0);
861159Sbill }
871159Sbill 
881159Sbill sendmes(tty)
891159Sbill char *tty;
901159Sbill {
91*16256Sralph 	register f, flags;
92*16256Sralph 	static char t[50] = "/dev/";
93*16256Sralph 	int e, i;
941159Sbill 
95*16256Sralph 	strcpy(t + 5, tty);
96*16256Sralph 
97*16256Sralph 	if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) {
98*16256Sralph 		if (errno != EWOULDBLOCK)
99*16256Sralph 			perror(t);
100*16256Sralph 		return;
101*16256Sralph 	}
102*16256Sralph 	if ((flags = fcntl(f, F_GETFL, 0)) == -1) {
103*16256Sralph 		perror(t);
104*16256Sralph 		return;
105*16256Sralph 	}
106*16256Sralph 	if (fcntl(f, F_SETFL, flags | FNDELAY) == -1)
107*16256Sralph 		goto oldway;
108*16256Sralph 	i = write(f, mesg, msize);
109*16256Sralph 	e = errno;
110*16256Sralph 	(void) fcntl(f, F_SETFL, flags);
111*16256Sralph 	if (i == msize) {
112*16256Sralph 		(void) close(f);
113*16256Sralph 		return;
114*16256Sralph 	}
115*16256Sralph 	if (e != EWOULDBLOCK) {
116*16256Sralph 		errno = e;
117*16256Sralph 		perror(t);
118*16256Sralph 		(void) close(f);
119*16256Sralph 		return;
120*16256Sralph 	}
121*16256Sralph oldway:
1223176Swnj 	while ((i = fork()) == -1)
1233176Swnj 		if (wait((int *)0) == -1) {
1243176Swnj 			fprintf(stderr, "Try again\n");
1253176Swnj 			return;
1263176Swnj 		}
127*16256Sralph 	if (i) {
128*16256Sralph 		(void) close(f);
1291159Sbill 		return;
1301159Sbill 	}
1311159Sbill 
132*16256Sralph 	(void) write(f, mesg, msize);
1331159Sbill 	exit(0);
1341159Sbill }
135