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