1*98e5374cSlukem /* $NetBSD: rwall.c,v 1.17 2008/07/21 14:19:25 lukem Exp $ */
289aaa1bbSagc
389aaa1bbSagc /*
489aaa1bbSagc * Copyright (c) 1988, 1990 Regents of the University of California.
589aaa1bbSagc * All rights reserved.
689aaa1bbSagc *
789aaa1bbSagc * Redistribution and use in source and binary forms, with or without
889aaa1bbSagc * modification, are permitted provided that the following conditions
989aaa1bbSagc * are met:
1089aaa1bbSagc * 1. Redistributions of source code must retain the above copyright
1189aaa1bbSagc * notice, this list of conditions and the following disclaimer.
1289aaa1bbSagc * 2. Redistributions in binary form must reproduce the above copyright
1389aaa1bbSagc * notice, this list of conditions and the following disclaimer in the
1489aaa1bbSagc * documentation and/or other materials provided with the distribution.
1589aaa1bbSagc * 3. Neither the name of the University nor the names of its contributors
1689aaa1bbSagc * may be used to endorse or promote products derived from this software
1789aaa1bbSagc * without specific prior written permission.
1889aaa1bbSagc *
1989aaa1bbSagc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2089aaa1bbSagc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2189aaa1bbSagc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2289aaa1bbSagc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2389aaa1bbSagc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2489aaa1bbSagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2589aaa1bbSagc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2689aaa1bbSagc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2789aaa1bbSagc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2889aaa1bbSagc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2989aaa1bbSagc * SUCH DAMAGE.
3089aaa1bbSagc */
319d225a17Stls
3215cf8058Scgd /*
3315cf8058Scgd * Copyright (c) 1993 Christopher G. Demetriou
3415cf8058Scgd *
3515cf8058Scgd * Redistribution and use in source and binary forms, with or without
3615cf8058Scgd * modification, are permitted provided that the following conditions
3715cf8058Scgd * are met:
3815cf8058Scgd * 1. Redistributions of source code must retain the above copyright
3915cf8058Scgd * notice, this list of conditions and the following disclaimer.
4015cf8058Scgd * 2. Redistributions in binary form must reproduce the above copyright
4115cf8058Scgd * notice, this list of conditions and the following disclaimer in the
4215cf8058Scgd * documentation and/or other materials provided with the distribution.
4315cf8058Scgd * 3. All advertising materials mentioning features or use of this software
4415cf8058Scgd * must display the following acknowledgement:
4515cf8058Scgd * This product includes software developed by the University of
4615cf8058Scgd * California, Berkeley and its contributors.
4715cf8058Scgd * 4. Neither the name of the University nor the names of its contributors
4815cf8058Scgd * may be used to endorse or promote products derived from this software
4915cf8058Scgd * without specific prior written permission.
5015cf8058Scgd *
5115cf8058Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
5215cf8058Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5315cf8058Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5415cf8058Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5515cf8058Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5615cf8058Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5715cf8058Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5815cf8058Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5915cf8058Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6015cf8058Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6115cf8058Scgd * SUCH DAMAGE.
6215cf8058Scgd */
6315cf8058Scgd
64b65c70efSlukem #include <sys/cdefs.h>
6515cf8058Scgd #ifndef lint
66*98e5374cSlukem __COPYRIGHT("@(#) Copyright (c) 1988\
67*98e5374cSlukem Regents of the University of California. All rights reserved.");
6815cf8058Scgd #endif /* not lint */
6915cf8058Scgd
7015cf8058Scgd #ifndef lint
71b65c70efSlukem #if 0
72b65c70efSlukem static char sccsid[] = "from: @(#)wall.c 5.14 (Berkeley) 3/2/91";
73b65c70efSlukem #else
74*98e5374cSlukem __RCSID("$NetBSD: rwall.c,v 1.17 2008/07/21 14:19:25 lukem Exp $");
75b65c70efSlukem #endif
7615cf8058Scgd #endif /* not lint */
7715cf8058Scgd
7815cf8058Scgd /*
7915cf8058Scgd * This program is not related to David Wall, whose Stanford Ph.D. thesis
8015cf8058Scgd * is entitled "Mechanisms for Broadcast and Selective Broadcast".
8115cf8058Scgd */
82b65c70efSlukem #include <sys/types.h>
83b65c70efSlukem #include <sys/param.h>
84b65c70efSlukem #include <sys/stat.h>
85b65c70efSlukem #include <err.h>
86b65c70efSlukem #include <paths.h>
87b65c70efSlukem #include <pwd.h>
8815cf8058Scgd #include <stdio.h>
8915cf8058Scgd #include <stdlib.h>
902a455818Sjtc #include <string.h>
912a455818Sjtc #include <time.h>
922a455818Sjtc #include <unistd.h>
9315cf8058Scgd
9415cf8058Scgd #include <rpc/rpc.h>
9515cf8058Scgd #include <rpcsvc/rwall.h>
9615cf8058Scgd
9781c9862bSchristos static struct timeval timeout = { 25, 0 };
9815cf8058Scgd
9981c9862bSchristos static char *makemsg(const char *);
1002a455818Sjtc
1012a455818Sjtc int
main(int argc,char ** argv)10281c9862bSchristos main(int argc, char **argv)
10315cf8058Scgd {
1045f2b3676Sbrezak char *wallhost, res;
10515cf8058Scgd CLIENT *cl;
10681c9862bSchristos char *mbuf;
10781c9862bSchristos
10881c9862bSchristos setprogname(*argv);
10915cf8058Scgd
11015cf8058Scgd if ((argc < 2) || (argc > 3)) {
11181c9862bSchristos (void)fprintf(stderr,
11281c9862bSchristos "Usage: %s hostname <file>\n", getprogname());
11381c9862bSchristos return 1;
11415cf8058Scgd }
11515cf8058Scgd
11615cf8058Scgd wallhost = argv[1];
11715cf8058Scgd
11815cf8058Scgd /*
11915cf8058Scgd * Create client "handle" used for calling MESSAGEPROG on the
12015cf8058Scgd * server designated on the command line. We tell the rpc package
12115cf8058Scgd * to use the "tcp" protocol when contacting the server.
12215cf8058Scgd */
12315cf8058Scgd cl = clnt_create(wallhost, WALLPROG, WALLVERS, "udp");
12415cf8058Scgd if (cl == NULL) {
12515cf8058Scgd /*
12615cf8058Scgd * Couldn't establish connection with server.
12715cf8058Scgd * Print error message and die.
12815cf8058Scgd */
12915cf8058Scgd clnt_pcreateerror(wallhost);
13081c9862bSchristos return 1;
13115cf8058Scgd }
13215cf8058Scgd
13381c9862bSchristos mbuf = makemsg(argv[2]);
13481c9862bSchristos
13581c9862bSchristos if (clnt_call(cl, WALLPROC_WALL, xdr_wrapstring, (void *)&mbuf,
13681c9862bSchristos xdr_void, &res, timeout) != RPC_SUCCESS) {
13781c9862bSchristos free(mbuf);
13815cf8058Scgd /*
13915cf8058Scgd * An error occurred while calling the server.
14015cf8058Scgd * Print error message and die.
14115cf8058Scgd */
14215cf8058Scgd clnt_perror(cl, wallhost);
14381c9862bSchristos return 1;
14481c9862bSchristos }
14581c9862bSchristos free(mbuf);
14681c9862bSchristos return 0;
14715cf8058Scgd }
14815cf8058Scgd
14981c9862bSchristos static char *
makemsg(const char * fname)15081c9862bSchristos makemsg(const char *fname)
15115cf8058Scgd {
15215cf8058Scgd struct tm *lt;
15315cf8058Scgd struct passwd *pw;
15415cf8058Scgd struct stat sbuf;
1552a455818Sjtc time_t now;
15681c9862bSchristos size_t mbufsize;
15781c9862bSchristos char *mbuf;
15815cf8058Scgd FILE *fp;
15915cf8058Scgd int fd;
160cc06efc9Smycroft const char *whom;
16181c9862bSchristos const char *tty;
16281c9862bSchristos char tmpname[MAXPATHLEN], lbuf[BUFSIZ], hostname[MAXHOSTNAMELEN + 1];
16315cf8058Scgd
16481c9862bSchristos (void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP);
16579dbd4baSenami if ((fd = mkstemp(tmpname)) == -1 || (fp = fdopen(fd, "r+")) == NULL)
16681c9862bSchristos err(1, "Can't open temporary file");
16715cf8058Scgd (void)unlink(tmpname);
16815cf8058Scgd
16915cf8058Scgd if (!(whom = getlogin()))
17015cf8058Scgd whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
17115cf8058Scgd (void)gethostname(hostname, sizeof(hostname));
1722beab49aSmrg hostname[sizeof(hostname) - 1] = '\0';
17315cf8058Scgd (void)time(&now);
17415cf8058Scgd lt = localtime(&now);
17515cf8058Scgd
17615cf8058Scgd /*
17715cf8058Scgd * all this stuff is to blank out a square for the message;
17815cf8058Scgd * we wrap message lines at column 79, not 80, because some
17915cf8058Scgd * terminals wrap after 79, some do not, and we can't tell.
18015cf8058Scgd * Which means that we may leave a non-blank character
18115cf8058Scgd * in column 80, but that can't be helped.
18215cf8058Scgd */
18315cf8058Scgd (void)fprintf(fp, "Remote Broadcast Message from %s@%s\n",
18415cf8058Scgd whom, hostname);
18599ebb803Staca tty = ttyname(STDERR_FILENO);
18699ebb803Staca if (tty == NULL)
18720117cd1Staca tty = "??";
18820117cd1Staca (void)fprintf(fp, " (%s) at %d:%02d ...\n", tty, lt->tm_hour,
18920117cd1Staca lt->tm_min);
19015cf8058Scgd
19181c9862bSchristos (void)putc('\n', fp);
19215cf8058Scgd
193b65c70efSlukem if (fname && !(freopen(fname, "r", stdin)))
19481c9862bSchristos err(1, "Can't open `%s'", fname);
19515cf8058Scgd while (fgets(lbuf, sizeof(lbuf), stdin))
19681c9862bSchristos (void)fputs(lbuf, fp);
19715cf8058Scgd rewind(fp);
19815cf8058Scgd
19981c9862bSchristos if (fstat(fd, &sbuf) == -1)
20081c9862bSchristos err(1, "Can't stat temporary file.");
20181c9862bSchristos mbufsize = (size_t)sbuf.st_size;
202b65c70efSlukem if (!(mbuf = malloc((u_int)mbufsize)))
203b65c70efSlukem err(1, "malloc");
204b65c70efSlukem if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize)
20581c9862bSchristos err(1, "Can't read temporary file.");
20615cf8058Scgd (void)close(fd);
20781c9862bSchristos return mbuf;
20815cf8058Scgd }
209