xref: /csrg-svn/usr.bin/wall/wall.c (revision 3176)
1*3176Swnj static char *sccsid = "@(#)wall.c	4.2 (Berkeley) 81/03/10";
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>
111159Sbill #include <time.h>
12*3176Swnj #include <whoami.h>
13*3176Swnj #include <signal.h>
141159Sbill #define	USERS	128
151159Sbill 
161159Sbill char	mesg[3000];
171159Sbill int	msize,sline;
181159Sbill struct	utmp utmp[USERS];
191159Sbill char	*strcpy();
201159Sbill char	*strcat();
211159Sbill char who[9] = "???";
221159Sbill long	clock;
231159Sbill struct tm *localtime();
241159Sbill struct tm *localclock;
251159Sbill 
261159Sbill main(argc, argv)
271159Sbill char *argv[];
281159Sbill {
291159Sbill 	register i;
301159Sbill 	register char c;
311159Sbill 	register struct utmp *p;
321159Sbill 	FILE *f;
33*3176Swnj 	FILE *mf;
341159Sbill 
351159Sbill 	if((f = fopen("/etc/utmp", "r")) == NULL) {
361159Sbill 		fprintf(stderr, "Cannot open /etc/utmp\n");
371159Sbill 		exit(1);
381159Sbill 	}
391159Sbill 	clock = time( 0 );
401159Sbill 	localclock = localtime( &clock );
41*3176Swnj 	mf = stdin;
421159Sbill 	if(argc >= 2) {
431159Sbill 		/* take message from unix file instead of standard input */
44*3176Swnj 		if((mf = fopen(argv[1], "r")) == NULL) {
451159Sbill 			fprintf(stderr,"Cannot open %s\n", argv[1]);
461159Sbill 			exit(1);
471159Sbill 		}
481159Sbill 	}
49*3176Swnj 	while((i = getc(mf)) != EOF) {
50*3176Swnj 		if (msize >= sizeof mesg) {
51*3176Swnj 			fprintf(stderr, "Message too long\n");
52*3176Swnj 			exit(1);
53*3176Swnj 		}
54*3176Swnj 		mesg[msize++] = i;
55*3176Swnj 	}
56*3176Swnj 	fclose(mf);
57*3176Swnj 	sline = ttyslot(2); /* 'utmp' slot no. of sender */
58*3176Swnj 	fread((char *)utmp, sizeof(struct utmp), USERS, f);
591159Sbill 	fclose(f);
60*3176Swnj 	if (sline)
61*3176Swnj 		strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
621159Sbill 	for(i=0; i<USERS; i++) {
631159Sbill 		p = &utmp[i];
641159Sbill 		if(p->ut_name[0] == 0)
651159Sbill 			continue;
66*3176Swnj 	/***		this might be nice, but utmp gets so out of date !!
671159Sbill 		sleep(1);
68*3176Swnj 	***/
691159Sbill 		sendmes(p->ut_line);
701159Sbill 	}
711159Sbill 	exit(0);
721159Sbill }
731159Sbill 
741159Sbill sendmes(tty)
751159Sbill char *tty;
761159Sbill {
771159Sbill 	register i;
781159Sbill 	char t[50], buf[BUFSIZ];
791159Sbill 	register char *cp;
801159Sbill 	register int c, ch;
811159Sbill 	FILE *f;
821159Sbill 
83*3176Swnj /***			you can't do this with lots of users & MAXUPROC
841159Sbill 	i = fork();
851159Sbill 	if(i == -1) {
861159Sbill 		fprintf(stderr, "Try again\n");
871159Sbill 		return;
881159Sbill 	}
89*3176Swnj  ***/
90*3176Swnj 	while ((i = fork()) == -1)
91*3176Swnj 		if (wait((int *)0) == -1) {
92*3176Swnj 			fprintf(stderr, "Try again\n");
93*3176Swnj 			return;
94*3176Swnj 		}
951159Sbill 	if(i)
961159Sbill 		return;
971159Sbill 	strcpy(t, "/dev/");
981159Sbill 	strcat(t, tty);
991159Sbill 
100*3176Swnj 	signal(SIGALRM, SIG_DFL);	/* blow away if open hangs */
101*3176Swnj 	alarm(10);
102*3176Swnj 
1031159Sbill 	if((f = fopen(t, "w")) == NULL) {
1041159Sbill 		fprintf(stderr,"cannot open %s\n", t);
1051159Sbill 		exit(1);
1061159Sbill 	}
1071159Sbill 	setbuf(f, buf);
108*3176Swnj 	fprintf(f,
109*3176Swnj 	    "\nBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n"
110*3176Swnj 		, sysname
111*3176Swnj 		, who
112*3176Swnj 		, sizeof(utmp[sline].ut_line)
113*3176Swnj 		, utmp[sline].ut_line
114*3176Swnj 		, localclock -> tm_hour
115*3176Swnj 		, localclock -> tm_min
116*3176Swnj 	);
1171159Sbill 	/* fwrite(mesg, msize, 1, f); */
1181159Sbill 	for (cp = mesg, c = msize; c-- > 0; cp++) {
1191159Sbill 		ch = *cp;
1201159Sbill 		if (ch == '\n')
1211159Sbill 			putc('\r', f);
1221159Sbill 		putc(ch, f);
1231159Sbill 	}
1241159Sbill 
1251159Sbill 	/*
1261159Sbill 	 * Bitchin'.
1271159Sbill 	 */
1281159Sbill 
1291159Sbill 	exit(0);
1301159Sbill }
131