xref: /csrg-svn/sbin/nfsd/nfsd.c (revision 52510)
138458Smckusick /*
238458Smckusick  * Copyright (c) 1989 The Regents of the University of California.
338458Smckusick  * All rights reserved.
438458Smckusick  *
538458Smckusick  * This code is derived from software contributed to Berkeley by
638458Smckusick  * Rick Macklem at The University of Guelph.
738458Smckusick  *
842704Sbostic  * %sccs.include.redist.c%
938458Smckusick  */
1038458Smckusick 
1138458Smckusick #ifndef lint
1238458Smckusick char copyright[] =
1338458Smckusick "@(#) Copyright (c) 1989 Regents of the University of California.\n\
1438458Smckusick  All rights reserved.\n";
1538458Smckusick #endif not lint
1638458Smckusick 
1738458Smckusick #ifndef lint
18*52510Smckusick static char sccsid[] = "@(#)nfsd.c	5.11 (Berkeley) 02/15/92";
1938458Smckusick #endif not lint
2038458Smckusick 
21*52510Smckusick #include <stdio.h>
22*52510Smckusick #include <signal.h>
23*52510Smckusick #include <fcntl.h>
24*52510Smckusick #include <strings.h>
25*52510Smckusick #include <pwd.h>
26*52510Smckusick #include <grp.h>
2738458Smckusick #include <sys/types.h>
28*52510Smckusick #include <sys/syslog.h>
29*52510Smckusick #include <sys/param.h>
30*52510Smckusick #include <sys/errno.h>
3138458Smckusick #include <sys/ioctl.h>
3238458Smckusick #include <sys/stat.h>
3341917Smckusick #include <sys/wait.h>
34*52510Smckusick #include <sys/uio.h>
35*52510Smckusick #include <sys/namei.h>
36*52510Smckusick #include <sys/ucred.h>
3738458Smckusick #include <sys/mount.h>
3838458Smckusick #include <sys/socket.h>
3938458Smckusick #include <sys/socketvar.h>
4038458Smckusick #include <rpc/rpc.h>
4138458Smckusick #include <rpc/pmap_clnt.h>
4238458Smckusick #include <rpc/pmap_prot.h>
43*52510Smckusick #ifdef ISO
44*52510Smckusick #include <netiso/iso.h>
45*52510Smckusick #endif
4638458Smckusick #include <nfs/rpcv2.h>
4738458Smckusick #include <nfs/nfsv2.h>
48*52510Smckusick #include <nfs/nfs.h>
49*52510Smckusick #ifdef KERBEROS
50*52510Smckusick #include <kerberosIV/krb.h>
51*52510Smckusick #endif
5238458Smckusick 
5338458Smckusick /* Global defs */
5438458Smckusick #ifdef DEBUG
5538458Smckusick #define	syslog(e, s)	fprintf(stderr,(s))
5648625Skarels int	debug = 1;
5738458Smckusick #else
5848625Skarels int	debug = 0;
5938458Smckusick #endif
60*52510Smckusick struct	nfsd_srvargs nsd;
61*52510Smckusick extern	int errno;
6248625Skarels char	**Argv = NULL;		/* pointer to argument vector */
6348625Skarels char	*LastArg = NULL;	/* end of argv */
6448625Skarels void	reapchild();
6538458Smckusick 
66*52510Smckusick #ifdef KERBEROS
67*52510Smckusick char		lnam[ANAME_SZ];
68*52510Smckusick KTEXT_ST	kt;
69*52510Smckusick AUTH_DAT	auth;
70*52510Smckusick char		inst[INST_SZ];
71*52510Smckusick #endif /* KERBEROS */
72*52510Smckusick 
7338458Smckusick /*
7438458Smckusick  * Nfs server daemon mostly just a user context for nfssvc()
7538458Smckusick  * 1 - do file descriptor and signal cleanup
76*52510Smckusick  * 2 - fork the nfsd(s)
77*52510Smckusick  * 3 - create server socket(s)
78*52510Smckusick  * 4 - register socket with portmap
79*52510Smckusick  * For connectionless protocols, just pass the socket into the kernel via.
80*52510Smckusick  * nfssvc().
8141917Smckusick  * For connection based sockets, loop doing accepts. When you get a new socket
82*52510Smckusick  * from accept, pass the msgsock into the kernel via. nfssvc().
8341917Smckusick  * The arguments are:
84*52510Smckusick  * -u - support udp nfs clients
8541917Smckusick  * -t - support tcp nfs clients
86*52510Smckusick  * -c - support iso cltp clients
87*52510Smckusick  * -r - reregister with portmapper
88*52510Smckusick  * followed by "n" which is the number of nfsds' to fork off
8938458Smckusick  */
9048625Skarels main(argc, argv, envp)
9138458Smckusick 	int argc;
9248625Skarels 	char *argv[], *envp[];
9338458Smckusick {
9438458Smckusick 	register int i;
95*52510Smckusick 	register char *cp, **cpp;
96*52510Smckusick 	register struct ucred *cr = &nsd.nsd_cr;
97*52510Smckusick 	struct passwd *pwd;
98*52510Smckusick 	struct group *grp;
99*52510Smckusick 	int sock, msgsock, tcpflag = 0, udpflag = 0, ret, len;
100*52510Smckusick 	int cltpflag = 0, tp4flag = 0, tpipflag = 0, connect_type_cnt = 0;
101*52510Smckusick 	int maxsock, tcpsock, tp4sock, tpipsock, nfsdcnt = 4;
102*52510Smckusick 	int nfssvc_flag, opt, on = 1, reregister = 0;
103*52510Smckusick 	struct sockaddr_in inetaddr, inetpeer;
104*52510Smckusick #ifdef ISO
105*52510Smckusick 	struct sockaddr_iso isoaddr, isopeer;
106*52510Smckusick #endif
107*52510Smckusick 	struct nfsd_args nfsdargs;
108*52510Smckusick 	fd_set ready, sockbits;
10941917Smckusick 	extern int optind;
11041917Smckusick 	extern char *optarg;
11138458Smckusick 
11248625Skarels 	/*
11348625Skarels 	 *  Save start and extent of argv for setproctitle.
11448625Skarels 	 */
11548625Skarels 	Argv = argv;
11648625Skarels 	if (envp == 0 || *envp == 0)
11748625Skarels 		envp = argv;
11848625Skarels 	while (*envp)
11948625Skarels 		envp++;
12048625Skarels 	LastArg = envp[-1] + strlen(envp[-1]);
121*52510Smckusick 	while ((opt = getopt(argc, argv, "utcr")) != EOF)
12241917Smckusick 		switch (opt) {
123*52510Smckusick 		case 'u':
124*52510Smckusick 			udpflag++;
12548625Skarels 			break;
12641917Smckusick 		case 't':
12741917Smckusick 			tcpflag++;
12841917Smckusick 			break;
129*52510Smckusick 		case 'r':
130*52510Smckusick 			reregister++;
13141917Smckusick 			break;
132*52510Smckusick #ifdef ISO
133*52510Smckusick 		case 'c':
134*52510Smckusick 			cltpflag++;
135*52510Smckusick 			break;
136*52510Smckusick #ifdef notyet
137*52510Smckusick 		case 'i':
138*52510Smckusick 			tp4cnt++;
139*52510Smckusick 			break;
140*52510Smckusick 		case 'p':
141*52510Smckusick 			tpipcnt++;
142*52510Smckusick 			break;
143*52510Smckusick #endif /* notyet */
144*52510Smckusick #endif	/* ISO */
14541917Smckusick 		default:
14641917Smckusick 		case '?':
14741917Smckusick 			usage();
148*52510Smckusick 		};
149*52510Smckusick 	if (optind < argc)
150*52510Smckusick 		nfsdcnt = atoi(argv[optind]);
151*52510Smckusick 	if (nfsdcnt < 1 || nfsdcnt > 20)
152*52510Smckusick 		nfsdcnt = 4;
15348625Skarels 
15438458Smckusick 	if (debug == 0) {
15544691Skarels 		daemon(0, 0);
15638458Smckusick 		signal(SIGINT, SIG_IGN);
15738458Smckusick 		signal(SIGQUIT, SIG_IGN);
15838458Smckusick 		signal(SIGTERM, SIG_IGN);
15938458Smckusick 		signal(SIGHUP, SIG_IGN);
16038458Smckusick 	}
16148625Skarels 	signal(SIGCHLD, reapchild);
16248625Skarels 
16348625Skarels 	if (reregister) {
16448625Skarels 		if (udpflag && !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP,
16548625Skarels 		    NFS_PORT)) {
16648625Skarels 			fprintf(stderr,
16748625Skarels 			    "Can't register with portmap for UDP\n");
16848625Skarels 			exit(1);
16948625Skarels 		}
17048625Skarels 		if (tcpflag && !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP,
17148625Skarels 		    NFS_PORT)) {
17248625Skarels 			fprintf(stderr,
17348625Skarels 			    "Can't register with portmap for TCP\n");
17448625Skarels 			exit(1);
17548625Skarels 		}
17648625Skarels 		exit(0);
17748625Skarels 	}
17838458Smckusick 	openlog("nfsd:", LOG_PID, LOG_DAEMON);
179*52510Smckusick 
180*52510Smckusick 	for (i = 0; i < nfsdcnt; i++)
181*52510Smckusick 	    if (fork() == 0) {
182*52510Smckusick 		setproctitle("nfsd-srv");
183*52510Smckusick 		nfssvc_flag = NFSSVC_NFSD;
184*52510Smckusick 		nsd.nsd_nfsd = (struct nfsd *)0;
185*52510Smckusick #ifdef KERBEROS
186*52510Smckusick 		nsd.nsd_authstr = (char *)kt.dat;
18748625Skarels #endif
188*52510Smckusick 		while (nfssvc(nfssvc_flag, (caddr_t)&nsd) < 0) {
189*52510Smckusick 		    if (errno == ENEEDAUTH) {
190*52510Smckusick 			nfssvc_flag = (NFSSVC_NFSD | NFSSVC_AUTHINFAIL);
191*52510Smckusick #ifdef KERBEROS
192*52510Smckusick 			kt.length = nsd.nsd_authlen;
193*52510Smckusick 			kt.mbz = 0;
194*52510Smckusick 			strcpy(inst, "*");
195*52510Smckusick 			if (krb_rd_req(&kt, "rcmd", inst, nsd.nsd_haddr,
196*52510Smckusick 			    &auth, "") == RD_AP_OK &&
197*52510Smckusick 			    krb_kntoln(&auth, lnam) == KSUCCESS &&
198*52510Smckusick 			    (pwd = getpwnam(lnam))) {
199*52510Smckusick 			    cr->cr_uid = pwd->pw_uid;
200*52510Smckusick 			    cr->cr_groups[0] = pwd->pw_gid;
201*52510Smckusick 			    cr->cr_ngroups = 1;
202*52510Smckusick 			    setgrent();
203*52510Smckusick 			    while (grp = getgrent()) {
204*52510Smckusick 				if (grp->gr_gid == cr->cr_groups[0])
205*52510Smckusick 				    continue;
206*52510Smckusick 				cpp = grp->gr_mem;
207*52510Smckusick 				while (*cpp) {
208*52510Smckusick 				    if (!strcmp(*cpp, lnam))
209*52510Smckusick 					break;
210*52510Smckusick 				    cpp++;
211*52510Smckusick 				}
212*52510Smckusick 				if (*cpp) {
213*52510Smckusick 				    cr->cr_groups[cr->cr_ngroups++] = grp->gr_gid;
214*52510Smckusick 				    if (cr->cr_ngroups == NGROUPS)
215*52510Smckusick 					break;
216*52510Smckusick 				}
217*52510Smckusick 			    }
218*52510Smckusick 			    endgrent();
219*52510Smckusick 			    nfssvc_flag = (NFSSVC_NFSD | NFSSVC_AUTHIN);
220*52510Smckusick 			}
221*52510Smckusick #endif	/* KERBEROS */
222*52510Smckusick 		    } else {
223*52510Smckusick fprintf(stderr, "errno=%d\n",errno);
224*52510Smckusick 			syslog(LOG_ERR, "Nfsd died %m");
225*52510Smckusick 			exit(1);
226*52510Smckusick 		    }
227*52510Smckusick 		}
228*52510Smckusick 		exit();
229*52510Smckusick 	    }
230*52510Smckusick 
231*52510Smckusick 	/*
232*52510Smckusick 	 * If we are serving udp, set up the socket.
233*52510Smckusick 	 */
23441917Smckusick 	if (udpflag) {
23541917Smckusick 		if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
236*52510Smckusick 			syslog(LOG_ERR, "Can't create udp socket");
23741917Smckusick 			exit(1);
23841917Smckusick 		}
239*52510Smckusick 		inetaddr.sin_family = AF_INET;
240*52510Smckusick 		inetaddr.sin_addr.s_addr = INADDR_ANY;
241*52510Smckusick 		inetaddr.sin_port = htons(NFS_PORT);
242*52510Smckusick 		inetaddr.sin_len = sizeof(inetaddr);
243*52510Smckusick 		if (bind(sock, (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) {
244*52510Smckusick 			syslog(LOG_ERR, "Can't bind udp addr");
24541917Smckusick 			exit(1);
24641917Smckusick 		}
24741917Smckusick 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
248*52510Smckusick 			syslog(LOG_ERR, "Can't register with udp portmap");
24941917Smckusick 			exit(1);
25041917Smckusick 		}
251*52510Smckusick 		nfsdargs.sock = sock;
252*52510Smckusick 		nfsdargs.name = (caddr_t)0;
253*52510Smckusick 		nfsdargs.namelen = 0;
254*52510Smckusick 		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
255*52510Smckusick 			syslog(LOG_ERR, "Can't Add UDP socket");
256*52510Smckusick 			exit(1);
257*52510Smckusick 		}
258*52510Smckusick 		close(sock);
259*52510Smckusick 	}
260*52510Smckusick 
261*52510Smckusick 	/*
262*52510Smckusick 	 * If we are serving cltp, set up the socket.
263*52510Smckusick 	 */
264*52510Smckusick #ifdef ISO
265*52510Smckusick 	if (cltpflag) {
266*52510Smckusick 		if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) {
267*52510Smckusick 			syslog(LOG_ERR, "Can't create cltp socket");
268*52510Smckusick 			exit(1);
269*52510Smckusick 		}
270*52510Smckusick 		bzero((caddr_t)&isoaddr, sizeof (isoaddr));
271*52510Smckusick 		isoaddr.siso_family = AF_ISO;
272*52510Smckusick 		isoaddr.siso_tlen = 2;
273*52510Smckusick 		cp = TSEL(&isoaddr);
274*52510Smckusick 		*cp++ = (NFS_PORT >> 8);
275*52510Smckusick 		*cp = (NFS_PORT & 0xff);
276*52510Smckusick 		isoaddr.siso_len = sizeof(isoaddr);
277*52510Smckusick 		if (bind(sock, (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) {
278*52510Smckusick 			syslog(LOG_ERR, "Can't bind cltp addr");
279*52510Smckusick 			exit(1);
280*52510Smckusick 		}
281*52510Smckusick #ifdef notyet
28241917Smckusick 		/*
283*52510Smckusick 		 * Someday this should probably use "rpcbind", the son of
284*52510Smckusick 		 * portmap.
28541917Smckusick 		 */
286*52510Smckusick 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
287*52510Smckusick 			syslog(LOG_ERR, "Can't register with udp portmap");
288*52510Smckusick 			exit(1);
289*52510Smckusick 		}
290*52510Smckusick #endif /* notyet */
291*52510Smckusick 		nfsdargs.sock = sock;
292*52510Smckusick 		nfsdargs.name = (caddr_t)0;
293*52510Smckusick 		nfsdargs.namelen = 0;
294*52510Smckusick 		if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
295*52510Smckusick 			syslog(LOG_ERR, "Can't Add UDP socket");
296*52510Smckusick 			exit();
297*52510Smckusick 		}
29841917Smckusick 		close(sock);
29938458Smckusick 	}
300*52510Smckusick #endif	/* ISO */
30141917Smckusick 
30241917Smckusick 	/*
303*52510Smckusick 	 * Now set up the master server socket waiting for tcp connections.
30441917Smckusick 	 */
305*52510Smckusick 	FD_ZERO(&sockbits);
30641917Smckusick 	if (tcpflag) {
307*52510Smckusick 		if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
308*52510Smckusick 			syslog(LOG_ERR, "Can't create tcp socket");
309*52510Smckusick 			exit(1);
310*52510Smckusick 		}
311*52510Smckusick 		if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR,
312*52510Smckusick 		    (char *) &on, sizeof(on)) < 0)
313*52510Smckusick 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
314*52510Smckusick 		inetaddr.sin_family = AF_INET;
315*52510Smckusick 		inetaddr.sin_addr.s_addr = INADDR_ANY;
316*52510Smckusick 		inetaddr.sin_port = htons(NFS_PORT);
317*52510Smckusick 		inetaddr.sin_len = sizeof (inetaddr);
318*52510Smckusick 		if (bind(tcpsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) {
319*52510Smckusick 			syslog(LOG_ERR, "Can't bind tcp addr");
320*52510Smckusick 			exit(1);
321*52510Smckusick 		}
322*52510Smckusick 		if (listen(tcpsock, 5) < 0) {
323*52510Smckusick 			syslog(LOG_ERR, "Listen failed");
324*52510Smckusick 			exit(1);
325*52510Smckusick 		}
326*52510Smckusick 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
327*52510Smckusick 			syslog(LOG_ERR, "Can't register tcp with portmap");
328*52510Smckusick 			exit(1);
329*52510Smckusick 		}
330*52510Smckusick 		FD_SET(tcpsock, &sockbits);
331*52510Smckusick 		maxsock = tcpsock;
332*52510Smckusick 		connect_type_cnt++;
333*52510Smckusick 	}
33448625Skarels 
335*52510Smckusick #ifdef notyet
336*52510Smckusick 	/*
337*52510Smckusick 	 * Now set up the master server socket waiting for tp4 connections.
338*52510Smckusick 	 */
339*52510Smckusick 	if (tp4flag) {
340*52510Smckusick 		if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) {
341*52510Smckusick 			syslog(LOG_ERR, "Can't create tp4 socket");
34241917Smckusick 			exit(1);
34341917Smckusick 		}
344*52510Smckusick 		if (setsockopt(tp4sock, SOL_SOCKET, SO_REUSEADDR,
34548625Skarels 		    (char *) &on, sizeof(on)) < 0)
34648625Skarels 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
347*52510Smckusick 		bzero((caddr_t)&isoaddr, sizeof (isoaddr));
348*52510Smckusick 		isoaddr.siso_family = AF_ISO;
349*52510Smckusick 		isoaddr.siso_tlen = 2;
350*52510Smckusick 		cp = TSEL(&isoaddr);
351*52510Smckusick 		*cp++ = (NFS_PORT >> 8);
352*52510Smckusick 		*cp = (NFS_PORT & 0xff);
353*52510Smckusick 		isoaddr.siso_len = sizeof(isoaddr);
354*52510Smckusick 		if (bind(tp4sock, (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) {
355*52510Smckusick 			syslog(LOG_ERR, "Can't bind tp4 addr");
35641917Smckusick 			exit(1);
35741917Smckusick 		}
358*52510Smckusick 		if (listen(tp4sock, 5) < 0) {
35941917Smckusick 			syslog(LOG_ERR, "Listen failed");
36041917Smckusick 			exit(1);
36141917Smckusick 		}
362*52510Smckusick 		/*
363*52510Smckusick 		 * Someday this should probably use "rpcbind".
364*52510Smckusick 		 */
36541917Smckusick 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
366*52510Smckusick 			syslog(LOG_ERR, "Can't register tcp with portmap");
36741917Smckusick 			exit(1);
36841917Smckusick 		}
369*52510Smckusick 		FD_SET(tp4sock, &sockbits);
370*52510Smckusick 		maxsock = tp4sock;
371*52510Smckusick 		connect_type_cnt++;
372*52510Smckusick 	}
373*52510Smckusick 
374*52510Smckusick 	/*
375*52510Smckusick 	 * Now set up the master server socket waiting for tpip connections.
376*52510Smckusick 	 */
377*52510Smckusick 	if (tpipflag) {
378*52510Smckusick 		if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) {
379*52510Smckusick 			syslog(LOG_ERR, "Can't create tpip socket");
380*52510Smckusick 			exit(1);
381*52510Smckusick 		}
382*52510Smckusick 		if (setsockopt(tpipsock, SOL_SOCKET, SO_REUSEADDR,
383*52510Smckusick 		    (char *) &on, sizeof(on)) < 0)
384*52510Smckusick 			syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m");
385*52510Smckusick 		inetaddr.sin_family = AF_INET;
386*52510Smckusick 		inetaddr.sin_addr.s_addr = INADDR_ANY;
387*52510Smckusick 		inetaddr.sin_port = htons(NFS_PORT);
388*52510Smckusick 		inetaddr.sin_len = sizeof (inetaddr);
389*52510Smckusick 		if (bind(tpipsock, (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) {
390*52510Smckusick 			syslog(LOG_ERR, "Can't bind tcp addr");
391*52510Smckusick 			exit(1);
392*52510Smckusick 		}
393*52510Smckusick 		if (listen(tpipsock, 5) < 0) {
394*52510Smckusick 			syslog(LOG_ERR, "Listen failed");
395*52510Smckusick 			exit(1);
396*52510Smckusick 		}
39741917Smckusick 		/*
398*52510Smckusick 		 * Someday this should use "rpcbind"
39941917Smckusick 		 */
400*52510Smckusick 		if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
401*52510Smckusick 			syslog(LOG_ERR, "Can't register tcp with portmap");
402*52510Smckusick 			exit(1);
403*52510Smckusick 		}
404*52510Smckusick 		FD_SET(tpipsock, &sockbits);
405*52510Smckusick 		maxsock = tpipsock;
406*52510Smckusick 		connect_type_cnt++;
407*52510Smckusick 	}
408*52510Smckusick #endif	/* notyet */
409*52510Smckusick 
410*52510Smckusick 	if (connect_type_cnt == 0)
411*52510Smckusick 		exit();
412*52510Smckusick 	setproctitle("nfsd-master");
413*52510Smckusick 	/*
414*52510Smckusick 	 * Loop forever accepting connections and passing the sockets
415*52510Smckusick 	 * into the kernel for the mounts.
416*52510Smckusick 	 */
417*52510Smckusick 	for (;;) {
418*52510Smckusick 		ready = sockbits;
419*52510Smckusick 		if (connect_type_cnt > 1) {
420*52510Smckusick 			if (select(maxsock + 1, &ready, (fd_set *)0,
421*52510Smckusick 				(fd_set *)0, (struct timeval *)0) < 1) {
422*52510Smckusick 				syslog(LOG_ERR, "Select failed");
423*52510Smckusick 				exit(1);
424*52510Smckusick 			}
425*52510Smckusick 		}
426*52510Smckusick 		if (tcpflag && FD_ISSET(tcpsock, &ready)) {
427*52510Smckusick 			len = sizeof(inetpeer);
428*52510Smckusick 			if ((msgsock = accept(tcpsock,
429*52510Smckusick 			    (struct sockaddr *)&inetpeer, &len)) < 0) {
43041917Smckusick 				syslog(LOG_ERR, "Accept failed: %m");
43141917Smckusick 				exit(1);
43241917Smckusick 			}
433*52510Smckusick 			if (setsockopt(msgsock, SOL_SOCKET,
434*52510Smckusick 			    SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0)
435*52510Smckusick 				syslog(LOG_ERR,
436*52510Smckusick 				    "setsockopt SO_KEEPALIVE: %m");
437*52510Smckusick 			nfsdargs.sock = msgsock;
438*52510Smckusick 			nfsdargs.name = (caddr_t)&inetpeer;
439*52510Smckusick 			nfsdargs.namelen = len;
440*52510Smckusick 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
441*52510Smckusick 			close(msgsock);
442*52510Smckusick 		}
443*52510Smckusick #ifdef notyet
444*52510Smckusick 		if (tp4flag && FD_ISSET(tp4sock, &ready)) {
445*52510Smckusick 			len = sizeof(isopeer);
446*52510Smckusick 			if ((msgsock = accept(tp4sock,
447*52510Smckusick 			    (struct sockaddr *)&isopeer, &len)) < 0) {
448*52510Smckusick 				syslog(LOG_ERR, "Accept failed: %m");
449*52510Smckusick 				exit(1);
45041917Smckusick 			}
451*52510Smckusick 			if (setsockopt(msgsock, SOL_SOCKET,
452*52510Smckusick 			    SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0)
453*52510Smckusick 				syslog(LOG_ERR,
454*52510Smckusick 				    "setsockopt SO_KEEPALIVE: %m");
455*52510Smckusick 			nfsdargs.sock = msgsock;
456*52510Smckusick 			nfsdargs.name = (caddr_t)&isopeer;
457*52510Smckusick 			nfsdargs.namelen = len;
458*52510Smckusick 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
459*52510Smckusick 			close(msgsock);
460*52510Smckusick 		}
461*52510Smckusick 		if (tpipflag && FD_ISSET(tpipsock, &ready)) {
462*52510Smckusick 			len = sizeof(inetpeer);
463*52510Smckusick 			if ((msgsock = accept(tpipsock,
464*52510Smckusick 			    (struct sockaddr *)&inetpeer, &len)) < 0) {
465*52510Smckusick 				syslog(LOG_ERR, "Accept failed: %m");
46645247Smckusick 				exit(1);
46741917Smckusick 			}
468*52510Smckusick 			if (setsockopt(msgsock, SOL_SOCKET,
469*52510Smckusick 			    SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0)
470*52510Smckusick 				syslog(LOG_ERR,
471*52510Smckusick 				    "setsockopt SO_KEEPALIVE: %m");
472*52510Smckusick 			nfsdargs.sock = msgsock;
473*52510Smckusick 			nfsdargs.name = (caddr_t)&inetpeer;
474*52510Smckusick 			nfsdargs.namelen = len;
475*52510Smckusick 			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
47641917Smckusick 			close(msgsock);
47741917Smckusick 		}
478*52510Smckusick #endif	/* notyet */
47939869Smckusick 	}
48038458Smckusick }
48141917Smckusick 
48241917Smckusick usage()
48341917Smckusick {
484*52510Smckusick 	fprintf(stderr, "nfsd [-u] [-t] [-c] [-r] [num_nfsds]\n");
48541917Smckusick 	exit(1);
48641917Smckusick }
48748625Skarels 
48848625Skarels void
48948625Skarels reapchild()
49048625Skarels {
49148625Skarels 
49248625Skarels 	while (wait3((int *) NULL, WNOHANG, (struct rusage *) NULL))
49348625Skarels 		;
49448625Skarels }
49548625Skarels 
496*52510Smckusick setproctitle(a)
49748625Skarels 	char *a;
49848625Skarels {
49948625Skarels 	register char *cp;
50048625Skarels 	char buf[80];
50148625Skarels 
50248625Skarels 	cp = Argv[0];
503*52510Smckusick 	(void) sprintf(buf, "%s", a);
50448625Skarels 	(void) strncpy(cp, buf, LastArg - cp);
50548625Skarels 	cp += strlen(cp);
50648625Skarels 	while (cp < LastArg)
50748625Skarels 		*cp++ = ' ';
50848625Skarels }
509