Commit | Line | Data |
---|---|---|
3071a7ff | 1 | static char *sccsid = "@(#)wall.c 4.8 (Berkeley) 84/03/30"; |
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> | |
3071a7ff | 11 | #include <errno.h> |
df3e00cc | 12 | #include <signal.h> |
3071a7ff RC |
13 | #include <sys/time.h> |
14 | #include <fcntl.h> | |
15 | ||
1addde1c | 16 | #define USERS 128 |
ec74d621 | 17 | #define IGNOREUSER "sleeper" |
1addde1c | 18 | |
cf288731 | 19 | char hostname[32]; |
1addde1c BJ |
20 | char mesg[3000]; |
21 | int msize,sline; | |
22 | struct utmp utmp[USERS]; | |
23 | char *strcpy(); | |
24 | char *strcat(); | |
3071a7ff | 25 | char who[9] = "???"; |
1eca479f | 26 | long clock, time(); |
1addde1c BJ |
27 | struct tm *localtime(); |
28 | struct tm *localclock; | |
29 | ||
3071a7ff RC |
30 | extern errno; |
31 | ||
1addde1c BJ |
32 | main(argc, argv) |
33 | char *argv[]; | |
34 | { | |
3071a7ff | 35 | register int i, c; |
1addde1c BJ |
36 | register struct utmp *p; |
37 | FILE *f; | |
38 | ||
cf288731 | 39 | gethostname(hostname, sizeof (hostname)); |
3071a7ff | 40 | if ((f = fopen("/etc/utmp", "r")) == NULL) { |
1addde1c BJ |
41 | fprintf(stderr, "Cannot open /etc/utmp\n"); |
42 | exit(1); | |
43 | } | |
44 | clock = time( 0 ); | |
45 | localclock = localtime( &clock ); | |
3071a7ff RC |
46 | sline = ttyslot(); /* 'utmp' slot no. of sender */ |
47 | c = fread((char *)utmp, sizeof(struct utmp), USERS, f); | |
48 | fclose(f); | |
49 | if (sline) | |
50 | strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); | |
51 | sprintf(mesg, | |
52 | "\n\a\a\aBroadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n" | |
53 | , who | |
54 | , hostname | |
55 | , sizeof(utmp[sline].ut_line) | |
56 | , utmp[sline].ut_line | |
57 | , localclock -> tm_hour | |
58 | , localclock -> tm_min | |
59 | ); | |
60 | msize = strlen(mesg); | |
61 | if (argc >= 2) { | |
1addde1c | 62 | /* take message from unix file instead of standard input */ |
3071a7ff RC |
63 | if (freopen(argv[1], "r", stdin) == NULL) { |
64 | perror(argv[1]); | |
1addde1c BJ |
65 | exit(1); |
66 | } | |
67 | } | |
3071a7ff RC |
68 | while ((i = getchar()) != EOF) { |
69 | if (i == '\n') | |
70 | mesg[msize++] = '\r'; | |
df3e00cc BJ |
71 | if (msize >= sizeof mesg) { |
72 | fprintf(stderr, "Message too long\n"); | |
73 | exit(1); | |
1addde1c | 74 | } |
df3e00cc BJ |
75 | mesg[msize++] = i; |
76 | } | |
3071a7ff RC |
77 | fclose(stdin); |
78 | for (i=0; i<c; i++) { | |
1addde1c | 79 | p = &utmp[i]; |
3071a7ff RC |
80 | if (p->ut_name[0] == 0 || |
81 | strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0) | |
1addde1c | 82 | continue; |
1addde1c BJ |
83 | sendmes(p->ut_line); |
84 | } | |
85 | exit(0); | |
86 | } | |
87 | ||
88 | sendmes(tty) | |
89 | char *tty; | |
90 | { | |
3071a7ff RC |
91 | register f, flags; |
92 | static char t[50] = "/dev/"; | |
93 | int e, i; | |
1addde1c | 94 | |
3071a7ff RC |
95 | strcpy(t + 5, tty); |
96 | ||
97 | if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) { | |
98 | if (errno != EWOULDBLOCK) | |
99 | perror(t); | |
100 | return; | |
101 | } | |
102 | if ((flags = fcntl(f, F_GETFL, 0)) == -1) { | |
103 | perror(t); | |
104 | return; | |
105 | } | |
106 | if (fcntl(f, F_SETFL, flags | FNDELAY) == -1) | |
107 | goto oldway; | |
108 | i = write(f, mesg, msize); | |
109 | e = errno; | |
110 | (void) fcntl(f, F_SETFL, flags); | |
111 | if (i == msize) { | |
112 | (void) close(f); | |
113 | return; | |
114 | } | |
115 | if (e != EWOULDBLOCK) { | |
116 | errno = e; | |
117 | perror(t); | |
118 | (void) close(f); | |
119 | return; | |
120 | } | |
121 | oldway: | |
df3e00cc BJ |
122 | while ((i = fork()) == -1) |
123 | if (wait((int *)0) == -1) { | |
124 | fprintf(stderr, "Try again\n"); | |
125 | return; | |
126 | } | |
3071a7ff RC |
127 | if (i) { |
128 | (void) close(f); | |
1addde1c | 129 | return; |
1addde1c | 130 | } |
1addde1c | 131 | |
3071a7ff | 132 | (void) write(f, mesg, msize); |
1addde1c BJ |
133 | exit(0); |
134 | } |