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 4291643Smarkmstatic const char sccsid[] = "from: @(#)wall.c 5.14 (Berkeley) 3/2/91"; 4327977Scharnier#endif 442347Scsgr 4591808Smarkm#include <sys/cdefs.h> 4691808Smarkm__FBSDID("$FreeBSD$"); 4791808Smarkm 482347Scsgr/* 492347Scsgr * This program is not related to David Wall, whose Stanford Ph.D. thesis 502347Scsgr * is entitled "Mechanisms for Broadcast and Selective Broadcast". 512347Scsgr */ 522347Scsgr 532347Scsgr#include <sys/param.h> 542347Scsgr#include <sys/stat.h> 552347Scsgr#include <sys/uio.h> 5691643Smarkm#include <rpc/rpc.h> 5791643Smarkm#include <rpcsvc/rwall.h> 5827977Scharnier#include <err.h> 5927977Scharnier#include <paths.h> 602347Scsgr#include <pwd.h> 612347Scsgr#include <stdio.h> 622347Scsgr#include <stdlib.h> 63200462Sdelphij#include <string.h> 6469231Skris#include <time.h> 6527977Scharnier#include <unistd.h> 662347Scsgr 67227180Sedstatic char *mbuf; 682347Scsgr 6991643Smarkmstatic char notty[] = "no tty"; 7027977Scharnier 71227180Sedstatic void makemsg(const char *); 7291643Smarkmstatic void usage(void); 7391643Smarkm 742347Scsgr/* ARGSUSED */ 7527977Scharnierint 7691643Smarkmmain(int argc, char *argv[]) 772347Scsgr{ 782347Scsgr char *wallhost, res; 792347Scsgr CLIENT *cl; 8021095Speter struct timeval tv; 812347Scsgr 8227977Scharnier if ((argc < 2) || (argc > 3)) 8327977Scharnier usage(); 842347Scsgr 852347Scsgr wallhost = argv[1]; 862347Scsgr 872347Scsgr makemsg(argv[2]); 882347Scsgr 892347Scsgr /* 902347Scsgr * Create client "handle" used for calling MESSAGEPROG on the 912347Scsgr * server designated on the command line. We tell the rpc package 922347Scsgr * to use the "tcp" protocol when contacting the server. 932347Scsgr */ 942347Scsgr cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp"); 952347Scsgr if (cl == NULL) { 962347Scsgr /* 972347Scsgr * Couldn't establish connection with server. 982347Scsgr * Print error message and die. 992347Scsgr */ 10027977Scharnier errx(1, "%s", clnt_spcreateerror(wallhost)); 1012347Scsgr } 1022347Scsgr 10321095Speter tv.tv_sec = 15; /* XXX ?? */ 10421095Speter tv.tv_usec = 0; 105121545Speter if (clnt_call(cl, WALLPROC_WALL, (xdrproc_t)xdr_wrapstring, &mbuf, 106121545Speter (xdrproc_t)xdr_void, &res, tv) != RPC_SUCCESS) { 1072347Scsgr /* 1088874Srgrimes * An error occurred while calling the server. 1092347Scsgr * Print error message and die. 1102347Scsgr */ 11127977Scharnier errx(1, "%s", clnt_sperror(cl, wallhost)); 1122347Scsgr } 1132347Scsgr 11491643Smarkm return (0); 1152347Scsgr} 1162347Scsgr 11727977Scharnierstatic void 11891643Smarkmusage(void) 11927977Scharnier{ 120146466Sru fprintf(stderr, "usage: rwall host [file]\n"); 12127977Scharnier exit(1); 12227977Scharnier} 12327977Scharnier 124227180Sedstatic void 12591643Smarkmmakemsg(const char *fname) 1262347Scsgr{ 1272347Scsgr struct tm *lt; 1282347Scsgr struct passwd *pw; 1292347Scsgr struct stat sbuf; 13069231Skris time_t now; 1312347Scsgr FILE *fp; 1322347Scsgr int fd; 13391643Smarkm size_t mbufsize; 13469231Skris char *tty, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64]; 13569231Skris const char *whom; 1362347Scsgr 13791643Smarkm snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); 13891808Smarkm if ((fd = mkstemp(tmpname)) == -1 || (fp = fdopen(fd, "r+")) == NULL) 13969231Skris err(1, "can't open temporary file"); 14091643Smarkm unlink(tmpname); 1412347Scsgr 14291643Smarkm whom = getlogin(); 14391643Smarkm if (!whom) { 14491643Smarkm pw = getpwuid(getuid()); 14591643Smarkm whom = pw ? pw->pw_name : "???"; 14691643Smarkm } 14791643Smarkm gethostname(hostname, sizeof(hostname)); 14891643Smarkm time(&now); 1492347Scsgr lt = localtime(&now); 1502347Scsgr 1512347Scsgr /* 1522347Scsgr * all this stuff is to blank out a square for the message; 1532347Scsgr * we wrap message lines at column 79, not 80, because some 1542347Scsgr * terminals wrap after 79, some do not, and we can't tell. 1552347Scsgr * Which means that we may leave a non-blank character 1562347Scsgr * in column 80, but that can't be helped. 1572347Scsgr */ 15891643Smarkm fprintf(fp, "Remote Broadcast Message from %s@%s\n", 1592347Scsgr whom, hostname); 16069231Skris tty = ttyname(STDERR_FILENO); 16169231Skris if (tty == NULL) 16291643Smarkm tty = notty; 16391643Smarkm fprintf(fp, " (%s) at %d:%02d ...\n", tty, 1642347Scsgr lt->tm_hour, lt->tm_min); 1652347Scsgr 1662347Scsgr putc('\n', fp); 1672347Scsgr 16827977Scharnier if (fname && !(freopen(fname, "r", stdin))) 16969231Skris err(1, "can't read %s", fname); 1702347Scsgr while (fgets(lbuf, sizeof(lbuf), stdin)) 1712347Scsgr fputs(lbuf, fp); 1722347Scsgr rewind(fp); 1732347Scsgr 17427977Scharnier if (fstat(fd, &sbuf)) 17569231Skris err(1, "can't stat temporary file"); 17691643Smarkm mbufsize = (size_t)sbuf.st_size; 17791643Smarkm mbuf = malloc(mbufsize); 17891643Smarkm if (mbuf == NULL) 17969231Skris err(1, "out of memory"); 180102944Sdwmalone if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != (u_int)mbufsize) 18169231Skris err(1, "can't read temporary file"); 18291643Smarkm close(fd); 1832347Scsgr} 184