rwall.c revision 302408
1193326Sed/*
2193326Sed * Copyright (c) 1993 Christopher G. Demetriou
3193326Sed * Copyright (c) 1988, 1990 Regents of the University of California.
4193326Sed * All rights reserved.
5193326Sed *
6193326Sed * Redistribution and use in source and binary forms, with or without
7193326Sed * modification, are permitted provided that the following conditions
8193326Sed * are met:
9193326Sed * 1. Redistributions of source code must retain the above copyright
10193326Sed *    notice, this list of conditions and the following disclaimer.
11193326Sed * 2. Redistributions in binary form must reproduce the above copyright
12193326Sed *    notice, this list of conditions and the following disclaimer in the
13193326Sed *    documentation and/or other materials provided with the distribution.
14221345Sdim * 3. All advertising materials mentioning features or use of this software
15193326Sed *    must display the following acknowledgement:
16199482Srdivacky *	This product includes software developed by the University of
17193326Sed *	California, Berkeley and its contributors.
18193326Sed * 4. Neither the name of the University nor the names of its contributors
19226890Sdim *    may be used to endorse or promote products derived from this software
20218893Sdim *    without specific prior written permission.
21193326Sed *
22193326Sed * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23193326Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24221345Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25221345Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26193326Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27193326Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28207619Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29207619Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30193326Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31207619Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32193326Sed * SUCH DAMAGE.
33218893Sdim */
34193326Sed
35193326Sed#ifndef lint
36193326Sedstatic const char copyright[] =
37226890Sdim"@(#) Copyright (c) 1988 Regents of the University of California.\n\
38226890Sdim All rights reserved.\n";
39193326Sed#endif /* not lint */
40193326Sed
41193326Sed#ifndef lint
42193326Sedstatic const char sccsid[] = "from: @(#)wall.c	5.14 (Berkeley) 3/2/91";
43193326Sed#endif
44193326Sed
45210299Sed#include <sys/cdefs.h>
46210299Sed__FBSDID("$FreeBSD: stable/11/usr.bin/rwall/rwall.c 227180 2011-11-06 08:16:53Z ed $");
47226890Sdim
48193326Sed/*
49193326Sed * This program is not related to David Wall, whose Stanford Ph.D. thesis
50193326Sed * is entitled "Mechanisms for Broadcast and Selective Broadcast".
51193326Sed */
52193326Sed
53193326Sed#include <sys/param.h>
54198398Srdivacky#include <sys/stat.h>
55198092Srdivacky#include <sys/uio.h>
56198092Srdivacky#include <rpc/rpc.h>
57195341Sed#include <rpcsvc/rwall.h>
58199990Srdivacky#include <err.h>
59207619Srdivacky#include <paths.h>
60226890Sdim#include <pwd.h>
61226890Sdim#include <stdio.h>
62226890Sdim#include <stdlib.h>
63193326Sed#include <string.h>
64193326Sed#include <time.h>
65193326Sed#include <unistd.h>
66193326Sed
67199482Srdivackystatic char *mbuf;
68193326Sed
69218893Sdimstatic char notty[] = "no tty";
70226890Sdim
71226890Sdimstatic void	makemsg(const char *);
72208600Srdivackystatic void usage(void);
73210299Sed
74210299Sed/* ARGSUSED */
75210299Sedint
76212904Sdimmain(int argc, char *argv[])
77212904Sdim{
78212904Sdim	char *wallhost, res;
79221345Sdim	CLIENT *cl;
80221345Sdim	struct timeval tv;
81221345Sdim
82221345Sdim	if ((argc < 2) || (argc > 3))
83221345Sdim		usage();
84221345Sdim
85221345Sdim	wallhost = argv[1];
86193326Sed
87193326Sed	makemsg(argv[2]);
88193326Sed
89193326Sed	/*
90193326Sed	 * Create client "handle" used for calling MESSAGEPROG on the
91193326Sed	 * server designated on the command line. We tell the rpc package
92193326Sed	 * to use the "tcp" protocol when contacting the server.
93193326Sed	*/
94193326Sed	cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp");
95226890Sdim	if (cl == NULL) {
96193326Sed		/*
97193326Sed		 * Couldn't establish connection with server.
98193326Sed		 * Print error message and die.
99193326Sed		 */
100193326Sed		errx(1, "%s", clnt_spcreateerror(wallhost));
101193326Sed	}
102193326Sed
103193326Sed	tv.tv_sec = 15;		/* XXX ?? */
104193326Sed	tv.tv_usec = 0;
105193326Sed	if (clnt_call(cl, WALLPROC_WALL, (xdrproc_t)xdr_wrapstring, &mbuf,
106193326Sed	    (xdrproc_t)xdr_void, &res, tv) != RPC_SUCCESS) {
107198398Srdivacky		/*
108198398Srdivacky		 * An error occurred while calling the server.
109198398Srdivacky		 * Print error message and die.
110198398Srdivacky		 */
111226890Sdim		errx(1, "%s", clnt_sperror(cl, wallhost));
112198398Srdivacky	}
113198398Srdivacky
114198398Srdivacky	return (0);
115198398Srdivacky}
116198398Srdivacky
117198398Srdivackystatic void
118198398Srdivackyusage(void)
119198398Srdivacky{
120198398Srdivacky	fprintf(stderr, "usage: rwall host [file]\n");
121198398Srdivacky	exit(1);
122198398Srdivacky}
123218893Sdim
124198398Srdivackystatic void
125198398Srdivackymakemsg(const char *fname)
126198398Srdivacky{
127226890Sdim	struct tm *lt;
128199482Srdivacky	struct passwd *pw;
129198398Srdivacky	struct stat sbuf;
130199482Srdivacky	time_t now;
131198398Srdivacky	FILE *fp;
132199482Srdivacky	int fd;
133198398Srdivacky	size_t mbufsize;
134199482Srdivacky	char *tty, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64];
135198398Srdivacky	const char *whom;
136198398Srdivacky
137198398Srdivacky	snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP);
138198398Srdivacky	if ((fd = mkstemp(tmpname)) == -1 || (fp = fdopen(fd, "r+")) == NULL)
139218893Sdim		err(1, "can't open temporary file");
140199482Srdivacky	unlink(tmpname);
141199482Srdivacky
142199482Srdivacky	whom = getlogin();
143226890Sdim	if (!whom) {
144199482Srdivacky		pw = getpwuid(getuid());
145199482Srdivacky		whom = pw ? pw->pw_name : "???";
146199482Srdivacky	}
147199482Srdivacky	gethostname(hostname, sizeof(hostname));
148199482Srdivacky	time(&now);
149199482Srdivacky	lt = localtime(&now);
150199482Srdivacky
151199482Srdivacky	/*
152199482Srdivacky	 * all this stuff is to blank out a square for the message;
153199482Srdivacky	 * we wrap message lines at column 79, not 80, because some
154199482Srdivacky	 * terminals wrap after 79, some do not, and we can't tell.
155198893Srdivacky	 * Which means that we may leave a non-blank character
156198398Srdivacky	 * in column 80, but that can't be helped.
157218893Sdim	 */
158198398Srdivacky	fprintf(fp, "Remote Broadcast Message from %s@%s\n",
159226890Sdim	    whom, hostname);
160198398Srdivacky	tty = ttyname(STDERR_FILENO);
161198398Srdivacky	if (tty == NULL)
162198398Srdivacky		tty = notty;
163218893Sdim	fprintf(fp, "        (%s) at %d:%02d ...\n", tty,
164198398Srdivacky	    lt->tm_hour, lt->tm_min);
165198398Srdivacky
166198398Srdivacky	putc('\n', fp);
167198398Srdivacky
168218893Sdim	if (fname && !(freopen(fname, "r", stdin)))
169198398Srdivacky		err(1, "can't read %s", fname);
170198398Srdivacky	while (fgets(lbuf, sizeof(lbuf), stdin))
171198398Srdivacky		fputs(lbuf, fp);
172198398Srdivacky	rewind(fp);
173199482Srdivacky
174199482Srdivacky	if (fstat(fd, &sbuf))
175199482Srdivacky		err(1, "can't stat temporary file");
176199482Srdivacky	mbufsize = (size_t)sbuf.st_size;
177207619Srdivacky	mbuf = malloc(mbufsize);
178207619Srdivacky	if (mbuf == NULL)
179207619Srdivacky		err(1, "out of memory");
180199482Srdivacky	if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != (u_int)mbufsize)
181199482Srdivacky		err(1, "can't read temporary file");
182198398Srdivacky	close(fd);
183193326Sed}
184193326Sed