xref: /csrg-svn/usr.bin/wall/wall.c (revision 19909)
11159Sbill /*
2*19909Sdist  * Copyright (c) 1980 Regents of the University of California.
3*19909Sdist  * All rights reserved.  The Berkeley software License Agreement
4*19909Sdist  * specifies the terms and conditions for redistribution.
5*19909Sdist  */
6*19909Sdist 
7*19909Sdist #ifndef lint
8*19909Sdist char copyright[] =
9*19909Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*19909Sdist  All rights reserved.\n";
11*19909Sdist #endif not lint
12*19909Sdist 
13*19909Sdist #ifndef lint
14*19909Sdist static char sccsid[] = "@(#)wall.c	5.1 (Berkeley) 05/02/85";
15*19909Sdist #endif not lint
16*19909Sdist 
17*19909Sdist /*
181159Sbill  * wall.c - Broadcast a message to all users.
191159Sbill  *
201159Sbill  * This program is not related to David Wall, whose Stanford Ph.D. thesis
211159Sbill  * is entitled "Mechanisms for Broadcast and Selective Broadcast".
221159Sbill  */
231159Sbill 
241159Sbill #include <stdio.h>
251159Sbill #include <utmp.h>
2616256Sralph #include <errno.h>
2716256Sralph #include <signal.h>
2813594Swnj #include <sys/time.h>
2916256Sralph #include <fcntl.h>
3016256Sralph 
311159Sbill #define	USERS	128
323884Sroot #define IGNOREUSER	"sleeper"
331159Sbill 
346200Sroot char	hostname[32];
351159Sbill char	mesg[3000];
361159Sbill int	msize,sline;
371159Sbill struct	utmp utmp[USERS];
381159Sbill char	*strcpy();
391159Sbill char	*strcat();
4016256Sralph char	who[9] = "???";
413660Smark long	clock, time();
421159Sbill struct tm *localtime();
431159Sbill struct tm *localclock;
441159Sbill 
4516256Sralph extern	errno;
4616256Sralph 
471159Sbill main(argc, argv)
481159Sbill char *argv[];
491159Sbill {
5016256Sralph 	register int i, c;
511159Sbill 	register struct utmp *p;
521159Sbill 	FILE *f;
531159Sbill 
546200Sroot 	gethostname(hostname, sizeof (hostname));
5516256Sralph 	if ((f = fopen("/etc/utmp", "r")) == NULL) {
561159Sbill 		fprintf(stderr, "Cannot open /etc/utmp\n");
571159Sbill 		exit(1);
581159Sbill 	}
591159Sbill 	clock = time( 0 );
601159Sbill 	localclock = localtime( &clock );
6116256Sralph 	sline = ttyslot();	/* 'utmp' slot no. of sender */
6216256Sralph 	c = fread((char *)utmp, sizeof(struct utmp), USERS, f);
6316256Sralph 	fclose(f);
6416256Sralph 	if (sline)
6516256Sralph 		strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
6616256Sralph 	sprintf(mesg,
6716256Sralph 	    "\nBroadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n"
6816256Sralph 		, who
6916256Sralph 		, hostname
7016256Sralph 		, sizeof(utmp[sline].ut_line)
7116256Sralph 		, utmp[sline].ut_line
7216256Sralph 		, localclock -> tm_hour
7316256Sralph 		, localclock -> tm_min
7416256Sralph 	);
7516256Sralph 	msize = strlen(mesg);
7616256Sralph 	if (argc >= 2) {
771159Sbill 		/* take message from unix file instead of standard input */
7816256Sralph 		if (freopen(argv[1], "r", stdin) == NULL) {
7916256Sralph 			perror(argv[1]);
801159Sbill 			exit(1);
811159Sbill 		}
821159Sbill 	}
8316256Sralph 	while ((i = getchar()) != EOF) {
8416256Sralph 		if (i == '\n')
8516256Sralph 			mesg[msize++] = '\r';
863176Swnj 		if (msize >= sizeof mesg) {
873176Swnj 			fprintf(stderr, "Message too long\n");
883176Swnj 			exit(1);
893176Swnj 		}
903176Swnj 		mesg[msize++] = i;
913176Swnj 	}
9216256Sralph 	fclose(stdin);
9316256Sralph 	for (i=0; i<c; i++) {
941159Sbill 		p = &utmp[i];
9516256Sralph 		if (p->ut_name[0] == 0 ||
9616256Sralph 		    strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0)
971159Sbill 			continue;
981159Sbill 		sendmes(p->ut_line);
991159Sbill 	}
1001159Sbill 	exit(0);
1011159Sbill }
1021159Sbill 
1031159Sbill sendmes(tty)
1041159Sbill char *tty;
1051159Sbill {
10616256Sralph 	register f, flags;
10716256Sralph 	static char t[50] = "/dev/";
10816256Sralph 	int e, i;
1091159Sbill 
11016256Sralph 	strcpy(t + 5, tty);
11116256Sralph 
11216256Sralph 	if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) {
11316256Sralph 		if (errno != EWOULDBLOCK)
11416256Sralph 			perror(t);
11516256Sralph 		return;
11616256Sralph 	}
11716256Sralph 	if ((flags = fcntl(f, F_GETFL, 0)) == -1) {
11816256Sralph 		perror(t);
11916256Sralph 		return;
12016256Sralph 	}
12116256Sralph 	if (fcntl(f, F_SETFL, flags | FNDELAY) == -1)
12216256Sralph 		goto oldway;
12316256Sralph 	i = write(f, mesg, msize);
12416256Sralph 	e = errno;
12516256Sralph 	(void) fcntl(f, F_SETFL, flags);
12616256Sralph 	if (i == msize) {
12716256Sralph 		(void) close(f);
12816256Sralph 		return;
12916256Sralph 	}
13016256Sralph 	if (e != EWOULDBLOCK) {
13116256Sralph 		errno = e;
13216256Sralph 		perror(t);
13316256Sralph 		(void) close(f);
13416256Sralph 		return;
13516256Sralph 	}
13616256Sralph oldway:
1373176Swnj 	while ((i = fork()) == -1)
1383176Swnj 		if (wait((int *)0) == -1) {
1393176Swnj 			fprintf(stderr, "Try again\n");
1403176Swnj 			return;
1413176Swnj 		}
14216256Sralph 	if (i) {
14316256Sralph 		(void) close(f);
1441159Sbill 		return;
1451159Sbill 	}
1461159Sbill 
14716256Sralph 	(void) write(f, mesg, msize);
1481159Sbill 	exit(0);
1491159Sbill }
150