Commit | Line | Data |
---|---|---|
ec74d621 | 1 | static 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 | |
17 | char mesg[3000]; | |
18 | int msize,sline; | |
19 | struct utmp utmp[USERS]; | |
20 | char *strcpy(); | |
21 | char *strcat(); | |
22 | char who[9] = "???"; | |
1eca479f | 23 | long clock, time(); |
1addde1c BJ |
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; | |
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 | ||
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 | ||
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 | } |