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#ifndef lint
33static const char rcsid[] =
34  "$FreeBSD$";
35#endif /* not lint */
36
37#include <stdlib.h>
38#include <rpc/rpc.h>
39#include <signal.h>
40#include <syslog.h>
41#include <rpcsvc/rstat.h>
42
43extern void rstat_service(struct svc_req *, SVCXPRT *);
44
45int from_inetd = 1;     /* started from inetd ? */
46int closedown = 20;	/* how long to wait before going dormant */
47
48void
49cleanup(int sig __unused)
50{
51        (void) rpcb_unset(RSTATPROG, RSTATVERS_TIME, NULL);
52        (void) rpcb_unset(RSTATPROG, RSTATVERS_SWTCH, NULL);
53        (void) rpcb_unset(RSTATPROG, RSTATVERS_ORIG, NULL);
54        exit(0);
55}
56
57int
58main(int argc, char *argv[])
59{
60	SVCXPRT *transp;
61	int ok;
62	struct sockaddr_storage from;
63	socklen_t fromlen;
64
65        if (argc == 2)
66                closedown = atoi(argv[1]);
67        if (closedown <= 0)
68                closedown = 20;
69
70        /*
71         * See if inetd started us
72         */
73	fromlen = sizeof(from);
74        if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) {
75                from_inetd = 0;
76        }
77
78        if (!from_inetd) {
79                daemon(0, 0);
80
81                (void)rpcb_unset(RSTATPROG, RSTATVERS_TIME, NULL);
82                (void)rpcb_unset(RSTATPROG, RSTATVERS_SWTCH, NULL);
83                (void)rpcb_unset(RSTATPROG, RSTATVERS_ORIG, NULL);
84
85		(void) signal(SIGINT, cleanup);
86		(void) signal(SIGTERM, cleanup);
87		(void) signal(SIGHUP, cleanup);
88        }
89
90        openlog("rpc.rstatd", LOG_CONS|LOG_PID, LOG_DAEMON);
91
92	if (from_inetd) {
93		transp = svc_tli_create(0, NULL, NULL, 0, 0);
94		if (transp == NULL) {
95			syslog(LOG_ERR, "cannot create udp service.");
96			exit(1);
97		}
98		ok = svc_reg(transp, RSTATPROG, RSTATVERS_TIME,
99			     rstat_service, NULL);
100	} else
101		ok = svc_create(rstat_service,
102				RSTATPROG, RSTATVERS_TIME, "udp");
103	if (!ok) {
104		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_TIME, %s)", (!from_inetd)?"udp":"(inetd)");
105  		exit(1);
106	}
107	if (from_inetd)
108		ok = svc_reg(transp, RSTATPROG, RSTATVERS_SWTCH,
109			     rstat_service, NULL);
110	else
111		ok = svc_create(rstat_service,
112				RSTATPROG, RSTATVERS_SWTCH, "udp");
113	if (!ok) {
114		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_SWTCH, %s)", (!from_inetd)?"udp":"(inetd)");
115  		exit(1);
116	}
117	if (from_inetd)
118		ok = svc_reg(transp, RSTATPROG, RSTATVERS_ORIG,
119			     rstat_service, NULL);
120	else
121		ok = svc_create(rstat_service,
122				RSTATPROG, RSTATVERS_ORIG, "udp");
123	if (!ok) {
124		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_ORIG, %s)", (!from_inetd)?"udp":"(inetd)");
125  		exit(1);
126	}
127
128        svc_run();
129	syslog(LOG_ERR, "svc_run returned");
130	exit(1);
131}
132