rwall.c revision 21095
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 362347Scsgrchar 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 422347Scsgr/*static char sccsid[] = "from: @(#)wall.c 5.14 (Berkeley) 3/2/91";*/ 4321095Speterstatic char rcsid[] = "$Id: rwall.c,v 1.2 1995/05/30 06:33:30 rgrimes Exp $"; 442347Scsgr#endif /* not lint */ 452347Scsgr 462347Scsgr/* 472347Scsgr * This program is not related to David Wall, whose Stanford Ph.D. thesis 482347Scsgr * is entitled "Mechanisms for Broadcast and Selective Broadcast". 492347Scsgr */ 502347Scsgr 512347Scsgr#include <sys/param.h> 522347Scsgr#include <sys/stat.h> 532347Scsgr#include <sys/time.h> 542347Scsgr#include <sys/uio.h> 552347Scsgr#include <utmp.h> 562347Scsgr#include <pwd.h> 572347Scsgr#include <stdio.h> 582347Scsgr#include <stdlib.h> 592347Scsgr#include <paths.h> 602347Scsgr 612347Scsgr#include <rpc/rpc.h> 622347Scsgr#include <rpcsvc/rwall.h> 632347Scsgr 642347Scsgrint mbufsize; 652347Scsgrchar *mbuf; 662347Scsgr 672347Scsgr/* ARGSUSED */ 682347Scsgrmain(argc, argv) 692347Scsgr int argc; 702347Scsgr char **argv; 712347Scsgr{ 722347Scsgr char *wallhost, res; 732347Scsgr CLIENT *cl; 7421095Speter struct timeval tv; 752347Scsgr 762347Scsgr if ((argc < 2) || (argc > 3)) { 772347Scsgr fprintf(stderr, "usage: %s hostname [file]\n", argv[0]); 782347Scsgr exit(1); 792347Scsgr } 802347Scsgr 812347Scsgr wallhost = argv[1]; 822347Scsgr 832347Scsgr makemsg(argv[2]); 842347Scsgr 852347Scsgr /* 862347Scsgr * Create client "handle" used for calling MESSAGEPROG on the 872347Scsgr * server designated on the command line. We tell the rpc package 882347Scsgr * to use the "tcp" protocol when contacting the server. 892347Scsgr */ 902347Scsgr cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp"); 912347Scsgr if (cl == NULL) { 922347Scsgr /* 932347Scsgr * Couldn't establish connection with server. 942347Scsgr * Print error message and die. 952347Scsgr */ 962347Scsgr clnt_pcreateerror(wallhost); 972347Scsgr exit(1); 982347Scsgr } 992347Scsgr 10021095Speter tv.tv_sec = 15; /* XXX ?? */ 10121095Speter tv.tv_usec = 0; 10221095Speter if (clnt_call(cl, WALLPROC_WALL, xdr_wrapstring, &mbuf, xdr_void, &res, tv) != RPC_SUCCESS) { 1032347Scsgr /* 1048874Srgrimes * An error occurred while calling the server. 1052347Scsgr * Print error message and die. 1062347Scsgr */ 1072347Scsgr clnt_perror(cl, wallhost); 1082347Scsgr exit(1); 1092347Scsgr } 1102347Scsgr 1112347Scsgr exit(0); 1122347Scsgr} 1132347Scsgr 1142347Scsgrmakemsg(fname) 1152347Scsgr char *fname; 1162347Scsgr{ 1172347Scsgr register int ch, cnt; 1182347Scsgr struct tm *lt; 1192347Scsgr struct passwd *pw; 1202347Scsgr struct stat sbuf; 1212347Scsgr time_t now, time(); 1222347Scsgr FILE *fp; 1232347Scsgr int fd; 1242347Scsgr char *p, *whom, hostname[MAXHOSTNAMELEN], lbuf[100], tmpname[15]; 1252347Scsgr char *getlogin(), *strcpy(), *ttyname(); 1262347Scsgr 1272347Scsgr (void)strcpy(tmpname, _PATH_TMP); 1282347Scsgr (void)strcat(tmpname, "/wall.XXXXXX"); 1292347Scsgr if (!(fd = mkstemp(tmpname)) || !(fp = fdopen(fd, "r+"))) { 1302347Scsgr (void)fprintf(stderr, "wall: can't open temporary file.\n"); 1312347Scsgr exit(1); 1322347Scsgr } 1332347Scsgr (void)unlink(tmpname); 1342347Scsgr 1352347Scsgr if (!(whom = getlogin())) 1362347Scsgr whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; 1372347Scsgr (void)gethostname(hostname, sizeof(hostname)); 1382347Scsgr (void)time(&now); 1392347Scsgr lt = localtime(&now); 1402347Scsgr 1412347Scsgr /* 1422347Scsgr * all this stuff is to blank out a square for the message; 1432347Scsgr * we wrap message lines at column 79, not 80, because some 1442347Scsgr * terminals wrap after 79, some do not, and we can't tell. 1452347Scsgr * Which means that we may leave a non-blank character 1462347Scsgr * in column 80, but that can't be helped. 1472347Scsgr */ 1482347Scsgr (void)fprintf(fp, "Remote Broadcast Message from %s@%s\n", 1492347Scsgr whom, hostname); 1502347Scsgr (void)fprintf(fp, " (%s) at %d:%02d ...\n", ttyname(2), 1512347Scsgr lt->tm_hour, lt->tm_min); 1522347Scsgr 1532347Scsgr putc('\n', fp); 1542347Scsgr 1552347Scsgr if (fname && !(freopen(fname, "r", stdin))) { 1562347Scsgr (void)fprintf(stderr, "wall: can't read %s.\n", fname); 1572347Scsgr exit(1); 1582347Scsgr } 1592347Scsgr while (fgets(lbuf, sizeof(lbuf), stdin)) 1602347Scsgr fputs(lbuf, fp); 1612347Scsgr rewind(fp); 1622347Scsgr 1632347Scsgr if (fstat(fd, &sbuf)) { 1642347Scsgr (void)fprintf(stderr, "wall: can't stat temporary file.\n"); 1652347Scsgr exit(1); 1662347Scsgr } 1672347Scsgr mbufsize = sbuf.st_size; 1682347Scsgr if (!(mbuf = malloc((u_int)mbufsize))) { 1692347Scsgr (void)fprintf(stderr, "wall: out of memory.\n"); 1702347Scsgr exit(1); 1712347Scsgr } 1722347Scsgr if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) { 1732347Scsgr (void)fprintf(stderr, "wall: can't read temporary file.\n"); 1742347Scsgr exit(1); 1752347Scsgr } 1762347Scsgr (void)close(fd); 1772347Scsgr} 178