1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1993, John Brezak
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <stdlib.h>
33#include <rpc/rpc.h>
34#include <signal.h>
35#include <syslog.h>
36#include <rpcsvc/rstat.h>
37
38extern void rstat_service(struct svc_req *, SVCXPRT *);
39
40int from_inetd = 1;     /* started from inetd ? */
41int closedown = 20;	/* how long to wait before going dormant */
42
43void
44cleanup(int sig __unused)
45{
46        (void) rpcb_unset(RSTATPROG, RSTATVERS_TIME, NULL);
47        (void) rpcb_unset(RSTATPROG, RSTATVERS_SWTCH, NULL);
48        (void) rpcb_unset(RSTATPROG, RSTATVERS_ORIG, NULL);
49        exit(0);
50}
51
52int
53main(int argc, char *argv[])
54{
55	SVCXPRT *transp;
56	int ok;
57	struct sockaddr_storage from;
58	socklen_t fromlen;
59
60        if (argc == 2)
61                closedown = atoi(argv[1]);
62        if (closedown <= 0)
63                closedown = 20;
64
65        /*
66         * See if inetd started us
67         */
68	fromlen = sizeof(from);
69        if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) {
70                from_inetd = 0;
71        }
72
73        if (!from_inetd) {
74                daemon(0, 0);
75
76                (void)rpcb_unset(RSTATPROG, RSTATVERS_TIME, NULL);
77                (void)rpcb_unset(RSTATPROG, RSTATVERS_SWTCH, NULL);
78                (void)rpcb_unset(RSTATPROG, RSTATVERS_ORIG, NULL);
79
80		(void) signal(SIGINT, cleanup);
81		(void) signal(SIGTERM, cleanup);
82		(void) signal(SIGHUP, cleanup);
83        }
84
85        openlog("rpc.rstatd", LOG_CONS|LOG_PID, LOG_DAEMON);
86
87	if (from_inetd) {
88		transp = svc_tli_create(0, NULL, NULL, 0, 0);
89		if (transp == NULL) {
90			syslog(LOG_ERR, "cannot create udp service.");
91			exit(1);
92		}
93		ok = svc_reg(transp, RSTATPROG, RSTATVERS_TIME,
94			     rstat_service, NULL);
95	} else
96		ok = svc_create(rstat_service,
97				RSTATPROG, RSTATVERS_TIME, "udp");
98	if (!ok) {
99		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_TIME, %s)", (!from_inetd)?"udp":"(inetd)");
100  		exit(1);
101	}
102	if (from_inetd)
103		ok = svc_reg(transp, RSTATPROG, RSTATVERS_SWTCH,
104			     rstat_service, NULL);
105	else
106		ok = svc_create(rstat_service,
107				RSTATPROG, RSTATVERS_SWTCH, "udp");
108	if (!ok) {
109		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_SWTCH, %s)", (!from_inetd)?"udp":"(inetd)");
110  		exit(1);
111	}
112	if (from_inetd)
113		ok = svc_reg(transp, RSTATPROG, RSTATVERS_ORIG,
114			     rstat_service, NULL);
115	else
116		ok = svc_create(rstat_service,
117				RSTATPROG, RSTATVERS_ORIG, "udp");
118	if (!ok) {
119		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_ORIG, %s)", (!from_inetd)?"udp":"(inetd)");
120  		exit(1);
121	}
122
123        svc_run();
124	syslog(LOG_ERR, "svc_run returned");
125	exit(1);
126}
127