rwall.c revision 69231
12347Scsgr/* 22347Scsgr * Copyright (c) 1993 Christopher G. Demetriou 32347Scsgr * Copyright (c) 1988, 1990 Regents of the University of California. 42347Scsgr * All rights reserved. 52347Scsgr * 62347Scsgr * Redistribution and use in source and binary forms, with or without 72347Scsgr * modification, are permitted provided that the following conditions 82347Scsgr * are met: 92347Scsgr * 1. Redistributions of source code must retain the above copyright 102347Scsgr * notice, this list of conditions and the following disclaimer. 112347Scsgr * 2. Redistributions in binary form must reproduce the above copyright 122347Scsgr * notice, this list of conditions and the following disclaimer in the 132347Scsgr * documentation and/or other materials provided with the distribution. 142347Scsgr * 3. All advertising materials mentioning features or use of this software 152347Scsgr * must display the following acknowledgement: 162347Scsgr * This product includes software developed by the University of 172347Scsgr * California, Berkeley and its contributors. 182347Scsgr * 4. Neither the name of the University nor the names of its contributors 192347Scsgr * may be used to endorse or promote products derived from this software 202347Scsgr * without specific prior written permission. 212347Scsgr * 222347Scsgr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 232347Scsgr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 242347Scsgr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 252347Scsgr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 262347Scsgr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 272347Scsgr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 282347Scsgr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 292347Scsgr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 302347Scsgr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 312347Scsgr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 322347Scsgr * SUCH DAMAGE. 332347Scsgr */ 342347Scsgr 352347Scsgr#ifndef lint 3627977Scharnierstatic const char copyright[] = 372347Scsgr"@(#) Copyright (c) 1988 Regents of the University of California.\n\ 382347Scsgr All rights reserved.\n"; 392347Scsgr#endif /* not lint */ 402347Scsgr 412347Scsgr#ifndef lint 4227977Scharnier#if 0 4327977Scharnierstatic char sccsid[] = "from: @(#)wall.c 5.14 (Berkeley) 3/2/91"; 4427977Scharnier#endif 4527977Scharnierstatic const char rcsid[] = 4650477Speter "$FreeBSD: head/usr.bin/rwall/rwall.c 69231 2000-11-26 22:36:35Z kris $"; 472347Scsgr#endif /* not lint */ 482347Scsgr 492347Scsgr/* 502347Scsgr * This program is not related to David Wall, whose Stanford Ph.D. thesis 512347Scsgr * is entitled "Mechanisms for Broadcast and Selective Broadcast". 522347Scsgr */ 532347Scsgr 542347Scsgr#include <sys/param.h> 552347Scsgr#include <sys/stat.h> 562347Scsgr#include <sys/time.h> 572347Scsgr#include <sys/uio.h> 5827977Scharnier#include <err.h> 5927977Scharnier#include <paths.h> 602347Scsgr#include <pwd.h> 612347Scsgr#include <stdio.h> 622347Scsgr#include <stdlib.h> 6327977Scharnier#include <string.h> 6469231Skris#include <time.h> 6527977Scharnier#include <unistd.h> 6627977Scharnier#include <utmp.h> 672347Scsgr 682347Scsgr#include <rpc/rpc.h> 692347Scsgr#include <rpcsvc/rwall.h> 702347Scsgr 712347Scsgrint mbufsize; 722347Scsgrchar *mbuf; 732347Scsgr 7469231Skrisvoid makemsg __P((char *)); 7527977Scharnierstatic void usage __P((void)); 7669231Skrischar *ttymsg __P((struct iovec *, int, char *, int)); 7727977Scharnier 782347Scsgr/* ARGSUSED */ 7927977Scharnierint 802347Scsgrmain(argc, argv) 812347Scsgr int argc; 822347Scsgr char **argv; 832347Scsgr{ 842347Scsgr char *wallhost, res; 852347Scsgr CLIENT *cl; 8621095Speter struct timeval tv; 872347Scsgr 8827977Scharnier if ((argc < 2) || (argc > 3)) 8927977Scharnier usage(); 902347Scsgr 912347Scsgr wallhost = argv[1]; 922347Scsgr 932347Scsgr makemsg(argv[2]); 942347Scsgr 952347Scsgr /* 962347Scsgr * Create client "handle" used for calling MESSAGEPROG on the 972347Scsgr * server designated on the command line. We tell the rpc package 982347Scsgr * to use the "tcp" protocol when contacting the server. 992347Scsgr */ 1002347Scsgr cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp"); 1012347Scsgr if (cl == NULL) { 1022347Scsgr /* 1032347Scsgr * Couldn't establish connection with server. 1042347Scsgr * Print error message and die. 1052347Scsgr */ 10627977Scharnier errx(1, "%s", clnt_spcreateerror(wallhost)); 1072347Scsgr } 1082347Scsgr 10921095Speter tv.tv_sec = 15; /* XXX ?? */ 11021095Speter tv.tv_usec = 0; 11121095Speter if (clnt_call(cl, WALLPROC_WALL, xdr_wrapstring, &mbuf, xdr_void, &res, tv) != RPC_SUCCESS) { 1122347Scsgr /* 1138874Srgrimes * An error occurred while calling the server. 1142347Scsgr * Print error message and die. 1152347Scsgr */ 11627977Scharnier errx(1, "%s", clnt_sperror(cl, wallhost)); 1172347Scsgr } 1182347Scsgr 1192347Scsgr exit(0); 1202347Scsgr} 1212347Scsgr 12227977Scharnierstatic void 12327977Scharnierusage() 12427977Scharnier{ 12569231Skris (void)fprintf(stderr, "usage: rwall hostname [file]\n"); 12627977Scharnier exit(1); 12727977Scharnier} 12827977Scharnier 12927977Scharniervoid 1302347Scsgrmakemsg(fname) 1312347Scsgr char *fname; 1322347Scsgr{ 1332347Scsgr struct tm *lt; 1342347Scsgr struct passwd *pw; 1352347Scsgr struct stat sbuf; 13669231Skris time_t now; 1372347Scsgr FILE *fp; 1382347Scsgr int fd; 13969231Skris char *tty, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64]; 14069231Skris const char *whom; 1412347Scsgr 14269231Skris (void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); 14369231Skris if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+"))) 14469231Skris err(1, "can't open temporary file"); 1452347Scsgr (void)unlink(tmpname); 1462347Scsgr 1472347Scsgr if (!(whom = getlogin())) 1482347Scsgr whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; 1492347Scsgr (void)gethostname(hostname, sizeof(hostname)); 1502347Scsgr (void)time(&now); 1512347Scsgr lt = localtime(&now); 1522347Scsgr 1532347Scsgr /* 1542347Scsgr * all this stuff is to blank out a square for the message; 1552347Scsgr * we wrap message lines at column 79, not 80, because some 1562347Scsgr * terminals wrap after 79, some do not, and we can't tell. 1572347Scsgr * Which means that we may leave a non-blank character 1582347Scsgr * in column 80, but that can't be helped. 1592347Scsgr */ 1602347Scsgr (void)fprintf(fp, "Remote Broadcast Message from %s@%s\n", 1612347Scsgr whom, hostname); 16269231Skris tty = ttyname(STDERR_FILENO); 16369231Skris if (tty == NULL) 16469231Skris tty = "no tty"; 16569231Skris (void)fprintf(fp, " (%s) at %d:%02d ...\n", tty, 1662347Scsgr lt->tm_hour, lt->tm_min); 1672347Scsgr 1682347Scsgr putc('\n', fp); 1692347Scsgr 17027977Scharnier if (fname && !(freopen(fname, "r", stdin))) 17169231Skris err(1, "can't read %s", fname); 1722347Scsgr while (fgets(lbuf, sizeof(lbuf), stdin)) 1732347Scsgr fputs(lbuf, fp); 1742347Scsgr rewind(fp); 1752347Scsgr 17627977Scharnier if (fstat(fd, &sbuf)) 17769231Skris err(1, "can't stat temporary file"); 1782347Scsgr mbufsize = sbuf.st_size; 17927977Scharnier if (!(mbuf = malloc((u_int)mbufsize))) 18069231Skris err(1, "out of memory"); 18127977Scharnier if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) 18269231Skris err(1, "can't read temporary file"); 1832347Scsgr (void)close(fd); 1842347Scsgr} 185