1 /*
2  * Please do not edit this file.
3  * It was generated using rpcgen.
4  */
5 
6 #include "spray.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 (c) 1987, 1991 by Sun Microsystems, Inc.
24  */
25 /* from spray.x */
26 static int _rpcpmstart;		/* Started by a port monitor ? */
27 
28 /* States a server can be in wrt request */
29 
30 #define	_IDLE 0
31 #define	_SERVED 1
32 
33 static int _rpcsvcstate = _IDLE;	/* Set when a request is serviced */
34 static int _rpcsvccount = 0;		/* Number of requests being serviced */
35 
36 #if	defined(RPC_MSGOUT)
37 extern void RPC_MSGOUT();
38 #else	/* defined(RPC_MSGOUT) */
39 static void
40 RPC_MSGOUT(fmt, msg)
41 	char *fmt;
42 	char *msg;
43 {
44 #ifdef RPC_SVC_FG
45 	if (_rpcpmstart)
46 		syslog(LOG_ERR, fmt, msg);
47 	else {
48 		(void) fprintf(stderr, fmt, msg);
49 		(void) putc('\n', stderr);
50 	}
51 #else
52 	syslog(LOG_ERR, fmt, msg);
53 #endif
54 }
55 #endif	/* defined(RPC_MSGOUT) */
56 
57 static void
58 closedown(sig)
59 	int sig;
60 {
61 	if (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {
62 		int size;
63 		int i, openfd = 0;
64 
65 		size = svc_max_pollfd;
66 		for (i = 0; i < size && openfd < 2; i++)
67 			if (svc_pollfd[i].fd >= 0)
68 				openfd++;
69 		if (openfd <= 1)
70 			exit(0);
71 	} else
72 		_rpcsvcstate = _IDLE;
73 
74 	(void) signal(SIGALRM, (void(*)()) closedown);
75 	(void) alarm(_RPCSVC_CLOSEDOWN/2);
76 }
77 
78 static void
79 sprayprog_1(rqstp, transp)
80 	struct svc_req *rqstp;
81 	register SVCXPRT *transp;
82 {
83 	union {
84 		sprayarr sprayproc_spray_1_arg;
85 	} argument;
86 	char *result;
87 	bool_t (*_xdr_argument)(), (*_xdr_result)();
88 	char *(*local)();
89 
90 	_rpcsvccount++;
91 	switch (rqstp->rq_proc) {
92 	case NULLPROC:
93 		(void) svc_sendreply(transp, xdr_void,
94 			NULL);
95 		_rpcsvccount--;
96 		_rpcsvcstate = _SERVED;
97 		return; /* CSTYLED */
98 
99 	case SPRAYPROC_SPRAY:
100 		_xdr_argument = xdr_sprayarr;
101 		_xdr_result = xdr_void;
102 		local = (char *(*)())
103 		    sprayproc_spray_1;
104 		break;
105 
106 	case SPRAYPROC_GET:
107 		_xdr_argument = xdr_void;
108 		_xdr_result = xdr_spraycumul;
109 		local = (char *(*)())
110 		    sprayproc_get_1;
111 		break;
112 
113 	case SPRAYPROC_CLEAR:
114 		_xdr_argument = xdr_void;
115 		_xdr_result = xdr_void;
116 		local = (char *(*)())
117 		    sprayproc_clear_1;
118 		break;
119 
120 	default:
121 		svcerr_noproc(transp);
122 		_rpcsvccount--;
123 		_rpcsvcstate = _SERVED;
124 		return; /* CSTYLED */
125 	}
126 	(void) memset((char *)&argument, 0, sizeof (argument));
127 	if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) {
128 		svcerr_decode(transp);
129 		_rpcsvccount--;
130 		_rpcsvcstate = _SERVED;
131 		return; /* CSTYLED */
132 	}
133 	result = (*local)(&argument, rqstp);
134 	if (_xdr_result && result != NULL &&
135 	    !svc_sendreply(transp, _xdr_result, result)) {
136 		svcerr_systemerr(transp);
137 	}
138 	if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) {
139 		RPC_MSGOUT("%s",
140 		    "unable to free arguments");
141 		exit(1);
142 	}
143 	_rpcsvccount--;
144 	_rpcsvcstate = _SERVED;
145 	return; /* CSTYLED */
146 }
147 
148 int
149 main()
150 {
151 	pid_t pid;
152 	int i;
153 
154 	(void) sigset(SIGPIPE, SIG_IGN);
155 
156 	/*
157 	 * If stdin looks like a TLI endpoint, we assume
158 	 * that we were started by a port monitor. If
159 	 * t_getstate fails with TBADF, this is not a
160 	 * TLI endpoint.
161 	 */
162 	if (t_getstate(0) != -1 || t_errno != TBADF) {
163 		char *netid;
164 		struct netconfig *nconf = NULL;
165 		SVCXPRT *transp;
166 		int pmclose;
167 
168 		_rpcpmstart = 1;
169 		openlog("spray", LOG_PID, LOG_DAEMON);
170 
171 		if ((netid = getenv("NLSPROVIDER")) == NULL) {
172 		/* started from inetd */
173 			pmclose = 1;
174 		} else {
175 			if ((nconf = getnetconfigent(netid)) == NULL)
176 				RPC_MSGOUT("%s",
177 				    "cannot get transport info");
178 
179 			pmclose = (t_getstate(0) != T_DATAXFER);
180 		}
181 		if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
182 			RPC_MSGOUT("%s",
183 			    "cannot create server handle");
184 			exit(1);
185 		}
186 		if (nconf)
187 			freenetconfigent(nconf);
188 		if (!svc_reg(transp, SPRAYPROG, SPRAYVERS,
189 		    sprayprog_1, 0)) {
190 			RPC_MSGOUT("%s",
191 			    "unable to register (SPRAYPROG, SPRAYVERS).");
192 			exit(1);
193 		}
194 		if (pmclose) {
195 			(void) signal(SIGALRM, (void(*)()) closedown);
196 			(void) alarm(_RPCSVC_CLOSEDOWN/2);
197 		}
198 		svc_run();
199 		exit(1);
200 		/* NOTREACHED */
201 	}	else {
202 #ifndef RPC_SVC_FG
203 #pragma weak closefrom
204 		extern void closefrom();
205 		int size;
206 		struct rlimit rl;
207 		pid = fork();
208 		if (pid < 0) {
209 			perror("cannot fork");
210 			exit(1);
211 		}
212 		if (pid)
213 			exit(0);
214 		if (closefrom != NULL)
215 			closefrom(0);
216 		else {
217 			rl.rlim_max = 0;
218 			getrlimit(RLIMIT_NOFILE, &rl);
219 			if ((size = rl.rlim_max) == 0)
220 				exit(1);
221 			for (i = 0; i < size; i++)
222 				(void) close(i);
223 		}
224 		i = open("/dev/null", 2);
225 		(void) dup2(i, 1);
226 		(void) dup2(i, 2);
227 		setsid();
228 		openlog("spray", LOG_PID, LOG_DAEMON);
229 #endif
230 	}
231 	if (!svc_create(
232 	    sprayprog_1, SPRAYPROG, SPRAYVERS,
233 	    "datagram_v")) {
234 		RPC_MSGOUT("%s",
235 		    "unable to create (SPRAYPROG, SPRAYVERS) for datagram_v.");
236 		exit(1);
237 	}
238 	if (!svc_create(
239 	    sprayprog_1, SPRAYPROG, SPRAYVERS,
240 	    "circuit_v")) {
241 		RPC_MSGOUT("%s",
242 		    "unable to create (SPRAYPROG, SPRAYVERS) for circuit_v.");
243 		exit(1);
244 	}
245 
246 	svc_run();
247 	RPC_MSGOUT("%s",
248 	    "svc_run returned");
249 	exit(1);
250 	/* NOTREACHED */
251 }
252