Commit | Line | Data |
---|---|---|
cf288731 | 1 | static char *sccsid = "@(#)wall.c 4.6 (Berkeley) 82/03/15"; |
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 | 12 | #include <signal.h> |
1addde1c | 13 | #define USERS 128 |
ec74d621 | 14 | #define IGNOREUSER "sleeper" |
1addde1c | 15 | |
cf288731 | 16 | char hostname[32]; |
1addde1c BJ |
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 | 35 | |
cf288731 | 36 | gethostname(hostname, sizeof (hostname)); |
1addde1c BJ |
37 | if((f = fopen("/etc/utmp", "r")) == NULL) { |
38 | fprintf(stderr, "Cannot open /etc/utmp\n"); | |
39 | exit(1); | |
40 | } | |
41 | clock = time( 0 ); | |
42 | localclock = localtime( &clock ); | |
df3e00cc | 43 | mf = stdin; |
1addde1c BJ |
44 | if(argc >= 2) { |
45 | /* take message from unix file instead of standard input */ | |
df3e00cc | 46 | if((mf = fopen(argv[1], "r")) == NULL) { |
1addde1c BJ |
47 | fprintf(stderr,"Cannot open %s\n", argv[1]); |
48 | exit(1); | |
49 | } | |
50 | } | |
df3e00cc BJ |
51 | while((i = getc(mf)) != EOF) { |
52 | if (msize >= sizeof mesg) { | |
53 | fprintf(stderr, "Message too long\n"); | |
54 | exit(1); | |
1addde1c | 55 | } |
df3e00cc BJ |
56 | mesg[msize++] = i; |
57 | } | |
58 | fclose(mf); | |
59 | sline = ttyslot(2); /* 'utmp' slot no. of sender */ | |
60 | fread((char *)utmp, sizeof(struct utmp), USERS, f); | |
61 | fclose(f); | |
62 | if (sline) | |
63 | strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); | |
1addde1c BJ |
64 | for(i=0; i<USERS; i++) { |
65 | p = &utmp[i]; | |
ec74d621 BJ |
66 | if ((p->ut_name[0] == 0) || |
67 | (strncmp (p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0)) | |
1addde1c | 68 | continue; |
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 BJ |
83 | while ((i = fork()) == -1) |
84 | if (wait((int *)0) == -1) { | |
85 | fprintf(stderr, "Try again\n"); | |
86 | return; | |
87 | } | |
1addde1c BJ |
88 | if(i) |
89 | return; | |
90 | strcpy(t, "/dev/"); | |
91 | strcat(t, tty); | |
92 | ||
df3e00cc BJ |
93 | signal(SIGALRM, SIG_DFL); /* blow away if open hangs */ |
94 | alarm(10); | |
95 | ||
1addde1c BJ |
96 | if((f = fopen(t, "w")) == NULL) { |
97 | fprintf(stderr,"cannot open %s\n", t); | |
98 | exit(1); | |
99 | } | |
100 | setbuf(f, buf); | |
df3e00cc BJ |
101 | fprintf(f, |
102 | "\n\a\a\aBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n" | |
cf288731 | 103 | , hostname |
df3e00cc BJ |
104 | , who |
105 | , sizeof(utmp[sline].ut_line) | |
106 | , utmp[sline].ut_line | |
107 | , localclock -> tm_hour | |
108 | , localclock -> tm_min | |
109 | ); | |
1addde1c BJ |
110 | /* fwrite(mesg, msize, 1, f); */ |
111 | for (cp = mesg, c = msize; c-- > 0; cp++) { | |
112 | ch = *cp; | |
113 | if (ch == '\n') | |
114 | putc('\r', f); | |
115 | putc(ch, f); | |
116 | } | |
117 | ||
118 | /* | |
119 | * Bitchin'. | |
120 | */ | |
121 | ||
122 | exit(0); | |
123 | } |