Annotation of 43BSDReno/sbin/nfsd/nfsd.c, revision 1.1.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.