112891Swpaul/*
212891Swpaul * Copyright (c) 1995
312891Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
412891Swpaul *
512891Swpaul * Redistribution and use in source and binary forms, with or without
612891Swpaul * modification, are permitted provided that the following conditions
712891Swpaul * are met:
812891Swpaul * 1. Redistributions of source code must retain the above copyright
912891Swpaul *    notice, this list of conditions and the following disclaimer.
1012891Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1112891Swpaul *    notice, this list of conditions and the following disclaimer in the
1212891Swpaul *    documentation and/or other materials provided with the distribution.
1312891Swpaul * 3. All advertising materials mentioning features or use of this software
1412891Swpaul *    must display the following acknowledgement:
1512891Swpaul *	This product includes software developed by Bill Paul.
1612891Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1712891Swpaul *    may be used to endorse or promote products derived from this software
1812891Swpaul *    without specific prior written permission.
1912891Swpaul *
2012891Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2112891Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2212891Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2312891Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2412891Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2512891Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2612891Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2712891Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2812891Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2912891Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3012891Swpaul * SUCH DAMAGE.
3112891Swpaul */
3212891Swpaul
33114601Sobrien#include <sys/cdefs.h>
34114601Sobrien__FBSDID("$FreeBSD$");
3530827Scharnier
3612891Swpaul/*
3712891Swpaul * ypserv startup function.
3812891Swpaul * We need out own main() since we have to do some additional work
3912891Swpaul * that rpcgen won't do for us. Most of this file was generated using
4012891Swpaul * rpcgen.new, and later modified.
4112891Swpaul */
4212891Swpaul
43200478Shrs#include <sys/types.h>
44226725Sglebius#include <sys/mman.h>
45200478Shrs#include <sys/queue.h>
46200478Shrs#include <sys/socket.h>
47200478Shrs#include <sys/wait.h>
4812891Swpaul#include "yp.h"
4930827Scharnier#include <err.h>
5030827Scharnier#include <errno.h>
5130827Scharnier#include <memory.h>
5212891Swpaul#include <stdio.h>
5330827Scharnier#include <signal.h>
54200478Shrs#include <stdarg.h>
5512891Swpaul#include <stdlib.h> /* getenv, exit */
5630827Scharnier#include <string.h> /* strcmp */
5730827Scharnier#include <syslog.h>
5830827Scharnier#include <unistd.h>
5912891Swpaul#ifdef __cplusplus
6012891Swpaul#include <sysent.h> /* getdtablesize, open */
6112891Swpaul#endif /* __cplusplus */
6212891Swpaul#include <netinet/in.h>
63200478Shrs#include <netdb.h>
6412891Swpaul#include "yp_extern.h"
65200478Shrs#include <netconfig.h>
6612891Swpaul#include <rpc/rpc.h>
67200478Shrs#include <rpc/rpc_com.h>
6812891Swpaul
6912891Swpaul#ifndef SIG_PF
7012891Swpaul#define	SIG_PF void(*)(int)
7112891Swpaul#endif
7212891Swpaul
7312891Swpaul#define	_RPCSVC_CLOSEDOWN 120
7412891Swpaulint _rpcpmstart;		/* Started by a port monitor ? */
7512891Swpaulstatic int _rpcfdtype;
7612891Swpaul		 /* Whether Stream or Datagram ? */
77200478Shrsstatic int _rpcaf;
78200478Shrsstatic int _rpcfd;
79200478Shrs
8012891Swpaul	/* States a server can be in wrt request */
8112891Swpaul
8212891Swpaul#define	_IDLE 0
8312891Swpaul#define	_SERVED 1
8412891Swpaul#define	_SERVING 2
8512891Swpaul
86200478Shrsextern void ypprog_1(struct svc_req *, SVCXPRT *);
87200478Shrsextern void ypprog_2(struct svc_req *, SVCXPRT *);
8890297Sdesextern int _rpc_dtablesize(void);
8912891Swpaulextern int _rpcsvcstate;	 /* Set when a request is serviced */
9012891Swpaulchar *progname = "ypserv";
9112891Swpaulchar *yp_dir = _PATH_YP;
9233250Swpaul/*int debug = 0;*/
9312891Swpaulint do_dns = 0;
9420818Swpaulint resfd;
9512891Swpaul
96200478Shrsstruct socklistent {
97200478Shrs	int				sle_sock;
98200478Shrs	struct sockaddr_storage		sle_ss;
99200478Shrs	SLIST_ENTRY(socklistent)	sle_next;
100175951Smatteo};
101200478Shrsstatic SLIST_HEAD(, socklistent) sle_head =
102201145Santoine	SLIST_HEAD_INITIALIZER(sle_head);
103200478Shrs
104200478Shrsstruct bindaddrlistent {
105200478Shrs	const char			*ble_hostname;
106200478Shrs	SLIST_ENTRY(bindaddrlistent)	ble_next;
107175951Smatteo};
108200478Shrsstatic SLIST_HEAD(, bindaddrlistent) ble_head =
109201145Santoine	SLIST_HEAD_INITIALIZER(ble_head);
110175951Smatteo
111200478Shrsstatic char *servname = "0";
112200478Shrs
11312891Swpaulstatic
114200478Shrsvoid _msgout(char* msg, ...)
11512891Swpaul{
116200478Shrs	va_list ap;
117200478Shrs
118200478Shrs	va_start(ap, msg);
11912891Swpaul	if (debug) {
12012891Swpaul		if (_rpcpmstart)
121200478Shrs			vsyslog(LOG_ERR, msg, ap);
12212891Swpaul		else
123200478Shrs			vwarnx(msg, ap);
12412891Swpaul	} else
125200478Shrs		vsyslog(LOG_ERR, msg, ap);
126200478Shrs	va_end(ap);
12712891Swpaul}
12812891Swpaul
12946186Swpaulpid_t	yp_pid;
13046186Swpaul
13120100Swpaulstatic void
13290298Sdesyp_svc_run(void)
13320100Swpaul{
13420100Swpaul#ifdef FD_SETSIZE
13520100Swpaul	fd_set readfds;
13620100Swpaul#else
13720100Swpaul	int readfds;
13820100Swpaul#endif /* def FD_SETSIZE */
13920100Swpaul	int fd_setsize = _rpc_dtablesize();
14021104Speter	struct timeval timeout;
14120100Swpaul
14220100Swpaul	/* Establish the identity of the parent ypserv process. */
14346186Swpaul	yp_pid = getpid();
14420100Swpaul
14520100Swpaul	for (;;) {
14620100Swpaul#ifdef FD_SETSIZE
14720100Swpaul		readfds = svc_fdset;
14820100Swpaul#else
14920100Swpaul		readfds = svc_fds;
15020100Swpaul#endif /* def FD_SETSIZE */
15120818Swpaul
15220907Swpaul		FD_SET(resfd, &readfds);
15320818Swpaul
15421104Speter		timeout.tv_sec = RESOLVER_TIMEOUT;
15521104Speter		timeout.tv_usec = 0;
15620100Swpaul		switch (select(fd_setsize, &readfds, NULL, NULL,
15720818Swpaul			       &timeout)) {
15820100Swpaul		case -1:
15920100Swpaul			if (errno == EINTR) {
16020100Swpaul				continue;
16120100Swpaul			}
16230827Scharnier			warn("svc_run: - select failed");
16320100Swpaul			return;
16420100Swpaul		case 0:
16546186Swpaul			if (getpid() == yp_pid)
16646186Swpaul				yp_prune_dnsq();
16720818Swpaul			break;
16820100Swpaul		default:
16946186Swpaul			if (getpid() == yp_pid) {
17046186Swpaul				if (FD_ISSET(resfd, &readfds)) {
17146186Swpaul					yp_run_dnsq();
17246186Swpaul					FD_CLR(resfd, &readfds);
17346186Swpaul				}
17446186Swpaul				svc_getreqset(&readfds);
17520818Swpaul			}
17620100Swpaul		}
17746186Swpaul		if (yp_pid != getpid())
17843847Swpaul			_exit(0);
17920100Swpaul	}
18020100Swpaul}
18120100Swpaul
18290298Sdesstatic void
18390298Sdesunregister(void)
18412891Swpaul{
185200478Shrs	(void)svc_unreg(YPPROG, YPVERS);
186200478Shrs	(void)svc_unreg(YPPROG, YPOLDVERS);
18712891Swpaul}
18812891Swpaul
18990298Sdesstatic void
19090298Sdesreaper(int sig)
19112891Swpaul{
19236639Swpaul	int			status;
19336639Swpaul	int			saved_errno;
19412891Swpaul
19536639Swpaul	saved_errno = errno;
19636639Swpaul
19714240Swpaul	if (sig == SIGHUP) {
19814240Swpaul		load_securenets();
19915426Swpaul#ifdef DB_CACHE
20015426Swpaul		yp_flush_all();
20115426Swpaul#endif
20236639Swpaul		errno = saved_errno;
20314240Swpaul		return;
20414240Swpaul	}
20514240Swpaul
20612891Swpaul	if (sig == SIGCHLD) {
20712891Swpaul		while (wait3(&status, WNOHANG, NULL) > 0)
20812891Swpaul			children--;
20912891Swpaul	} else {
21012891Swpaul		unregister();
21112891Swpaul		exit(0);
21212891Swpaul	}
21336639Swpaul	errno = saved_errno;
21436639Swpaul	return;
21512891Swpaul}
21612891Swpaul
21790298Sdesstatic void
21890298Sdesusage(void)
21912891Swpaul{
220223340Skuriyama	fprintf(stderr, "usage: ypserv [-h addr] [-d] [-n] [-p path] [-P port]\n");
22112891Swpaul	exit(1);
22212891Swpaul}
22312891Swpaul
22412891Swpaulstatic void
22512891Swpaulclosedown(int sig)
22612891Swpaul{
22712891Swpaul	if (_rpcsvcstate == _IDLE) {
22812891Swpaul		extern fd_set svc_fdset;
22912891Swpaul		static int size;
23012891Swpaul		int i, openfd;
23112891Swpaul
23212891Swpaul		if (_rpcfdtype == SOCK_DGRAM) {
23312891Swpaul			unregister();
23412891Swpaul			exit(0);
23512891Swpaul		}
23612891Swpaul		if (size == 0) {
23712891Swpaul			size = getdtablesize();
23812891Swpaul		}
23912891Swpaul		for (i = 0, openfd = 0; i < size && openfd < 2; i++)
24012891Swpaul			if (FD_ISSET(i, &svc_fdset))
24112891Swpaul				openfd++;
24212891Swpaul		if (openfd <= 1) {
24312891Swpaul			unregister();
24412891Swpaul			exit(0);
24512891Swpaul		}
24612891Swpaul	}
24712891Swpaul	if (_rpcsvcstate == _SERVED)
24812891Swpaul		_rpcsvcstate = _IDLE;
24912891Swpaul
25012891Swpaul	(void) signal(SIGALRM, (SIG_PF) closedown);
25112891Swpaul	(void) alarm(_RPCSVC_CLOSEDOWN/2);
25212891Swpaul}
25312891Swpaul
254200478Shrsstatic int
255200478Shrscreate_service(const int sock, const struct netconfig *nconf,
256200478Shrs	const struct __rpc_sockinfo *si)
257200478Shrs{
258200478Shrs	int error;
259200478Shrs
260200478Shrs	SVCXPRT *transp;
261200478Shrs	struct addrinfo hints, *res, *res0;
262200478Shrs	struct socklistent *slep;
263200478Shrs	struct bindaddrlistent *blep;
264200478Shrs	struct netbuf svcaddr;
265200478Shrs
266200478Shrs	SLIST_INIT(&sle_head);
267200478Shrs	memset(&hints, 0, sizeof(hints));
268200478Shrs	memset(&svcaddr, 0, sizeof(svcaddr));
269200478Shrs
270200478Shrs	hints.ai_family = si->si_af;
271200478Shrs	hints.ai_socktype = si->si_socktype;
272200478Shrs	hints.ai_protocol = si->si_proto;
273200478Shrs
274200478Shrs	/*
275200478Shrs	 * Build socketlist from bindaddrlist.
276200478Shrs	 */
277200478Shrs	if (sock == RPC_ANYFD) {
278200478Shrs		SLIST_FOREACH(blep, &ble_head, ble_next) {
279200478Shrs			if (blep->ble_hostname == NULL)
280200478Shrs				hints.ai_flags = AI_PASSIVE;
281200478Shrs			else
282200478Shrs				hints.ai_flags = 0;
283200478Shrs			error = getaddrinfo(blep->ble_hostname, servname,
284200478Shrs				    &hints, &res0);
285200478Shrs			if (error) {
286200478Shrs				_msgout("getaddrinfo(): %s",
287200478Shrs				    gai_strerror(error));
288200478Shrs				return -1;
289200478Shrs			}
290200478Shrs			for (res = res0; res; res = res->ai_next) {
291200478Shrs				int s;
292200478Shrs
293200478Shrs				s = __rpc_nconf2fd(nconf);
294200478Shrs				if (s < 0) {
295244538Skevlo					if (errno == EAFNOSUPPORT)
296200478Shrs						_msgout("unsupported"
297200478Shrs						    " transport: %s",
298200478Shrs						    nconf->nc_netid);
299200478Shrs					else
300200478Shrs						_msgout("cannot create"
301200478Shrs						    " %s socket: %s",
302200478Shrs						    nconf->nc_netid,
303200478Shrs						    strerror(errno));
304200478Shrs					freeaddrinfo(res0);
305200478Shrs					return -1;
306200478Shrs				}
307202686Shrs				if (bindresvport_sa(s, res->ai_addr) == -1) {
308202686Shrs					if ((errno != EPERM) ||
309202686Shrs					    (bind(s, res->ai_addr,
310202686Shrs					    res->ai_addrlen) == -1)) {
311202686Shrs						_msgout("cannot bind "
312202686Shrs						    "%s socket: %s",
313202686Shrs						    nconf->nc_netid,
314202686Shrs						strerror(errno));
315202686Shrs						freeaddrinfo(res0);
316202686Shrs						close(sock);
317202686Shrs						return -1;
318202686Shrs					}
319200478Shrs				}
320200478Shrs				if (nconf->nc_semantics != NC_TPI_CLTS)
321200478Shrs					listen(s, SOMAXCONN);
322200478Shrs
323200478Shrs				slep = malloc(sizeof(*slep));
324200478Shrs				if (slep == NULL) {
325200478Shrs					_msgout("malloc failed: %s",
326200478Shrs					    strerror(errno));
327200478Shrs					freeaddrinfo(res0);
328200478Shrs					close(s);
329200478Shrs					return -1;
330200478Shrs				}
331200478Shrs				memset(slep, 0, sizeof(*slep));
332253253Shrs				memcpy(&slep->sle_ss, res->ai_addr,
333253253Shrs				    res->ai_addrlen);
334200478Shrs				slep->sle_sock = s;
335200478Shrs				SLIST_INSERT_HEAD(&sle_head, slep, sle_next);
336200478Shrs
337200478Shrs				/*
338200478Shrs				 * If servname == "0", redefine it by using
339200478Shrs				 * the bound socket.
340200478Shrs				 */
341200478Shrs				if (strncmp("0", servname, 1) == 0) {
342200478Shrs					struct sockaddr *sap;
343200478Shrs					socklen_t slen;
344230279Shrs					char *sname;
345200478Shrs
346200478Shrs					sname = malloc(NI_MAXSERV);
347200478Shrs					if (sname == NULL) {
348200478Shrs						_msgout("malloc(): %s",
349200478Shrs						    strerror(errno));
350200478Shrs						freeaddrinfo(res0);
351200478Shrs						close(s);
352200478Shrs						return -1;
353200478Shrs					}
354200478Shrs					memset(sname, 0, NI_MAXSERV);
355200478Shrs
356200478Shrs					sap = (struct sockaddr *)&slep->sle_ss;
357200478Shrs					slen = sizeof(*sap);
358200478Shrs					error = getsockname(s, sap, &slen);
359200478Shrs					if (error) {
360200478Shrs						_msgout("getsockname(): %s",
361200478Shrs						    strerror(errno));
362200478Shrs						freeaddrinfo(res0);
363200478Shrs						close(s);
364228790Seadler						free(sname);
365200478Shrs						return -1;
366200478Shrs					}
367200478Shrs					error = getnameinfo(sap, slen,
368200478Shrs					    NULL, 0,
369200478Shrs					    sname, NI_MAXSERV,
370200478Shrs					    NI_NUMERICHOST | NI_NUMERICSERV);
371200478Shrs					if (error) {
372200478Shrs						_msgout("getnameinfo(): %s",
373200478Shrs						    strerror(errno));
374200478Shrs						freeaddrinfo(res0);
375200478Shrs						close(s);
376228790Seadler						free(sname);
377200478Shrs						return -1;
378200478Shrs					}
379200478Shrs					servname = sname;
380200478Shrs				}
381200478Shrs			}
382200478Shrs			freeaddrinfo(res0);
383200478Shrs		}
384200478Shrs	} else {
385200478Shrs		slep = malloc(sizeof(*slep));
386200478Shrs		if (slep == NULL) {
387200478Shrs			_msgout("malloc failed: %s", strerror(errno));
388200478Shrs			return -1;
389200478Shrs		}
390200478Shrs		memset(slep, 0, sizeof(*slep));
391200478Shrs		slep->sle_sock = sock;
392200478Shrs		SLIST_INSERT_HEAD(&sle_head, slep, sle_next);
393200478Shrs	}
394200478Shrs
395200478Shrs	/*
396200478Shrs	 * Traverse socketlist and create rpc service handles for each socket.
397200478Shrs	 */
398200478Shrs	SLIST_FOREACH(slep, &sle_head, sle_next) {
399200478Shrs		if (nconf->nc_semantics == NC_TPI_CLTS)
400200478Shrs			transp = svc_dg_create(slep->sle_sock, 0, 0);
401200478Shrs		else
402200478Shrs			transp = svc_vc_create(slep->sle_sock, RPC_MAXDATASIZE,
403200478Shrs			    RPC_MAXDATASIZE);
404200478Shrs		if (transp == NULL) {
405200478Shrs			_msgout("unable to create service: %s",
406200478Shrs			    nconf->nc_netid);
407200478Shrs			continue;
408200478Shrs		}
409200478Shrs		if (!svc_reg(transp, YPPROG, YPOLDVERS, ypprog_1, NULL)) {
410200478Shrs			svc_destroy(transp);
411200478Shrs			close(slep->sle_sock);
412200478Shrs			_msgout("unable to register (YPPROG, YPOLDVERS, %s):"
413200478Shrs			    " %s", nconf->nc_netid, strerror(errno));
414200478Shrs			continue;
415200478Shrs		}
416200478Shrs		if (!svc_reg(transp, YPPROG, YPVERS, ypprog_2, NULL)) {
417200478Shrs			svc_destroy(transp);
418200478Shrs			close(slep->sle_sock);
419200478Shrs			_msgout("unable to register (YPPROG, YPVERS, %s): %s",
420200478Shrs			    nconf->nc_netid, strerror(errno));
421200478Shrs			continue;
422200478Shrs		}
423200478Shrs	}
424200478Shrs	while(!(SLIST_EMPTY(&sle_head)))
425200478Shrs		SLIST_REMOVE_HEAD(&sle_head, sle_next);
426200478Shrs
427200478Shrs	/*
428200478Shrs	 * Register RPC service to rpcbind by using AI_PASSIVE address.
429200478Shrs	 */
430200478Shrs	hints.ai_flags = AI_PASSIVE;
431200478Shrs	error = getaddrinfo(NULL, servname, &hints, &res0);
432200478Shrs	if (error) {
433200478Shrs		_msgout("getaddrinfo(): %s", gai_strerror(error));
434200478Shrs		return -1;
435200478Shrs	}
436200478Shrs	svcaddr.buf = res0->ai_addr;
437200478Shrs	svcaddr.len = res0->ai_addrlen;
438200478Shrs
439200478Shrs	if (si->si_af == AF_INET) {
440200478Shrs		/* XXX: ignore error intentionally */
441200478Shrs		rpcb_set(YPPROG, YPOLDVERS, nconf, &svcaddr);
442200478Shrs	}
443200478Shrs	/* XXX: ignore error intentionally */
444200478Shrs	rpcb_set(YPPROG, YPVERS, nconf, &svcaddr);
445200478Shrs	freeaddrinfo(res0);
446200478Shrs	return 0;
447200478Shrs}
448200478Shrs
44930827Scharnierint
45090298Sdesmain(int argc, char *argv[])
45112891Swpaul{
45212891Swpaul	int ch;
453200478Shrs	int error;
454202707Shrs	int ntrans;
455200478Shrs
456200478Shrs	void *nc_handle;
457200478Shrs	struct netconfig *nconf;
458200478Shrs	struct __rpc_sockinfo si;
459200478Shrs	struct bindaddrlistent *blep;
46012891Swpaul
461200478Shrs	memset(&si, 0, sizeof(si));
462200478Shrs	SLIST_INIT(&ble_head);
463200478Shrs
464200478Shrs	while ((ch = getopt(argc, argv, "dh:np:P:")) != -1) {
46590297Sdes		switch (ch) {
46612891Swpaul		case 'd':
46712997Swpaul			debug = ypdb_debug = 1;
46812891Swpaul			break;
469200478Shrs		case 'h':
470200478Shrs			blep = malloc(sizeof(*blep));
471200478Shrs			if (blep == NULL)
472200478Shrs				err(1, "malloc() failed: -h %s", optarg);
473200478Shrs			blep->ble_hostname = optarg;
474200478Shrs			SLIST_INSERT_HEAD(&ble_head, blep, ble_next);
475200478Shrs			break;
47612891Swpaul		case 'n':
47712891Swpaul			do_dns = 1;
47812891Swpaul			break;
47912891Swpaul		case 'p':
48012891Swpaul			yp_dir = optarg;
48112891Swpaul			break;
482175951Smatteo		case 'P':
483200478Shrs			servname = optarg;
484175951Smatteo			break;
48512891Swpaul		default:
48612891Swpaul			usage();
48712891Swpaul		}
48812891Swpaul	}
489200478Shrs	/*
490200478Shrs	 * Add "anyaddr" entry if no -h is specified.
491200478Shrs	 */
492200478Shrs	if (SLIST_EMPTY(&ble_head)) {
493200478Shrs		blep = malloc(sizeof(*blep));
494200478Shrs		if (blep == NULL)
495200478Shrs			err(1, "malloc() failed");
496200478Shrs		memset(blep, 0, sizeof(*blep));
497200478Shrs		SLIST_INSERT_HEAD(&ble_head, blep, ble_next);
498200478Shrs	}
49912891Swpaul
50014240Swpaul	load_securenets();
50120818Swpaul	yp_init_resolver();
50215426Swpaul#ifdef DB_CACHE
50315426Swpaul	yp_init_dbs();
50415426Swpaul#endif
505200478Shrs	nc_handle = setnetconfig();
506200478Shrs	if (nc_handle == NULL)
507200478Shrs		err(1, "cannot read %s", NETCONFIG);
508200478Shrs	if (__rpc_fd2sockinfo(0, &si) != 0) {
509200478Shrs		/* invoked from inetd */
51012891Swpaul		_rpcpmstart = 1;
511200478Shrs		_rpcfdtype = si.si_socktype;
512200478Shrs		_rpcaf = si.si_af;
513200478Shrs		_rpcfd = 0;
51430827Scharnier		openlog("ypserv", LOG_PID, LOG_DAEMON);
51512891Swpaul	} else {
516200478Shrs		/* standalone mode */
51712891Swpaul		if (!debug) {
51812891Swpaul			if (daemon(0,0)) {
51916044Swpaul				err(1,"cannot fork");
52012891Swpaul			}
52130827Scharnier			openlog("ypserv", LOG_PID, LOG_DAEMON);
52212891Swpaul		}
523200478Shrs		_rpcpmstart = 0;
524200478Shrs		_rpcaf = AF_INET;
525200478Shrs		_rpcfd = RPC_ANYFD;
526200478Shrs		unregister();
52712891Swpaul	}
52812891Swpaul
529226725Sglebius	if (madvise(NULL, 0, MADV_PROTECT) != 0)
530226725Sglebius		_msgout("madvise(): %s", strerror(errno));
531226725Sglebius
532175951Smatteo	/*
533200478Shrs	 * Create RPC service for each transport.
534175951Smatteo	 */
535202707Shrs	ntrans = 0;
536200478Shrs	while((nconf = getnetconfig(nc_handle))) {
537200478Shrs		if ((nconf->nc_flag & NC_VISIBLE)) {
538200478Shrs			if (__rpc_nconf2sockinfo(nconf, &si) == 0) {
539202707Shrs				_msgout("cannot get information for %s.  "
540202707Shrs				    "Ignored.", nconf->nc_netid);
541202707Shrs				continue;
542200478Shrs			}
543200478Shrs			if (_rpcpmstart) {
544200478Shrs				if (si.si_socktype != _rpcfdtype ||
545200478Shrs				    si.si_af != _rpcaf)
546200478Shrs					continue;
547200478Shrs			} else if (si.si_af != _rpcaf)
548200478Shrs					continue;
549200478Shrs			error = create_service(_rpcfd, nconf, &si);
550200478Shrs			if (error) {
551200478Shrs				endnetconfig(nc_handle);
552200478Shrs				exit(1);
553200478Shrs			}
554202707Shrs			ntrans++;
555175951Smatteo		}
556175951Smatteo	}
557200478Shrs	endnetconfig(nc_handle);
558200478Shrs	while(!(SLIST_EMPTY(&ble_head)))
559200478Shrs		SLIST_REMOVE_HEAD(&ble_head, ble_next);
560202707Shrs	if (ntrans == 0) {
561202707Shrs		_msgout("no transport is available.  Aborted.");
562202707Shrs		exit(1);
563202707Shrs	}
56412891Swpaul	if (_rpcpmstart) {
56512891Swpaul		(void) signal(SIGALRM, (SIG_PF) closedown);
56612891Swpaul		(void) alarm(_RPCSVC_CLOSEDOWN/2);
56712891Swpaul	}
56812891Swpaul/*
56912891Swpaul * Make sure SIGPIPE doesn't blow us away while servicing TCP
57012891Swpaul * connections.
57112891Swpaul */
57212891Swpaul	(void) signal(SIGPIPE, SIG_IGN);
57312891Swpaul	(void) signal(SIGCHLD, (SIG_PF) reaper);
57412891Swpaul	(void) signal(SIGTERM, (SIG_PF) reaper);
57512891Swpaul	(void) signal(SIGINT, (SIG_PF) reaper);
57612891Swpaul	(void) signal(SIGHUP, (SIG_PF) reaper);
57712891Swpaul	yp_svc_run();
57812891Swpaul	_msgout("svc_run returned");
57912891Swpaul	exit(1);
58012891Swpaul	/* NOTREACHED */
58112891Swpaul}
582