138458Smckusick /* 266235Sbostic * Copyright (c) 1989, 1993, 1994 361525Sbostic * The Regents of the University of California. 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 1261525Sbostic static char copyright[] = 1366235Sbostic "@(#) Copyright (c) 1989, 1993, 1994\n\ 1461525Sbostic The Regents of the University of California. All rights reserved.\n"; 1538458Smckusick #endif not lint 1638458Smckusick 1738458Smckusick #ifndef lint 18*66243Sbostic static char sccsid[] = "@(#)nfsd.c 8.6 (Berkeley) 02/22/94"; 1938458Smckusick #endif not lint 2038458Smckusick 2166235Sbostic #include <sys/param.h> 2252510Smckusick #include <sys/syslog.h> 2338458Smckusick #include <sys/ioctl.h> 2438458Smckusick #include <sys/stat.h> 2541917Smckusick #include <sys/wait.h> 2652510Smckusick #include <sys/uio.h> 2752510Smckusick #include <sys/ucred.h> 2838458Smckusick #include <sys/mount.h> 2938458Smckusick #include <sys/socket.h> 3038458Smckusick #include <sys/socketvar.h> 3166235Sbostic 3238458Smckusick #include <rpc/rpc.h> 3338458Smckusick #include <rpc/pmap_clnt.h> 3438458Smckusick #include <rpc/pmap_prot.h> 3566235Sbostic 3652510Smckusick #ifdef ISO 3752510Smckusick #include <netiso/iso.h> 3852510Smckusick #endif 3938458Smckusick #include <nfs/rpcv2.h> 4038458Smckusick #include <nfs/nfsv2.h> 4152510Smckusick #include <nfs/nfs.h> 4266235Sbostic 4352510Smckusick #ifdef KERBEROS 4457812Smckusick #include <kerberosIV/des.h> 4552510Smckusick #include <kerberosIV/krb.h> 4652510Smckusick #endif 4738458Smckusick 4866235Sbostic #include <err.h> 4966235Sbostic #include <errno.h> 5066235Sbostic #include <fcntl.h> 5166235Sbostic #include <grp.h> 5266235Sbostic #include <pwd.h> 5366235Sbostic #include <signal.h> 5466235Sbostic #include <stdio.h> 5566235Sbostic #include <stdlib.h> 5666235Sbostic #include <strings.h> 5766235Sbostic #include <unistd.h> 5866235Sbostic 5938458Smckusick /* Global defs */ 6038458Smckusick #ifdef DEBUG 6138458Smckusick #define syslog(e, s) fprintf(stderr,(s)) 6248625Skarels int debug = 1; 6338458Smckusick #else 6448625Skarels int debug = 0; 6538458Smckusick #endif 6666235Sbostic 6752510Smckusick struct nfsd_srvargs nsd; 6848625Skarels char **Argv = NULL; /* pointer to argument vector */ 6948625Skarels char *LastArg = NULL; /* end of argv */ 7038458Smckusick 7152510Smckusick #ifdef KERBEROS 7252510Smckusick char lnam[ANAME_SZ]; 7352510Smckusick KTEXT_ST kt; 7452510Smckusick AUTH_DAT auth; 7552510Smckusick char inst[INST_SZ]; 7666235Sbostic #endif 7752510Smckusick 7866240Sbostic void nonfs __P((int)); 7966235Sbostic void reapchild __P((int)); 8066235Sbostic void setproctitle __P((char *)); 8166235Sbostic void usage __P((void)); 8266235Sbostic 8338458Smckusick /* 8438458Smckusick * Nfs server daemon mostly just a user context for nfssvc() 8566235Sbostic * 8638458Smckusick * 1 - do file descriptor and signal cleanup 8752510Smckusick * 2 - fork the nfsd(s) 8852510Smckusick * 3 - create server socket(s) 8952510Smckusick * 4 - register socket with portmap 9066235Sbostic * 9152510Smckusick * For connectionless protocols, just pass the socket into the kernel via. 9252510Smckusick * nfssvc(). 9366235Sbostic * For connection based sockets, loop doing accepts. When you get a new 9466235Sbostic * socket from accept, pass the msgsock into the kernel via. nfssvc(). 9541917Smckusick * The arguments are: 9666235Sbostic * -c - support iso cltp clients 9766235Sbostic * -r - reregister with portmapper 9866235Sbostic * -t - support tcp nfs clients 9966235Sbostic * -u - support udp nfs clients 10052510Smckusick * followed by "n" which is the number of nfsds' to fork off 10138458Smckusick */ 10266235Sbostic int 10348625Skarels main(argc, argv, envp) 10438458Smckusick int argc; 10548625Skarels char *argv[], *envp[]; 10638458Smckusick { 10766235Sbostic extern int optind; 10866235Sbostic struct group *grp; 10966235Sbostic struct nfsd_args nfsdargs; 11052510Smckusick struct passwd *pwd; 11166235Sbostic struct ucred *cr; 11252510Smckusick struct sockaddr_in inetaddr, inetpeer; 11352510Smckusick #ifdef ISO 11452510Smckusick struct sockaddr_iso isoaddr, isopeer; 11552510Smckusick #endif 11652510Smckusick fd_set ready, sockbits; 11766235Sbostic int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock; 11866235Sbostic int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock; 11966235Sbostic int tp4cnt, tp4flag, tp4sock, tpipcnt, tpipflag, tpipsock, udpflag; 12066235Sbostic char *cp, **cpp; 12138458Smckusick 12266235Sbostic /* Save start and extent of argv for setproctitle. */ 12348625Skarels Argv = argv; 12448625Skarels if (envp == 0 || *envp == 0) 12548625Skarels envp = argv; 12648625Skarels while (*envp) 12748625Skarels envp++; 12848625Skarels LastArg = envp[-1] + strlen(envp[-1]); 12966235Sbostic 13066238Sbostic #define MAXNFSDCNT 20 13166238Sbostic #define DEFNFSDCNT 4 13266238Sbostic nfsdcnt = DEFNFSDCNT; 13366235Sbostic cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0; 13466235Sbostic tpipflag = udpflag = 0; 13566235Sbostic #ifdef ISO 13666238Sbostic #define GETOPT "cn:rtu" 13766238Sbostic #define USAGE "[-crtu] [-n num_servers]" 13866235Sbostic #else 13966238Sbostic #define GETOPT "n:rtu" 14066238Sbostic #define USAGE "[-rtu] [-n num_servers]" 14166235Sbostic #endif 14266238Sbostic while ((ch = getopt(argc, argv, GETOPT)) != EOF) 14366235Sbostic switch (ch) { 14466238Sbostic case 'n': 145*66243Sbostic nfsdcnt = atoi(optarg); 14666238Sbostic if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 14766238Sbostic warnx("nfsd count %d; reset to %d", DEFNFSDCNT); 14866238Sbostic nfsdcnt = DEFNFSDCNT; 14966238Sbostic } 15066238Sbostic break; 15166235Sbostic case 'r': 15266235Sbostic reregister = 1; 15348625Skarels break; 15441917Smckusick case 't': 15566235Sbostic tcpflag = 1; 15641917Smckusick break; 15766235Sbostic case 'u': 15866235Sbostic udpflag = 1; 15941917Smckusick break; 16052510Smckusick #ifdef ISO 16152510Smckusick case 'c': 16266235Sbostic cltpflag = 1; 16352510Smckusick break; 16452510Smckusick #ifdef notyet 16552510Smckusick case 'i': 16666235Sbostic tp4cnt = 1; 16752510Smckusick break; 16852510Smckusick case 'p': 16966235Sbostic tpipcnt = 1; 17052510Smckusick break; 17152510Smckusick #endif /* notyet */ 17266235Sbostic #endif /* ISO */ 17341917Smckusick default: 17441917Smckusick case '?': 17541917Smckusick usage(); 17652510Smckusick }; 17766235Sbostic argv += optind; 17866235Sbostic argc -= optind; 17966235Sbostic 18066238Sbostic /* 18166238Sbostic * XXX 18266238Sbostic * Backward compatibility, trailing number is the count of daemons. 18366238Sbostic */ 18466235Sbostic if (argc > 1) 18566235Sbostic usage(); 18666235Sbostic if (argc == 1) { 187*66243Sbostic nfsdcnt = atoi(argv[0]); 18866238Sbostic if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { 18966238Sbostic warnx("nfsd count %d; reset to %d", DEFNFSDCNT); 19066238Sbostic nfsdcnt = DEFNFSDCNT; 19166235Sbostic } 19266235Sbostic } 19348625Skarels 19438458Smckusick if (debug == 0) { 19544691Skarels daemon(0, 0); 19666235Sbostic (void)signal(SIGINT, SIG_IGN); 19766235Sbostic (void)signal(SIGQUIT, SIG_IGN); 19866235Sbostic (void)signal(SIGTERM, SIG_IGN); 19966235Sbostic (void)signal(SIGHUP, SIG_IGN); 20038458Smckusick } 20166240Sbostic (void)signal(SIGSYS, nonfs); 20266235Sbostic (void)signal(SIGCHLD, reapchild); 20348625Skarels 20448625Skarels if (reregister) { 20566235Sbostic if (udpflag && 20666235Sbostic !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) 20766235Sbostic err(1, "can't register with portmap for UDP."); 20866235Sbostic if (tcpflag && 20966235Sbostic !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) 21066235Sbostic err(1, "can't register with portmap for TCP."); 21148625Skarels exit(0); 21248625Skarels } 21338458Smckusick openlog("nfsd:", LOG_PID, LOG_DAEMON); 21452510Smckusick 21566235Sbostic for (i = 0; i < nfsdcnt; i++) { 21666235Sbostic switch (fork()) { 21766235Sbostic case -1: 21866235Sbostic syslog(LOG_ERR, "fork: %m"); 21966235Sbostic exit (1); 22066235Sbostic case 0: 22166235Sbostic break; 22266235Sbostic default: 22366235Sbostic continue; 22466235Sbostic } 22566235Sbostic 22652510Smckusick setproctitle("nfsd-srv"); 22752510Smckusick nfssvc_flag = NFSSVC_NFSD; 22866235Sbostic nsd.nsd_nfsd = NULL; 22952510Smckusick #ifdef KERBEROS 23052510Smckusick nsd.nsd_authstr = (char *)kt.dat; 23148625Skarels #endif 23266235Sbostic while (nfssvc(nfssvc_flag, &nsd) < 0) { 23366235Sbostic if (errno != ENEEDAUTH) { 23466235Sbostic syslog(LOG_ERR, "nfssvc: %m"); 23566235Sbostic exit(1); 23666235Sbostic } 23766235Sbostic nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL; 23852510Smckusick #ifdef KERBEROS 23952510Smckusick kt.length = nsd.nsd_authlen; 24052510Smckusick kt.mbz = 0; 24166235Sbostic (void)strcpy(inst, "*"); 24266235Sbostic if (krb_rd_req(&kt, "rcmd", 24366235Sbostic inst, nsd.nsd_haddr, &auth, "") == RD_AP_OK && 24452510Smckusick krb_kntoln(&auth, lnam) == KSUCCESS && 24566235Sbostic (pwd = getpwnam(lnam)) != NULL) { 24666235Sbostic cr = &nsd.nsd_cr; 24766235Sbostic cr->cr_uid = pwd->pw_uid; 24866235Sbostic cr->cr_groups[0] = pwd->pw_gid; 24966235Sbostic cr->cr_ngroups = 1; 25066235Sbostic setgrent(); 25166235Sbostic while ((grp = getgrent()) != NULL) { 25266235Sbostic if (grp->gr_gid == cr->cr_groups[0]) 25366235Sbostic continue; 25466235Sbostic for (cpp = grp->gr_mem; 25566235Sbostic *cpp != NULL; ++cpp) 25666235Sbostic if (!strcmp(*cpp, lnam)) 25766235Sbostic break; 25866235Sbostic if (*cpp == NULL) 25966235Sbostic continue; 26066235Sbostic cr->cr_groups[cr->cr_ngroups++] 26166235Sbostic = grp->gr_gid; 26266235Sbostic if (cr->cr_ngroups == NGROUPS) 26366235Sbostic break; 26452510Smckusick } 26566235Sbostic endgrent(); 26666235Sbostic nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN; 26752510Smckusick } 26866235Sbostic #endif /* KERBEROS */ 26952510Smckusick } 27066235Sbostic exit(0); 27166235Sbostic } 27252510Smckusick 27366235Sbostic /* If we are serving udp, set up the socket. */ 27441917Smckusick if (udpflag) { 27541917Smckusick if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 27666235Sbostic syslog(LOG_ERR, "can't create udp socket"); 27741917Smckusick exit(1); 27841917Smckusick } 27952510Smckusick inetaddr.sin_family = AF_INET; 28052510Smckusick inetaddr.sin_addr.s_addr = INADDR_ANY; 28152510Smckusick inetaddr.sin_port = htons(NFS_PORT); 28252510Smckusick inetaddr.sin_len = sizeof(inetaddr); 28366235Sbostic if (bind(sock, 28466235Sbostic (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) { 28566235Sbostic syslog(LOG_ERR, "can't bind udp addr"); 28641917Smckusick exit(1); 28741917Smckusick } 28841917Smckusick if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 28966235Sbostic syslog(LOG_ERR, "can't register with udp portmap"); 29041917Smckusick exit(1); 29141917Smckusick } 29252510Smckusick nfsdargs.sock = sock; 29366235Sbostic nfsdargs.name = NULL; 29452510Smckusick nfsdargs.namelen = 0; 29552510Smckusick if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 29666235Sbostic syslog(LOG_ERR, "can't Add UDP socket"); 29752510Smckusick exit(1); 29852510Smckusick } 29966235Sbostic (void)close(sock); 30052510Smckusick } 30152510Smckusick 30252510Smckusick #ifdef ISO 30366235Sbostic /* If we are serving cltp, set up the socket. */ 30452510Smckusick if (cltpflag) { 30552510Smckusick if ((sock = socket(AF_ISO, SOCK_DGRAM, 0)) < 0) { 30666235Sbostic syslog(LOG_ERR, "can't create cltp socket"); 30752510Smckusick exit(1); 30852510Smckusick } 30966235Sbostic memset(&isoaddr, 0, sizeof(isoaddr)); 31052510Smckusick isoaddr.siso_family = AF_ISO; 31152510Smckusick isoaddr.siso_tlen = 2; 31252510Smckusick cp = TSEL(&isoaddr); 31352510Smckusick *cp++ = (NFS_PORT >> 8); 31452510Smckusick *cp = (NFS_PORT & 0xff); 31552510Smckusick isoaddr.siso_len = sizeof(isoaddr); 31666235Sbostic if (bind(sock, 31766235Sbostic (struct sockaddr *)&isoaddr, sizeof(isoaddr)) < 0) { 31866235Sbostic syslog(LOG_ERR, "can't bind cltp addr"); 31952510Smckusick exit(1); 32052510Smckusick } 32152510Smckusick #ifdef notyet 32241917Smckusick /* 32366235Sbostic * XXX 32452510Smckusick * Someday this should probably use "rpcbind", the son of 32552510Smckusick * portmap. 32641917Smckusick */ 32752510Smckusick if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { 32866235Sbostic syslog(LOG_ERR, "can't register with udp portmap"); 32952510Smckusick exit(1); 33052510Smckusick } 33152510Smckusick #endif /* notyet */ 33252510Smckusick nfsdargs.sock = sock; 33366235Sbostic nfsdargs.name = NULL; 33452510Smckusick nfsdargs.namelen = 0; 33552510Smckusick if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) { 33666235Sbostic syslog(LOG_ERR, "can't add UDP socket"); 33766235Sbostic exit(1); 33852510Smckusick } 33941917Smckusick close(sock); 34038458Smckusick } 34166235Sbostic #endif /* ISO */ 34241917Smckusick 34366235Sbostic /* Now set up the master server socket waiting for tcp connections. */ 34466235Sbostic on = 1; 34552510Smckusick FD_ZERO(&sockbits); 34666235Sbostic connect_type_cnt = 0; 34741917Smckusick if (tcpflag) { 34852510Smckusick if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 34966235Sbostic syslog(LOG_ERR, "can't create tcp socket"); 35052510Smckusick exit(1); 35152510Smckusick } 35266235Sbostic if (setsockopt(tcpsock, 35366235Sbostic SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 35452510Smckusick syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 35552510Smckusick inetaddr.sin_family = AF_INET; 35652510Smckusick inetaddr.sin_addr.s_addr = INADDR_ANY; 35752510Smckusick inetaddr.sin_port = htons(NFS_PORT); 35866235Sbostic inetaddr.sin_len = sizeof(inetaddr); 35966235Sbostic if (bind(tcpsock, 36066235Sbostic (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 36166235Sbostic syslog(LOG_ERR, "can't bind tcp addr"); 36252510Smckusick exit(1); 36352510Smckusick } 36452510Smckusick if (listen(tcpsock, 5) < 0) { 36566235Sbostic syslog(LOG_ERR, "listen failed"); 36652510Smckusick exit(1); 36752510Smckusick } 36852510Smckusick if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 36966235Sbostic syslog(LOG_ERR, "can't register tcp with portmap"); 37052510Smckusick exit(1); 37152510Smckusick } 37252510Smckusick FD_SET(tcpsock, &sockbits); 37352510Smckusick maxsock = tcpsock; 37452510Smckusick connect_type_cnt++; 37552510Smckusick } 37648625Skarels 37752510Smckusick #ifdef notyet 37866235Sbostic /* Now set up the master server socket waiting for tp4 connections. */ 37952510Smckusick if (tp4flag) { 38052510Smckusick if ((tp4sock = socket(AF_ISO, SOCK_SEQPACKET, 0)) < 0) { 38166235Sbostic syslog(LOG_ERR, "can't create tp4 socket"); 38241917Smckusick exit(1); 38341917Smckusick } 38466235Sbostic if (setsockopt(tp4sock, 38566235Sbostic SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 38648625Skarels syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 38766235Sbostic memset(&isoaddr, 0, sizeof(isoaddr)); 38852510Smckusick isoaddr.siso_family = AF_ISO; 38952510Smckusick isoaddr.siso_tlen = 2; 39052510Smckusick cp = TSEL(&isoaddr); 39152510Smckusick *cp++ = (NFS_PORT >> 8); 39252510Smckusick *cp = (NFS_PORT & 0xff); 39352510Smckusick isoaddr.siso_len = sizeof(isoaddr); 39466235Sbostic if (bind(tp4sock, 39566235Sbostic (struct sockaddr *)&isoaddr, sizeof (isoaddr)) < 0) { 39666235Sbostic syslog(LOG_ERR, "can't bind tp4 addr"); 39741917Smckusick exit(1); 39841917Smckusick } 39952510Smckusick if (listen(tp4sock, 5) < 0) { 40066235Sbostic syslog(LOG_ERR, "listen failed"); 40141917Smckusick exit(1); 40241917Smckusick } 40352510Smckusick /* 40466235Sbostic * XXX 40566235Sbostic * Someday this should probably use "rpcbind", the son of 40666235Sbostic * portmap. 40752510Smckusick */ 40841917Smckusick if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 40966235Sbostic syslog(LOG_ERR, "can't register tcp with portmap"); 41041917Smckusick exit(1); 41141917Smckusick } 41252510Smckusick FD_SET(tp4sock, &sockbits); 41352510Smckusick maxsock = tp4sock; 41452510Smckusick connect_type_cnt++; 41552510Smckusick } 41652510Smckusick 41766235Sbostic /* Now set up the master server socket waiting for tpip connections. */ 41852510Smckusick if (tpipflag) { 41952510Smckusick if ((tpipsock = socket(AF_INET, SOCK_SEQPACKET, 0)) < 0) { 42066235Sbostic syslog(LOG_ERR, "can't create tpip socket"); 42152510Smckusick exit(1); 42252510Smckusick } 42366235Sbostic if (setsockopt(tpipsock, 42466235Sbostic SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 42552510Smckusick syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); 42652510Smckusick inetaddr.sin_family = AF_INET; 42752510Smckusick inetaddr.sin_addr.s_addr = INADDR_ANY; 42852510Smckusick inetaddr.sin_port = htons(NFS_PORT); 42966235Sbostic inetaddr.sin_len = sizeof(inetaddr); 43066235Sbostic if (bind(tpipsock, 43166235Sbostic (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { 43266235Sbostic syslog(LOG_ERR, "can't bind tcp addr"); 43352510Smckusick exit(1); 43452510Smckusick } 43552510Smckusick if (listen(tpipsock, 5) < 0) { 43666235Sbostic syslog(LOG_ERR, "listen failed"); 43752510Smckusick exit(1); 43852510Smckusick } 43941917Smckusick /* 44066235Sbostic * XXX 44166235Sbostic * Someday this should probably use "rpcbind", the son of 44266235Sbostic * portmap. 44341917Smckusick */ 44452510Smckusick if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { 44566235Sbostic syslog(LOG_ERR, "can't register tcp with portmap"); 44652510Smckusick exit(1); 44752510Smckusick } 44852510Smckusick FD_SET(tpipsock, &sockbits); 44952510Smckusick maxsock = tpipsock; 45052510Smckusick connect_type_cnt++; 45152510Smckusick } 45266235Sbostic #endif /* notyet */ 45352510Smckusick 45452510Smckusick if (connect_type_cnt == 0) 45566235Sbostic exit(0); 45666235Sbostic 45752510Smckusick setproctitle("nfsd-master"); 45866235Sbostic 45952510Smckusick /* 46052510Smckusick * Loop forever accepting connections and passing the sockets 46152510Smckusick * into the kernel for the mounts. 46252510Smckusick */ 46352510Smckusick for (;;) { 46452510Smckusick ready = sockbits; 46552510Smckusick if (connect_type_cnt > 1) { 46666235Sbostic if (select(maxsock + 1, 46766235Sbostic &ready, NULL, NULL, NULL) < 1) { 46866235Sbostic syslog(LOG_ERR, "select failed: %m"); 46952510Smckusick exit(1); 47052510Smckusick } 47152510Smckusick } 47252510Smckusick if (tcpflag && FD_ISSET(tcpsock, &ready)) { 47352510Smckusick len = sizeof(inetpeer); 47452510Smckusick if ((msgsock = accept(tcpsock, 47552510Smckusick (struct sockaddr *)&inetpeer, &len)) < 0) { 47666235Sbostic syslog(LOG_ERR, "accept failed: %m"); 47741917Smckusick exit(1); 47841917Smckusick } 47966235Sbostic memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero)); 48052510Smckusick if (setsockopt(msgsock, SOL_SOCKET, 48166235Sbostic SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 48252510Smckusick syslog(LOG_ERR, 48352510Smckusick "setsockopt SO_KEEPALIVE: %m"); 48452510Smckusick nfsdargs.sock = msgsock; 48552510Smckusick nfsdargs.name = (caddr_t)&inetpeer; 48657074Smckusick nfsdargs.namelen = sizeof(inetpeer); 48752510Smckusick nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 48866235Sbostic (void)close(msgsock); 48952510Smckusick } 49052510Smckusick #ifdef notyet 49152510Smckusick if (tp4flag && FD_ISSET(tp4sock, &ready)) { 49252510Smckusick len = sizeof(isopeer); 49352510Smckusick if ((msgsock = accept(tp4sock, 49452510Smckusick (struct sockaddr *)&isopeer, &len)) < 0) { 49566235Sbostic syslog(LOG_ERR, "accept failed: %m"); 49652510Smckusick exit(1); 49741917Smckusick } 49852510Smckusick if (setsockopt(msgsock, SOL_SOCKET, 49966235Sbostic SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 50052510Smckusick syslog(LOG_ERR, 50152510Smckusick "setsockopt SO_KEEPALIVE: %m"); 50252510Smckusick nfsdargs.sock = msgsock; 50352510Smckusick nfsdargs.name = (caddr_t)&isopeer; 50452510Smckusick nfsdargs.namelen = len; 50552510Smckusick nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 50666235Sbostic (void)close(msgsock); 50752510Smckusick } 50852510Smckusick if (tpipflag && FD_ISSET(tpipsock, &ready)) { 50952510Smckusick len = sizeof(inetpeer); 51052510Smckusick if ((msgsock = accept(tpipsock, 51152510Smckusick (struct sockaddr *)&inetpeer, &len)) < 0) { 51252510Smckusick syslog(LOG_ERR, "Accept failed: %m"); 51345247Smckusick exit(1); 51441917Smckusick } 51552510Smckusick if (setsockopt(msgsock, SOL_SOCKET, 51666235Sbostic SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) 51766235Sbostic syslog(LOG_ERR, "setsockopt SO_KEEPALIVE: %m"); 51852510Smckusick nfsdargs.sock = msgsock; 51952510Smckusick nfsdargs.name = (caddr_t)&inetpeer; 52052510Smckusick nfsdargs.namelen = len; 52152510Smckusick nfssvc(NFSSVC_ADDSOCK, &nfsdargs); 52266235Sbostic (void)close(msgsock); 52341917Smckusick } 52466235Sbostic #endif /* notyet */ 52539869Smckusick } 52638458Smckusick } 52741917Smckusick 52866235Sbostic void 52941917Smckusick usage() 53041917Smckusick { 53166238Sbostic (void)fprintf(stderr, "nfsd %s\n", USAGE); 53241917Smckusick exit(1); 53341917Smckusick } 53448625Skarels 53548625Skarels void 53666240Sbostic nonfs(signo) 53766240Sbostic int signo; 53866240Sbostic { 53966240Sbostic syslog(LOG_ERR, "missing system call: NFS not available."); 54066240Sbostic } 54166240Sbostic 54266240Sbostic void 54366235Sbostic reapchild(signo) 54466235Sbostic int signo; 54548625Skarels { 54648625Skarels 54766235Sbostic while (wait3(NULL, WNOHANG, NULL)); 54848625Skarels } 54948625Skarels 55066235Sbostic void 55152510Smckusick setproctitle(a) 55248625Skarels char *a; 55348625Skarels { 55448625Skarels register char *cp; 55548625Skarels char buf[80]; 55648625Skarels 55748625Skarels cp = Argv[0]; 55866235Sbostic (void)snprintf(buf, sizeof(buf), "%s", a); 55966235Sbostic (void)strncpy(cp, buf, LastArg - cp); 56048625Skarels cp += strlen(cp); 56148625Skarels while (cp < LastArg) 56248625Skarels *cp++ = ' '; 56348625Skarels } 564