]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/nfsmount.c
mount.nfs: Eliminate some C macros that use implicit arguments
[nfs-utils.git] / utils / mount / nfsmount.c
index 45cdcdaf1c32336c20091d09fb4a319d6fcf46d2..4b862f05a3f7f8aee7dfa2b4f5534450b874260d 100644 (file)
@@ -48,7 +48,6 @@
 #include <rpc/pmap_clnt.h>
 #include <sys/socket.h>
 #include <sys/time.h>
-#include <sys/utsname.h>
 #include <sys/stat.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #define NFS_FHSIZE 32
 #endif
 
-#define MAKE_VERSION(p,q,r)    (65536*(p) + 256*(q) + (r))
-#define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
-#define MAX_MNTPROT ((nfs_mount_version >= 4) ? 3 : 2)
-#define HAVE_RELIABLE_TCP (nfs_mount_version >= 4)
-
 #ifndef HAVE_INET_ATON
 #define inet_aton(a,b) (0)
 #endif
@@ -93,109 +87,52 @@ typedef union {
        mnt3res_t nfsv3;
 } mntres_t;
 
+extern int nfs_mount_data_version;
 extern int verbose;
 extern int sloppy;
 
-/* Define the order in which to probe for UDP/TCP services */
-enum plist {
-       use_tcp = 0,
-       udp_tcp,
-       udp_only,
+extern int linux_version_code();
+
+static const unsigned int probe_udp_only[] = {
+       IPPROTO_UDP,
+       0,
 };
-static const u_int *
-proto_probelist(enum plist list)
-{
-       static const u_int probe_udp_tcp[] = { IPPROTO_UDP, IPPROTO_TCP, 0 };
-       static const u_int probe_both[] = { IPPROTO_TCP, IPPROTO_UDP, 0 };
-       static const u_int probe_udponly[] = { IPPROTO_UDP, 0 };
-
-       if (list == use_tcp)
-               return probe_both;
-       if (list == udp_tcp)
-               return probe_udp_tcp;
-       return probe_udponly;
-}
 
-/* Define the order in which NFS versions are probed on portmapper */
-static const u_long *
-nfs_probelist(const int vers)
-{
-       static const u_long nfs2_probe[] = { 2, 0};
-       static const u_long nfs3_probe[] = { 3, 2, 0};
-       switch (vers) {
-       case 3:
-               return nfs3_probe;
-       default:
-               return nfs2_probe;
-       }
-}
+static const unsigned int probe_udp_first[] = {
+       IPPROTO_UDP,
+       IPPROTO_TCP,
+       0,
+};
 
-/* Define the order in which Mountd versions are probed on portmapper */
-static const u_long *
-mnt_probelist(const int vers)
-{
-       static const u_long mnt1_probe[] = { 1, 2, 0 };
-       static const u_long mnt3_probe[] = { 3, 1, 2, 0 };
-       switch (vers) {
-       case 3:
-               return mnt3_probe;
-       default:
-               return mnt1_probe;
-       }
-}
+static const unsigned int probe_tcp_first[] = {
+       IPPROTO_TCP,
+       IPPROTO_UDP,
+       0,
+};
 
-static int
-linux_version_code(void) {
-       struct utsname my_utsname;
-       int p, q, r;
-
-       if (uname(&my_utsname) == 0) {
-               p = atoi(strtok(my_utsname.release, "."));
-               q = atoi(strtok(NULL, "."));
-               r = atoi(strtok(NULL, "."));
-               return MAKE_VERSION(p,q,r);
-       }
-       return 0;
-}
+static const unsigned long probe_nfs2_only[] = {
+       2,
+       0,
+};
 
-/*
- * Unfortunately, the kernel prints annoying console messages
- * in case of an unexpected nfs mount version (instead of
- * just returning some error).  Therefore we'll have to try
- * and figure out what version the kernel expects.
- *
- * Variables:
- *     NFS_MOUNT_VERSION: these nfsmount sources at compile time
- *     nfs_mount_version: version this source and running kernel can handle
- */
-int nfs_mount_version = NFS_MOUNT_VERSION;
+static const unsigned long probe_nfs3_first[] = {
+       3,
+       2,
+       0,
+};
 
-int
-find_kernel_nfs_mount_version(void) {
-       static int kernel_version = -1;
-       int mnt_version = NFS_MOUNT_VERSION;
-
-       if (kernel_version == -1)
-               kernel_version = linux_version_code();
-
-       if (kernel_version) {
-            if (kernel_version < MAKE_VERSION(2,1,32))
-                 mnt_version = 1;
-            else if (kernel_version < MAKE_VERSION(2,2,18))
-                 mnt_version = 3;
-            else if (kernel_version < MAKE_VERSION(2,3,0))
-                 mnt_version = 4; /* since 2.2.18pre9 */
-            else if (kernel_version < MAKE_VERSION(2,3,99))
-                 mnt_version = 3;
-            else if (kernel_version < MAKE_VERSION(2,6,3))
-                 mnt_version = 4;
-            else
-                 mnt_version = 6;
-       }
-       if (mnt_version > NFS_MOUNT_VERSION)
-            mnt_version = NFS_MOUNT_VERSION;
-       return mnt_version;
-}
+static const unsigned long probe_mnt1_first[] = {
+       1,
+       2,
+       0,
+};
+
+static const unsigned long probe_mnt3_first[] = {
+       3,
+       1,
+       2,
+       0,
+};
 
 int nfs_gethostbyname(const char *, struct sockaddr_in *);
 int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
@@ -345,31 +282,30 @@ out_bad:
        return 1;
 }
 
-static int
-probe_nfsport(clnt_addr_t *nfs_server)
+static int probe_nfsport(clnt_addr_t *nfs_server)
 {
-       const struct pmap *pmap = &nfs_server->pmap;
-       const u_long *probe_vers;
-       const u_int *probe_prot;
+       struct pmap *pmap = &nfs_server->pmap;
 
        if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
                return 1;
-       probe_vers = nfs_probelist(MAX_NFSPROT);
-       probe_prot = proto_probelist(HAVE_RELIABLE_TCP ? use_tcp : udp_only);
-       return probe_port(nfs_server, probe_vers, probe_prot);
+
+       if (nfs_mount_data_version >= 4)
+               return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first);
+       else
+               return probe_port(nfs_server, probe_nfs2_only, probe_udp_only);
 }
 
 int probe_mntport(clnt_addr_t *mnt_server)
 {
-       const struct pmap *pmap = &mnt_server->pmap;
-       const u_long *probe_vers;
-       const u_int *probe_prot;
+       struct pmap *pmap = &mnt_server->pmap;
 
        if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
                return 1;
-       probe_vers = mnt_probelist(MAX_MNTPROT);
-       probe_prot = proto_probelist(HAVE_RELIABLE_TCP ? udp_tcp : udp_only);
-       return probe_port(mnt_server, probe_vers, probe_prot);
+
+       if (nfs_mount_data_version >= 4)
+               return probe_port(mnt_server, probe_mnt3_first, probe_udp_first);
+       else
+               return probe_port(mnt_server, probe_mnt1_first, probe_udp_only);
 }
 
 static int
@@ -379,7 +315,7 @@ probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
        struct pmap *mnt_pmap = &mnt_server->pmap;
        struct pmap save_nfs, save_mnt;
        int res;
-       const u_long *probe_vers;
+       const unsigned long *probe_vers;
 
        if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers)
                nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers);
@@ -387,9 +323,13 @@ probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
                mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
        if (nfs_pmap->pm_vers)
                goto version_fixed;
+
        memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
        memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
-       for (probe_vers = mnt_probelist(MAX_MNTPROT); *probe_vers; probe_vers++) {
+       probe_vers = (nfs_mount_data_version >= 4) ?
+                       probe_mnt3_first : probe_mnt1_first;
+
+       for (; *probe_vers; probe_vers++) {
                nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
                if ((res = probe_nfsport(nfs_server) != 0)) {
                        mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
@@ -406,9 +346,11 @@ probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
                }
                memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
        }
- out_bad:
+
+out_bad:
        return 0;
- version_fixed:
+
+version_fixed:
        if (!probe_nfsport(nfs_server))
                goto out_bad;
        return probe_mntport(mnt_server);
@@ -554,7 +496,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                                opt = "nfsvers";
 #if NFS_MOUNT_VERSION >= 2
                        } else if (!strcmp(opt, "namlen")) {
-                               if (nfs_mount_version >= 2)
+                               if (nfs_mount_data_version >= 2)
                                        data->namlen = val;
                                else if (sloppy)
                                        continue;
@@ -578,7 +520,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
 #if NFS_MOUNT_VERSION >= 2
                                        data->flags &= ~NFS_MOUNT_TCP;
                                } else if (!strcmp(opteq+1, "tcp") &&
-                                          nfs_mount_version > 2) {
+                                          nfs_mount_data_version > 2) {
                                        nfs_pmap->pm_prot = IPPROTO_TCP;
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
                                        data->flags |= NFS_MOUNT_TCP;
@@ -591,7 +533,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "sec")) {
                                char *secflavor = opteq+1;
                                /* see RFC 2623 */
-                               if (nfs_mount_version < 5) {
+                               if (nfs_mount_data_version < 5) {
                                        printf(_("Warning: ignoring sec=%s option\n"), secflavor);
                                        continue;
                                } else if (!strcmp(secflavor, "none"))
@@ -690,7 +632,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "tcp")) {
                                data->flags &= ~NFS_MOUNT_TCP;
                                if (val) {
-                                       if (nfs_mount_version < 2)
+                                       if (nfs_mount_data_version < 2)
                                                goto bad_option;
                                        nfs_pmap->pm_prot = IPPROTO_TCP;
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
@@ -702,7 +644,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "udp")) {
                                data->flags &= ~NFS_MOUNT_TCP;
                                if (!val) {
-                                       if (nfs_mount_version < 2)
+                                       if (nfs_mount_data_version < 2)
                                                goto bad_option;
                                        nfs_pmap->pm_prot = IPPROTO_TCP;
                                        mnt_pmap->pm_prot = IPPROTO_TCP;
@@ -716,7 +658,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "lock")) {
                                data->flags &= ~NFS_MOUNT_NONLM;
                                if (!val) {
-                                       if (nfs_mount_version < 3)
+                                       if (nfs_mount_data_version < 3)
                                                goto bad_option;
                                        data->flags |= NFS_MOUNT_NONLM;
                                }
@@ -725,7 +667,7 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
                        } else if (!strcmp(opt, "broken_suid")) {
                                data->flags &= ~NFS_MOUNT_BROKEN_SUID;
                                if (val) {
-                                       if (nfs_mount_version < 4)
+                                       if (nfs_mount_data_version < 4)
                                                goto bad_option;
                                        data->flags |= NFS_MOUNT_BROKEN_SUID;
                                }
@@ -772,26 +714,35 @@ parse_options(char *old_opts, struct nfs_mount_data *data,
        return 0;
 }
 
-static inline int
-nfsmnt_check_compat(const struct pmap *nfs_pmap, const struct pmap *mnt_pmap)
+static int nfsmnt_check_compat(const struct pmap *nfs_pmap,
+                               const struct pmap *mnt_pmap)
 {
-       if (nfs_pmap->pm_vers && 
-               (nfs_pmap->pm_vers > MAX_NFSPROT || nfs_pmap->pm_vers < 2)) {
-               if (nfs_pmap->pm_vers == 4)
-                       fprintf(stderr, _("'vers=4' is not supported.  "
-                               "Use '-t nfs4' instead.\n"));
-               else
-                       fprintf(stderr, _("NFS version %ld is not supported.\n"), 
-                               nfs_pmap->pm_vers);
+       unsigned int max_nfs_vers = (nfs_mount_data_version >= 4) ? 3 : 2;
+       unsigned int max_mnt_vers = (nfs_mount_data_version >= 4) ? 3 : 2;
+
+       if (nfs_pmap->pm_vers == 4) {
+               fprintf(stderr, _("Please use '-t nfs4' "
+                                       "instead of '-o vers=4'.\n"));
                goto out_bad;
        }
-       if (mnt_pmap->pm_vers > MAX_MNTPROT) {
+
+       if (nfs_pmap->pm_vers) {
+               if (nfs_pmap->pm_vers > max_nfs_vers || nfs_pmap->pm_vers < 2) {
+                       fprintf(stderr, _("NFS version %ld is not supported.\n"), 
+                                       nfs_pmap->pm_vers);
+                       goto out_bad;
+               }
+       }
+
+       if (mnt_pmap->pm_vers > max_mnt_vers) {
                fprintf(stderr, _("NFS mount version %ld s not supported.\n"), 
                        mnt_pmap->pm_vers);
                goto out_bad;
        }
+
        return 1;
- out_bad:
+
+out_bad:
        return 0;
 }
 
@@ -827,8 +778,6 @@ nfsmount(const char *spec, const char *node, int *flags,
        time_t prevt;
        time_t timeout;
 
-       nfs_mount_version = find_kernel_nfs_mount_version();
-
        if (strlen(spec) >= sizeof(hostdir)) {
                fprintf(stderr, _("mount: "
                                  "excessively long host:dir argument\n"));
@@ -929,7 +878,7 @@ nfsmount(const char *spec, const char *node, int *flags,
        printf("\n");
 #endif
 
-       data.version = nfs_mount_version;
+       data.version = nfs_mount_data_version;
        *mount_opts = (char *) &data;
 
        if (*flags & MS_REMOUNT)
@@ -1105,7 +1054,7 @@ noauth_flavors:
 #endif
        }
 
-       if (nfs_mount_version == 1) {
+       if (nfs_mount_data_version == 1) {
                /* create nfs socket for kernel */
                if (nfs_pmap->pm_prot == IPPROTO_TCP)
                        fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);