xref: /original-bsd/usr.bin/wall/wall.c (revision 1f3a482a)
1 static char *sccsid = "@(#)wall.c	4.5 (Berkeley) 81/06/12";
2 /*
3  * wall.c - Broadcast a message to all users.
4  *
5  * This program is not related to David Wall, whose Stanford Ph.D. thesis
6  * is entitled "Mechanisms for Broadcast and Selective Broadcast".
7  */
8 
9 #include <stdio.h>
10 #include <utmp.h>
11 #include <time.h>
12 #include <whoami.h>
13 #include <signal.h>
14 #define	USERS	128
15 #define IGNOREUSER	"sleeper"
16 
17 char	mesg[3000];
18 int	msize,sline;
19 struct	utmp utmp[USERS];
20 char	*strcpy();
21 char	*strcat();
22 char who[9] = "???";
23 long	clock, time();
24 struct tm *localtime();
25 struct tm *localclock;
26 
27 main(argc, argv)
28 char *argv[];
29 {
30 	register i;
31 	register char c;
32 	register struct utmp *p;
33 	FILE *f;
34 	FILE *mf;
35 
36 	if((f = fopen("/etc/utmp", "r")) == NULL) {
37 		fprintf(stderr, "Cannot open /etc/utmp\n");
38 		exit(1);
39 	}
40 	clock = time( 0 );
41 	localclock = localtime( &clock );
42 	mf = stdin;
43 	if(argc >= 2) {
44 		/* take message from unix file instead of standard input */
45 		if((mf = fopen(argv[1], "r")) == NULL) {
46 			fprintf(stderr,"Cannot open %s\n", argv[1]);
47 			exit(1);
48 		}
49 	}
50 	while((i = getc(mf)) != EOF) {
51 		if (msize >= sizeof mesg) {
52 			fprintf(stderr, "Message too long\n");
53 			exit(1);
54 		}
55 		mesg[msize++] = i;
56 	}
57 	fclose(mf);
58 	sline = ttyslot(2); /* 'utmp' slot no. of sender */
59 	fread((char *)utmp, sizeof(struct utmp), USERS, f);
60 	fclose(f);
61 	if (sline)
62 		strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
63 	for(i=0; i<USERS; i++) {
64 		p = &utmp[i];
65 		if ((p->ut_name[0] == 0) ||
66 		    (strncmp (p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0))
67 			continue;
68 	/***		this might be nice, but utmp gets so out of date !!
69 		sleep(1);
70 	***/
71 		sendmes(p->ut_line);
72 	}
73 	exit(0);
74 }
75 
76 sendmes(tty)
77 char *tty;
78 {
79 	register i;
80 	char t[50], buf[BUFSIZ];
81 	register char *cp;
82 	register int c, ch;
83 	FILE *f;
84 
85 /***			you can't do this with lots of users & MAXUPROC
86 	i = fork();
87 	if(i == -1) {
88 		fprintf(stderr, "Try again\n");
89 		return;
90 	}
91  ***/
92 	while ((i = fork()) == -1)
93 		if (wait((int *)0) == -1) {
94 			fprintf(stderr, "Try again\n");
95 			return;
96 		}
97 	if(i)
98 		return;
99 	strcpy(t, "/dev/");
100 	strcat(t, tty);
101 
102 	signal(SIGALRM, SIG_DFL);	/* blow away if open hangs */
103 	alarm(10);
104 
105 	if((f = fopen(t, "w")) == NULL) {
106 		fprintf(stderr,"cannot open %s\n", t);
107 		exit(1);
108 	}
109 	setbuf(f, buf);
110 	fprintf(f,
111 	    "\nBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n"
112 		, sysname
113 		, who
114 		, sizeof(utmp[sline].ut_line)
115 		, utmp[sline].ut_line
116 		, localclock -> tm_hour
117 		, localclock -> tm_min
118 	);
119 	/* fwrite(mesg, msize, 1, f); */
120 	for (cp = mesg, c = msize; c-- > 0; cp++) {
121 		ch = *cp;
122 		if (ch == '\n')
123 			putc('\r', f);
124 		putc(ch, f);
125 	}
126 
127 	/*
128 	 * Bitchin'.
129 	 */
130 
131 	exit(0);
132 }
133