Annotation of 43BSDReno/sbin/nfsd/nfsd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Rick Macklem at The University of Guelph.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms are permitted provided
        !             9:  * that: (1) source distributions retain this entire copyright notice and
        !            10:  * comment, and (2) distributions including binaries display the following
        !            11:  * acknowledgement:  ``This product includes software developed by the
        !            12:  * University of California, Berkeley and its contributors'' in the
        !            13:  * documentation or other materials provided with the distribution and in
        !            14:  * all advertising materials mentioning features or use of this software.
        !            15:  * Neither the name of the University nor the names of its contributors may
        !            16:  * be used to endorse or promote products derived from this software without
        !            17:  * specific prior written permission.
        !            18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            19:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            20:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            21:  */
        !            22: 
        !            23: #ifndef lint
        !            24: char copyright[] =
        !            25: "@(#) Copyright (c) 1989 Regents of the University of California.\n\
        !            26:  All rights reserved.\n";
        !            27: #endif not lint
        !            28: 
        !            29: #ifndef lint
        !            30: static char sccsid[] = "@(#)nfsd.c     5.8 (Berkeley) 6/29/90";
        !            31: #endif not lint
        !            32: 
        !            33: #include <sys/types.h>
        !            34: #include <sys/signal.h>
        !            35: #include <sys/ioctl.h>
        !            36: #include <sys/stat.h>
        !            37: #include <sys/wait.h>
        !            38: #include <sys/mount.h>
        !            39: #include <sys/socket.h>
        !            40: #include <sys/socketvar.h>
        !            41: #include <stdio.h>
        !            42: #include <syslog.h>
        !            43: #include <fcntl.h>
        !            44: #include <string.h>
        !            45: #include <netdb.h>
        !            46: #include <rpc/rpc.h>
        !            47: #include <rpc/pmap_clnt.h>
        !            48: #include <rpc/pmap_prot.h>
        !            49: #include <nfs/rpcv2.h>
        !            50: #include <nfs/nfsv2.h>
        !            51: 
        !            52: /* Global defs */
        !            53: #ifdef DEBUG
        !            54: #define        syslog(e, s)    fprintf(stderr,(s))
        !            55: int debug = 1;
        !            56: #else
        !            57: int debug = 0;
        !            58: #endif
        !            59: struct hadr {
        !            60:        u_long  ha_sad;
        !            61:        struct hadr *ha_next;
        !            62: };
        !            63: struct hadr hphead;
        !            64: 
        !            65: /*
        !            66:  * Nfs server daemon mostly just a user context for nfssvc()
        !            67:  * 1 - do file descriptor and signal cleanup
        !            68:  * 2 - create server socket
        !            69:  * 3 - register socket with portmap
        !            70:  * For SOCK_DGRAM, just fork children and send them into the kernel
        !            71:  * by calling nfssvc()
        !            72:  * For connection based sockets, loop doing accepts. When you get a new socket
        !            73:  * from accept, fork a child that drops into the kernel via. nfssvc.
        !            74:  * This child will return from nfssvc when the connection is closed, so
        !            75:  * just shutdown() and exit().
        !            76:  * The arguments are:
        !            77:  * -t - support tcp nfs clients
        !            78:  * -u - support udp nfs clients
        !            79:  */
        !            80: main(argc, argv)
        !            81:        int argc;
        !            82:        char **argv;
        !            83: {
        !            84:        register int i;
        !            85:        register char *cp, *cp2;
        !            86:        register struct hadr *hp;
        !            87:        int udpcnt, sock, msgsock, tcpflag = 0, udpflag = 0, ret, len;
        !            88:        char opt;
        !            89:        union wait chldstat;
        !            90:        extern int optind;
        !            91:        extern char *optarg;
        !            92:        struct sockaddr_in saddr, msk, mtch, peername;
        !            93: 
        !            94:        while ((opt = getopt(argc, argv, "t:u:")) != EOF)
        !            95:                switch (opt) {
        !            96:                case 't':
        !            97:                        tcpflag++;
        !            98:                        if (cp = index(optarg, ',')) {
        !            99:                                *cp++ = '\0';
        !           100:                                msk.sin_addr.s_addr = inet_addr(optarg);
        !           101:                                if (msk.sin_addr.s_addr == -1)
        !           102:                                        usage();
        !           103:                                if (cp2 = index(cp, ','))
        !           104:                                        *cp2++ = '\0';
        !           105:                                mtch.sin_addr.s_addr = inet_addr(cp);
        !           106:                                if (mtch.sin_addr.s_addr == -1)
        !           107:                                        usage();
        !           108:                                cp = cp2;
        !           109:                                hphead.ha_next = (struct hadr *)0;
        !           110:                                while (cp) {
        !           111:                                        if (cp2 = index(cp, ','))
        !           112:                                                *cp2++ = '\0';
        !           113:                                        hp = (struct hadr *)
        !           114:                                                malloc(sizeof (struct hadr));
        !           115:                                        hp->ha_sad = inet_addr(cp);
        !           116:                                        if (hp->ha_sad == -1)
        !           117:                                                usage();
        !           118:                                        hp->ha_next = hphead.ha_next;
        !           119:                                        hphead.ha_next = hp;
        !           120:                                        cp = cp2;
        !           121:                                }
        !           122:                        } else
        !           123:                                usage();
        !           124:                        break;
        !           125:                case 'u':
        !           126:                        udpflag++;
        !           127:                        if (cp = index(optarg, ',')) {
        !           128:                                *cp++ = '\0';
        !           129:                                msk.sin_addr.s_addr = inet_addr(optarg);
        !           130:                                if (msk.sin_addr.s_addr == -1)
        !           131:                                        usage();
        !           132:                                if (cp2 = index(cp, ','))
        !           133:                                        *cp2++ = '\0';
        !           134:                                mtch.sin_addr.s_addr = inet_addr(cp);
        !           135:                                if (mtch.sin_addr.s_addr == -1)
        !           136:                                        usage();
        !           137:                                if (cp2)
        !           138:                                        udpcnt = atoi(cp2);
        !           139:                                if (udpcnt < 1 || udpcnt > 20)
        !           140:                                        udpcnt = 1;
        !           141:                        } else
        !           142:                                usage();
        !           143:                        break;
        !           144:                default:
        !           145:                case '?':
        !           146:                        usage();
        !           147:                };
        !           148:        if (optind == 1) {
        !           149:                if (argc > 1)
        !           150:                        udpcnt = atoi(*++argv);
        !           151:                if (udpcnt < 1 || udpcnt > 20)
        !           152:                        udpcnt = 1;
        !           153:                msk.sin_addr.s_addr = mtch.sin_addr.s_addr = 0;
        !           154:                udpflag++;
        !           155:        }
        !           156:        if (debug == 0) {
        !           157:                daemon(0, 0);
        !           158:                signal(SIGINT, SIG_IGN);
        !           159:                signal(SIGQUIT, SIG_IGN);
        !           160:                signal(SIGTERM, SIG_IGN);
        !           161:                signal(SIGHUP, SIG_IGN);
        !           162:        }
        !           163:        openlog("nfsd:", LOG_PID, LOG_DAEMON);
        !           164:        pmap_unset(RPCPROG_NFS, NFS_VER2);
        !           165:        if (udpflag) {
        !           166:                if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        !           167:                        syslog(LOG_ERR, "Can't create socket");
        !           168:                        exit(1);
        !           169:                }
        !           170:                saddr.sin_family = AF_INET;
        !           171:                saddr.sin_addr.s_addr = INADDR_ANY;
        !           172:                saddr.sin_port = htons(NFS_PORT);
        !           173:                if (bind(sock, &saddr, sizeof(saddr)) < 0) {
        !           174:                        syslog(LOG_ERR, "Can't bind addr");
        !           175:                        exit(1);
        !           176:                }
        !           177:                if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
        !           178:                        syslog(LOG_ERR, "Can't register with portmap");
        !           179:                        exit(1);
        !           180:                }
        !           181:        
        !           182:                /*
        !           183:                 * Send the nfs datagram servers right down into the kernel
        !           184:                 */
        !           185:                for (i = 0; i < udpcnt; i++)
        !           186:                        if (fork() == 0) {
        !           187:                                ret = nfssvc(sock, &msk, sizeof(msk),
        !           188:                                                &mtch, sizeof(mtch));
        !           189:                                if (ret < 0)
        !           190:                                        syslog(LOG_ERR, "nfssvc() failed %m");
        !           191:                                exit();
        !           192:                        }
        !           193:                close(sock);
        !           194:        }
        !           195: 
        !           196:        /*
        !           197:         * Now set up the master STREAM server waiting for tcp connections.
        !           198:         */
        !           199:        if (tcpflag) {
        !           200:                if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        !           201:                        syslog(LOG_ERR, "Can't create socket");
        !           202:                        exit(1);
        !           203:                }
        !           204:                saddr.sin_family = AF_INET;
        !           205:                saddr.sin_addr.s_addr = INADDR_ANY;
        !           206:                saddr.sin_port = htons(NFS_PORT);
        !           207:                if (bind(sock, &saddr, sizeof(saddr)) < 0) {
        !           208:                        syslog(LOG_ERR, "Can't bind addr");
        !           209:                        exit(1);
        !           210:                }
        !           211:                if (listen(sock, 5) < 0) {
        !           212:                        syslog(LOG_ERR, "Listen failed");
        !           213:                        exit(1);
        !           214:                }
        !           215:                if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
        !           216:                        syslog(LOG_ERR, "Can't register with portmap");
        !           217:                        exit(1);
        !           218:                }
        !           219:                /*
        !           220:                 * Loop forever accepting connections and sending the children
        !           221:                 * into the kernel to service the mounts.
        !           222:                 */
        !           223:                for (;;) {
        !           224:                        if ((msgsock = accept(sock, (struct sockaddr *)0,
        !           225:                                (int *)0)) < 0) {
        !           226:                                syslog(LOG_ERR, "Accept failed: %m");
        !           227:                                exit(1);
        !           228:                        }
        !           229:                        /*
        !           230:                         * Grab child termination status' just so defuncts
        !           231:                         * are not left lying about.
        !           232:                         */
        !           233:                        while (wait3(&chldstat, WNOHANG, (struct rusage *)0))
        !           234:                                ;
        !           235:                        len = sizeof(peername);
        !           236:                        if (getsockname(msgsock, &peername, &len) < 0) {
        !           237:                                syslog(LOG_ERR, "Getsockname failed\n");
        !           238:                                exit(1);
        !           239:                        }
        !           240:                        if ((peername.sin_addr.s_addr & msk.sin_addr.s_addr)
        !           241:                                != mtch.sin_addr.s_addr) {
        !           242:                                hp = hphead.ha_next;
        !           243:                                while (hp) {
        !           244:                                        if (peername.sin_addr.s_addr ==
        !           245:                                                hp->ha_sad)
        !           246:                                                break;
        !           247:                                        hp = hp->ha_next;
        !           248:                                }
        !           249:                                if (hp == NULL) {
        !           250:                                        shutdown(msgsock, 2);
        !           251:                                        close(msgsock);
        !           252:                                        continue;
        !           253:                                }
        !           254:                        }
        !           255:                        if (fork() == 0) {
        !           256:                                close(sock);
        !           257:                                ret = nfssvc(msgsock, &msk, sizeof(msk),
        !           258:                                                &mtch, sizeof(mtch));
        !           259:                                shutdown(msgsock, 2);
        !           260:                                if (ret < 0)
        !           261:                                        syslog(LOG_NOTICE,
        !           262:                                            "Nfssvc STREAM Failed");
        !           263:                                exit();
        !           264:                        }
        !           265:                        close(msgsock);
        !           266:                }
        !           267:        }
        !           268: }
        !           269: 
        !           270: usage()
        !           271: {
        !           272:        fprintf(stderr, "nfsd [-t msk,mtch[,addrs]] [-u msk,mtch,numprocs]\n");
        !           273:        exit(1);
        !           274: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.