more or less 4.3
[unix-history] / usr / src / usr.bin / wall / wall.c
CommitLineData
02072412
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
13#ifndef lint
4689f60b 14static char sccsid[] = "@(#)wall.c 5.3 (Berkeley) %G%";
02072412
DF
15#endif not lint
16
1addde1c
BJ
17/*
18 * wall.c - Broadcast a message to all users.
19 *
20 * This program is not related to David Wall, whose Stanford Ph.D. thesis
21 * is entitled "Mechanisms for Broadcast and Selective Broadcast".
22 */
23
24#include <stdio.h>
25#include <utmp.h>
3071a7ff 26#include <errno.h>
df3e00cc 27#include <signal.h>
3071a7ff
RC
28#include <sys/time.h>
29#include <fcntl.h>
734f8abe
JB
30#include <sys/types.h>
31#include <sys/stat.h>
3071a7ff 32
ec74d621 33#define IGNOREUSER "sleeper"
1addde1c 34
cf288731 35char hostname[32];
1addde1c
BJ
36char mesg[3000];
37int msize,sline;
734f8abe 38struct utmp *utmp;
1addde1c
BJ
39char *strcpy();
40char *strcat();
734f8abe 41char *malloc();
3071a7ff 42char who[9] = "???";
1eca479f 43long clock, time();
1addde1c
BJ
44struct tm *localtime();
45struct tm *localclock;
46
3071a7ff
RC
47extern errno;
48
1addde1c
BJ
49main(argc, argv)
50char *argv[];
51{
3071a7ff 52 register int i, c;
1addde1c 53 register struct utmp *p;
734f8abe
JB
54 int f;
55 struct stat statb;
1addde1c 56
734f8abe
JB
57 (void) gethostname(hostname, sizeof (hostname));
58 if ((f = open("/etc/utmp", O_RDONLY, 0)) < 0) {
1addde1c
BJ
59 fprintf(stderr, "Cannot open /etc/utmp\n");
60 exit(1);
61 }
62 clock = time( 0 );
63 localclock = localtime( &clock );
3071a7ff 64 sline = ttyslot(); /* 'utmp' slot no. of sender */
734f8abe
JB
65 (void) fstat(f, &statb);
66 utmp = (struct utmp *)malloc(statb.st_size);
67 c = read(f, (char *)utmp, statb.st_size);
68 (void) close(f);
69 c /= sizeof(struct utmp);
3071a7ff
RC
70 if (sline)
71 strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
72 sprintf(mesg,
4689f60b 73 "\n\007\007Broadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n"
3071a7ff
RC
74 , who
75 , hostname
76 , sizeof(utmp[sline].ut_line)
77 , utmp[sline].ut_line
78 , localclock -> tm_hour
79 , localclock -> tm_min
80 );
81 msize = strlen(mesg);
82 if (argc >= 2) {
1addde1c 83 /* take message from unix file instead of standard input */
3071a7ff
RC
84 if (freopen(argv[1], "r", stdin) == NULL) {
85 perror(argv[1]);
1addde1c
BJ
86 exit(1);
87 }
88 }
3071a7ff
RC
89 while ((i = getchar()) != EOF) {
90 if (i == '\n')
91 mesg[msize++] = '\r';
df3e00cc
BJ
92 if (msize >= sizeof mesg) {
93 fprintf(stderr, "Message too long\n");
94 exit(1);
1addde1c 95 }
df3e00cc
BJ
96 mesg[msize++] = i;
97 }
3071a7ff
RC
98 fclose(stdin);
99 for (i=0; i<c; i++) {
1addde1c 100 p = &utmp[i];
3071a7ff
RC
101 if (p->ut_name[0] == 0 ||
102 strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0)
1addde1c 103 continue;
1addde1c
BJ
104 sendmes(p->ut_line);
105 }
106 exit(0);
107}
108
109sendmes(tty)
110char *tty;
111{
3071a7ff
RC
112 register f, flags;
113 static char t[50] = "/dev/";
114 int e, i;
1addde1c 115
3071a7ff
RC
116 strcpy(t + 5, tty);
117
118 if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) {
119 if (errno != EWOULDBLOCK)
120 perror(t);
121 return;
122 }
123 if ((flags = fcntl(f, F_GETFL, 0)) == -1) {
124 perror(t);
125 return;
126 }
127 if (fcntl(f, F_SETFL, flags | FNDELAY) == -1)
128 goto oldway;
129 i = write(f, mesg, msize);
130 e = errno;
131 (void) fcntl(f, F_SETFL, flags);
132 if (i == msize) {
133 (void) close(f);
134 return;
135 }
136 if (e != EWOULDBLOCK) {
137 errno = e;
138 perror(t);
139 (void) close(f);
140 return;
141 }
142oldway:
df3e00cc
BJ
143 while ((i = fork()) == -1)
144 if (wait((int *)0) == -1) {
145 fprintf(stderr, "Try again\n");
146 return;
147 }
3071a7ff
RC
148 if (i) {
149 (void) close(f);
1addde1c 150 return;
1addde1c 151 }
1addde1c 152
3071a7ff 153 (void) write(f, mesg, msize);
1addde1c
BJ
154 exit(0);
155}