xref: /illumos-gate/usr/src/cmd/rpcsvc/rwall_subr.c (revision 355b4669e025ff377602b6fc7caaf30dbc218371)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28  * University Copyright- Copyright (c) 1982, 1986, 1988
29  * The Regents of the University of California
30  * All Rights Reserved
31  *
32  * University Acknowledgment- Portions of this document are derived from
33  * software developed by the University of California, Berkeley, and its
34  * contributors.
35  */
36 
37 #pragma ident	"%Z%%M%	%I%	%E% SMI"
38 
39 /*
40  * rwall_subr.c
41  *	The server procedure for rwalld
42  */
43 
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <rpc/rpc.h>
48 #include <thread.h>
49 #include <rpcsvc/rwall.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <syslog.h>
53 #include <string.h>
54 
55 #define	WALL_PROG	"/usr/sbin/wall"
56 
57 static mutex_t wall_mutex = DEFAULTMUTEX;
58 static char *oldmsg;
59 
60 /* ARGSUSED */
61 bool_t
62 wallproc_wall_1_svc(wrapstring *argp, void *res, struct svc_req *rqstp)
63 {
64 	char *msg;
65 	FILE *fp;
66 	int rval;
67 	struct stat wall;
68 
69 	msg = *argp;
70 
71 	/*
72 	 * Do not wall the same message twice in case of a retransmission
73 	 * in the rare case that two walls arrive close enough with
74 	 * a retransmission we might get a duplicate, but that is OK.
75 	 */
76 	(void) mutex_lock(&wall_mutex);
77 	if ((oldmsg != 0) && (strcmp(msg, oldmsg) == 0)) {
78 		(void) mutex_unlock(&wall_mutex);
79 		return (TRUE);
80 	}
81 
82 	if (oldmsg)
83 		free(oldmsg);
84 	oldmsg = strdup(msg);
85 
86 	rval = stat(WALL_PROG, &wall);
87 
88 	/*
89 	 * Make sure the wall programs exists, is executeable, and runs
90 	 */
91 	if (rval == -1 || (wall.st_mode & S_IXUSR) == 0 ||
92 	    (fp = popen(WALL_PROG, "w")) == NULL) {
93 		syslog(LOG_NOTICE,
94 			"rwall message received but could not execute %s",
95 			WALL_PROG);
96 		syslog(LOG_NOTICE, "%s", msg);
97 #ifdef	DEBUG
98 		(void) fprintf(stderr,
99 			"rwall message received but could not execute %s",
100 			WALL_PROG);
101 		(void) fprintf(stderr, "%s", msg);
102 #endif
103 		(void) mutex_unlock(&wall_mutex);
104 		return (TRUE);
105 	}
106 
107 	(void) fprintf(fp, "%s", msg);
108 	(void) pclose(fp);
109 	(void) mutex_unlock(&wall_mutex);
110 
111 	return (TRUE);
112 }
113 
114 /* ARGSUSED */
115 int
116 wallprog_1_freeresult(SVCXPRT *transp, xdrproc_t proc, caddr_t arg)
117 {
118 	return (TRUE);
119 }
120