1 /* 2 * Please do not edit this file. 3 * It was generated using rpcgen. 4 */ 5 6 #include "rwall.h" 7 #include <stdio.h> 8 #include <stdlib.h> /* getenv, exit */ 9 #include <signal.h> 10 #include <sys/types.h> 11 #include <memory.h> 12 #include <stropts.h> 13 #include <netconfig.h> 14 #include <sys/resource.h> /* rlimit */ 15 #include <syslog.h> 16 17 #ifdef DEBUG 18 #define RPC_SVC_FG 19 #endif 20 21 #define _RPCSVC_CLOSEDOWN 120 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * CDDL HEADER START 27 * 28 * The contents of this file are subject to the terms of the 29 * Common Development and Distribution License, Version 1.0 only 30 * (the "License"). You may not use this file except in compliance 31 * with the License. 32 * 33 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 34 * or http://www.opensolaris.org/os/licensing. 35 * See the License for the specific language governing permissions 36 * and limitations under the License. 37 * 38 * When distributing Covered Code, include this CDDL HEADER in each 39 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 40 * If applicable, add the following below this CDDL HEADER, with the 41 * fields enclosed by brackets "[]" replaced with your own identifying 42 * information: Portions Copyright [yyyy] [name of copyright owner] 43 * 44 * CDDL HEADER END 45 */ 46 /* from rwall.x */ 47 48 /* 49 * Remote write-all ONC service 50 */ 51 52 /* 53 * Server side stub routines for the rpc.rwalld daemon 54 */ 55 56 static int _rpcpmstart; /* Started by a port monitor ? */ 57 58 /* States a server can be in wrt request */ 59 60 #define _IDLE 0 61 #define _SERVED 1 62 63 static int _rpcsvcstate = _IDLE; /* Set when a request is serviced */ 64 static int _rpcsvccount = 0; /* Number of requests being serviced */ 65 mutex_t _svcstate_lock; /* lock for _rpcsvcstate, _rpcsvccount */ 66 67 #if defined(RPC_MSGOUT) 68 extern void RPC_MSGOUT(); 69 #else /* defined(RPC_MSGOUT) */ 70 static void 71 RPC_MSGOUT(fmt, msg) 72 char *fmt; 73 char *msg; 74 { 75 #ifdef RPC_SVC_FG 76 if (_rpcpmstart) 77 syslog(LOG_ERR, fmt, msg); 78 else { 79 (void) fprintf(stderr, fmt, msg); 80 (void) putc('\n', stderr); 81 } 82 #else 83 syslog(LOG_ERR, fmt, msg); 84 #endif 85 } 86 #endif /* defined(RPC_MSGOUT) */ 87 88 /*ARGSUSED*/ 89 static void * 90 closedown(arg) 91 void *arg; 92 { 93 /*CONSTCOND*/ 94 while (1) { 95 (void) sleep(_RPCSVC_CLOSEDOWN/2); 96 97 if (mutex_trylock(&_svcstate_lock) != 0) 98 continue; 99 100 if (_rpcsvcstate == _IDLE && _rpcsvccount == 0) { 101 int size; 102 int i, openfd = 0; 103 104 size = svc_max_pollfd; 105 for (i = 0; i < size && openfd < 2; i++) 106 if (svc_pollfd[i].fd >= 0) 107 openfd++; 108 if (openfd <= 1) 109 exit(0); 110 } else 111 _rpcsvcstate = _IDLE; 112 113 (void) mutex_unlock(&_svcstate_lock); 114 } 115 } 116 117 static void 118 wallprog_1(rqstp, transp) 119 struct svc_req *rqstp; 120 register SVCXPRT *transp; 121 { 122 union { 123 wrapstring wallproc_wall_1_arg; 124 } argument; 125 union { 126 int fill; 127 } result; 128 bool_t retval; 129 bool_t (*_xdr_argument)(), (*_xdr_result)(); 130 bool_t (*local)(); 131 132 (void) mutex_lock(&_svcstate_lock); 133 _rpcsvccount++; 134 (void) mutex_unlock(&_svcstate_lock); 135 switch (rqstp->rq_proc) { 136 case NULLPROC: 137 (void) svc_sendreply(transp, xdr_void, 138 NULL); 139 (void) mutex_lock(&_svcstate_lock); 140 _rpcsvccount--; 141 _rpcsvcstate = _SERVED; 142 (void) mutex_unlock(&_svcstate_lock); 143 return; /* CSTYLED */ 144 145 case WALLPROC_WALL: 146 _xdr_argument = xdr_wrapstring; 147 _xdr_result = xdr_void; 148 local = (bool_t (*)()) 149 wallproc_wall_1_svc; 150 break; 151 152 default: 153 svcerr_noproc(transp); 154 (void) mutex_lock(&_svcstate_lock); 155 _rpcsvccount--; 156 _rpcsvcstate = _SERVED; 157 (void) mutex_unlock(&_svcstate_lock); 158 return; /* CSTYLED */ 159 } 160 (void) memset((char *)&argument, 0, sizeof (argument)); 161 if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) { 162 svcerr_decode(transp); 163 (void) mutex_lock(&_svcstate_lock); 164 _rpcsvccount--; 165 _rpcsvcstate = _SERVED; 166 (void) mutex_unlock(&_svcstate_lock); 167 return; /* CSTYLED */ 168 } 169 retval = (bool_t)(*local)(&argument, &result, rqstp); 170 if (_xdr_result && retval > 0 && 171 !svc_sendreply(transp, _xdr_result, (char *)&result)) { 172 svcerr_systemerr(transp); 173 } 174 if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) { 175 RPC_MSGOUT("%s", 176 "unable to free arguments"); 177 exit(1); 178 } 179 if (_xdr_result != NULL) { 180 if (!wallprog_1_freeresult(transp, _xdr_result, 181 (caddr_t)&result)) 182 RPC_MSGOUT("%s", 183 "unable to free results"); 184 185 } 186 (void) mutex_lock(&_svcstate_lock); 187 _rpcsvccount--; 188 _rpcsvcstate = _SERVED; 189 (void) mutex_unlock(&_svcstate_lock); 190 return; /* CSTYLED */ 191 } 192 193 int 194 main() 195 { 196 pid_t pid; 197 int i; 198 int mode = RPC_SVC_MT_AUTO; 199 200 if (!rpc_control(RPC_SVC_MTMODE_SET, &mode)) { 201 RPC_MSGOUT("%s", 202 "unable to set automatic MT mode."); 203 exit(1); 204 } 205 mutex_init(&_svcstate_lock, USYNC_THREAD, NULL); 206 (void) sigset(SIGPIPE, SIG_IGN); 207 208 /* 209 * If stdin looks like a TLI endpoint, we assume 210 * that we were started by a port monitor. If 211 * t_getstate fails with TBADF, this is not a 212 * TLI endpoint. 213 */ 214 if (t_getstate(0) != -1 || t_errno != TBADF) { 215 char *netid; 216 struct netconfig *nconf = NULL; 217 SVCXPRT *transp; 218 int pmclose; 219 220 _rpcpmstart = 1; 221 openlog("rwall", LOG_PID, LOG_DAEMON); 222 223 if ((netid = getenv("NLSPROVIDER")) == NULL) { 224 /* started from inetd */ 225 pmclose = 1; 226 } else { 227 if ((nconf = getnetconfigent(netid)) == NULL) 228 RPC_MSGOUT("%s", 229 "cannot get transport info"); 230 231 pmclose = (t_getstate(0) != T_DATAXFER); 232 } 233 if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) { 234 RPC_MSGOUT("%s", 235 "cannot create server handle"); 236 exit(1); 237 } 238 if (nconf) 239 freenetconfigent(nconf); 240 if (!svc_reg(transp, WALLPROG, WALLVERS, 241 wallprog_1, 0)) { 242 RPC_MSGOUT("%s", 243 "unable to register (WALLPROG, WALLVERS)."); 244 exit(1); 245 } 246 if (pmclose) { 247 if (thr_create(NULL, 0, closedown, NULL, 248 0, NULL) != 0) { 249 RPC_MSGOUT("%s", 250 "cannot create closedown thread"); 251 exit(1); 252 } 253 } 254 svc_run(); 255 exit(1); 256 /* NOTREACHED */ 257 } else { 258 #ifndef RPC_SVC_FG 259 #pragma weak closefrom 260 extern void closefrom(); 261 int size; 262 struct rlimit rl; 263 pid = fork(); 264 if (pid < 0) { 265 perror("cannot fork"); 266 exit(1); 267 } 268 if (pid) 269 exit(0); 270 if (closefrom != NULL) 271 closefrom(0); 272 else { 273 rl.rlim_max = 0; 274 getrlimit(RLIMIT_NOFILE, &rl); 275 if ((size = rl.rlim_max) == 0) 276 exit(1); 277 for (i = 0; i < size; i++) 278 (void) close(i); 279 } 280 i = open("/dev/null", 2); 281 (void) dup2(i, 1); 282 (void) dup2(i, 2); 283 setsid(); 284 openlog("rwall", LOG_PID, LOG_DAEMON); 285 #endif 286 } 287 if (!svc_create( 288 wallprog_1, WALLPROG, WALLVERS, 289 "datagram_v")) { 290 RPC_MSGOUT("%s", 291 "unable to create (WALLPROG, WALLVERS) for datagram_v."); 292 exit(1); 293 } 294 295 svc_run(); 296 RPC_MSGOUT("%s", 297 "svc_run returned"); 298 exit(1); 299 /* NOTREACHED */ 300 } 301