Add spl's around queue manipulation
[unix-history] / usr / src / usr.bin / wall / wall.c
CommitLineData
3071a7ff 1static 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 19char hostname[32];
1addde1c
BJ
20char mesg[3000];
21int msize,sline;
22struct utmp utmp[USERS];
23char *strcpy();
24char *strcat();
3071a7ff 25char who[9] = "???";
1eca479f 26long clock, time();
1addde1c
BJ
27struct tm *localtime();
28struct tm *localclock;
29
3071a7ff
RC
30extern errno;
31
1addde1c
BJ
32main(argc, argv)
33char *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
88sendmes(tty)
89char *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 }
121oldway:
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}