rwall.c revision 91643
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 3591643Smarkm#include <sys/cdefs.h> 3691643Smarkm 3791643Smarkm__FBSDID("$FreeBSD: head/usr.bin/rwall/rwall.c 91643 2002-03-04 20:27:38Z markm $"); 3891643Smarkm 392347Scsgr#ifndef lint 4027977Scharnierstatic const char copyright[] = 412347Scsgr"@(#) Copyright (c) 1988 Regents of the University of California.\n\ 422347Scsgr All rights reserved.\n"; 432347Scsgr#endif /* not lint */ 442347Scsgr 452347Scsgr#ifndef lint 4691643Smarkmstatic const char sccsid[] = "from: @(#)wall.c 5.14 (Berkeley) 3/2/91"; 4727977Scharnier#endif 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/uio.h> 5791643Smarkm#include <rpc/rpc.h> 5891643Smarkm#include <rpcsvc/rwall.h> 5927977Scharnier#include <err.h> 6027977Scharnier#include <paths.h> 612347Scsgr#include <pwd.h> 622347Scsgr#include <stdio.h> 632347Scsgr#include <stdlib.h> 6427977Scharnier#include <string.h> 6569231Skris#include <time.h> 6627977Scharnier#include <unistd.h> 672347Scsgr 682347Scsgrchar *mbuf; 692347Scsgr 7091643Smarkmstatic char notty[] = "no tty"; 7127977Scharnier 7291643Smarkmvoid makemsg(const char *); 7391643Smarkmstatic void usage(void); 7491643Smarkm 752347Scsgr/* ARGSUSED */ 7627977Scharnierint 7791643Smarkmmain(int argc, char *argv[]) 782347Scsgr{ 792347Scsgr char *wallhost, res; 802347Scsgr CLIENT *cl; 8121095Speter struct timeval tv; 822347Scsgr 8327977Scharnier if ((argc < 2) || (argc > 3)) 8427977Scharnier usage(); 852347Scsgr 862347Scsgr wallhost = argv[1]; 872347Scsgr 882347Scsgr makemsg(argv[2]); 892347Scsgr 902347Scsgr /* 912347Scsgr * Create client "handle" used for calling MESSAGEPROG on the 922347Scsgr * server designated on the command line. We tell the rpc package 932347Scsgr * to use the "tcp" protocol when contacting the server. 942347Scsgr */ 952347Scsgr cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp"); 962347Scsgr if (cl == NULL) { 972347Scsgr /* 982347Scsgr * Couldn't establish connection with server. 992347Scsgr * Print error message and die. 1002347Scsgr */ 10127977Scharnier errx(1, "%s", clnt_spcreateerror(wallhost)); 1022347Scsgr } 1032347Scsgr 10421095Speter tv.tv_sec = 15; /* XXX ?? */ 10521095Speter tv.tv_usec = 0; 10691643Smarkm if (clnt_call(cl, WALLPROC_WALL, xdr_wrapstring, &mbuf, xdr_void, 10791643Smarkm &res, tv) != RPC_SUCCESS) { 1082347Scsgr /* 1098874Srgrimes * An error occurred while calling the server. 1102347Scsgr * Print error message and die. 1112347Scsgr */ 11227977Scharnier errx(1, "%s", clnt_sperror(cl, wallhost)); 1132347Scsgr } 1142347Scsgr 11591643Smarkm return (0); 1162347Scsgr} 1172347Scsgr 11827977Scharnierstatic void 11991643Smarkmusage(void) 12027977Scharnier{ 12191643Smarkm fprintf(stderr, "usage: rwall hostname [file]\n"); 12227977Scharnier exit(1); 12327977Scharnier} 12427977Scharnier 12527977Scharniervoid 12691643Smarkmmakemsg(const char *fname) 1272347Scsgr{ 1282347Scsgr struct tm *lt; 1292347Scsgr struct passwd *pw; 1302347Scsgr struct stat sbuf; 13169231Skris time_t now; 1322347Scsgr FILE *fp; 1332347Scsgr int fd; 13491643Smarkm size_t mbufsize; 13569231Skris char *tty, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64]; 13669231Skris const char *whom; 1372347Scsgr 13891643Smarkm snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); 13991643Smarkm fd = mkstemp(tmpname); 14091643Smarkm fp = fdopen(fd, "r+"); 14191643Smarkm if (fd == -1 || !fp) 14269231Skris err(1, "can't open temporary file"); 14391643Smarkm unlink(tmpname); 1442347Scsgr 14591643Smarkm whom = getlogin(); 14691643Smarkm if (!whom) { 14791643Smarkm pw = getpwuid(getuid()); 14891643Smarkm whom = pw ? pw->pw_name : "???"; 14991643Smarkm } 15091643Smarkm gethostname(hostname, sizeof(hostname)); 15191643Smarkm time(&now); 1522347Scsgr lt = localtime(&now); 1532347Scsgr 1542347Scsgr /* 1552347Scsgr * all this stuff is to blank out a square for the message; 1562347Scsgr * we wrap message lines at column 79, not 80, because some 1572347Scsgr * terminals wrap after 79, some do not, and we can't tell. 1582347Scsgr * Which means that we may leave a non-blank character 1592347Scsgr * in column 80, but that can't be helped. 1602347Scsgr */ 16191643Smarkm fprintf(fp, "Remote Broadcast Message from %s@%s\n", 1622347Scsgr whom, hostname); 16369231Skris tty = ttyname(STDERR_FILENO); 16469231Skris if (tty == NULL) 16591643Smarkm tty = notty; 16691643Smarkm fprintf(fp, " (%s) at %d:%02d ...\n", tty, 1672347Scsgr lt->tm_hour, lt->tm_min); 1682347Scsgr 1692347Scsgr putc('\n', fp); 1702347Scsgr 17127977Scharnier if (fname && !(freopen(fname, "r", stdin))) 17269231Skris err(1, "can't read %s", fname); 1732347Scsgr while (fgets(lbuf, sizeof(lbuf), stdin)) 1742347Scsgr fputs(lbuf, fp); 1752347Scsgr rewind(fp); 1762347Scsgr 17727977Scharnier if (fstat(fd, &sbuf)) 17869231Skris err(1, "can't stat temporary file"); 17991643Smarkm mbufsize = (size_t)sbuf.st_size; 18091643Smarkm mbuf = malloc(mbufsize); 18191643Smarkm if (mbuf == NULL) 18269231Skris err(1, "out of memory"); 18327977Scharnier if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) 18469231Skris err(1, "can't read temporary file"); 18591643Smarkm close(fd); 1862347Scsgr} 187