]> git.saurik.com Git - apple/network_cmds.git/blob - wall.tproj/wall.c
network_cmds-76.tar.gz
[apple/network_cmds.git] / wall.tproj / wall.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1988, 1990, 1993
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57
58 #ifndef lint
59 static char copyright[] =
60 "@(#) Copyright (c) 1988, 1990, 1993\n\
61 The Regents of the University of California. All rights reserved.\n";
62 #endif /* not lint */
63
64 /*
65 * This program is not related to David Wall, whose Stanford Ph.D. thesis
66 * is entitled "Mechanisms for Broadcast and Selective Broadcast".
67 */
68
69 #include <sys/param.h>
70 #include <sys/stat.h>
71 #include <sys/time.h>
72 #include <sys/uio.h>
73
74 #include <paths.h>
75 #include <pwd.h>
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
79 #include <unistd.h>
80 #include <utmp.h>
81
82 void makemsg __P((char *));
83
84 #define IGNOREUSER "sleeper"
85
86 int nobanner;
87 int mbufsize;
88 char *mbuf;
89
90 /* ARGSUSED */
91 int
92 main(argc, argv)
93 int argc;
94 char **argv;
95 {
96 extern int optind;
97 int ch;
98 struct iovec iov;
99 struct utmp utmp;
100 FILE *fp;
101 char *p, *ttymsg();
102 char line[sizeof(utmp.ut_line) + 1];
103
104 while ((ch = getopt(argc, argv, "n")) != EOF)
105 switch (ch) {
106 case 'n':
107 /* undoc option for shutdown: suppress banner */
108 if (geteuid() == 0)
109 nobanner = 1;
110 break;
111 case '?':
112 default:
113 usage:
114 (void)fprintf(stderr, "usage: wall [file]\n");
115 exit(1);
116 }
117 argc -= optind;
118 argv += optind;
119 if (argc > 1)
120 goto usage;
121
122 makemsg(*argv);
123
124 if (!(fp = fopen(_PATH_UTMP, "r"))) {
125 (void)fprintf(stderr, "wall: cannot read %s.\n", _PATH_UTMP);
126 exit(1);
127 }
128 iov.iov_base = mbuf;
129 iov.iov_len = mbufsize;
130 /* NOSTRICT */
131 while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) {
132 if (!utmp.ut_name[0] ||
133 !strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name)))
134 continue;
135 strncpy(line, utmp.ut_line, sizeof(utmp.ut_line));
136 line[sizeof(utmp.ut_line)] = '\0';
137 if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
138 (void)fprintf(stderr, "wall: %s\n", p);
139 }
140 exit(0);
141 }
142
143 void
144 makemsg(fname)
145 char *fname;
146 {
147 register int ch, cnt;
148 struct tm *lt;
149 struct passwd *pw;
150 struct stat sbuf;
151 time_t now, time();
152 FILE *fp;
153 int fd;
154 char *p, *whom, hostname[MAXHOSTNAMELEN], lbuf[100], tmpname[15];
155 char *getlogin(), *strcpy(), *ttyname();
156
157 (void)strcpy(tmpname, _PATH_TMP);
158 (void)strcat(tmpname, "/wall.XXXXXX");
159 if (!(fd = mkstemp(tmpname)) || !(fp = fdopen(fd, "r+"))) {
160 (void)fprintf(stderr, "wall: can't open temporary file.\n");
161 exit(1);
162 }
163 (void)unlink(tmpname);
164
165 if (!nobanner) {
166 if (!(whom = getlogin()))
167 whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
168 (void)gethostname(hostname, sizeof(hostname));
169 (void)time(&now);
170 lt = localtime(&now);
171
172 /*
173 * all this stuff is to blank out a square for the message;
174 * we wrap message lines at column 79, not 80, because some
175 * terminals wrap after 79, some do not, and we can't tell.
176 * Which means that we may leave a non-blank character
177 * in column 80, but that can't be helped.
178 */
179 (void)fprintf(fp, "\r%79s\r\n", " ");
180 (void)sprintf(lbuf, "Broadcast Message from %s@%s",
181 whom, hostname);
182 (void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
183 (void)sprintf(lbuf, " (%s) at %d:%02d ...", ttyname(2),
184 lt->tm_hour, lt->tm_min);
185 (void)fprintf(fp, "%-79.79s\r\n", lbuf);
186 }
187 (void)fprintf(fp, "%79s\r\n", " ");
188
189 if (fname && !(freopen(fname, "r", stdin))) {
190 (void)fprintf(stderr, "wall: can't read %s.\n", fname);
191 exit(1);
192 }
193 while (fgets(lbuf, sizeof(lbuf), stdin))
194 for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
195 if (cnt == 79 || ch == '\n') {
196 for (; cnt < 79; ++cnt)
197 putc(' ', fp);
198 putc('\r', fp);
199 putc('\n', fp);
200 cnt = 0;
201 } else
202 putc(ch, fp);
203 }
204 (void)fprintf(fp, "%79s\r\n", " ");
205 rewind(fp);
206
207 if (fstat(fd, &sbuf)) {
208 (void)fprintf(stderr, "wall: can't stat temporary file.\n");
209 exit(1);
210 }
211 mbufsize = sbuf.st_size;
212 if (!(mbuf = malloc((u_int)mbufsize))) {
213 (void)fprintf(stderr, "wall: out of memory.\n");
214 exit(1);
215 }
216 if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) {
217 (void)fprintf(stderr, "wall: can't read temporary file.\n");
218 exit(1);
219 }
220 (void)close(fd);
221 }