12334Scsgr/*-
22334Scsgr * Copyright (c) 1993, John Brezak
32334Scsgr * All rights reserved.
42334Scsgr *
52334Scsgr * Redistribution and use in source and binary forms, with or without
62334Scsgr * modification, are permitted provided that the following conditions
72334Scsgr * are met:
82334Scsgr * 1. Redistributions of source code must retain the above copyright
92334Scsgr *    notice, this list of conditions and the following disclaimer.
102334Scsgr * 2. Redistributions in binary form must reproduce the above copyright
112334Scsgr *    notice, this list of conditions and the following disclaimer in the
122334Scsgr *    documentation and/or other materials provided with the distribution.
13262136Sbrueffer * 3. Neither the name of the University nor the names of its contributors
142334Scsgr *    may be used to endorse or promote products derived from this software
152334Scsgr *    without specific prior written permission.
162334Scsgr *
172334Scsgr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
182334Scsgr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
192334Scsgr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
202334Scsgr * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
212334Scsgr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
222334Scsgr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
232334Scsgr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
242334Scsgr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
252334Scsgr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
262334Scsgr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
272334Scsgr * SUCH DAMAGE.
282334Scsgr */
292334Scsgr
302334Scsgr#ifndef lint
3131421Scharnierstatic const char rcsid[] =
3250476Speter  "$FreeBSD$";
332334Scsgr#endif /* not lint */
342334Scsgr
3531421Scharnier#include <stdlib.h>
362334Scsgr#include <rpc/rpc.h>
372334Scsgr#include <signal.h>
382334Scsgr#include <syslog.h>
392334Scsgr#include <rpcsvc/rstat.h>
402334Scsgr
4190336Simpextern void rstat_service(struct svc_req *, SVCXPRT *);
422334Scsgr
432334Scsgrint from_inetd = 1;     /* started from inetd ? */
442334Scsgrint closedown = 20;	/* how long to wait before going dormant */
452334Scsgr
462334Scsgrvoid
4790336Simpcleanup(int sig __unused)
482334Scsgr{
49100120Salfred        (void) rpcb_unset(RSTATPROG, RSTATVERS_TIME, NULL);
50100120Salfred        (void) rpcb_unset(RSTATPROG, RSTATVERS_SWTCH, NULL);
51100120Salfred        (void) rpcb_unset(RSTATPROG, RSTATVERS_ORIG, NULL);
522334Scsgr        exit(0);
532334Scsgr}
542334Scsgr
5531421Scharnierint
5690336Simpmain(int argc, char *argv[])
572334Scsgr{
582334Scsgr	SVCXPRT *transp;
59100120Salfred	int ok;
60100120Salfred	struct sockaddr_storage from;
61141918Sstefanf	socklen_t fromlen;
628870Srgrimes
632334Scsgr        if (argc == 2)
642334Scsgr                closedown = atoi(argv[1]);
652334Scsgr        if (closedown <= 0)
662334Scsgr                closedown = 20;
672334Scsgr
682334Scsgr        /*
692334Scsgr         * See if inetd started us
702334Scsgr         */
714656Sats	fromlen = sizeof(from);
722334Scsgr        if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) {
732334Scsgr                from_inetd = 0;
742334Scsgr        }
752334Scsgr
762334Scsgr        if (!from_inetd) {
772334Scsgr                daemon(0, 0);
782334Scsgr
79100120Salfred                (void)rpcb_unset(RSTATPROG, RSTATVERS_TIME, NULL);
80100120Salfred                (void)rpcb_unset(RSTATPROG, RSTATVERS_SWTCH, NULL);
81100120Salfred                (void)rpcb_unset(RSTATPROG, RSTATVERS_ORIG, NULL);
822334Scsgr
832334Scsgr		(void) signal(SIGINT, cleanup);
842334Scsgr		(void) signal(SIGTERM, cleanup);
852334Scsgr		(void) signal(SIGHUP, cleanup);
862334Scsgr        }
878870Srgrimes
882334Scsgr        openlog("rpc.rstatd", LOG_CONS|LOG_PID, LOG_DAEMON);
892334Scsgr
90100120Salfred	if (from_inetd) {
91100120Salfred		transp = svc_tli_create(0, NULL, NULL, 0, 0);
92100120Salfred		if (transp == NULL) {
93100120Salfred			syslog(LOG_ERR, "cannot create udp service.");
94100120Salfred			exit(1);
95100120Salfred		}
96100120Salfred		ok = svc_reg(transp, RSTATPROG, RSTATVERS_TIME,
97100120Salfred			     rstat_service, NULL);
98100120Salfred	} else
99100120Salfred		ok = svc_create(rstat_service,
100100120Salfred				RSTATPROG, RSTATVERS_TIME, "udp");
101100120Salfred	if (!ok) {
102100120Salfred		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_TIME, %s)", (!from_inetd)?"udp":"(inetd)");
103100120Salfred  		exit(1);
1042334Scsgr	}
105100120Salfred	if (from_inetd)
106100120Salfred		ok = svc_reg(transp, RSTATPROG, RSTATVERS_SWTCH,
107100120Salfred			     rstat_service, NULL);
108100120Salfred	else
109100120Salfred		ok = svc_create(rstat_service,
110100120Salfred				RSTATPROG, RSTATVERS_SWTCH, "udp");
111100120Salfred	if (!ok) {
112100120Salfred		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_SWTCH, %s)", (!from_inetd)?"udp":"(inetd)");
113100120Salfred  		exit(1);
1142334Scsgr	}
115100120Salfred	if (from_inetd)
116100120Salfred		ok = svc_reg(transp, RSTATPROG, RSTATVERS_ORIG,
117100120Salfred			     rstat_service, NULL);
118100120Salfred	else
119100120Salfred		ok = svc_create(rstat_service,
120100120Salfred				RSTATPROG, RSTATVERS_ORIG, "udp");
121100120Salfred	if (!ok) {
122100120Salfred		syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_ORIG, %s)", (!from_inetd)?"udp":"(inetd)");
123100120Salfred  		exit(1);
1242334Scsgr	}
1252334Scsgr
1262334Scsgr        svc_run();
1272334Scsgr	syslog(LOG_ERR, "svc_run returned");
1282334Scsgr	exit(1);
1292334Scsgr}
130