]> git.pld-linux.org Git - packages/util-linux.git/commitdiff
- we now use mount.nfs from nfs-utils package, so there is no point in
authorJan Rękorajski <baggins@pld-linux.org>
Thu, 22 Mar 2007 18:39:05 +0000 (18:39 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
  maintaining nfs stuff in util-linux mount

Changed files:
    util-linux-2.10m-mount-compat.patch -> 1.2
    util-linux-2.12-01-nfs.dif -> 1.2
    util-linux-2.12-02-base-nfsv4.dif -> 1.2
    util-linux-2.12-03-krb5.dif -> 1.2
    util-linux-2.12-04-modify_mount_to_support_multiple_security_flavors.dif -> 1.2
    util-linux-2.12-05-mount_sloppy_fix.dif -> 1.2
    util-linux-2.12-06-redhat-nfs-mount.dif -> 1.2

util-linux-2.10m-mount-compat.patch [deleted file]
util-linux-2.12-01-nfs.dif [deleted file]
util-linux-2.12-02-base-nfsv4.dif [deleted file]
util-linux-2.12-03-krb5.dif [deleted file]
util-linux-2.12-04-modify_mount_to_support_multiple_security_flavors.dif [deleted file]
util-linux-2.12-05-mount_sloppy_fix.dif [deleted file]
util-linux-2.12-06-redhat-nfs-mount.dif [deleted file]

diff --git a/util-linux-2.10m-mount-compat.patch b/util-linux-2.10m-mount-compat.patch
deleted file mode 100644 (file)
index b688834..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
---- util-linux-2.10m/mount/nfs_mount4.h.compat Sun Apr 16 14:48:48 2000
-+++ util-linux-2.10m/mount/nfs_mount4.h        Thu Jun 29 20:51:22 2000
-@@ -4,11 +4,16 @@
-  * Thus, if necessary we teach nfsmount.c the structure of new fields
-  * that will come later.
-  *
-- * Moreover, the new kernel includes conflict with glibc includes
-- * so it is easiest to ignore the kernel altogether (at compile time).
-  */
-+#include "nfs_mountversion.h"
-+
- #define NFS_MOUNT_VERSION     4
-+
-+#if KERNEL_NFS_MOUNT_VERSION >= 4
-+#define NFS_FHSIZE    32
-+#define NFS_PORT      2049
-+#endif
- struct nfs2_fh {
-         char                    data[32];
---- util-linux-2.10m/mount/Makefile.compat     Thu Jun 29 20:49:43 2000
-+++ util-linux-2.10m/mount/Makefile    Thu Jun 29 20:50:23 2000
-@@ -108,7 +108,10 @@ nfsmount.h nfsmount_xdr.c nfsmount_clnt.
-       cp $(RPCSVCDIR)/nfsmount_clnt.c .
- endif
--nfsmount.o: nfs_mount4.h
-+nfsmount.o: nfs_mount4.h nfs_mountversion.h
-+
-+nfs_mountversion.h: /usr/include/linux/nfs_mount.h
-+      grep NFS_MOUNT_VERSION $< | sed -e 's/NFS/KERNEL_NFS/' > $@
- swapargs.h:
-       sh swap.configure
diff --git a/util-linux-2.12-01-nfs.dif b/util-linux-2.12-01-nfs.dif
deleted file mode 100644 (file)
index fb10ed8..0000000
+++ /dev/null
@@ -1,1504 +0,0 @@
-
-Miscellaneous nfs mount changes from Trond.
-
----
-
- util-linux-2.12-bfields/mount/Makefile   |    4 
- util-linux-2.12-bfields/mount/nfsmount.c | 1235 +++++++++++++++++++------------
- util-linux-2.12-bfields/mount/sundries.h |    1 
- util-linux-2.12-bfields/mount/umount.c   |    4 
- 4 files changed, 794 insertions(+), 450 deletions(-)
-
-diff -puN mount/Makefile~nfs mount/Makefile
---- util-linux-2.12/mount/Makefile~nfs 2004-10-13 13:51:44.000000000 -0400
-+++ util-linux-2.12-bfields/mount/Makefile     2004-10-13 14:13:30.000000000 -0400
-@@ -31,7 +31,7 @@
- LO_OBJS = lomount.o $(LIB)/xstrncpy.o
- CRYPT_OBJS = cryptsetup.o -lcryptsetup
--NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
-+NFS_OBJS = nfsmount.o nfsmount_xdr.o
- GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
- all: $(PROGS)
-@@ -55,7 +55,7 @@
- umount: umount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o \
-       getusername.o get_label_uuid.o mount_by_label.o mount_blkid.o \
--      version.o $(LIB)/env.o $(LO_OBJS) $(CRYPT_OBJS)
-+      version.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) $(CRYPT_OBJS)
-       $(LINK) $^ -o $@ $(BLKID_LIB)
- swapon:       swapon.o version.o xmalloc.o \
-diff -puN mount/nfsmount.c~nfs mount/nfsmount.c
---- util-linux-2.12/mount/nfsmount.c~nfs       2004-10-13 13:51:44.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfsmount.c   2004-10-13 14:13:30.000000000 -0400
-@@ -34,6 +34,7 @@
- #include "../defines.h"       /* for HAVE_rpcsvc_nfs_prot_h and HAVE_inet_aton */
-+#include <ctype.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
-@@ -72,11 +73,100 @@
- #define NFS_FHSIZE 32
- #endif
-+#define MNT_SENDBUFSIZE ((u_int)2048)
-+#define MNT_RECVBUFSIZE ((u_int)1024)
-+
- static char *nfs_strerror(int stat);
- #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
-+
-+typedef dirpath mnt2arg_t;
-+typedef dirpath mnt3arg_t;
-+typedef dirpath mntarg_t;
-+
-+typedef struct fhstatus  mnt2res_t;
-+typedef struct mountres3 mnt3res_t;
-+typedef union {
-+      mnt2res_t nfsv2;
-+      mnt3res_t nfsv3;
-+} mntres_t;
-+
-+typedef struct {
-+      char **hostname;
-+      struct sockaddr_in saddr;
-+      struct pmap pmap;
-+} clnt_addr_t;
-+
-+/* RPC call timeout values */
-+static const struct timeval TIMEOUT = { 20, 0 };
-+static const struct timeval RETRY_TIMEOUT = { 3, 0 };
-+
-+/* Define the order in which to probe for UDP/TCP services */
-+static const u_int *
-+proto_probelist(const int use_tcp)
-+{
-+      static const u_int probe_both[] = { IPPROTO_TCP, IPPROTO_UDP, 0 };
-+      static const u_int probe_udponly[] = { IPPROTO_UDP, 0 };
-+      if (use_tcp)
-+              return probe_both;
-+      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;
-+      }
-+}
-+
-+/* 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;
-+      }
-+}
-+
-+/* Map an NFS version into the corresponding Mountd version */
-+static u_long
-+nfsvers_to_mnt(const u_long vers)
-+{
-+      static const u_long nfs_to_mnt[] = { 0, 0, 1, 3 };
-+      if (vers <= 3)
-+              return nfs_to_mnt[vers];
-+      return 0;
-+}
-+
-+/* Map a Mountd version into the corresponding NFS version */
-+static u_long
-+mntvers_to_nfs(const u_long vers)
-+{
-+      static const u_long mnt_to_nfs[] = { 0, 2, 2, 3 };
-+      if (vers <= 3)
-+              return mnt_to_nfs[vers];
-+      return 0;
-+}
- static int
- linux_version_code(void) {
-@@ -102,123 +192,558 @@ linux_version_code(void) {
-  *    NFS_MOUNT_VERSION: these nfsmount sources at compile time
-  *    nfs_mount_version: version this source and running kernel can handle
-  */
-+static int nfs_mount_version = NFS_MOUNT_VERSION;
-+
- static int
- find_kernel_nfs_mount_version(void) {
-       static int kernel_version = -1;
--      int nfs_mount_version = NFS_MOUNT_VERSION;
-+      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))
--                nfs_mount_version = 1;
-+                mnt_version = 1;
-            else if (kernel_version < MAKE_VERSION(2,2,18))
--                nfs_mount_version = 3;
-+                mnt_version = 3;
-            else if (kernel_version < MAKE_VERSION(2,3,0))
--                nfs_mount_version = 4; /* since 2.2.18pre9 */
-+                mnt_version = 4; /* since 2.2.18pre9 */
-            else if (kernel_version < MAKE_VERSION(2,3,99))
--                nfs_mount_version = 3;
-+                mnt_version = 3;
-            else
--                nfs_mount_version = 4; /* since 2.3.99pre4 */
-+                mnt_version = 4; /* since 2.3.99pre4 */
-       }
--      if (nfs_mount_version > NFS_MOUNT_VERSION)
--           nfs_mount_version = NFS_MOUNT_VERSION;
--      return nfs_mount_version;
--}
--
--static struct pmap *
--get_mountport(struct sockaddr_in *server_addr,
--      long unsigned prog,
--      long unsigned version,
--      long unsigned proto,
--      long unsigned port,
--      int nfs_mount_version)
--{
--      struct pmaplist *pmap;
--      static struct pmap p = {0, 0, 0, 0};
--
--      if (version > MAX_NFSPROT)
--              version = MAX_NFSPROT;
--      if (!prog)
--              prog = MOUNTPROG;
--      p.pm_prog = prog;
--      p.pm_vers = version;
--      p.pm_prot = proto;
--      p.pm_port = port;
--
--      server_addr->sin_port = PMAPPORT;
--      pmap = pmap_getmaps(server_addr);
--
--      while (pmap) {
--              if (pmap->pml_map.pm_prog != prog)
--                      goto next;
--              if (!version && p.pm_vers > pmap->pml_map.pm_vers)
--                      goto next;
--              if (version > 2 && pmap->pml_map.pm_vers != version)
--                      goto next;
--              if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
--                      goto next;
--              if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
--                  (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
--                  (port && pmap->pml_map.pm_port != port))
--                      goto next;
--              memcpy(&p, &pmap->pml_map, sizeof(p));
--      next:
--              pmap = pmap->pml_next;
--      }
--      if (!p.pm_vers)
--              p.pm_vers = MOUNTVERS;
--      if (!p.pm_prot)
--              p.pm_prot = IPPROTO_TCP;
--#if 0
--      if (!p.pm_port) {
--              p.pm_port = pmap_getport(server_addr, p.pm_prog, p.pm_vers,
--                                       p.pm_prot);
-+      if (mnt_version > NFS_MOUNT_VERSION)
-+           mnt_version = NFS_MOUNT_VERSION;
-+      return mnt_version;
-+}
-+
-+static int
-+nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
-+{
-+      struct hostent *hp;
-+
-+      saddr->sin_family = AF_INET;
-+      if (!inet_aton(hostname, &saddr->sin_addr)) {
-+              if ((hp = gethostbyname(hostname)) == NULL) {
-+                      fprintf(stderr, _("mount: can't get address for %s\n"),
-+                              hostname);
-+                      return 0;
-+              } else {
-+                      if (hp->h_length > sizeof(*saddr)) {
-+                              fprintf(stderr,
-+                                      _("mount: got bad hp->h_length\n"));
-+                              hp->h_length = sizeof(*saddr);
-+                      }
-+                      memcpy(&saddr->sin_addr, hp->h_addr, hp->h_length);
-+              }
-+      }
-+      return 1;
-+}
-+
-+/*
-+ * Sigh... pmap_getport() doesn't actually check the version number.
-+ * In order to make sure that the server actually supports the service
-+ * we're requesting, we open and RPC client, and fire off a NULL
-+ * RPC call.
-+ */
-+static int
-+clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
-+        const u_int prot)
-+{
-+      CLIENT *clnt;
-+      int sock, stat;
-+      static char clnt_res;
-+
-+      sock = RPC_ANYSOCK;
-+      switch(prot) {
-+      case IPPROTO_UDP:
-+              clnt = clntudp_bufcreate(saddr, prog, vers,
-+                                       RETRY_TIMEOUT, &sock,
-+                                       RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
-+              break;
-+      case IPPROTO_TCP:
-+              clnt = clnttcp_create(saddr, prog, vers, &sock,
-+                                    RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
-+              break;
-+      default:
-+              goto out_bad;
-+      }
-+      if (!clnt)
-+              goto out_bad;
-+      memset(&clnt_res, 0, sizeof(clnt_res));
-+      stat = clnt_call(clnt, NULLPROC,
-+                       (xdrproc_t)xdr_void, (caddr_t)NULL,
-+                       (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
-+                       TIMEOUT);
-+      clnt_destroy(clnt);
-+      close(sock);
-+      if (stat != RPC_PROGVERSMISMATCH)
-+              return 1;
-+ out_bad:
-+      return 0;
-+}
-+
-+/*
-+ * Use the portmapper to discover whether or not the service we want is
-+ * available. The lists 'versions' and 'protos' define ordered sequences
-+ * of service versions and udp/tcp protocols to probe for.
-+ */
-+static int
-+probe_port(clnt_addr_t *server,
-+         const u_long *versions,
-+         const u_int *protos)
-+{
-+      struct sockaddr_in *saddr = &server->saddr;
-+      struct pmap *pmap = &server->pmap;
-+      const u_long prog = pmap->pm_prog,
-+              vers = pmap->pm_vers,
-+              *p_vers;
-+      const u_int prot = (u_int)pmap->pm_prot,
-+              *p_prot;
-+      const u_short port = (u_short) pmap->pm_port;
-+      u_short p_port;
-+
-+      p_prot = prot ? &prot : protos;
-+      p_vers = vers ? &vers : versions;
-+      for (;;) {
-+              saddr->sin_port = htons(PMAPPORT);
-+              p_port = pmap_getport(saddr, prog, *p_vers, *p_prot);
-+              if (p_port) {
-+                      if (!port || port == p_port) {
-+                              saddr->sin_port = htons(port);
-+                              if (clnt_ping(saddr, prog, *p_vers, *p_prot))
-+                                      goto out_ok;
-+                      }
-+              } else if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
-+                      break;
-+              if (!prot) {
-+                      if (*++p_prot)
-+                              continue;
-+                      p_prot = protos;
-+              }
-+              if (vers || !*++p_vers)
-+                      break;
-+      }
-+      return 0;
-+ out_ok:
-+      if (!vers)
-+              pmap->pm_vers = *p_vers;
-+      if (!prot)
-+              pmap->pm_prot = *p_prot;
-+      if (!port)
-+              pmap->pm_port = p_port;
-+      return 1;
-+}
-+
-+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;
-+
-+      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);
-+      return probe_port(nfs_server, probe_vers, probe_prot);
-+}
-+
-+static 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;
-+
-+      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);
-+      return probe_port(mnt_server, probe_vers, probe_prot);
-+}
-+
-+static int
-+probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
-+{
-+      struct pmap *nfs_pmap = &nfs_server->pmap;
-+      struct pmap *mnt_pmap = &mnt_server->pmap;
-+      struct pmap save_nfs, save_mnt;
-+      int res;
-+      const u_long *probe_vers;
-+
-+      if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers)
-+              nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers);
-+      else if (nfs_pmap->pm_vers && !mnt_pmap->pm_vers)
-+              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++) {
-+              nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
-+              if ((res = probe_nfsport(nfs_server) != 0)) {
-+                      mnt_pmap->pm_vers = *probe_vers;
-+                      if ((res = probe_mntport(mnt_server)) != 0)
-+                              return 1;
-+                      memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
-+              }
-+              memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
-       }
-+ out_bad:
-+      return 0;
-+ version_fixed:
-+      if (!probe_nfsport(nfs_server))
-+              goto out_bad;
-+      return probe_mntport(mnt_server);
-+}
-+
-+static CLIENT *
-+mnt_openclnt(clnt_addr_t *mnt_server, int *msock, const int report_errs)
-+{
-+      struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
-+      struct pmap *mnt_pmap = &mnt_server->pmap;
-+      CLIENT *clnt;
-+
-+      /* contact the mount daemon via TCP */
-+      mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
-+      *msock = RPC_ANYSOCK;
-+
-+      switch (mnt_pmap->pm_prot) {
-+      case IPPROTO_UDP:
-+              clnt = clntudp_bufcreate(mnt_saddr,
-+                                       mnt_pmap->pm_prog, mnt_pmap->pm_vers,
-+                                       RETRY_TIMEOUT, msock,
-+                                       MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
-+              break;
-+      case IPPROTO_TCP:
-+              clnt = clnttcp_create(mnt_saddr,
-+                                    mnt_pmap->pm_prog, mnt_pmap->pm_vers,
-+                                    msock,
-+                                    MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
-+              break;
-+      default:
-+              goto out_bad;
-+      }
-+      if (!clnt)
-+              goto report_err;
-+      /* try to mount hostname:dirname */
-+      clnt->cl_auth = authunix_create_default();
-+      return clnt;
-+ report_err:
-+      if (report_errs)
-+              clnt_pcreateerror("mount");
-+ out_bad:
-+      return NULL;
-+}
-+
-+static inline void
-+mnt_closeclnt(CLIENT *clnt, int msock)
-+{
-+      auth_destroy(clnt->cl_auth);
-+      clnt_destroy(clnt);
-+      close(msock);
-+}
-+
-+static inline enum clnt_stat
-+nfs3_mount(CLIENT *clnt, mnt3arg_t *mnt3arg, mnt3res_t *mnt3res)
-+{
-+      return clnt_call(clnt, MOUNTPROC3_MNT,
-+                       (xdrproc_t) xdr_dirpath, (caddr_t) mnt3arg,
-+                       (xdrproc_t) xdr_mountres3, (caddr_t) mnt3res,
-+                       TIMEOUT);
-+}
-+
-+static inline enum clnt_stat
-+nfs2_mount(CLIENT *clnt, mnt2arg_t *mnt2arg, mnt2res_t *mnt2res)
-+{
-+      return clnt_call(clnt, MOUNTPROC_MNT,
-+                       (xdrproc_t) xdr_dirpath, (caddr_t) mnt2arg,
-+                       (xdrproc_t) xdr_fhstatus, (caddr_t) mnt2res,
-+                       TIMEOUT);
-+}
-+
-+static int
-+nfs_call_mount(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server,
-+             mntarg_t *mntarg, mntres_t *mntres, const int report_errs)
-+{
-+      CLIENT *clnt;
-+      enum clnt_stat stat;
-+      int msock;
-+
-+
-+      if (!probe_bothports(mnt_server, nfs_server)) {
-+              if (report_errs)
-+                      fprintf(stderr,_("mount: failed to probe ports on NFS server %s\n"),
-+                              *nfs_server->hostname);
-+              goto out_bad;
-+      }
-+
-+      clnt = mnt_openclnt(mnt_server, &msock, report_errs);
-+      if (!clnt)
-+              goto out_bad;
-+      /* make pointers in xdr_mountres3 NULL so
-+       * that xdr_array allocates memory for us
-+       */
-+      memset(mntres, 0, sizeof(*mntres));
-+      switch (mnt_server->pmap.pm_vers) {
-+      case 3:
-+              stat = nfs3_mount(clnt, mntarg, &mntres->nfsv3);
-+              break;
-+      case 2:
-+      case 1:
-+              stat = nfs2_mount(clnt, mntarg, &mntres->nfsv2);
-+              break;
-+      default:
-+              goto out_bad;
-+      }
-+      if (stat != RPC_SUCCESS && report_errs)
-+              clnt_perror(clnt, "mount");
-+      mnt_closeclnt(clnt, msock);
-+      if (stat == RPC_SUCCESS)
-+              return 1;
-+ out_bad:
-+      return 0;
-+}
-+
-+static int
-+parse_options(char *old_opts, struct nfs_mount_data *data,
-+            int *bg, int *retry, clnt_addr_t *mnt_server,
-+            clnt_addr_t *nfs_server, char *new_opts, const int opt_size)
-+{
-+      struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
-+      struct pmap *mnt_pmap = &mnt_server->pmap;
-+      struct pmap *nfs_pmap = &nfs_server->pmap;
-+      int len;
-+      char *opt, *opteq;
-+      char *mounthost = NULL;
-+      char cbuf[128];
-+
-+      data->flags = 0;
-+      *bg = 0;
-+
-+      len = strlen(new_opts);
-+      for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
-+              if (strlen(opt) >= sizeof(cbuf))
-+                      goto bad_parameter;
-+              if ((opteq = strchr(opt, '=')) && isdigit(opteq[1])) {
-+                      int val = atoi(opteq + 1);
-+                      *opteq = '\0';
-+                      if (!strcmp(opt, "rsize"))
-+                              data->rsize = val;
-+                      else if (!strcmp(opt, "wsize"))
-+                              data->wsize = val;
-+                      else if (!strcmp(opt, "timeo"))
-+                              data->timeo = val;
-+                      else if (!strcmp(opt, "retrans"))
-+                              data->retrans = val;
-+                      else if (!strcmp(opt, "acregmin"))
-+                              data->acregmin = val;
-+                      else if (!strcmp(opt, "acregmax"))
-+                              data->acregmax = val;
-+                      else if (!strcmp(opt, "acdirmin"))
-+                              data->acdirmin = val;
-+                      else if (!strcmp(opt, "acdirmax"))
-+                              data->acdirmax = val;
-+                      else if (!strcmp(opt, "actimeo")) {
-+                              data->acregmin = val;
-+                              data->acregmax = val;
-+                              data->acdirmin = val;
-+                              data->acdirmax = val;
-+                      }
-+                      else if (!strcmp(opt, "retry"))
-+                              *retry = val;
-+                      else if (!strcmp(opt, "port"))
-+                              nfs_pmap->pm_port = val;
-+                      else if (!strcmp(opt, "mountport"))
-+                              mnt_pmap->pm_port = val;
-+                      else if (!strcmp(opt, "mountprog"))
-+                              mnt_pmap->pm_prog = val;
-+                      else if (!strcmp(opt, "mountvers"))
-+                              mnt_pmap->pm_vers = val;
-+                      else if (!strcmp(opt, "nfsprog"))
-+                              nfs_pmap->pm_prog = val;
-+                      else if (!strcmp(opt, "nfsvers") ||
-+                               !strcmp(opt, "vers")) {
-+                              nfs_pmap->pm_vers = val;
-+                              opt = "nfsvers";
-+#if NFS_MOUNT_VERSION >= 2
-+                      } else if (!strcmp(opt, "namlen")) {
-+                              if (nfs_mount_version >= 2)
-+                                      data->namlen = val;
-+                              else if (!sloppy)
-+                                      goto bad_parameter;
- #endif
--#if 0
--#define MOUNTPORT 635
--      /* HJLu wants to remove all traces of the old default port.
--         Are there still people running a mount RPC service on this
--         port without having a portmapper? */
--      if (!p.pm_port)
--              p.pm_port = MOUNTPORT;
--#endif
--      return &p;
-+                      } else if (!strcmp(opt, "addr")) {
-+                              /* ignore */;
-+                              continue;
-+                      } else if (!sloppy)
-+                              goto bad_parameter;
-+                      sprintf(cbuf, "%s=%s,", opt, opteq+1);
-+              } else if (opteq) {
-+                      *opteq = '\0';
-+                      if (!strcmp(opt, "proto")) {
-+                              if (!strcmp(opteq+1, "udp")) {
-+                                      nfs_pmap->pm_prot = IPPROTO_UDP;
-+#if NFS_MOUNT_VERSION >= 2
-+                                      data->flags &= ~NFS_MOUNT_TCP;
-+                              } else if (!strcmp(opteq+1, "tcp") &&
-+                                         nfs_mount_version >= 2) {
-+                                      nfs_pmap->pm_prot = IPPROTO_TCP;
-+                                      data->flags |= NFS_MOUNT_TCP;
-+#endif
-+                              } else if (!sloppy)
-+                                      goto bad_parameter;
-+                      } else if (!strcmp(opt, "mounthost"))
-+                              mounthost=xstrndup(opteq+1,
-+                                                 strcspn(opteq+1," \t\n\r,"));
-+                      else
-+                              goto bad_parameter;
-+                      sprintf(cbuf, "%s=%s,", opt, opteq+1);
-+              } else {
-+                      int val = 1;
-+                      if (!strncmp(opt, "no", 2)) {
-+                              val = 0;
-+                              opt += 2;
-+                      }
-+                      if (!strcmp(opt, "bg"))
-+                              *bg = val;
-+                      else if (!strcmp(opt, "fg"))
-+                              *bg = !val;
-+                      else if (!strcmp(opt, "soft")) {
-+                              data->flags &= ~NFS_MOUNT_SOFT;
-+                              if (val)
-+                                      data->flags |= NFS_MOUNT_SOFT;
-+                      } else if (!strcmp(opt, "hard")) {
-+                              data->flags &= ~NFS_MOUNT_SOFT;
-+                              if (!val)
-+                                      data->flags |= NFS_MOUNT_SOFT;
-+                      } else if (!strcmp(opt, "intr")) {
-+                              data->flags &= ~NFS_MOUNT_INTR;
-+                              if (val)
-+                                      data->flags |= NFS_MOUNT_INTR;
-+                      } else if (!strcmp(opt, "posix")) {
-+                              data->flags &= ~NFS_MOUNT_POSIX;
-+                              if (val)
-+                                      data->flags |= NFS_MOUNT_POSIX;
-+                      } else if (!strcmp(opt, "cto")) {
-+                              data->flags &= ~NFS_MOUNT_NOCTO;
-+                              if (!val)
-+                                      data->flags |= NFS_MOUNT_NOCTO;
-+                      } else if (!strcmp(opt, "ac")) {
-+                              data->flags &= ~NFS_MOUNT_NOAC;
-+                              if (!val)
-+                                      data->flags |= NFS_MOUNT_NOAC;
-+#if NFS_MOUNT_VERSION >= 2
-+                      } else if (!strcmp(opt, "tcp")) {
-+                              data->flags &= ~NFS_MOUNT_TCP;
-+                              if (val) {
-+                                      if (nfs_mount_version < 2)
-+                                              goto bad_option;
-+                                      nfs_pmap->pm_prot = IPPROTO_TCP;
-+                                      data->flags |= NFS_MOUNT_TCP;
-+                              } else
-+                                      nfs_pmap->pm_prot = IPPROTO_UDP;
-+                      } else if (!strcmp(opt, "udp")) {
-+                              data->flags &= ~NFS_MOUNT_TCP;
-+                              if (!val) {
-+                                      if (nfs_mount_version < 2)
-+                                              goto bad_option;
-+                                      nfs_pmap->pm_prot = IPPROTO_TCP;
-+                                      data->flags |= NFS_MOUNT_TCP;
-+                              } else
-+                                      nfs_pmap->pm_prot = IPPROTO_UDP;
-+#endif
-+#if NFS_MOUNT_VERSION >= 3
-+                      } else if (!strcmp(opt, "lock")) {
-+                              data->flags &= ~NFS_MOUNT_NONLM;
-+                              if (!val) {
-+                                      if (nfs_mount_version < 3)
-+                                              goto bad_option;
-+                                      data->flags |= NFS_MOUNT_NONLM;
-+                              }
-+#endif
-+#if NFS_MOUNT_VERSION >= 4
-+                      } else if (!strcmp(opt, "broken_suid")) {
-+                              data->flags &= ~NFS_MOUNT_BROKEN_SUID;
-+                              if (val) {
-+                                      if (nfs_mount_version < 4)
-+                                              goto bad_option;
-+                                      data->flags |= NFS_MOUNT_BROKEN_SUID;
-+                              }
-+#endif
-+                      } else {
-+                      bad_option:
-+                              printf(_("Unsupported nfs mount option: "
-+                                       "%s%s\n"), val ? "" : "no", opt);
-+                              goto out_bad;
-+                      }
-+                      sprintf(cbuf, val ? "%s,":"no%s,", opt);
-+              }
-+              len += strlen(cbuf);
-+              if (len >= opt_size) {
-+                      printf(_("mount: excessively long option argument\n"));
-+                      goto out_bad;
-+              }
-+              strcat(new_opts, cbuf);
-+      }
-+      /* See if the nfs host = mount host. */
-+      if (mounthost) {
-+              if (!nfs_gethostbyname(mounthost, mnt_saddr))
-+                      goto out_bad;
-+              *mnt_server->hostname = mounthost;
-+      }
-+      return 1;
-+ bad_parameter:
-+      printf(_("Bad nfs mount parameter: %s\n"), opt);
-+ out_bad:
-+      return 0;
-+}
-+
-+static inline int
-+nfsmnt_check_compat(const struct pmap *nfs_pmap, const struct pmap *mnt_pmap)
-+{
-+      if (nfs_pmap->pm_vers > MAX_NFSPROT) {
-+              fprintf(stderr, _("NFSv%ld not supported!\n"), nfs_pmap->pm_vers);
-+              goto out_bad;
-+      }
-+      if (mnt_pmap->pm_vers > MAX_MNTPROT) {
-+              fprintf(stderr, _("NFS mount v%ld not supported!\n"), mnt_pmap->pm_vers);
-+              goto out_bad;
-+      }
-+      return 1;
-+ out_bad:
-+      return 0;
- }
--int nfsmount(const char *spec, const char *node, int *flags,
--           char **extra_opts, char **mount_opts, int *nfs_mount_vers,
--           int running_bg)
-+int
-+nfsmount(const char *spec, const char *node, int *flags,
-+       char **extra_opts, char **mount_opts, int *nfs_mount_vers,
-+       int running_bg)
- {
-       static char *prev_bg_host;
-       char hostdir[1024];
--      CLIENT *mclient;
-       char *hostname, *dirname, *old_opts, *mounthost = NULL;
--      char new_opts[1024];
--      struct timeval total_timeout;
--      enum clnt_stat clnt_stat;
-+      char new_opts[1024], cbuf[20];
-       static struct nfs_mount_data data;
--      char *opt, *opteq;
--      int nfs_mount_version;
-       int val;
--      struct hostent *hp;
--      struct sockaddr_in server_addr;
--      struct sockaddr_in mount_server_addr;
--      struct pmap *pm_mnt;
--      int msock, fsock;
--      struct timeval retry_timeout;
--      union {
--              struct fhstatus nfsv2;
--              struct mountres3 nfsv3;
--      } status;
-+
-+      clnt_addr_t mnt_server = { &mounthost, };
-+      clnt_addr_t nfs_server = { &hostname, };
-+      struct sockaddr_in *nfs_saddr = &nfs_server.saddr;
-+      struct pmap  *mnt_pmap = &mnt_server.pmap,
-+                   *nfs_pmap = &nfs_server.pmap;
-+      struct pmap  save_mnt, save_nfs;
-+
-+      int fsock;
-+
-+      mntres_t mntres;
-+
-       struct stat statbuf;
--      char *s;
--      int port, mountport, proto, bg, soft, intr;
--      int posix, nocto, noac, nolock, broken_suid;
--      int retry, tcp;
--      int mountprog, mountvers, nfsprog, nfsvers;
-+      char *s, *p;
-+      int bg, retry;
-       int retval;
-       time_t t;
-       time_t prevt;
-@@ -231,8 +756,7 @@ int nfsmount(const char *spec, const cha
-       nfs_mount_version = *nfs_mount_vers;
-       retval = EX_FAIL;
--      msock = fsock = -1;
--      mclient = NULL;
-+      fsock = -1;
-       if (strlen(spec) >= sizeof(hostdir)) {
-               fprintf(stderr, _("mount: "
-                                 "excessively long host:dir argument\n"));
-@@ -258,49 +782,23 @@ int nfsmount(const char *spec, const cha
-               goto fail;
-       }
--      server_addr.sin_family = AF_INET;
--#ifdef HAVE_inet_aton
--      if (!inet_aton(hostname, &server_addr.sin_addr))
--#endif
--      {
--              if ((hp = gethostbyname(hostname)) == NULL) {
--                      fprintf(stderr, _("mount: can't get address for %s\n"),
--                              hostname);
--                      goto fail;
--              } else {
--                      if (hp->h_length > sizeof(struct in_addr)) {
--                              fprintf(stderr,
--                                      _("mount: got bad hp->h_length\n"));
--                              hp->h_length = sizeof(struct in_addr);
--                      }
--                      memcpy(&server_addr.sin_addr,
--                             hp->h_addr, hp->h_length);
--              }
--      }
--
--      memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
-+      if (!nfs_gethostbyname(hostname, nfs_saddr))
-+              goto fail;
-+      mounthost = hostname;
-+      memcpy (&mnt_server.saddr, nfs_saddr, sizeof (mnt_server.saddr));
-       /* add IP address to mtab options for use when unmounting */
--      s = inet_ntoa(server_addr.sin_addr);
-+      s = inet_ntoa(nfs_saddr->sin_addr);
-       old_opts = *extra_opts;
-       if (!old_opts)
-               old_opts = "";
--      if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
--              fprintf(stderr, _("mount: "
--                                "excessively long option argument\n"));
--              goto fail;
--      }
--      sprintf(new_opts, "%s%saddr=%s",
--              old_opts, *old_opts ? "," : "", s);
--      *extra_opts = xstrdup(new_opts);
-       /* Set default options.
-        * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
-        * let the kernel decide.
-        * timeo is filled in after we know whether it'll be TCP or UDP. */
-       memset(&data, 0, sizeof(data));
--      data.retrans    = 3;
-       data.acregmin   = 3;
-       data.acregmax   = 60;
-       data.acdirmin   = 30;
-@@ -310,167 +808,21 @@ int nfsmount(const char *spec, const cha
- #endif
-       bg = 0;
--      soft = 0;
--      intr = 0;
--      posix = 0;
--      nocto = 0;
--      nolock = 0;
--      broken_suid = 0;
--      noac = 0;
-       retry = 10000;          /* 10000 minutes ~ 1 week */
--      tcp = 0;
--      mountprog = MOUNTPROG;
--      mountvers = 0;
--      port = 0;
--      mountport = 0;
--      nfsprog = NFS_PROGRAM;
--      nfsvers = 0;
-+      memset(mnt_pmap, 0, sizeof(*mnt_pmap));
-+      mnt_pmap->pm_prog = MOUNTPROG;
-+      memset(nfs_pmap, 0, sizeof(*nfs_pmap));
-+      nfs_pmap->pm_prog = NFS_PROGRAM;
-       /* parse options */
-+      new_opts[0] = 0;
-+      if (!parse_options(old_opts, &data, &bg, &retry, &mnt_server, &nfs_server,
-+                         new_opts, sizeof(new_opts)))
-+              goto fail;
-+      if (!nfsmnt_check_compat(nfs_pmap, mnt_pmap))
-+              goto fail;
--      for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
--              if ((opteq = strchr(opt, '='))) {
--                      val = atoi(opteq + 1);  
--                      *opteq = '\0';
--                      if (!strcmp(opt, "rsize"))
--                              data.rsize = val;
--                      else if (!strcmp(opt, "wsize"))
--                              data.wsize = val;
--                      else if (!strcmp(opt, "timeo"))
--                              data.timeo = val;
--                      else if (!strcmp(opt, "retrans"))
--                              data.retrans = val;
--                      else if (!strcmp(opt, "acregmin"))
--                              data.acregmin = val;
--                      else if (!strcmp(opt, "acregmax"))
--                              data.acregmax = val;
--                      else if (!strcmp(opt, "acdirmin"))
--                              data.acdirmin = val;
--                      else if (!strcmp(opt, "acdirmax"))
--                              data.acdirmax = val;
--                      else if (!strcmp(opt, "actimeo")) {
--                              data.acregmin = val;
--                              data.acregmax = val;
--                              data.acdirmin = val;
--                              data.acdirmax = val;
--                      }
--                      else if (!strcmp(opt, "retry"))
--                              retry = val;
--                      else if (!strcmp(opt, "port"))
--                              port = val;
--                      else if (!strcmp(opt, "mountport"))
--                              mountport = val;
--                      else if (!strcmp(opt, "mounthost"))
--                              mounthost=xstrndup(opteq+1,
--                                                 strcspn(opteq+1," \t\n\r,"));
--                      else if (!strcmp(opt, "mountprog"))
--                              mountprog = val;
--                      else if (!strcmp(opt, "mountvers"))
--                              mountvers = val;
--                      else if (!strcmp(opt, "nfsprog"))
--                              nfsprog = val;
--                      else if (!strcmp(opt, "nfsvers") ||
--                               !strcmp(opt, "vers"))
--                              nfsvers = val;
--                      else if (!strcmp(opt, "proto")) {
--                              if (!strncmp(opteq+1, "tcp", 3))
--                                      tcp = 1;
--                              else if (!strncmp(opteq+1, "udp", 3))
--                                      tcp = 0;
--                              else
--                                      printf(_("Warning: Unrecognized proto= option.\n"));
--                      } else if (!strcmp(opt, "namlen")) {
--#if NFS_MOUNT_VERSION >= 2
--                              if (nfs_mount_version >= 2)
--                                      data.namlen = val;
--                              else
--#endif
--                                      printf(_("Warning: Option namlen is not supported.\n"));
--                      } else if (!strcmp(opt, "addr")) {
--                              /* ignore */;
--                      } else {
--                              printf(_("unknown nfs mount parameter: "
--                                       "%s=%d\n"), opt, val);
--                              goto fail;
--                      }
--              } else {
--                      val = 1;
--                      if (!strncmp(opt, "no", 2)) {
--                              val = 0;
--                              opt += 2;
--                      }
--                      if (!strcmp(opt, "bg")) 
--                              bg = val;
--                      else if (!strcmp(opt, "fg")) 
--                              bg = !val;
--                      else if (!strcmp(opt, "soft"))
--                              soft = val;
--                      else if (!strcmp(opt, "hard"))
--                              soft = !val;
--                      else if (!strcmp(opt, "intr"))
--                              intr = val;
--                      else if (!strcmp(opt, "posix"))
--                              posix = val;
--                      else if (!strcmp(opt, "cto"))
--                              nocto = !val;
--                      else if (!strcmp(opt, "ac"))
--                              noac = !val;
--                      else if (!strcmp(opt, "tcp"))
--                              tcp = val;
--                      else if (!strcmp(opt, "udp"))
--                              tcp = !val;
--                      else if (!strcmp(opt, "lock")) {
--                              if (nfs_mount_version >= 3)
--                                      nolock = !val;
--                              else
--                                      printf(_("Warning: option nolock is not supported.\n"));
--                      } else if (!strcmp(opt, "broken_suid")) {
--                              broken_suid = val;
--                      } else {
--                              if (!sloppy) {
--                                      printf(_("unknown nfs mount option: "
--                                               "%s%s\n"), val ? "" : "no", opt);
--                                      goto fail;
--                              }
--                      }
--              }
--      }
--      proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
--
--      data.flags = (soft ? NFS_MOUNT_SOFT : 0)
--              | (intr ? NFS_MOUNT_INTR : 0)
--              | (posix ? NFS_MOUNT_POSIX : 0)
--              | (nocto ? NFS_MOUNT_NOCTO : 0)
--              | (noac ? NFS_MOUNT_NOAC : 0);
--#if NFS_MOUNT_VERSION >= 2
--      if (nfs_mount_version >= 2)
--              data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
--#endif
--#if NFS_MOUNT_VERSION >= 3
--      if (nfs_mount_version >= 3)
--              data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
--#endif
--#if NFS_MOUNT_VERSION >= 4
--      if (nfs_mount_version >= 4)
--              data.flags |= (broken_suid ? NFS_MOUNT_BROKEN_SUID : 0);
--#endif
--      if (nfsvers > MAX_NFSPROT) {
--              fprintf(stderr, "NFSv%d not supported!\n", nfsvers);
--              return 0;
--      }
--      if (mountvers > MAX_NFSPROT) {
--              fprintf(stderr, "NFSv%d not supported!\n", nfsvers);
--              return 0;
--      }
--      if (nfsvers && !mountvers)
--              mountvers = (nfsvers < 3) ? 1 : nfsvers;
--      if (nfsvers && nfsvers < mountvers)
--              mountvers = nfsvers;
--
--      /* Adjust options if none specified */
--      if (!data.timeo)
--              data.timeo = tcp ? 70 : 7;
- #ifdef NFS_MOUNT_DEBUG
-       printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
-@@ -478,9 +830,10 @@ int nfsmount(const char *spec, const cha
-       printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
-              data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
-       printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
--             port, bg, retry, data.flags);
-+             nfs_pmap->pm_port, bg, retry, data.flags);
-       printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
--             mountprog, mountvers, nfsprog, nfsvers);
-+             mnt_pmap->pm_prog, mnt_pmap->pm_vers,
-+             nfs_pmap->pm_prog, nfs_pmap->pm_vers);
-       printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
-              (data.flags & NFS_MOUNT_SOFT) != 0,
-              (data.flags & NFS_MOUNT_INTR) != 0,
-@@ -497,7 +850,7 @@ int nfsmount(const char *spec, const cha
-       *mount_opts = (char *) &data;
-       if (*flags & MS_REMOUNT)
--              return 0;
-+              goto out_ok;
-       /*
-        * If the previous mount operation on the same host was
-@@ -512,28 +865,6 @@ int nfsmount(const char *spec, const cha
-       }
-       /* create mount deamon client */
--      /* See if the nfs host = mount host. */
--      if (mounthost) {
--              if (mounthost[0] >= '0' && mounthost[0] <= '9') {
--                      mount_server_addr.sin_family = AF_INET;
--                      mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
--              } else {
--                      if ((hp = gethostbyname(mounthost)) == NULL) {
--                              fprintf(stderr, _("mount: can't get address for %s\n"),
--                                      mounthost);
--                              goto fail;
--                      } else {
--                              if (hp->h_length > sizeof(struct in_addr)) {
--                                      fprintf(stderr,
--                                              _("mount: got bad hp->h_length?\n"));
--                                      hp->h_length = sizeof(struct in_addr);
--                              }
--                              mount_server_addr.sin_family = AF_INET;
--                              memcpy(&mount_server_addr.sin_addr,
--                                     hp->h_addr, hp->h_length);
--                      }
--              }
--      }
-       /*
-        * The following loop implements the mount retries. On the first
-@@ -551,15 +882,13 @@ int nfsmount(const char *spec, const cha
-        *
-        * Only the first error message will be displayed.
-        */
--      retry_timeout.tv_sec = 3;
--      retry_timeout.tv_usec = 0;
--      total_timeout.tv_sec = 20;
--      total_timeout.tv_usec = 0;
-       timeout = time(NULL) + 60 * retry;
-       prevt = 0;
-       t = 30;
-       val = 1;
-+      memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
-+      memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
-       for (;;) {
-               if (bg && stat(node, &statbuf) == -1) {
-                       /* no mount point yet - sleep */
-@@ -570,89 +899,18 @@ int nfsmount(const char *spec, const cha
-                                       val = 30;
-                       }
-               } else {
-+                      int stat;
-                       /* be careful not to use too many CPU cycles */
-                       if (t - prevt < 30)
-                               sleep(30);
--                      pm_mnt = get_mountport(&mount_server_addr,
--                                             mountprog,
--                                             mountvers,
--                                             proto,
--                                             mountport,
--                                             nfs_mount_version);
--
--                      /* contact the mount daemon via TCP */
--                      mount_server_addr.sin_port = htons(pm_mnt->pm_port);
--                      msock = RPC_ANYSOCK;
--
--                      switch (pm_mnt->pm_prot) {
--                      case IPPROTO_UDP:
--                              mclient = clntudp_create(&mount_server_addr,
--                                                       pm_mnt->pm_prog,
--                                                       pm_mnt->pm_vers,
--                                                       retry_timeout,
--                                                       &msock);
--                              if (mclient)
--                                      break;
--                              mount_server_addr.sin_port =
--                                      htons(pm_mnt->pm_port);
--                              msock = RPC_ANYSOCK;
--                      case IPPROTO_TCP:
--                              mclient = clnttcp_create(&mount_server_addr,
--                                                       pm_mnt->pm_prog,
--                                                       pm_mnt->pm_vers,
--                                                       &msock, 0, 0);
-+                      stat = nfs_call_mount(&mnt_server, &nfs_server,
-+                                            &dirname, &mntres,
-+                                            !running_bg && prevt == 0);
-+                      if (stat)
-                               break;
--                      default:
--                              mclient = 0;
--                      }
--
--                      if (mclient) {
--                              /* try to mount hostname:dirname */
--                              mclient->cl_auth = authunix_create_default();
--
--                              /* make pointers in xdr_mountres3 NULL so
--                               * that xdr_array allocates memory for us
--                               */
--                              memset(&status, 0, sizeof(status));
--
--                              if (pm_mnt->pm_vers == 3)
--                                      clnt_stat = clnt_call(mclient,
--                                                   MOUNTPROC3_MNT,
--                                                   (xdrproc_t) xdr_dirpath,
--                                                   (caddr_t) &dirname,
--                                                   (xdrproc_t) xdr_mountres3,
--                                                   (caddr_t) &status,
--                                                   total_timeout);
--                              else
--                                      clnt_stat = clnt_call(mclient,
--                                                   MOUNTPROC_MNT,
--                                                   (xdrproc_t) xdr_dirpath,
--                                                   (caddr_t) &dirname,
--                                                   (xdrproc_t) xdr_fhstatus,
--                                                   (caddr_t) &status,
--                                                   total_timeout);
--
--                              if (clnt_stat == RPC_SUCCESS)
--                                      break;          /* we're done */
--#if 0
--                              /* errno? who sets errno? */
--                              /* this fragment breaks bg mounting */
--                              if (errno != ECONNREFUSED) {
--                                      clnt_perror(mclient, "mount");
--                                      goto fail;      /* don't retry */
--                              }
--#endif
--                              if (!running_bg && prevt == 0)
--                                      clnt_perror(mclient, "mount");
--                              auth_destroy(mclient->cl_auth);
--                              clnt_destroy(mclient);
--                              mclient = 0;
--                              close(msock);
--                      } else {
--                              if (!running_bg && prevt == 0)
--                                      clnt_pcreateerror("mount");
--                      }
-+                      memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
-+                      memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
-                       prevt = t;
-               }
-@@ -668,36 +926,35 @@ int nfsmount(const char *spec, const cha
-               if (t >= timeout)
-                       goto fail;
-       }
--      nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
--      if (nfsvers == 2) {
--              if (status.nfsv2.fhs_status != 0) {
-+      if (nfs_pmap->pm_vers == 2) {
-+              if (mntres.nfsv2.fhs_status != 0) {
-                       fprintf(stderr,
--                              "mount: %s:%s failed, reason given by server: %s\n",
-+                              _("mount: %s:%s failed, reason given by server: %s\n"),
-                               hostname, dirname,
--                              nfs_strerror(status.nfsv2.fhs_status));
-+                              nfs_strerror(mntres.nfsv2.fhs_status));
-                       goto fail;
-               }
-               memcpy(data.root.data,
--                     (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
-+                     (char *) mntres.nfsv2.fhstatus_u.fhs_fhandle,
-                      NFS_FHSIZE);
- #if NFS_MOUNT_VERSION >= 4
-               data.root.size = NFS_FHSIZE;
-               memcpy(data.old_root.data,
--                     (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
-+                     (char *) mntres.nfsv2.fhstatus_u.fhs_fhandle,
-                      NFS_FHSIZE);
- #endif
-       } else {
- #if NFS_MOUNT_VERSION >= 4
-               fhandle3 *fhandle;
--              if (status.nfsv3.fhs_status != 0) {
-+              if (mntres.nfsv3.fhs_status != 0) {
-                       fprintf(stderr,
--                              "mount: %s:%s failed, reason given by server: %s\n",
-+                              _("mount: %s:%s failed, reason given by server: %s\n"),
-                               hostname, dirname,
--                              nfs_strerror(status.nfsv3.fhs_status));
-+                              nfs_strerror(mntres.nfsv3.fhs_status));
-                       goto fail;
-               }
--              fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
-+              fhandle = &mntres.nfsv3.mountres3_u.mountinfo.fhandle;
-               memset(data.old_root.data, 0, NFS_FHSIZE);
-               memset(&data.root, 0, sizeof(data.root));
-               data.root.size = fhandle->fhandle3_len;
-@@ -711,13 +968,9 @@ int nfsmount(const char *spec, const cha
-       /* create nfs socket for kernel */
--      if (tcp) {
--              if (nfs_mount_version < 3) {
--                      printf(_("NFS over TCP is not supported.\n"));
--                      goto fail;
--              }
-+      if (nfs_pmap->pm_prot == IPPROTO_TCP)
-               fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
--      } else
-+      else
-               fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       if (fsock < 0) {
-               perror(_("nfs socket"));
-@@ -727,72 +980,162 @@ int nfsmount(const char *spec, const cha
-               perror(_("nfs bindresvport"));
-               goto fail;
-       }
--      if (port == 0) {
--              server_addr.sin_port = PMAPPORT;
--              port = pmap_getport(&server_addr, nfsprog, nfsvers,
--                                  tcp ? IPPROTO_TCP : IPPROTO_UDP);
--#if 1
--              /* Here we check to see if user is mounting with the
--               * tcp option.  If so, and if the portmap returns a
--               * '0' for port (service unavailable), we then exit,
--               * notifying the user, rather than hanging up mount.
--               */
--              if (port == 0 && tcp == 1) {
--                      perror(_("nfs server reported service unavailable"));
--                      goto fail;
--              }
--#endif
--
--              if (port == 0)
--                      port = NFS_PORT;
- #ifdef NFS_MOUNT_DEBUG
--              else
--                      printf(_("used portmapper to find NFS port\n"));
-+      printf(_("using port %d for nfs deamon\n"), nfs_pmap->pm_port);
- #endif
--      }
--#ifdef NFS_MOUNT_DEBUG
--      printf(_("using port %d for nfs deamon\n"), port);
--#endif
--      server_addr.sin_port = htons(port);
-+      nfs_saddr->sin_port = htons(nfs_pmap->pm_port);
-       /*
-        * connect() the socket for kernels 1.3.10 and below only,
-        * to avoid problems with multihomed hosts.
-        * --Swen
-        */
-       if (linux_version_code() <= 66314
--          && connect(fsock, (struct sockaddr *) &server_addr,
--                     sizeof (server_addr)) < 0) {
-+          && connect(fsock, (struct sockaddr *) nfs_saddr,
-+                     sizeof (*nfs_saddr)) < 0) {
-               perror(_("nfs connect"));
-               goto fail;
-       }
-+#if NFS_MOUNT_VERSION >= 2
-+      if (nfs_pmap->pm_prot == IPPROTO_TCP)
-+              data.flags |= NFS_MOUNT_TCP;
-+      else
-+              data.flags &= ~NFS_MOUNT_TCP;
-+#endif
-+
-       /* prepare data structure for kernel */
-       data.fd = fsock;
--      memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
-+      memcpy((char *) &data.addr, (char *) nfs_saddr, sizeof(data.addr));
-       strncpy(data.hostname, hostname, sizeof(data.hostname));
--      /* clean up */
-+ out_ok:
-+      /* Ensure we have enough padding for the following strcat()s */
-+      if (strlen(new_opts) + strlen(s) + 30 >= sizeof(new_opts)) {
-+              fprintf(stderr, _("mount: "
-+                                "excessively long option argument\n"));
-+              goto fail;
-+      }
--      auth_destroy(mclient->cl_auth);
--      clnt_destroy(mclient);
--      close(msock);
-+      sprintf(cbuf, "addr=%s", s);
-+      strcat(new_opts, cbuf);
-+
-+      *extra_opts = xstrdup(new_opts);
-       return 0;
-       /* abort */
--
-  fail:
--      if (msock != -1) {
--              if (mclient) {
--                      auth_destroy(mclient->cl_auth);
--                      clnt_destroy(mclient);
--              }
--              close(msock);
--      }
-       if (fsock != -1)
-               close(fsock);
-       return retval;
--}     
-+}
-+
-+static inline enum clnt_stat
-+nfs3_umount(dirpath *argp, CLIENT *clnt)
-+{
-+      static char clnt_res;
-+      memset (&clnt_res, 0, sizeof(clnt_res));
-+      return clnt_call(clnt, MOUNTPROC_UMNT,
-+                       (xdrproc_t) xdr_dirpath, (caddr_t)argp,
-+                       (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
-+                       TIMEOUT);
-+}
-+
-+static inline enum clnt_stat
-+nfs2_umount(dirpath *argp, CLIENT *clnt)
-+{
-+      static char clnt_res;
-+      memset (&clnt_res, 0, sizeof(clnt_res));
-+      return clnt_call(clnt, MOUNTPROC_UMNT,
-+                       (xdrproc_t) xdr_dirpath, (caddr_t)argp,
-+                       (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
-+                       TIMEOUT);
-+}
-+
-+static int
-+nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
-+{
-+      CLIENT *clnt;
-+      enum clnt_stat res = 0;
-+      int msock;
-+
-+      clnt = mnt_openclnt(mnt_server, &msock, 1);
-+      if (!clnt)
-+              goto out_bad;
-+      switch (mnt_server->pmap.pm_vers) {
-+      case 3:
-+              res = nfs3_umount(argp, clnt);
-+              break;
-+      case 2:
-+      case 1:
-+              res = nfs2_umount(argp, clnt);
-+              break;
-+      default:
-+      }
-+      mnt_closeclnt(clnt, msock);
-+      if (res == RPC_SUCCESS)
-+              return 1;
-+ out_bad:
-+      return 0;
-+}
-+
-+int
-+nfsumount(const char *spec, const char *opts)
-+{
-+      char *hostname;
-+      char *dirname;
-+      clnt_addr_t mnt_server = { &hostname, };
-+      struct pmap *pmap = &mnt_server.pmap;
-+      char *p;
-+
-+      nfs_mount_version = find_kernel_nfs_mount_version();
-+      if (spec == NULL || (p = strchr(spec,':')) == NULL)
-+              goto out_bad;
-+      hostname = xstrndup(spec, p-spec);
-+      dirname = xstrdup(p+1);
-+#ifdef NFS_MOUNT_DEBUG
-+      printf(_("host: %s, directory: %s\n"), hostname, dirname);
-+#endif
-+
-+      if (opts && (p = strstr(opts, "addr="))) {
-+              char *q;
-+
-+              free(hostname);
-+              p += 5;
-+              q = p;
-+              while (*q && *q != ',') q++;
-+              hostname = xstrndup(p,q-p);
-+      }
-+
-+      if (opts && (p = strstr(opts, "mounthost="))) {
-+              char *q;
-+
-+              free(hostname);
-+              p += 10;
-+              q = p;
-+              while (*q && *q != ',') q++;
-+              hostname = xstrndup(p,q-p);
-+      }
-+
-+      pmap->pm_prog = MOUNTPROG;
-+      pmap->pm_vers = MOUNTVERS;
-+      if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10)))
-+              pmap->pm_prog = atoi(p+10);
-+      if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10)))
-+              pmap->pm_port = atoi(p+10);
-+      if (opts && (p = strstr(opts, "nfsvers=")) && isdigit(*(p+8)))
-+              pmap->pm_vers = nfsvers_to_mnt(atoi(p+8));
-+      if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10)))
-+              pmap->pm_vers = atoi(p+10);
-+
-+      if (!nfs_gethostbyname(hostname, &mnt_server.saddr))
-+              goto out_bad;
-+      if (!probe_mntport(&mnt_server))
-+              goto out_bad;
-+      return nfs_call_umount(&mnt_server, &dirname);
-+ out_bad:
-+      return 0;
-+}
- /*
-  * We need to translate between nfs status return values and
-diff -puN mount/sundries.h~nfs mount/sundries.h
---- util-linux-2.12/mount/sundries.h~nfs       2004-10-13 13:51:44.000000000 -0400
-+++ util-linux-2.12-bfields/mount/sundries.h   2004-10-13 14:13:30.000000000 -0400
-@@ -37,6 +37,7 @@ void die (int errcode, const char *fmt, 
- #ifdef HAVE_NFS
- int nfsmount (const char *spec, const char *node, int *flags,
-             char **orig_opts, char **opt_args, int *version, int running_bg);
-+int nfsumount(const char *spec, const char *opts);
- #endif
- /* exit status - bits below are ORed */
-diff -puN mount/umount.c~nfs mount/umount.c
---- util-linux-2.12/mount/umount.c~nfs 2004-10-13 13:51:44.000000000 -0400
-+++ util-linux-2.12-bfields/mount/umount.c     2004-10-13 14:13:30.000000000 -0400
-@@ -122,7 +122,7 @@ check_special_umountprog() {
- }
- #endif
--#ifdef HAVE_NFS
-+#if 0
- static int xdr_dir(XDR *xdrsp, char *dirp)
- {
-       return (xdr_string(xdrsp, &dirp, MNTPATHLEN));
-@@ -265,7 +265,7 @@ umount_one (const char *spec, const char
-       /* Ignore any RPC errors, so that you can umount the filesystem
-          if the server is down.  */
-       if (strcasecmp(type, "nfs") == 0)
--              nfs_umount_rpc_call(spec, opts);
-+              nfsumount(spec, opts);
- #endif
-  
-       umnt_err = umnt_err2 = 0;
-_
diff --git a/util-linux-2.12-02-base-nfsv4.dif b/util-linux-2.12-02-base-nfsv4.dif
deleted file mode 100644 (file)
index 5fce319..0000000
+++ /dev/null
@@ -1,866 +0,0 @@
-
-Add basic nfsv4 support
-
----
-
- util-linux-2.12-bfields/mount/Makefile     |    2 
- util-linux-2.12-bfields/mount/fstab.5      |    1 
- util-linux-2.12-bfields/mount/mount.8      |   75 ++++++
- util-linux-2.12-bfields/mount/mount.c      |   13 +
- util-linux-2.12-bfields/mount/nfs.5        |  200 +++++++++++++++++
- util-linux-2.12-bfields/mount/nfs4_mount.h |   82 +++++++
- util-linux-2.12-bfields/mount/nfs4mount.c  |  335 +++++++++++++++++++++++++++++
- util-linux-2.12-bfields/mount/nfsmount.c   |    5 
- util-linux-2.12-bfields/mount/sundries.h   |    2 
- util-linux-2.12-bfields/mount/umount.c     |    3 
- 10 files changed, 710 insertions(+), 8 deletions(-)
-
-diff -puN mount/fstab.5~base-nfsv4 mount/fstab.5
---- util-linux-2.12/mount/fstab.5~base-nfsv4   2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/fstab.5      2004-10-13 13:51:50.000000000 -0400
-@@ -115,6 +115,7 @@ of filesystem types, such as
- .IR msdos ,
- .IR ncpfs ,
- .IR nfs ,
-+.IR nfs4 ,
- .IR ntfs ,
- .IR proc ,
- .IR qnx4 ,
-diff -puN mount/Makefile~base-nfsv4 mount/Makefile
---- util-linux-2.12/mount/Makefile~base-nfsv4  2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/Makefile     2004-10-13 13:51:50.000000000 -0400
-@@ -31,7 +31,7 @@
- LO_OBJS = lomount.o $(LIB)/xstrncpy.o
- CRYPT_OBJS = cryptsetup.o -lcryptsetup
--NFS_OBJS = nfsmount.o nfsmount_xdr.o
-+NFS_OBJS = nfsmount.o nfsmount_xdr.o nfs4mount.o
- GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
- all: $(PROGS)
-diff -puN mount/mount.8~base-nfsv4 mount/mount.8
---- util-linux-2.12/mount/mount.8~base-nfsv4   2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/mount.8      2004-10-13 13:51:50.000000000 -0400
-@@ -370,6 +370,7 @@ currently supported are:
- .IR msdos ,
- .IR ncpfs ,
- .IR nfs ,
-+.IR nfs4 ,
- .IR ntfs ,
- .IR proc ,
- .IR qnx4 ,
-@@ -403,7 +404,7 @@ For most types all the
- program has to do is issue a simple
- .IR mount (2)
- system call, and no detailed knowledge of the filesystem type is required.
--For a few types however (like nfs, smbfs, ncpfs) ad hoc code is
-+For a few types however (like nfs, nfs4, smbfs, ncpfs) ad hoc code is
- necessary. The nfs ad hoc code is built in, but smbfs and ncpfs
- have a separate mount program. In order to make it possible to
- treat all types in a uniform way, mount will execute the program
-@@ -451,9 +452,10 @@ or, if that does not exist,
- All of the filesystem types listed there will be tried,
- except for those that are labeled "nodev" (e.g.,
- .IR devpts ,
--.I proc
-+.IR proc ,
-+.IR nfs ,
- and
--.IR nfs ).
-+.IR nfs4 ).
- If
- .I /etc/filesystems
- ends in a line with a single * only, mount will read
-@@ -1243,6 +1245,73 @@ Usually it just causes lots of trouble.
- .B nolock
- Do not use locking. Do not start lockd.
-+.SH "Mount options for nfs4"
-+Instead of a textual option string, parsed by the kernel, the
-+.I nfs4
-+file system expects a binary argument of type
-+.IR "struct nfs4_mount_data" .
-+The program
-+.B mount
-+itself parses the following options of the form `tag=value',
-+and puts them in the structure mentioned:
-+.BI rsize= n,
-+.BI wsize= n,
-+.BI timeo= n,
-+.BI retrans= n,
-+.BI acregmin= n,
-+.BI acregmax= n,
-+.BI acdirmin= n,
-+.BI acdirmax= n,
-+.BI actimeo= n,
-+.BI retry= n,
-+.BI port= n,
-+.BI proto= n,
-+.BI clientaddr= n,
-+.BI sec= n.
-+The option
-+.BI addr= n
-+is accepted but ignored.
-+Also the following Boolean options, possibly preceded by
-+.B no
-+are recognized:
-+.BR bg ,
-+.BR fg ,
-+.BR soft ,
-+.BR hard ,
-+.BR intr ,
-+.BR cto ,
-+.BR ac ,
-+For details, see
-+.BR nfs (5).
-+
-+Especially useful options include
-+.TP
-+.B rsize=32768,wsize=32768
-+This will make your NFS connection faster than with the default
-+buffer size of 4096.
-+.TP
-+.B hard
-+The program accessing a file on a NFS mounted file system will hang
-+when the server crashes. The process cannot be interrupted or
-+killed unless you also specify
-+.BR intr .
-+When the NFS server is back online the program will continue undisturbed
-+from where it was. This is probably what you want.
-+.TP
-+.B soft
-+This option allows the kernel to time out if the NFS server is not
-+responding for some time. The time can be
-+specified with
-+.BR timeo=time .
-+This timeout value is expressed in tenths of a second.
-+The
-+.BR soft
-+option might be useful if your NFS server sometimes doesn't respond
-+or will be rebooted while some process tries to get a file from the server.
-+Avoid using this option with
-+.BR proto=udp
-+or with a short timeout.
-+
- .SH "Mount options for ntfs"
- .TP
- .BI iocharset= name
-diff -puN mount/mount.c~base-nfsv4 mount/mount.c
---- util-linux-2.12/mount/mount.c~base-nfsv4   2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/mount.c      2004-10-13 13:51:50.000000000 -0400
-@@ -821,6 +821,19 @@ retry_nfs:
-                     "without support for the type `nfs'"));
- #endif
-   }
-+#ifdef HAVE_NFS
-+  /*
-+   * NFSv4 support
-+   */
-+  if (!fake && types && streq (types, "nfs4")) {
-+    mnt_err = nfs4mount(spec, node, &flags, &extra_opts, &mount_opts, bg);
-+    if (mnt_err)
-+      return mnt_err;
-+#else
-+    die (EX_SOFTWARE, _("mount: this version was compiled "
-+                    "without support for the type `nfs4'"));
-+#endif
-+  }
-   block_signals (SIG_BLOCK);
-diff -puN /dev/null mount/nfs4mount.c
---- /dev/null  2004-08-19 17:44:20.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfs4mount.c  2004-10-13 13:52:38.000000000 -0400
-@@ -0,0 +1,335 @@
-+/*
-+ * nfs4mount.c -- Linux NFS mount
-+ * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * Note: this file based on the original nfsmount.c
-+ */
-+
-+#include "../defines.h"       /* for HAVE_rpcsvc_nfs_prot_h and HAVE_inet_aton */
-+
-+#include <linux/posix_types.h>
-+#include <asm/posix_types.h>
-+#undef __FD_CLR
-+#undef __FD_SET
-+#undef __FD_ISSET
-+#undef __FD_ZERO
-+
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <netdb.h>
-+#include <time.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>
-+
-+#include "sundries.h"
-+
-+#include "mount_constants.h"
-+#include "nfs4_mount.h"
-+
-+#include "nls.h"
-+
-+#ifndef NFS_PORT
-+#define NFS_PORT 2049
-+#endif
-+
-+static int parse_devname(char *hostdir, char **hostname, char **dirname)
-+{
-+      char *s;
-+
-+      if (!(s = strchr(hostdir, ':'))) {
-+              fprintf(stderr,
-+                      _("mount: "
-+                        "directory to mount not in host:dir format\n"));
-+              return -1;
-+      }
-+      *hostname = hostdir;
-+      *dirname = s + 1;
-+      *s = '\0';
-+      /* Ignore all but first hostname in replicated mounts
-+         until they can be fully supported. (mack@sgi.com) */
-+      if ((s = strchr(hostdir, ','))) {
-+              *s = '\0';
-+              fprintf(stderr,
-+                      _("mount: warning: "
-+                        "multiple hostnames not supported\n"));
-+      }
-+      return 0;
-+}
-+
-+static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr)
-+{
-+      struct hostent *hp;
-+      addr->sin_family = AF_INET;
-+
-+      if (inet_aton(hostname, &addr->sin_addr))
-+              return 0;
-+      if ((hp = gethostbyname(hostname)) == NULL) {
-+              fprintf(stderr, _("mount: can't get address for %s\n"),
-+                      hostname);
-+              return -1;
-+      }
-+      if (hp->h_length > sizeof(struct in_addr)) {
-+              fprintf(stderr,
-+                      _("mount: got bad hp->h_length\n"));
-+              hp->h_length = sizeof(struct in_addr);
-+      }
-+      memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
-+      return 0;
-+}
-+
-+static int get_my_ipv4addr(char *ip_addr, int len)
-+{
-+      char myname[1024];
-+      struct sockaddr_in myaddr;
-+
-+      if (gethostname(myname, sizeof(myname))) {
-+              fprintf(stderr, _("mount: can't determine client address\n"));
-+              return -1;
-+      }
-+      if (fill_ipv4_sockaddr(myname, &myaddr))
-+              return -1;
-+      snprintf(ip_addr, len, "%s", inet_ntoa(myaddr.sin_addr));
-+      ip_addr[len-1] = '\0';
-+      return 0;
-+}
-+
-+int nfs4mount(const char *spec, const char *node, int *flags,
-+            char **extra_opts, char **mount_opts,
-+            int running_bg)
-+{
-+      static struct nfs4_mount_data data;
-+      static char hostdir[1024];
-+      static char ip_addr[16] = "127.0.0.1";
-+      static struct sockaddr_in server_addr;
-+      static int pseudoflavour = 0;
-+
-+      char *hostname, *dirname, *old_opts;
-+      char new_opts[1024];
-+      char *opt, *opteq;
-+      char *s;
-+      int val;
-+      int bg, soft, intr;
-+      int nocto, noac;
-+      int retry;
-+      int retval;
-+
-+      retval = EX_FAIL;
-+      if (strlen(spec) >= sizeof(hostdir)) {
-+              fprintf(stderr, _("mount: "
-+                                "excessively long host:dir argument\n"));
-+              goto fail;
-+      }
-+      strcpy(hostdir, spec);
-+      if (parse_devname(hostdir, &hostname, &dirname))
-+              goto fail;
-+
-+      if (fill_ipv4_sockaddr(hostname, &server_addr))
-+              goto fail;
-+      if (get_my_ipv4addr(ip_addr, sizeof(ip_addr)))
-+              goto fail;
-+
-+      /* add IP address to mtab options for use when unmounting */
-+      s = inet_ntoa(server_addr.sin_addr);
-+      old_opts = *extra_opts;
-+      if (!old_opts)
-+              old_opts = "";
-+      if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
-+              fprintf(stderr, _("mount: "
-+                                "excessively long option argument\n"));
-+              goto fail;
-+      }
-+      snprintf(new_opts, sizeof(new_opts), "%s%saddr=%s",
-+               old_opts, *old_opts ? "," : "", s);
-+      *extra_opts = xstrdup(new_opts);
-+
-+      /* Set default options.
-+       * rsize/wsize and timeo are left 0 in order to
-+       * let the kernel decide.
-+       */
-+      memset(&data, 0, sizeof(data));
-+      data.retrans    = 3;
-+      data.acregmin   = 3;
-+      data.acregmax   = 60;
-+      data.acdirmin   = 30;
-+      data.acdirmax   = 60;
-+      data.proto      = IPPROTO_TCP;
-+
-+      bg = 0;
-+      soft = 0;
-+      intr = 0;
-+      nocto = 0;
-+      noac = 0;
-+      retry = 10000;          /* 10000 minutes ~ 1 week */
-+
-+      /*
-+       * NFSv4 specifies that the default port should be 2049
-+       */
-+      server_addr.sin_port = htons(NFS_PORT);
-+
-+      /* parse options */
-+
-+      for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
-+              if ((opteq = strchr(opt, '='))) {
-+                      val = atoi(opteq + 1);
-+                      *opteq = '\0';
-+                      if (!strcmp(opt, "rsize"))
-+                              data.rsize = val;
-+                      else if (!strcmp(opt, "wsize"))
-+                              data.wsize = val;
-+                      else if (!strcmp(opt, "timeo"))
-+                              data.timeo = val;
-+                      else if (!strcmp(opt, "retrans"))
-+                              data.retrans = val;
-+                      else if (!strcmp(opt, "acregmin"))
-+                              data.acregmin = val;
-+                      else if (!strcmp(opt, "acregmax"))
-+                              data.acregmax = val;
-+                      else if (!strcmp(opt, "acdirmin"))
-+                              data.acdirmin = val;
-+                      else if (!strcmp(opt, "acdirmax"))
-+                              data.acdirmax = val;
-+                      else if (!strcmp(opt, "actimeo")) {
-+                              data.acregmin = val;
-+                              data.acregmax = val;
-+                              data.acdirmin = val;
-+                              data.acdirmax = val;
-+                      }
-+                      else if (!strcmp(opt, "retry"))
-+                              retry = val;
-+                      else if (!strcmp(opt, "port"))
-+                              server_addr.sin_port = htons(val);
-+                      else if (!strcmp(opt, "proto")) {
-+                              if (!strncmp(opteq+1, "tcp", 3))
-+                                      data.proto = IPPROTO_TCP;
-+                              else if (!strncmp(opteq+1, "udp", 3))
-+                                      data.proto = IPPROTO_UDP;
-+                              else
-+                                      printf(_("Warning: Unrecognized proto= option.\n"));
-+                      } else if (!strcmp(opt, "clientaddr")) {
-+                              if (strlen(opteq+1) >= sizeof(ip_addr))
-+                                      printf(_("Invalid client address %s"),
-+                                                              opteq+1);
-+                              strncpy(ip_addr,opteq+1, sizeof(ip_addr));
-+                              ip_addr[sizeof(ip_addr)-1] = '\0';
-+                      } else if (!strcmp(opt, "sec")) {
-+                              if (!strcmp(opteq+1, "krb5"))
-+                                      pseudoflavour = 390003;
-+                              else if (!strcmp(opteq+1, "krb5i"))
-+                                      pseudoflavour = 390004;
-+                              else if (!strcmp(opteq+1, "krb5p"))
-+                                      pseudoflavour = 390005;
-+                              else if (!strcmp(opteq+1, "lipkey"))
-+                                      pseudoflavour = 390006;
-+                              else if (!strcmp(opteq+1, "lipkey-i"))
-+                                      pseudoflavour = 390007;
-+                              else if (!strcmp(opteq+1, "lipkey-p"))
-+                                      pseudoflavour = 390008;
-+                              else if (!strcmp(opteq+1, "spkm3"))
-+                                      pseudoflavour = 390009;
-+                              else if (!strcmp(opteq+1, "spkm3i"))
-+                                      pseudoflavour = 390010;
-+                              else if (!strcmp(opteq+1, "spkm3p"))
-+                                      pseudoflavour = 390011;
-+                              else {
-+                                      printf(_("unknown security type %s\n"),
-+                                                      opteq+1);
-+                                      goto fail;
-+                              }
-+                      } else if (!strcmp(opt, "addr")) {
-+                              /* ignore */;
-+                      } else {
-+                              printf(_("unknown nfs mount parameter: "
-+                                       "%s=%d\n"), opt, val);
-+                              goto fail;
-+                      }
-+              } else {
-+                      val = 1;
-+                      if (!strncmp(opt, "no", 2)) {
-+                              val = 0;
-+                              opt += 2;
-+                      }
-+                      if (!strcmp(opt, "bg"))
-+                              bg = val;
-+                      else if (!strcmp(opt, "fg"))
-+                              bg = !val;
-+                      else if (!strcmp(opt, "soft"))
-+                              soft = val;
-+                      else if (!strcmp(opt, "hard"))
-+                              soft = !val;
-+                      else if (!strcmp(opt, "intr"))
-+                              intr = val;
-+                      else if (!strcmp(opt, "cto"))
-+                              nocto = !val;
-+                      else if (!strcmp(opt, "ac"))
-+                              noac = !val;
-+                      else {
-+                              if (!sloppy) {
-+                                      printf(_("unknown nfs mount option: "
-+                                               "%s%s\n"), val ? "" : "no", opt);
-+                                      goto fail;
-+                              }
-+                      }
-+              }
-+      }
-+
-+      data.flags = (soft ? NFS4_MOUNT_SOFT : 0)
-+              | (intr ? NFS4_MOUNT_INTR : 0)
-+              | (nocto ? NFS4_MOUNT_NOCTO : 0)
-+              | (noac ? NFS4_MOUNT_NOAC : 0);
-+
-+      if (pseudoflavour != 0) {
-+              data.auth_flavourlen = 1;
-+              data.auth_flavours = &pseudoflavour;
-+      }
-+
-+      data.client_addr.data = ip_addr;
-+      data.client_addr.len = strlen(ip_addr);
-+
-+      data.mnt_path.data = dirname;
-+      data.mnt_path.len = strlen(dirname);
-+
-+      data.hostname.data = hostname;
-+      data.hostname.len = strlen(hostname);
-+      data.host_addr = (struct sockaddr *)&server_addr;
-+      data.host_addrlen = sizeof(server_addr);
-+
-+#ifdef NFS_MOUNT_DEBUG
-+      printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
-+             data.rsize, data.wsize, data.timeo, data.retrans);
-+      printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
-+             data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
-+      printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
-+             ntohs(server_addr.sin_port), bg, retry, data.flags);
-+      printf("soft = %d, intr = %d, nocto = %d, noac = %d\n",
-+             (data.flags & NFS4_MOUNT_SOFT) != 0,
-+             (data.flags & NFS4_MOUNT_INTR) != 0,
-+             (data.flags & NFS4_MOUNT_NOCTO) != 0,
-+             (data.flags & NFS4_MOUNT_NOAC) != 0);
-+      printf("proto = %s\n", (data.proto == IPPROTO_TCP) ? "tcp" : "udp");
-+#endif
-+
-+      data.version = NFS4_MOUNT_VERSION;
-+
-+      *mount_opts = (char *) &data;
-+      /* clean up */
-+      return 0;
-+
-+fail:
-+      return retval;
-+}
-diff -puN /dev/null mount/nfs4_mount.h
---- /dev/null  2004-08-19 17:44:20.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfs4_mount.h 2004-10-13 13:51:50.000000000 -0400
-@@ -0,0 +1,82 @@
-+#ifndef _LINUX_NFS4_MOUNT_H
-+#define _LINUX_NFS4_MOUNT_H
-+
-+/*
-+ *  linux/include/linux/nfs4_mount.h
-+ *
-+ *  Copyright (C) 2002  Trond Myklebust
-+ *
-+ *  structure passed from user-space to kernel-space during an nfsv4 mount
-+ */
-+
-+/*
-+ * WARNING!  Do not delete or change the order of these fields.  If
-+ * a new field is required then add it to the end.  The version field
-+ * tracks which fields are present.  This will ensure some measure of
-+ * mount-to-kernel version compatibility.  Some of these aren't used yet
-+ * but here they are anyway.
-+ */
-+#define NFS4_MOUNT_VERSION    1
-+
-+struct nfs_string {
-+      unsigned int len;
-+      const char* data;
-+};
-+
-+struct nfs4_mount_data {
-+      int version;                            /* 1 */
-+      int flags;                              /* 1 */
-+      int rsize;                              /* 1 */
-+      int wsize;                              /* 1 */
-+      int timeo;                              /* 1 */
-+      int retrans;                            /* 1 */
-+      int acregmin;                           /* 1 */
-+      int acregmax;                           /* 1 */
-+      int acdirmin;                           /* 1 */
-+      int acdirmax;                           /* 1 */
-+
-+      /* see the definition of 'struct clientaddr4' in RFC3010 */
-+      struct nfs_string client_addr;          /* 1 */
-+
-+      /* Mount path */
-+      struct nfs_string mnt_path;             /* 1 */
-+
-+      /* Server details */
-+      struct nfs_string hostname;             /* 1 */
-+      /* Server IP address */
-+      unsigned int host_addrlen;              /* 1 */
-+      struct sockaddr* host_addr;             /* 1 */
-+
-+      /* Transport protocol to use */
-+      int proto;                              /* 1 */
-+
-+      /* Pseudo-flavours to use for authentication. See RFC2623 */
-+      int auth_flavourlen;                    /* 1 */
-+      int *auth_flavours;                     /* 1 */
-+};
-+
-+/* bits in the flags field */
-+/* Note: the fields that correspond to existing NFSv2/v3 mount options
-+ *     should mirror the values from include/linux/nfs_mount.h
-+ */
-+
-+#define NFS4_MOUNT_SOFT               0x0001  /* 1 */
-+#define NFS4_MOUNT_INTR               0x0002  /* 1 */
-+#define NFS4_MOUNT_NOCTO      0x0010  /* 1 */
-+#define NFS4_MOUNT_NOAC               0x0020  /* 1 */
-+#define NFS4_MOUNT_STRICTLOCK 0x1000  /* 1 */
-+#define NFS4_MOUNT_FLAGMASK   0xFFFF
-+
-+/* pseudoflavors: */
-+
-+#define RPC_AUTH_GSS_KRB5       390003
-+#define RPC_AUTH_GSS_KRB5I      390004
-+#define RPC_AUTH_GSS_KRB5P      390005
-+#define RPC_AUTH_GSS_LKEY       390006
-+#define RPC_AUTH_GSS_LKEYI      390007
-+#define RPC_AUTH_GSS_LKEYP      390008
-+#define RPC_AUTH_GSS_SPKM       390009
-+#define RPC_AUTH_GSS_SPKMI      390010
-+#define RPC_AUTH_GSS_SPKMP      390011
-+
-+#endif
-diff -puN mount/nfs.5~base-nfsv4 mount/nfs.5
---- util-linux-2.12/mount/nfs.5~base-nfsv4     2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfs.5        2004-10-13 13:51:50.000000000 -0400
-@@ -3,7 +3,7 @@
- .\" patches. "
- .TH NFS 5 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual"
- .SH NAME
--nfs \- nfs fstab format and options
-+nfs \- nfs and nfs4 fstab format and options
- .SH SYNOPSIS
- .B /etc/fstab
- .SH DESCRIPTION
-@@ -17,14 +17,51 @@ the local directory that is the mount po
- and the NFS specific options that control
- the way the filesystem is mounted.
- .P
--Here is an example from an \fI/etc/fstab\fP file from an NFS mount.
-+Three different versions of the NFS protocol are
-+supported by the Linux NFS client:
-+NFS version 2, NFS version 3, and NFS version 4.
-+To mount via NFS version 2, use the
-+.BR nfs
-+file system type and specify
-+.BR nfsvers=2 .
-+Version 2 is the default protocol version for the
-+.BR nfs
-+file system type when
-+.BR nfsvers=
-+is not specified on the mount command.
-+To mount via NFS version 3, use the
-+.BR nfs
-+file system type and specify
-+.BR nfsvers=3 .
-+To mount via NFS version 4, use the
-+.BR nfs4
-+file system type.
-+The
-+.BR nfsvers=
-+keyword is not supported for the
-+.BR nfs4
-+file system type.
-+.P
-+These file system types share similar mount options;
-+the differences are listed below.
-+.P
-+Here is an example from an \fI/etc/fstab\fP file for an NFSv2 mount
-+over UDP.
- .sp
- .nf
- .ta 2.5i +0.75i +0.75i +1.0i
- server:/usr/local/pub /pub    nfs     rsize=8192,wsize=8192,timeo=14,intr
- .fi
-+.P
-+Here is an example for an NFSv4 mount over TCP using Kerberos
-+5 mutual authentication.
-+.sp
-+.nf
-+.ta 2.5i +0.75i +0.75i +1.0i
-+server:/usr/local/pub /pub    nfs4    proto=tcp,sec=krb5,hard,intr
-+.fi
- .DT
--.SS Options
-+.SS Options for the nfs file system type
- .TP 1.5i
- .I rsize=n
- The number of bytes NFS uses when reading files from an NFS server.
-@@ -208,6 +245,163 @@ is the default.
- All of the non-value options have corresponding nooption forms.
- For example, nointr means don't allow file operations to be
- interrupted.
-+.SS Options for the nfs4 file system type
-+.TP 1.5i
-+.I rsize=n
-+The number of bytes NFS uses when reading files from an NFS server.
-+The default value is dependent on the kernel, currently 4096 bytes.
-+(However, throughput is improved greatly by asking for
-+.IR rsize=32768 .)
-+This value is negotiated with the server.
-+.TP 1.5i
-+.I wsize=n
-+The number of bytes NFS uses when writing files to an NFS server.
-+The default value is dependent on the kernel, currently 4096 bytes.
-+(However, throughput is improved greatly by asking for
-+.IR wsize=32768 .)
-+This value is negotiated with the server.
-+.TP 1.5i
-+.I timeo=n
-+The value in tenths of a second before sending the
-+first retransmission after an RPC timeout.
-+The default value depends on whether
-+.IR proto=udp
-+or
-+.IR proto=tcp
-+is in effect (see below).
-+The default value for UDP is 7 tenths of a second.
-+The default value for TCP is 60 seconds.
-+After the first timeout,
-+the timeout is doubled after each successive timeout until a maximum
-+timeout of 60 seconds is reached or the enough retransmissions
-+have occured to cause a major timeout.  Then, if the filesystem
-+is hard mounted, each new timeout cascade restarts at twice the
-+initial value of the previous cascade, again doubling at each
-+retransmission.  The maximum timeout is always 60 seconds.
-+.TP 1.5i
-+.I retrans=n
-+The number of minor timeouts and retransmissions that must occur before
-+a major timeout occurs.  The default is 5 timeouts for
-+.IR proto=udp
-+and 2 timeouts for
-+.IR proto=tcp .
-+When a major timeout
-+occurs, the file operation is either aborted or a "server not responding"
-+message is printed on the console.
-+.TP 1.5i
-+.I acregmin=n
-+The minimum time in seconds that attributes of a regular file should
-+be cached before requesting fresh information from a server.
-+The default is 3 seconds.
-+.TP 1.5i
-+.I acregmax=n
-+The maximum time in seconds that attributes of a regular file can
-+be cached before requesting fresh information from a server.
-+The default is 60 seconds.
-+.TP 1.5i
-+.I acdirmin=n
-+The minimum time in seconds that attributes of a directory should
-+be cached before requesting fresh information from a server.
-+The default is 30 seconds.
-+.TP 1.5i
-+.I acdirmax=n
-+The maximum time in seconds that attributes of a directory can
-+be cached before requesting fresh information from a server.
-+The default is 60 seconds.
-+.TP 1.5i
-+.I actimeo=n
-+Using actimeo sets all of
-+.I acregmin,
-+.I acregmax,
-+.I acdirmin,
-+and
-+.I acdirmax
-+to the same value.
-+There is no default value.
-+.TP 1.5i
-+.I retry=n
-+The number of minutes to retry an NFS mount operation
-+in the foreground or background before giving up.
-+The default value is 10000 minutes, which is roughly one week.
-+.TP 1.5i
-+.I port=n
-+The numeric value of the port to connect to the NFS server on.
-+If the port number is 0 (the default) then query the
-+remote host's portmapper for the port number to use.
-+If the remote host's NFS daemon is not registered with
-+its portmapper, the standard NFS port number 2049 is
-+used instead.
-+.TP 1.5i
-+.I proto=n
-+Mount the NFS filesystem using a specific network protocol
-+instead of the default UDP protocol.
-+Many NFS version 4 servers only support TCP.
-+Valid protocol types are
-+.IR udp
-+and
-+.IR tcp .
-+.TP 1.5i
-+.I clientaddr=n
-+On a multi-homed client, this
-+causes the client to use a specific callback address when
-+communicating with an NFS version 4 server.
-+This option is currently ignored.
-+.TP 1.5i
-+.I sec=n
-+Specify an advanced security mechanism for this file system.
-+To use Kerberos 5 mutual authentication, specify
-+.IR krb5 .
-+Kerberos 5 integrity checking is specified with
-+.IR krb5i ,
-+and Kerberos 5 privacy is specified with
-+.IR krb5p .
-+Other security mechanisms may become available in the future.
-+.TP 1.5i
-+.I bg
-+If an NFS mount attempt times out, retry the mount
-+in the background.
-+After a mount operation is backgrounded, all subsequent mounts
-+on the same NFS server will be backgrounded immediately, without
-+first attempting the mount.
-+A missing mount point is treated as a timeout,
-+to allow for nested NFS mounts.
-+.TP 1.5i
-+.I fg
-+If the first NFS mount attempt times out, retry the mount
-+in the foreground.
-+This is the complement of the
-+.I bg
-+option, and also the default behavior.
-+.TP 1.5i
-+.I soft
-+If an NFS file operation has a major timeout then report an I/O error to
-+the calling program.
-+The default is to continue retrying NFS file operations indefinitely.
-+.TP 1.5i
-+.I hard
-+If an NFS file operation has a major timeout then report
-+"server not responding" on the console and continue retrying indefinitely.
-+This is the default.
-+.TP 1.5i
-+.I intr
-+If an NFS file operation has a major timeout and it is hard mounted,
-+then allow signals to interupt the file operation and cause it to
-+return EINTR to the calling program.  The default is to not
-+allow file operations to be interrupted.
-+.TP 1.5i
-+.I nocto
-+Suppress the retrieval of new attributes when creating a file.
-+.TP 1.5i
-+.I noac
-+Disable attribute caching, and force synchronous writes.
-+This extracts a
-+server performance penalty but it allows two different NFS clients
-+to get reasonable good results when both clients are actively
-+writing to common filesystem on the server.
-+.P
-+All of the non-value options have corresponding nooption forms.
-+For example, nointr means don't allow file operations to be
-+interrupted.
- .SH FILES
- .I /etc/fstab
- .SH "SEE ALSO"
-diff -puN mount/nfsmount.c~base-nfsv4 mount/nfsmount.c
---- util-linux-2.12/mount/nfsmount.c~base-nfsv4        2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfsmount.c   2004-10-13 13:51:50.000000000 -0400
-@@ -706,7 +706,10 @@ static inline int
- nfsmnt_check_compat(const struct pmap *nfs_pmap, const struct pmap *mnt_pmap)
- {
-       if (nfs_pmap->pm_vers > MAX_NFSPROT) {
--              fprintf(stderr, _("NFSv%ld not supported!\n"), nfs_pmap->pm_vers);
-+              if (nfs_pmap->pm_vers == 4)
-+                      fprintf(stderr, _("'vers=4' is not supported.  Use '-t nfs4' instead.\n"));
-+              else
-+                      fprintf(stderr, _("NFSv%ld not supported!\n"), nfs_pmap->pm_vers);
-               goto out_bad;
-       }
-       if (mnt_pmap->pm_vers > MAX_MNTPROT) {
-diff -puN mount/sundries.h~base-nfsv4 mount/sundries.h
---- util-linux-2.12/mount/sundries.h~base-nfsv4        2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/sundries.h   2004-10-13 13:51:50.000000000 -0400
-@@ -37,6 +37,8 @@ void die (int errcode, const char *fmt, 
- #ifdef HAVE_NFS
- int nfsmount (const char *spec, const char *node, int *flags,
-             char **orig_opts, char **opt_args, int *version, int running_bg);
-+int nfs4mount (const char *spec, const char *node, int *flags,
-+              char **orig_opts, char **opt_args, int running_bg);
- int nfsumount(const char *spec, const char *opts);
- #endif
-diff -puN mount/umount.c~base-nfsv4 mount/umount.c
---- util-linux-2.12/mount/umount.c~base-nfsv4  2004-10-13 13:51:50.000000000 -0400
-+++ util-linux-2.12-bfields/mount/umount.c     2004-10-13 13:51:50.000000000 -0400
-@@ -89,6 +89,9 @@
- /* True if ruid != euid.  */
- int suid = 0;
-+/* Needed by nfs4mount.c */
-+int sloppy = 0;
-+
- /*
-  * check_special_umountprog()
-  *    If there is a special umount program for this type, exec it.
-
diff --git a/util-linux-2.12-03-krb5.dif b/util-linux-2.12-03-krb5.dif
deleted file mode 100644 (file)
index a2eff07..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-
-Allow nfs versions 2 and 3 to mount with -osec=krb5.
-
-
----
-
- util-linux-2.12-bfields/mount/nfs.5        |   37 +++++++++-----
- util-linux-2.12-bfields/mount/nfs_mount4.h |   18 ++++++-
- util-linux-2.12-bfields/mount/nfsmount.c   |   74 ++++++++++++++++++++++++++++-
- 3 files changed, 112 insertions(+), 17 deletions(-)
-
-diff -puN mount/nfs.5~krb5 mount/nfs.5
---- util-linux-2.12/mount/nfs.5~krb5   2004-10-13 14:15:03.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfs.5        2004-10-13 14:15:03.000000000 -0400
-@@ -165,7 +165,7 @@ mount daemon program number.
- Use an alternate RPC version number to contact the
- mount daemon on the remote host.  This option is useful
- for hosts that can run multiple NFS servers.
--The default value is version 1.
-+The default value depends on which kernel you are using.
- .TP 1.5i
- .I nfsprog=n
- Use an alternate RPC program number to contact the
-@@ -178,7 +178,7 @@ NFS daemon program number.
- Use an alternate RPC version number to contact the
- NFS daemon on the remote host.  This option is useful
- for hosts that can run multiple NFS servers.
--The default value is version 2.
-+The default value depends on which kernel you are using.
- .TP 1.5i
- .I nolock
- Disable NFS locking. Do not start lockd.
-@@ -230,9 +230,25 @@ Suppress the retrieval of new attributes
- .TP 1.5i
- .I noac
- Disable all forms of attribute caching entirely.  This extracts a
--server performance penalty but it allows two different NFS clients
--to get reasonable good results when both clients are actively
--writing to common filesystem on the server.
-+significant performance penalty but it allows two different NFS clients
-+to get reasonable results when both clients are actively
-+writing to a common export on the server.
-+.TP 1.5i
-+.I sec=mode
-+Set the security flavor for this mount to "mode".
-+The default setting is \f3sec=sys\f1, which uses local
-+unix uids and gids to authenticate NFS operations (AUTH_SYS).
-+Other currently supported settings are:
-+\f3sec=krb5\f1, which uses Kerberos V5 instead of local unix uids
-+and gids to authenticate users;
-+\f3sec=krb5i\f1, which uses Kerberos V5 for user authentication
-+and performs integrity checking of NFS operations using secure
-+checksums to prevent data tampering; and
-+\f3sec=krb5p\f1, which uses Kerberos V5 for user authentication
-+and integrity checking, and encrypts NFS traffic to prevent
-+traffic sniffing (this is the most secure setting).
-+Note that there is a performance penalty when using integrity
-+or privacy.
- .TP 1.5i
- .I tcp
- Mount the NFS filesystem using the TCP protocol instead of the
-@@ -347,15 +363,8 @@ causes the client to use a specific call
- communicating with an NFS version 4 server.
- This option is currently ignored.
- .TP 1.5i
--.I sec=n
--Specify an advanced security mechanism for this file system.
--To use Kerberos 5 mutual authentication, specify
--.IR krb5 .
--Kerberos 5 integrity checking is specified with
--.IR krb5i ,
--and Kerberos 5 privacy is specified with
--.IR krb5p .
--Other security mechanisms may become available in the future.
-+.I sec=mode
-+Same as \f3sec=mode\f1 for the nfs filesystem type (see above).
- .TP 1.5i
- .I bg
- If an NFS mount attempt times out, retry the mount
-diff -puN mount/nfs_mount4.h~krb5 mount/nfs_mount4.h
---- util-linux-2.12/mount/nfs_mount4.h~krb5    2004-10-13 14:15:03.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfs_mount4.h 2004-10-13 14:16:45.000000000 -0400
-@@ -8,7 +8,7 @@
-  * so it is easiest to ignore the kernel altogether (at compile time).
-  */
--#define NFS_MOUNT_VERSION     4
-+#define NFS_MOUNT_VERSION     5
- struct nfs2_fh {
-         char                    data[32];
-@@ -36,6 +36,7 @@ struct nfs_mount_data {
-       int             namlen;                 /* 2 */
-       unsigned int    bsize;                  /* 3 */
-       struct nfs3_fh  root;                   /* 4 */
-+      int             pseudoflavor;           /* 5 */
- };
- /* bits in the flags field */
-@@ -51,4 +52,19 @@ struct nfs_mount_data {
- #define NFS_MOUNT_KERBEROS    0x0100  /* 3 */
- #define NFS_MOUNT_NONLM               0x0200  /* 3 */
- #define NFS_MOUNT_BROKEN_SUID 0x0400  /* 4 */
-+#define NFS_MOUNT_SECFLAVOUR  0x2000  /* 5 */
-+
-+/* security pseudoflavors */
-+
-+#ifndef AUTH_GSS_KRB5
-+#define AUTH_GSS_KRB5         390003
-+#define AUTH_GSS_KRB5I                390004
-+#define AUTH_GSS_KRB5P                390005
-+#define AUTH_GSS_LKEY         390006
-+#define AUTH_GSS_LKEYI                390007
-+#define AUTH_GSS_LKEYP                390008
-+#define AUTH_GSS_SPKM         390009
-+#define AUTH_GSS_SPKMI                390010
-+#define AUTH_GSS_SPKMP                390011
-+#endif
-diff -puN mount/nfsmount.c~krb5 mount/nfsmount.c
---- util-linux-2.12/mount/nfsmount.c~krb5      2004-10-13 14:15:03.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfsmount.c   2004-10-13 14:16:46.000000000 -0400
-@@ -109,6 +109,8 @@ typedef struct {
- static const struct timeval TIMEOUT = { 20, 0 };
- static const struct timeval RETRY_TIMEOUT = { 3, 0 };
-+static int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp);
-+
- /* Define the order in which to probe for UDP/TCP services */
- static const u_int *
- proto_probelist(const int use_tcp)
-@@ -211,8 +213,10 @@ find_kernel_nfs_mount_version(void) {
-                 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,0))
-+                mnt_version = 4;
-            else
--                mnt_version = 4; /* since 2.3.99pre4 */
-+                mnt_version = 5;
-       }
-       if (mnt_version > NFS_MOUNT_VERSION)
-            mnt_version = NFS_MOUNT_VERSION;
-@@ -596,6 +600,40 @@ parse_options(char *old_opts, struct nfs
- #endif
-                               } else if (!sloppy)
-                                       goto bad_parameter;
-+#if NFS_MOUNT_VERSION >= 5
-+                      } else if (!strcmp(opt, "sec")) {
-+                              char *secflavor = opteq+1;
-+                              /* see RFC 2623 */
-+                              if (nfs_mount_version < 5) {
-+                                      printf(_("Warning: ignoring sec=%s option\n"), secflavor);
-+                                      continue;
-+                              } else if (!strcmp(secflavor, "sys"))
-+                                      data->pseudoflavor = AUTH_SYS;
-+                              else if (!strcmp(secflavor, "krb5"))
-+                                      data->pseudoflavor = AUTH_GSS_KRB5;
-+                              else if (!strcmp(secflavor, "krb5i"))
-+                                      data->pseudoflavor = AUTH_GSS_KRB5I;
-+                              else if (!strcmp(secflavor, "krb5p"))
-+                                      data->pseudoflavor = AUTH_GSS_KRB5P;
-+                              else if (!strcmp(secflavor, "lipkey"))
-+                                      data->pseudoflavor = AUTH_GSS_LKEY;
-+                              else if (!strcmp(secflavor, "lipkey-i"))
-+                                      data->pseudoflavor = AUTH_GSS_LKEYI;
-+                              else if (!strcmp(secflavor, "lipkey-p"))
-+                                      data->pseudoflavor = AUTH_GSS_LKEYP;
-+                              else if (!strcmp(secflavor, "spkm3"))
-+                                      data->pseudoflavor = AUTH_GSS_SPKM;
-+                              else if (!strcmp(secflavor, "spkm3i"))
-+                                      data->pseudoflavor = AUTH_GSS_SPKMI;
-+                              else if (!strcmp(secflavor, "spkm3p"))
-+                                      data->pseudoflavor = AUTH_GSS_SPKMP;
-+                              else if (!sloppy) {
-+                                      printf(_("Warning: Unrecognized security flavor %s.\n"),
-+                                              secflavor);
-+                                      goto bad_parameter;
-+                              }
-+                              data->flags |= NFS_MOUNT_SECFLAVOUR;
-+#endif
-                       } else if (!strcmp(opt, "mounthost"))
-                               mounthost=xstrndup(opteq+1,
-                                                  strcspn(opteq+1," \t\n\r,"));
-@@ -745,7 +783,7 @@ nfsmount(const char *spec, const char *n
-       mntres_t mntres;
-       struct stat statbuf;
--      char *s, *p;
-+      char *s;
-       int bg, retry;
-       int retval;
-       time_t t;
-@@ -809,6 +847,7 @@ nfsmount(const char *spec, const char *n
- #if NFS_MOUNT_VERSION >= 2
-       data.namlen     = NAME_MAX;
- #endif
-+      data.pseudoflavor = AUTH_SYS;
-       bg = 0;
-       retry = 10000;          /* 10000 minutes ~ 1 week */
-@@ -847,6 +886,9 @@ nfsmount(const char *spec, const char *n
-       printf("tcp = %d\n",
-              (data.flags & NFS_MOUNT_TCP) != 0);
- #endif
-+#if NFS_MOUNT_VERSION >= 5
-+      printf("sec = %u\n", data.pseudoflavor);
-+#endif
- #endif
-       data.version = nfs_mount_version;
-@@ -949,7 +991,9 @@ nfsmount(const char *spec, const char *n
- #endif
-       } else {
- #if NFS_MOUNT_VERSION >= 4
-+              mountres3_ok *mountres;
-               fhandle3 *fhandle;
-+              int i, *flavor, yum = 0;
-               if (mntres.nfsv3.fhs_status != 0) {
-                       fprintf(stderr,
-                               _("mount: %s:%s failed, reason given by server: %s\n"),
-@@ -957,6 +1001,32 @@ nfsmount(const char *spec, const char *n
-                               nfs_strerror(mntres.nfsv3.fhs_status));
-                       goto fail;
-               }
-+#if NFS_MOUNT_VERSION >= 5
-+              mountres = &mntres.nfsv3.mountres3_u.mountinfo;
-+              i = mountres->auth_flavours.auth_flavours_len;
-+              if (i <= 0)
-+                      goto noauth_flavours;
-+
-+              flavor = mountres->auth_flavours.auth_flavours_val;
-+              while (--i >= 0) {
-+                      if (flavor[i] == data.pseudoflavor)
-+                              yum = 1;
-+#ifdef NFS_MOUNT_DEBUG
-+                      printf("auth flavor %d: %d\n",
-+                              i, flavor[i]);
-+#endif
-+              }
-+              if (!yum) {
-+                      fprintf(stderr,
-+                              "mount: %s:%s failed, "
-+                              "security flavor not supported\n",
-+                              hostname, dirname);
-+                      /* server has registered us in mtab, send umount */
-+                      nfs_call_umount(&mnt_server, &dirname);
-+                      goto fail;
-+              }
-+noauth_flavours:
-+#endif
-               fhandle = &mntres.nfsv3.mountres3_u.mountinfo.fhandle;
-               memset(data.old_root.data, 0, NFS_FHSIZE);
-               memset(&data.root, 0, sizeof(data.root));
-_
diff --git a/util-linux-2.12-04-modify_mount_to_support_multiple_security_flavors.dif b/util-linux-2.12-04-modify_mount_to_support_multiple_security_flavors.dif
deleted file mode 100644 (file)
index b10f87c..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-
-This patch modifies the NFSv4 'mount' command to accept multiple
-authentication flavors. This list of flavors will be used during security
-negotiation to determine which flavors the user is willing to use (most
-preferred flavor is listed first).
-
-This patch applies on top of CITI's version 2.11z-3 of util-linux.
-
-The format for passing one flavor is unchanged:
-    mount -tnfs4 -osec=krb5 server:/ /mnt/nfs4
-
-The format for passing multiple flavors is:
-    mount -tnfs4 -osec=krb5:spkm3p:unix server:/ /mnt/nfs4
-
-If no sec= option is given, we assume AUTH_UNIX.
-
-From Nick Wilson <njw@us.ibm.com>
-
----
-
- util-linux-2.12-bfields/mount/nfs4mount.c |  102 ++++++++++++++++++++++--------
- 1 files changed, 75 insertions(+), 27 deletions(-)
-
-diff -puN mount/nfs4mount.c~modify_mount_to_support_multiple_security_flavors mount/nfs4mount.c
---- util-linux-2.12/mount/nfs4mount.c~modify_mount_to_support_multiple_security_flavors        2004-10-13 14:18:23.000000000 -0400
-+++ util-linux-2.12-bfields/mount/nfs4mount.c  2004-10-13 14:21:18.000000000 -0400
-@@ -36,6 +36,7 @@
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-+#include <rpc/auth.h>
- #include "sundries.h"
-@@ -48,6 +49,57 @@
- #define NFS_PORT 2049
- #endif
-+struct {
-+      char    *flavour;
-+      int     fnum;
-+} flav_map[] = {
-+      { "krb5",       RPC_AUTH_GSS_KRB5       },
-+      { "krb5i",      RPC_AUTH_GSS_KRB5I      },
-+      { "krb5p",      RPC_AUTH_GSS_KRB5P      },
-+      { "lipkey",     RPC_AUTH_GSS_LKEY       },
-+      { "lipkey-i",   RPC_AUTH_GSS_LKEYI      },
-+      { "lipkey-p",   RPC_AUTH_GSS_LKEYP      },
-+      { "spkm3",      RPC_AUTH_GSS_SPKM       },
-+      { "spkm3i",     RPC_AUTH_GSS_SPKMI      },
-+      { "spkm3p",     RPC_AUTH_GSS_SPKMP      },
-+      { "unix",       AUTH_UNIX               },
-+      { "sys",        AUTH_SYS                },
-+      { "null",       AUTH_NULL               },
-+      { "none",       AUTH_NONE               },
-+};
-+
-+#define FMAPSIZE              (sizeof(flav_map)/sizeof(flav_map[0]))
-+#define MAX_USER_FLAVOUR      16
-+
-+static int parse_sec(char *sec, int *pseudoflavour)
-+{
-+      int i, num_flavour = 0;
-+
-+      for (sec = strtok(sec, ":"); sec; sec = strtok(NULL, ":")) {
-+              if (num_flavour >= MAX_USER_FLAVOUR) {
-+                      fprintf(stderr,
-+                              _("mount: maximum number of security flavors "
-+                                "exceeded\n"));
-+                      return 0;
-+              }
-+              for (i = 0; i < FMAPSIZE; i++) {
-+                      if (strcmp(sec, flav_map[i].flavour) == 0) {
-+                              pseudoflavour[num_flavour++] = flav_map[i].fnum;
-+                              break;
-+                      }
-+              }
-+              if (i == FMAPSIZE) {
-+                      fprintf(stderr,
-+                              _("mount: unknown security type %s\n"), sec);
-+                      return 0;
-+              }
-+      }
-+      if (!num_flavour)
-+              fprintf(stderr,
-+                      _("mount: no security flavors passed to sec= option\n"));
-+      return num_flavour;
-+}
-+
- static int parse_devname(char *hostdir, char **hostname, char **dirname)
- {
-       char *s;
-@@ -117,7 +169,8 @@ int nfs4mount(const char *spec, const ch
-       static char hostdir[1024];
-       static char ip_addr[16] = "127.0.0.1";
-       static struct sockaddr_in server_addr;
--      static int pseudoflavour = 0;
-+      static int pseudoflavour[MAX_USER_FLAVOUR];
-+      int num_flavour = 0;
-       char *hostname, *dirname, *old_opts;
-       char new_opts[1024];
-@@ -228,29 +281,9 @@ int nfs4mount(const char *spec, const ch
-                               strncpy(ip_addr,opteq+1, sizeof(ip_addr));
-                               ip_addr[sizeof(ip_addr)-1] = '\0';
-                       } else if (!strcmp(opt, "sec")) {
--                              if (!strcmp(opteq+1, "krb5"))
--                                      pseudoflavour = 390003;
--                              else if (!strcmp(opteq+1, "krb5i"))
--                                      pseudoflavour = 390004;
--                              else if (!strcmp(opteq+1, "krb5p"))
--                                      pseudoflavour = 390005;
--                              else if (!strcmp(opteq+1, "lipkey"))
--                                      pseudoflavour = 390006;
--                              else if (!strcmp(opteq+1, "lipkey-i"))
--                                      pseudoflavour = 390007;
--                              else if (!strcmp(opteq+1, "lipkey-p"))
--                                      pseudoflavour = 390008;
--                              else if (!strcmp(opteq+1, "spkm3"))
--                                      pseudoflavour = 390009;
--                              else if (!strcmp(opteq+1, "spkm3i"))
--                                      pseudoflavour = 390010;
--                              else if (!strcmp(opteq+1, "spkm3p"))
--                                      pseudoflavour = 390011;
--                              else {
--                                      printf(_("unknown security type %s\n"),
--                                                      opteq+1);
-+                              num_flavour = parse_sec(opteq+1, pseudoflavour);
-+                              if (!num_flavour)
-                                       goto fail;
--                              }
-                       } else if (!strcmp(opt, "addr")) {
-                               /* ignore */;
-                       } else {
-@@ -293,10 +326,10 @@ int nfs4mount(const char *spec, const ch
-               | (nocto ? NFS4_MOUNT_NOCTO : 0)
-               | (noac ? NFS4_MOUNT_NOAC : 0);
--      if (pseudoflavour != 0) {
--              data.auth_flavourlen = 1;
--              data.auth_flavours = &pseudoflavour;
--      }
-+      if (num_flavour == 0)
-+              pseudoflavour[num_flavour++] = AUTH_UNIX;
-+      data.auth_flavourlen = num_flavour;
-+      data.auth_flavours = pseudoflavour;
-       data.client_addr.data = ip_addr;
-       data.client_addr.len = strlen(ip_addr);
-@@ -321,6 +354,21 @@ int nfs4mount(const char *spec, const ch
-              (data.flags & NFS4_MOUNT_INTR) != 0,
-              (data.flags & NFS4_MOUNT_NOCTO) != 0,
-              (data.flags & NFS4_MOUNT_NOAC) != 0);
-+
-+      if (num_flavour > 0) {
-+              int pf_cnt, i;
-+
-+              printf("sec = ");
-+              for (pf_cnt = 0; pf_cnt < num_flavour; pf_cnt++) {
-+                      for (i = 0; i < FMAPSIZE; i++) {
-+                              if (flav_map[i].fnum == pseudoflavour[pf_cnt]) {
-+                                      printf("%s", flav_map[i].flavour);
-+                                      break;
-+                              }
-+                      }
-+                      printf("%s", (pf_cnt < num_flavour-1) ? ":" : "\n");
-+              }
-+      }
-       printf("proto = %s\n", (data.proto == IPPROTO_TCP) ? "tcp" : "udp");
- #endif
-_
diff --git a/util-linux-2.12-05-mount_sloppy_fix.dif b/util-linux-2.12-05-mount_sloppy_fix.dif
deleted file mode 100644 (file)
index 56a2c83..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
----
-
- util-linux-2.12-bfields/mount/nfsmount.c |    2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
-diff -puN mount/nfsmount.c~mount_sloppy_fix mount/nfsmount.c
---- util-linux-2.12/mount/nfsmount.c~mount_sloppy_fix  2004-12-13 12:21:52.000000000 -0500
-+++ util-linux-2.12-bfields/mount/nfsmount.c   2004-12-13 12:21:52.000000000 -0500
-@@ -712,7 +712,7 @@ parse_options(char *old_opts, struct nfs
-                                       data->flags |= NFS_MOUNT_BROKEN_SUID;
-                               }
- #endif
--                      } else {
-+                      } else if (!sloppy) {
-                       bad_option:
-                               printf(_("Unsupported nfs mount option: "
-                                        "%s%s\n"), val ? "" : "no", opt);
-_
diff --git a/util-linux-2.12-06-redhat-nfs-mount.dif b/util-linux-2.12-06-redhat-nfs-mount.dif
deleted file mode 100644 (file)
index d2c3fde..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-
-
-Changes from redhat srpm.
-
----
-
- util-linux-2.12-bfields/mount/mount.c     |    2 
- util-linux-2.12-bfields/mount/nfs4mount.c |   20 +++++++++
- util-linux-2.12-bfields/mount/nfsmount.c  |   61 +++++++++++++++++++++++++-----
- 3 files changed, 72 insertions(+), 11 deletions(-)
-
-diff -puN mount/mount.c~redhat-nfs-mount mount/mount.c
---- util-linux-2.12/mount/mount.c~redhat-nfs-mount     2004-12-13 12:34:18.000000000 -0500
-+++ util-linux-2.12-bfields/mount/mount.c      2004-12-13 12:34:18.000000000 -0500
-@@ -829,6 +829,7 @@ retry_nfs:
-     mnt_err = nfs4mount(spec, node, &flags, &extra_opts, &mount_opts, bg);
-     if (mnt_err)
-       return mnt_err;
-+      goto nosigblock;
- #else
-     die (EX_SOFTWARE, _("mount: this version was compiled "
-                     "without support for the type `nfs4'"));
-@@ -836,6 +837,7 @@ retry_nfs:
-   }
-   block_signals (SIG_BLOCK);
-+nosigblock:
-   if (!fake)
-     mnt5_res = guess_fstype_and_mount (spec, node, &types, flags & ~MS_NOSYS,
-diff -puN mount/nfs4mount.c~redhat-nfs-mount mount/nfs4mount.c
---- util-linux-2.12/mount/nfs4mount.c~redhat-nfs-mount 2004-12-13 12:34:18.000000000 -0500
-+++ util-linux-2.12-bfields/mount/nfs4mount.c  2004-12-13 12:34:18.000000000 -0500
-@@ -37,6 +37,12 @@
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <rpc/auth.h>
-+#ifdef HAVE_rpcsvc_nfs_prot_h
-+#include <rpcsvc/nfs_prot.h>
-+#else
-+#include <linux/nfs.h>
-+#define nfsstat nfs_stat
-+#endif
- #include "sundries.h"
-@@ -49,6 +55,9 @@
- #define NFS_PORT 2049
- #endif
-+extern int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int);
-+extern void rpc_strerror(void);
-+
- struct {
-       char    *flavour;
-       int     fnum;
-@@ -225,7 +234,7 @@ int nfs4mount(const char *spec, const ch
-       bg = 0;
-       soft = 0;
--      intr = 0;
-+      intr = NFS4_MOUNT_INTR;
-       nocto = 0;
-       noac = 0;
-       retry = 10000;          /* 10000 minutes ~ 1 week */
-@@ -374,10 +383,19 @@ int nfs4mount(const char *spec, const ch
-       data.version = NFS4_MOUNT_VERSION;
-+      clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto);
-+      if (rpc_createerr.cf_stat) {
-+              fprintf(stderr, "mount to NFS server '%s' failed.\n", data.hostname.data);
-+              goto fail;
-+      }
-+
-       *mount_opts = (char *) &data;
-       /* clean up */
-       return 0;
- fail:
-+      if (verbose) {
-+              rpc_strerror();
-+      }
-       return retval;
- }
-diff -puN mount/nfsmount.c~redhat-nfs-mount mount/nfsmount.c
---- util-linux-2.12/mount/nfsmount.c~redhat-nfs-mount  2004-12-13 12:34:18.000000000 -0500
-+++ util-linux-2.12-bfields/mount/nfsmount.c   2004-12-13 12:34:18.000000000 -0500
-@@ -111,6 +111,25 @@ static const struct timeval RETRY_TIMEOU
- static int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp);
-+int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int);
-+
-+/* Convert RPC errors into strings */
-+void rpc_strerror(void)
-+{
-+      int cf_stat = rpc_createerr.cf_stat;
-+      int cf_errno = rpc_createerr.cf_error.re_errno;
-+      char *ptr, *estr = clnt_sperrno(cf_stat);
-+
-+      if (estr) {
-+              if ((ptr = index(estr, ':')))
-+                      estr = ++ptr;
-+
-+              fprintf(stderr, "RPC Error: %d (%s )\n", cf_stat, estr);
-+              if (cf_stat == RPC_SYSTEMERROR)
-+                      fprintf(stderr, "System Error: %d (%s)\n", cf_errno, strerror(cf_errno));
-+      }
-+}
-+
- /* Define the order in which to probe for UDP/TCP services */
- static const u_int *
- proto_probelist(const int use_tcp)
-@@ -252,14 +271,15 @@ nfs_gethostbyname(const char *hostname, 
-  * we're requesting, we open and RPC client, and fire off a NULL
-  * RPC call.
-  */
--static int
-+int
- clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
-         const u_int prot)
- {
--      CLIENT *clnt;
-+      CLIENT *clnt=NULL;
-       int sock, stat;
-       static char clnt_res;
-+      rpc_createerr.cf_stat = stat = 0;
-       sock = RPC_ANYSOCK;
-       switch(prot) {
-       case IPPROTO_UDP:
-@@ -285,6 +305,7 @@ clnt_ping(struct sockaddr_in *saddr, con
-       close(sock);
-       if (stat != RPC_PROGVERSMISMATCH)
-               return 1;
-+
-  out_bad:
-       return 0;
- }
-@@ -308,9 +329,9 @@ probe_port(clnt_addr_t *server,
-               *p_prot;
-       const u_short port = (u_short) pmap->pm_port;
-       u_short p_port;
--
-       p_prot = prot ? &prot : protos;
-       p_vers = vers ? &vers : versions;
-+      rpc_createerr.cf_stat = 0;
-       for (;;) {
-               saddr->sin_port = htons(PMAPPORT);
-               p_port = pmap_getport(saddr, prog, *p_vers, *p_prot);
-@@ -338,6 +359,7 @@ probe_port(clnt_addr_t *server,
-               pmap->pm_prot = *p_prot;
-       if (!port)
-               pmap->pm_port = p_port;
-+      rpc_createerr.cf_stat = 0;
-       return 1;
- }
-@@ -394,6 +416,8 @@ probe_bothports(clnt_addr_t *mnt_server,
-                               return 1;
-                       memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
-               }
-+              if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
-+                      break;
-               memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
-       }
-  out_bad:
-@@ -477,11 +501,23 @@ nfs_call_mount(clnt_addr_t *mnt_server, 
-       enum clnt_stat stat;
-       int msock;
--
-       if (!probe_bothports(mnt_server, nfs_server)) {
--              if (report_errs)
--                      fprintf(stderr,_("mount: failed to probe ports on NFS server %s\n"),
-+              if (report_errs) {
-+                      fprintf(stderr, "mount to NFS server '%s' failed",
-                               *nfs_server->hostname);
-+                      if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) {
-+                              fprintf(stderr, ": server is down.\n");
-+                      } else  if (nfs_server->pmap.pm_prot) {
-+                              fprintf(stderr, ": possible invalid protocol.\n");
-+                      } else if (nfs_server->pmap.pm_port) {
-+                              fprintf(stderr, ": possible invalid port.\n");
-+                      } else {
-+                              fprintf(stderr, ".\n");
-+                      }
-+                      if (verbose) {
-+                              rpc_strerror();
-+                      }
-+              }
-               goto out_bad;
-       }
-@@ -743,15 +779,19 @@ parse_options(char *old_opts, struct nfs
- static inline int
- nfsmnt_check_compat(const struct pmap *nfs_pmap, const struct pmap *mnt_pmap)
- {
--      if (nfs_pmap->pm_vers > MAX_NFSPROT) {
-+      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"));
-+                      fprintf(stderr, _("'vers=4' is not supported.  "
-+                              "Use '-t nfs4' instead.\n"));
-               else
--                      fprintf(stderr, _("NFSv%ld not supported!\n"), nfs_pmap->pm_vers);
-+                      fprintf(stderr, _("NFS version %ld is not supported.\n"),
-+                              nfs_pmap->pm_vers);
-               goto out_bad;
-       }
-       if (mnt_pmap->pm_vers > MAX_MNTPROT) {
--              fprintf(stderr, _("NFS mount v%ld not supported!\n"), mnt_pmap->pm_vers);
-+              fprintf(stderr, _("NFS mount version %ld s not supported.\n"),
-+                      mnt_pmap->pm_vers);
-               goto out_bad;
-       }
-       return 1;
-@@ -1144,6 +1184,7 @@ nfs_call_umount(clnt_addr_t *mnt_server,
-               res = nfs2_umount(argp, clnt);
-               break;
-       default:
-+              break;
-       }
-       mnt_closeclnt(clnt, msock);
-       if (res == RPC_SUCCESS)
-_
This page took 0.299816 seconds and 4 git commands to generate.