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