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