X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fnfsd%2Fnfsd.c;h=aaf8d298e3ad9c589c1d0d0c31df7cd64d36da27;hp=86e809499236c8a4bf3e3bf3c213d91dbcbdf4a1;hb=e64f7f6b73cfc80662cf5f724f3c1eb86a392883;hpb=87fe487c6f5abe9f40f2f036c3cf6c7f02fa0385 diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c index 86e8094..aaf8d29 100644 --- a/utils/nfsd/nfsd.c +++ b/utils/nfsd/nfsd.c @@ -7,7 +7,9 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include "config.h" +#ifdef HAVE_CONFIG_H +#include +#endif #include #include @@ -18,15 +20,35 @@ #include #include #include +#include +#include +#include + #include "nfslib.h" static void usage(const char *); +static struct option longopts[] = +{ + { "host", 1, 0, 'H' }, + { "help", 0, 0, 'h' }, + { "no-nfs-version", 1, 0, 'N' }, + { "no-tcp", 0, 0, 'T' }, + { "no-udp", 0, 0, 'U' }, + { "port", 1, 0, 'P' }, + { "port", 1, 0, 'p' }, + { NULL, 0, 0, 0 } +}; +unsigned int protobits = NFSCTL_ALLBITS; +unsigned int versbits = NFSCTL_ALLBITS; +char *haddr = NULL; + int main(int argc, char **argv) { - int count = 1, c, error, port, fd; + int count = 1, c, error, port, fd, found_one; struct servent *ent; + struct hostent *hp; ent = getservbyname ("nfs", "udp"); if (ent != NULL) @@ -34,8 +56,19 @@ main(int argc, char **argv) else port = 2049; - while ((c = getopt(argc, argv, "hp:P:")) != EOF) { + while ((c = getopt_long(argc, argv, "H:hN:p:P:TU", longopts, NULL)) != EOF) { switch(c) { + case 'H': + if (inet_addr(optarg) != INADDR_NONE) { + haddr = strdup(optarg); + } else if ((hp = gethostbyname(optarg)) != NULL) { + haddr = inet_ntoa((*(struct in_addr*)(hp->h_addr_list[0]))); + } else { + fprintf(stderr, "%s: Unknown hostname: %s\n", + argv[0], optarg); + usage(argv [0]); + } + break; case 'P': /* XXX for nfs-server compatibility */ case 'p': port = atoi(optarg); @@ -45,12 +78,55 @@ main(int argc, char **argv) usage(argv [0]); } break; + case 'N': + switch((c = atoi(optarg))) { + case 2: + case 3: + case 4: + NFSCTL_VERUNSET(versbits, c); + break; + default: + fprintf(stderr, "%c: Unsupported version\n", c); + exit(1); + } break; - case 'h': + case 'T': + NFSCTL_TCPUNSET(protobits); + break; + case 'U': + NFSCTL_UDPUNSET(protobits); + break; default: + fprintf(stderr, "Invalid argument: '%c'\n", c); + case 'h': usage(argv[0]); } } + /* + * Do some sanity checking, if the ctlbits are set + */ + if (!NFSCTL_UDPISSET(protobits) && !NFSCTL_TCPISSET(protobits)) { + fprintf(stderr, "invalid protocol specified\n"); + exit(1); + } + found_one = 0; + for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { + if (NFSCTL_VERISSET(versbits, c)) + found_one = 1; + } + if (!found_one) { + fprintf(stderr, "no version specified\n"); + exit(1); + } + + if (NFSCTL_VERISSET(versbits, 4) && !NFSCTL_TCPISSET(protobits)) { + fprintf(stderr, "version 4 requires the TCP protocol\n"); + exit(1); + } + if (haddr == NULL) { + struct in_addr in = {INADDR_ANY}; + haddr = strdup(inet_ntoa(in)); + } if (chdir(NFS_STATEDIR)) { fprintf(stderr, "%s: chdir(%s) failed: %s\n", @@ -67,7 +143,6 @@ main(int argc, char **argv) count = 1; } } - /* KLUDGE ALERT: Some kernels let nfsd kernel threads inherit open files from the program that spawns them (i.e. us). So close @@ -80,13 +155,11 @@ main(int argc, char **argv) (void) dup2(fd, 1); (void) dup2(fd, 2); } - fd = sysconf(_SC_OPEN_MAX); - while (--fd > 2) - (void) close(fd); + closeall(3); - if ((error = nfssvc(port, count)) < 0) { + openlog("nfsd", LOG_PID, LOG_DAEMON); + if ((error = nfssvc(port, count, versbits, protobits, haddr)) < 0) { int e = errno; - openlog("nfsd", LOG_PID, LOG_DAEMON); syslog(LOG_ERR, "nfssvc: %s", strerror(e)); closelog(); } @@ -97,7 +170,8 @@ main(int argc, char **argv) static void usage(const char *prog) { - fprintf(stderr, "usage:\n" - "%s nrservs\n", prog); + fprintf(stderr, "Usage:\n" + "%s [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-T|--no-tcp] [-U|--no-udp] nrservs\n", + prog); exit(2); }