1 /* 2 * Copyright (c) 1993 Christopher G. Demetriou 3 * Copyright (c) 1988, 1990 Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#) Copyright (c) 1988 Regents of the University of California. All rights reserved. 35 * @(#)wall.c 5.14 (Berkeley) 3/2/91 36 * $FreeBSD: src/usr.bin/rwall/rwall.c,v 1.8.2.1 2001/02/18 02:27:54 kris Exp $ 37 * $DragonFly: src/usr.bin/rwall/rwall.c,v 1.3 2003/11/03 19:31:32 eirikn Exp $ 38 */ 39 40 /* 41 * This program is not related to David Wall, whose Stanford Ph.D. thesis 42 * is entitled "Mechanisms for Broadcast and Selective Broadcast". 43 */ 44 45 #include <sys/param.h> 46 #include <sys/stat.h> 47 #include <sys/time.h> 48 #include <sys/uio.h> 49 #include <err.h> 50 #include <paths.h> 51 #include <pwd.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <time.h> 56 #include <unistd.h> 57 #include <utmp.h> 58 59 #include <rpc/rpc.h> 60 #include <rpcsvc/rwall.h> 61 62 int mbufsize; 63 char *mbuf; 64 65 void makemsg(char *); 66 static void usage(void); 67 char *ttymsg(struct iovec *, int, char *, int); 68 69 /* ARGSUSED */ 70 int 71 main(argc, argv) 72 int argc; 73 char **argv; 74 { 75 char *wallhost, res; 76 CLIENT *cl; 77 struct timeval tv; 78 79 if ((argc < 2) || (argc > 3)) 80 usage(); 81 82 wallhost = argv[1]; 83 84 makemsg(argv[2]); 85 86 /* 87 * Create client "handle" used for calling MESSAGEPROG on the 88 * server designated on the command line. We tell the rpc package 89 * to use the "tcp" protocol when contacting the server. 90 */ 91 cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp"); 92 if (cl == NULL) { 93 /* 94 * Couldn't establish connection with server. 95 * Print error message and die. 96 */ 97 errx(1, "%s", clnt_spcreateerror(wallhost)); 98 } 99 100 tv.tv_sec = 15; /* XXX ?? */ 101 tv.tv_usec = 0; 102 if (clnt_call(cl, WALLPROC_WALL, xdr_wrapstring, &mbuf, xdr_void, &res, tv) != RPC_SUCCESS) { 103 /* 104 * An error occurred while calling the server. 105 * Print error message and die. 106 */ 107 errx(1, "%s", clnt_sperror(cl, wallhost)); 108 } 109 110 exit(0); 111 } 112 113 static void 114 usage() 115 { 116 (void)fprintf(stderr, "usage: rwall hostname [file]\n"); 117 exit(1); 118 } 119 120 void 121 makemsg(fname) 122 char *fname; 123 { 124 struct tm *lt; 125 struct passwd *pw; 126 struct stat sbuf; 127 time_t now; 128 FILE *fp; 129 int fd; 130 char *tty, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64]; 131 const char *whom; 132 133 (void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); 134 if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+"))) 135 err(1, "can't open temporary file"); 136 (void)unlink(tmpname); 137 138 if (!(whom = getlogin())) 139 whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; 140 (void)gethostname(hostname, sizeof(hostname)); 141 (void)time(&now); 142 lt = localtime(&now); 143 144 /* 145 * all this stuff is to blank out a square for the message; 146 * we wrap message lines at column 79, not 80, because some 147 * terminals wrap after 79, some do not, and we can't tell. 148 * Which means that we may leave a non-blank character 149 * in column 80, but that can't be helped. 150 */ 151 (void)fprintf(fp, "Remote Broadcast Message from %s@%s\n", 152 whom, hostname); 153 tty = ttyname(STDERR_FILENO); 154 if (tty == NULL) 155 tty = "no tty"; 156 (void)fprintf(fp, " (%s) at %d:%02d ...\n", tty, 157 lt->tm_hour, lt->tm_min); 158 159 putc('\n', fp); 160 161 if (fname && !(freopen(fname, "r", stdin))) 162 err(1, "can't read %s", fname); 163 while (fgets(lbuf, sizeof(lbuf), stdin)) 164 fputs(lbuf, fp); 165 rewind(fp); 166 167 if (fstat(fd, &sbuf)) 168 err(1, "can't stat temporary file"); 169 mbufsize = sbuf.st_size; 170 if (!(mbuf = malloc((u_int)mbufsize))) 171 err(1, "out of memory"); 172 if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) 173 err(1, "can't read temporary file"); 174 (void)close(fd); 175 } 176