local version
[unix-history] / usr / src / usr.bin / wall / wall.c
CommitLineData
ec74d621 1static char *sccsid = "@(#)wall.c 4.5 (Berkeley) 81/06/12";
1addde1c
BJ
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>
df3e00cc
BJ
12#include <whoami.h>
13#include <signal.h>
1addde1c 14#define USERS 128
ec74d621 15#define IGNOREUSER "sleeper"
1addde1c
BJ
16
17char mesg[3000];
18int msize,sline;
19struct utmp utmp[USERS];
20char *strcpy();
21char *strcat();
22char who[9] = "???";
1eca479f 23long clock, time();
1addde1c
BJ
24struct tm *localtime();
25struct tm *localclock;
26
27main(argc, argv)
28char *argv[];
29{
30 register i;
31 register char c;
32 register struct utmp *p;
33 FILE *f;
df3e00cc 34 FILE *mf;
1addde1c
BJ
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 );
df3e00cc 42 mf = stdin;
1addde1c
BJ
43 if(argc >= 2) {
44 /* take message from unix file instead of standard input */
df3e00cc 45 if((mf = fopen(argv[1], "r")) == NULL) {
1addde1c
BJ
46 fprintf(stderr,"Cannot open %s\n", argv[1]);
47 exit(1);
48 }
49 }
df3e00cc
BJ
50 while((i = getc(mf)) != EOF) {
51 if (msize >= sizeof mesg) {
52 fprintf(stderr, "Message too long\n");
53 exit(1);
1addde1c 54 }
df3e00cc
BJ
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));
1addde1c
BJ
63 for(i=0; i<USERS; i++) {
64 p = &utmp[i];
ec74d621
BJ
65 if ((p->ut_name[0] == 0) ||
66 (strncmp (p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0))
1addde1c 67 continue;
df3e00cc 68 /*** this might be nice, but utmp gets so out of date !!
1addde1c 69 sleep(1);
df3e00cc 70 ***/
1addde1c
BJ
71 sendmes(p->ut_line);
72 }
73 exit(0);
74}
75
76sendmes(tty)
77char *tty;
78{
79 register i;
80 char t[50], buf[BUFSIZ];
81 register char *cp;
82 register int c, ch;
83 FILE *f;
84
df3e00cc 85/*** you can't do this with lots of users & MAXUPROC
1addde1c
BJ
86 i = fork();
87 if(i == -1) {
88 fprintf(stderr, "Try again\n");
89 return;
90 }
df3e00cc
BJ
91 ***/
92 while ((i = fork()) == -1)
93 if (wait((int *)0) == -1) {
94 fprintf(stderr, "Try again\n");
95 return;
96 }
1addde1c
BJ
97 if(i)
98 return;
99 strcpy(t, "/dev/");
100 strcat(t, tty);
101
df3e00cc
BJ
102 signal(SIGALRM, SIG_DFL); /* blow away if open hangs */
103 alarm(10);
104
1addde1c
BJ
105 if((f = fopen(t, "w")) == NULL) {
106 fprintf(stderr,"cannot open %s\n", t);
107 exit(1);
108 }
109 setbuf(f, buf);
df3e00cc
BJ
110 fprintf(f,
111 "\n\a\a\aBroadcast 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 );
1addde1c
BJ
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}