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