Fixed NFS so it supports 2.4.x kernels and NFSv3. Should close bug #1009.
authorEric Andersen <andersen@codepoet.org>
Mon, 10 Jul 2000 23:39:44 +0000 (23:39 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 10 Jul 2000 23:39:44 +0000 (23:39 -0000)
 -Erik

Changelog
busybox.def.h
internal.h
nfsmount.c
nfsmount.h
util-linux/nfsmount.c
util-linux/nfsmount.h
utility.c

index c8f3bfb1ea19c8f2cc3aa016a88f956e71034fb3..5d86803907022b69379690879c71c5c9ad18cf62 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -41,6 +41,7 @@
            couldn't maintain it very well, so including it was not really
            very appropriate.  Those wanting an fdisk are invited to
            grab a copy from util-linux.
+       * Fixed NFS so it supports 2.4.x kernels and NFSv3.
 
 
         -Erik Andersen
index 4871d8a7215ef4ce6a88a0ea7bfeb026e6a43675..0f2bcefeb3326e1fa8ab4856ad09ba0429b2d9de 100644 (file)
 // Enable support for a real /etc/mtab file instead of /proc/mounts
 //#define BB_FEATURE_MOUNT_MTAB_SUPPORT
 //
+// Enable support for mounting remote NFS volumes
+// (This does not yet work with Linux 2.[34].x kernels)
+#define BB_FEATURE_NFSMOUNT
+//
 // Enable support forced filesystem unmounting 
 // (i.e. in case of an unreachable NFS system).
 #define BB_FEATURE_MOUNT_FORCE
 //
-// Enable support for mounting remote NFS volumes
-// (This does not yet work with Linux 2.[34].x kernels)
-//#define BB_FEATURE_NFSMOUNT
-//
 // Enable support for creation of tar files.
 #define BB_FEATURE_TAR_CREATE
 //
index a4772b82055632323ed05d6163051e0aa6d323ed..5864c47acf5a33398f4bf6d24a9927d600296ba4 100644 (file)
@@ -255,12 +255,16 @@ extern char *mtab_getinfo(const char *match, const char which);
 extern int check_wildcard_match(const char* text, const char* pattern);
 extern long getNum (const char *cp);
 extern pid_t* findPidByName( char* pidName);
-extern void *xmalloc (size_t size);
 extern int find_real_root_device_name(char* name);
 extern char *get_line_from_file(FILE *file);
 extern char process_escape_sequence(char **ptr);
 extern char *get_last_path_component(char *path);
 
+extern void *xmalloc (size_t size);
+extern char *xstrdup (const char *s);
+extern char *xstrndup (const char *s, int n);
+
+
 /* These parse entries in /etc/passwd and /etc/group.  This is desirable
  * for BusyBox since we want to avoid using the glibc NSS stuff, which
  * increases target size and is often not needed embedded systems.  */
index 03ce5844797b4f48d27820fca6fa84942ebeab30..8cdfebfce6d80bc4f1044ce121c4e10a5017d03d 100644 (file)
@@ -25,6 +25,8 @@
  * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
  * - added Native Language Support
  * 
+ * Modified by Olaf Kirch and Trond Myklebust for new NFS code,
+ * plus NFSv3 stuff.
  */
 
 /*
 #include <arpa/inet.h>
 
 #include "nfsmount.h"
+#include <linux/nfs.h>  /* For the kernels nfs stuff */
+
+
+/* Disable the nls stuff */
+# undef bindtextdomain
+# define bindtextdomain(Domain, Directory) /* empty */
+# undef textdomain
+# define textdomain(Domain) /* empty */
+# define _(Text) (Text)
+# define N_(Text) (Text)
+
+#define MS_MGC_VAL             0xc0ed0000 /* Magic number indicatng "new" flags */
+#define MS_RDONLY        1      /* Mount read-only */
+#define MS_NOSUID        2      /* Ignore suid and sgid bits */
+#define MS_NODEV         4      /* Disallow access to device special files */
+#define MS_NOEXEC        8      /* Disallow program execution */
+#define MS_SYNCHRONOUS  16      /* Writes are synced at once */
+#define MS_REMOUNT      32      /* Alter flags of a mounted FS */
+#define MS_MANDLOCK     64      /* Allow mandatory locks on an FS */
+#define S_QUOTA         128     /* Quota initialized for file/directory/symlink */
+#define S_APPEND        256     /* Append-only file */
+#define S_IMMUTABLE     512     /* Immutable file */
+#define MS_NOATIME      1024    /* Do not update access times. */
+#define MS_NODIRATIME   2048    /* Do not update directory access times */
 
-#include <linux/nfs.h>
-/* we suppose that libc-dev is providing NFSv3 headers (kernel >= 2.2) */
-#include <linux/nfs_mount.h>
 
-#define _
-#define HAVE_inet_aton
-#define MS_REMOUNT     32                      /* Alter flags of a mounted FS */
-#define sloppy 0
-#define EX_FAIL 1
-#define EX_BG 1
-#define xstrdup strdup
-#define xstrndup strndup
+/*
+ * We want to be able to compile mount on old kernels in such a way
+ * that the binary will work well on more recent kernels.
+ * 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).
+ */
+
+#define NFS_MOUNT_VERSION      4
 
+struct nfs2_fh {
+        char                    data[32];
+};
+struct nfs3_fh {
+        unsigned short          size;
+        unsigned char           data[64];
+};
+
+struct nfs_mount_data {
+       int             version;                /* 1 */
+       int             fd;                     /* 1 */
+       struct nfs2_fh  old_root;               /* 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 */
+       struct sockaddr_in addr;                /* 1 */
+       char            hostname[256];          /* 1 */
+       int             namlen;                 /* 2 */
+       unsigned int    bsize;                  /* 3 */
+       struct nfs3_fh  root;                   /* 4 */
+};
 
+/* bits in the flags field */
+
+#define NFS_MOUNT_SOFT         0x0001  /* 1 */
+#define NFS_MOUNT_INTR         0x0002  /* 1 */
+#define NFS_MOUNT_SECURE       0x0004  /* 1 */
+#define NFS_MOUNT_POSIX                0x0008  /* 1 */
+#define NFS_MOUNT_NOCTO                0x0010  /* 1 */
+#define NFS_MOUNT_NOAC         0x0020  /* 1 */
+#define NFS_MOUNT_TCP          0x0040  /* 2 */
+#define NFS_MOUNT_VER3         0x0080  /* 3 */
+#define NFS_MOUNT_KERBEROS     0x0100  /* 3 */
+#define NFS_MOUNT_NONLM                0x0200  /* 3 */
+
+
+#define UTIL_LINUX_VERSION "2.10m"
+#define util_linux_version "util-linux-2.10m"
+
+#define HAVE_inet_aton
+#define HAVE_scsi_h
+#define HAVE_blkpg_h
+#define HAVE_kd_h
+#define HAVE_termcap
+#define HAVE_locale_h
+#define HAVE_libintl_h
+#define ENABLE_NLS
+#define HAVE_langinfo_h
+#define HAVE_progname
+#define HAVE_openpty
+#define HAVE_nanosleep
+#define HAVE_personality
+#define HAVE_tm_gmtoff
+
+extern char *xstrdup (const char *s);
+extern char *xstrndup (const char *s, int n);
 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)
 
-static int linux_version_code(void)
-{
+#define EX_FAIL                        32       /* mount failure */
+#define EX_BG                  256       /* retry in background (internal only) */
+
+
+static int
+linux_version_code(void) {
        struct utsname my_utsname;
        int p, q, r;
 
@@ -75,15 +167,15 @@ static int linux_version_code(void)
                p = atoi(strtok(my_utsname.release, "."));
                q = atoi(strtok(NULL, "."));
                r = atoi(strtok(NULL, "."));
-               return MAKE_VERSION(p, q, r);
+               return MAKE_VERSION(p,q,r);
        }
        return 0;
 }
 
 /*
- * nfs_mount_version according to the kernel sources seen at compile time.
+ * nfs_mount_version according to the sources seen at compile time.
  */
-static int nfs_mount_version = NFS_MOUNT_VERSION;
+int nfs_mount_version = NFS_MOUNT_VERSION;
 
 /*
  * Unfortunately, the kernel prints annoying console messages
@@ -96,22 +188,77 @@ static int nfs_mount_version = NFS_MOUNT_VERSION;
  *     NFS_MOUNT_VERSION: these nfsmount sources at compile time
  *     nfs_mount_version: version this source and running kernel can handle
  */
-static void find_kernel_nfs_mount_version(void)
-{
-       int kernel_version = linux_version_code();
+static void
+find_kernel_nfs_mount_version(void) {
+       static int kernel_version = 0;
+
+       if (kernel_version)
+               return;
+
+       kernel_version = linux_version_code();
 
        if (kernel_version) {
-               if (kernel_version < MAKE_VERSION(2, 1, 32))
-                       nfs_mount_version = 1;
-               else
-                       nfs_mount_version = 3;
+            if (kernel_version < MAKE_VERSION(2,1,32))
+                 nfs_mount_version = 1;
+            else if (kernel_version < MAKE_VERSION(2,3,99))
+                 nfs_mount_version = 3;
+            else
+                 nfs_mount_version = 4; /* since 2.3.99pre4 */
        }
        if (nfs_mount_version > NFS_MOUNT_VERSION)
-               nfs_mount_version = NFS_MOUNT_VERSION;
+            nfs_mount_version = NFS_MOUNT_VERSION;
 }
 
-int nfsmount(const char *spec, const char *node, unsigned long *flags,
-                        char **extra_opts, char **mount_opts, int running_bg)
+static struct pmap *
+get_mountport(struct sockaddr_in *server_addr,
+      long unsigned prog,
+      long unsigned version,
+      long unsigned proto,
+      long unsigned port)
+{
+struct pmaplist *pmap;
+static struct pmap p = {0, 0, 0, 0};
+
+server_addr->sin_port = PMAPPORT;
+pmap = pmap_getmaps(server_addr);
+
+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;
+
+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_port)
+       p.pm_port = MOUNTPORT;
+if (!p.pm_prot)
+       p.pm_prot = IPPROTO_TCP;
+return &p;
+}
+
+int nfsmount(const char *spec, const char *node, int *flags,
+            char **extra_opts, char **mount_opts, int running_bg)
 {
        static char *prev_bg_host;
        char hostdir[1024];
@@ -119,9 +266,8 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        char *hostname;
        char *dirname;
        char *old_opts;
-       char *mounthost = NULL;
+       char *mounthost=NULL;
        char new_opts[1024];
-       fhandle root_fhandle;
        struct timeval total_timeout;
        enum clnt_stat clnt_stat;
        static struct nfs_mount_data data;
@@ -130,13 +276,18 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        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;
-       struct fhstatus status;
+       union {
+               struct fhstatus nfsv2;
+               struct mountres3 nfsv3;
+       } status;
        struct stat statbuf;
        char *s;
        int port;
        int mountport;
+       int proto;
        int bg;
        int soft;
        int intr;
@@ -162,7 +313,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        mclient = NULL;
        if (strlen(spec) >= sizeof(hostdir)) {
                fprintf(stderr, _("mount: "
-                                                 "excessively long host:dir argument\n"));
+                       "excessively long host:dir argument\n"));
                goto fail;
        }
        strcpy(hostdir, spec);
@@ -175,11 +326,11 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                if ((s = strchr(hostdir, ','))) {
                        *s = '\0';
                        fprintf(stderr, _("mount: warning: "
-                                                         "multiple hostnames not supported\n"));
+                               "multiple hostnames not supported\n"));
                }
        } else {
                fprintf(stderr, _("mount: "
-                                                 "directory to mount not in host:dir format\n"));
+                       "directory to mount not in host:dir format\n"));
                goto fail;
        }
 
@@ -190,18 +341,20 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        {
                if ((hp = gethostbyname(hostname)) == NULL) {
                        fprintf(stderr, _("mount: can't get address for %s\n"),
-                                       hostname);
+                               hostname);
                        goto fail;
                } else {
                        if (hp->h_length > sizeof(struct in_addr)) {
-                               fprintf(stderr, _("mount: got bad hp->h_length\n"));
+                               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(&server_addr.sin_addr,
+                              hp->h_addr, hp->h_length);
                }
        }
 
-       memcpy(&mount_server_addr, &server_addr, sizeof(mount_server_addr));
+       memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
 
        /* add IP address to mtab options for use when unmounting */
 
@@ -210,10 +363,12 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (!old_opts)
                old_opts = "";
        if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
-               fprintf(stderr, _("mount: " "excessively long option argument\n"));
+               fprintf(stderr, _("mount: "
+                       "excessively long option argument\n"));
                goto fail;
        }
-       sprintf(new_opts, "%s%saddr=%s", old_opts, *old_opts ? "," : "", s);
+       sprintf(new_opts, "%s%saddr=%s",
+               old_opts, *old_opts ? "," : "", s);
        *extra_opts = xstrdup(new_opts);
 
        /* Set default options.
@@ -221,13 +376,13 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
         * 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;
-       data.acdirmax = 60;
+       data.retrans    = 3;
+       data.acregmin   = 3;
+       data.acregmax   = 60;
+       data.acdirmin   = 30;
+       data.acdirmax   = 60;
 #if NFS_MOUNT_VERSION >= 2
-       data.namlen = NAME_MAX;
+       data.namlen     = NAME_MAX;
 #endif
 
        bg = 0;
@@ -237,21 +392,21 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        nocto = 0;
        nolock = 0;
        noac = 0;
-       retry = 10000;                          /* 10000 minutes ~ 1 week */
+       retry = 10000;          /* 10000 minutes ~ 1 week */
        tcp = 0;
 
        mountprog = MOUNTPROG;
-       mountvers = MOUNTVERS;
+       mountvers = 0;
        port = 0;
        mountport = 0;
        nfsprog = NFS_PROGRAM;
-       nfsvers = NFS_VERSION;
+       nfsvers = 0;
 
        /* parse options */
 
        for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
                if ((opteq = strchr(opt, '='))) {
-                       val = atoi(opteq + 1);
+                       val = atoi(opteq + 1);  
                        *opteq = '\0';
                        if (!strcmp(opt, "rsize"))
                                data.rsize = val;
@@ -274,27 +429,29 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                                data.acregmax = val;
                                data.acdirmin = val;
                                data.acdirmax = val;
-                       } else if (!strcmp(opt, "retry"))
+                       }
+                       else if (!strcmp(opt, "retry"))
                                retry = val;
                        else if (!strcmp(opt, "port"))
                                port = val;
                        else if (!strcmp(opt, "mountport"))
-                               mountport = val;
+                               mountport = val;
                        else if (!strcmp(opt, "mounthost"))
-                               mounthost = xstrndup(opteq + 1,
-                                                                        strcspn(opteq + 1, " \t\n\r,"));
+                               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"))
+                       else if (!strcmp(opt, "nfsvers") ||
+                                !strcmp(opt, "vers"))
                                nfsvers = val;
                        else if (!strcmp(opt, "proto")) {
-                               if (!strncmp(opteq + 1, "tcp", 3))
+                               if (!strncmp(opteq+1, "tcp", 3))
                                        tcp = 1;
-                               else if (!strncmp(opteq + 1, "udp", 3))
+                               else if (!strncmp(opteq+1, "udp", 3))
                                        tcp = 0;
                                else
                                        printf(_("Warning: Unrecognized proto= option.\n"));
@@ -304,24 +461,24 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                                        data.namlen = val;
                                else
 #endif
-                                       printf(_
-                                                  ("Warning: Option namlen is not supported.\n"));
+                               printf(_("Warning: Option namlen is not supported.\n"));
                        } else if (!strcmp(opt, "addr"))
-                               /* ignore */ ;
+                               /* ignore */;
                        else {
                                printf(_("unknown nfs mount parameter: "
-                                                "%s=%d\n"), opt, val);
+                                      "%s=%d\n"), opt, val);
                                goto fail;
                        }
-               } else {
+               }
+               else {
                        val = 1;
                        if (!strncmp(opt, "no", 2)) {
                                val = 0;
                                opt += 2;
                        }
-                       if (!strcmp(opt, "bg"))
+                       if (!strcmp(opt, "bg")) 
                                bg = val;
-                       else if (!strcmp(opt, "fg"))
+                       else if (!strcmp(opt, "fg")) 
                                bg = !val;
                        else if (!strcmp(opt, "soft"))
                                soft = val;
@@ -343,17 +500,16 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                                if (nfs_mount_version >= 3)
                                        nolock = !val;
                                else
-                                       printf(_
-                                                  ("Warning: option nolock is not supported.\n"));
+                                       printf(_("Warning: option nolock is not supported.\n"));
                        } else {
-                               if (!sloppy) {
-                                       printf(_("unknown nfs mount option: "
-                                                        "%s%s\n"), val ? "" : "no", opt);
-                                       goto fail;
-                               }
+                               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)
@@ -367,6 +523,19 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (nfs_mount_version >= 3)
                data.flags |= (nolock ? NFS_MOUNT_NONLM : 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)
@@ -374,21 +543,22 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
 
 #ifdef NFS_MOUNT_DEBUG
        printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
-                  data.rsize, data.wsize, data.timeo, data.retrans);
+               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);
+               data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
        printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
-                  port, bg, retry, data.flags);
+               port, bg, retry, data.flags);
        printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
-                  mountprog, mountvers, nfsprog, nfsvers);
+               mountprog, mountvers, nfsprog, nfsvers);
        printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
-                  (data.flags & NFS_MOUNT_SOFT) != 0,
-                  (data.flags & NFS_MOUNT_INTR) != 0,
-                  (data.flags & NFS_MOUNT_POSIX) != 0,
-                  (data.flags & NFS_MOUNT_NOCTO) != 0,
-                  (data.flags & NFS_MOUNT_NOAC) != 0);
+               (data.flags & NFS_MOUNT_SOFT) != 0,
+               (data.flags & NFS_MOUNT_INTR) != 0,
+               (data.flags & NFS_MOUNT_POSIX) != 0,
+               (data.flags & NFS_MOUNT_NOCTO) != 0,
+               (data.flags & NFS_MOUNT_NOAC) != 0);
 #if NFS_MOUNT_VERSION >= 2
-       printf("tcp = %d\n", (data.flags & NFS_MOUNT_TCP) != 0);
+       printf("tcp = %d\n",
+               (data.flags & NFS_MOUNT_TCP) != 0);
 #endif
 #endif
 
@@ -404,7 +574,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
         * give up immediately, to avoid the initial timeout.
         */
        if (bg && !running_bg &&
-               prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
+           prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
                if (retry > 0)
                        retval = EX_BG;
                return retval;
@@ -413,24 +583,25 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        /* 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"),
-                                               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);
-                               }
-                               mount_server_addr.sin_family = AF_INET;
-                               memcpy(&mount_server_addr.sin_addr,
-                                          hp->h_addr, hp->h_length);
-                       }
-               }
+         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"),
+                                 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);
+                         }
+                         mount_server_addr.sin_family = AF_INET;
+                         memcpy(&mount_server_addr.sin_addr,
+                                hp->h_addr, hp->h_length);
+                 }
+         }
        }
 
        /*
@@ -460,7 +631,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        for (;;) {
                if (bg && stat(node, &statbuf) == -1) {
                        if (running_bg) {
-                               sleep(val);             /* 1, 2, 4, 8, 16, 30, ... */
+                               sleep(val);     /* 1, 2, 4, 8, 16, 30, ... */
                                val *= 2;
                                if (val > 30)
                                        val = 30;
@@ -470,28 +641,60 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                        if (t - prevt < 30)
                                sleep(30);
 
+                       pm_mnt = get_mountport(&mount_server_addr,
+                                      mountprog,
+                                      mountvers,
+                                      proto,
+                                      mountport);
+
                        /* contact the mount daemon via TCP */
-                       mount_server_addr.sin_port = htons(mountport);
+                       mount_server_addr.sin_port = htons(pm_mnt->pm_port);
                        msock = RPC_ANYSOCK;
-                       mclient = clnttcp_create(&mount_server_addr,
-                                                                        mountprog, mountvers, &msock, 0, 0);
 
-                       /* if this fails, contact the mount daemon via UDP */
-                       if (!mclient) {
-                               mount_server_addr.sin_port = htons(mountport);
-                               msock = RPC_ANYSOCK;
+                       switch (pm_mnt->pm_prot) {
+                       case IPPROTO_UDP:
                                mclient = clntudp_create(&mount_server_addr,
-                                                                                mountprog, mountvers,
-                                                                                retry_timeout, &msock);
+                                                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);
+                       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);
+                                                     (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 (errno != ECONNREFUSED) {
@@ -511,7 +714,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                        prevt = t;
                }
                if (!bg)
-                       goto fail;
+                       goto fail;
                if (!running_bg) {
                        prev_bg_host = xstrdup(hostname);
                        if (retry > 0)
@@ -522,21 +725,52 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                if (t >= timeout)
                        goto fail;
        }
+       nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
 
-       if (status.fhs_status != 0) {
-               fprintf(stderr,
-                               _("mount: %s:%s failed, reason given by server: %s\n"),
-                               hostname, dirname, nfs_strerror(status.fhs_status));
-               goto fail;
+       if (nfsvers == 2) {
+               if (status.nfsv2.fhs_status != 0) {
+                       fprintf(stderr,
+                               "mount: %s:%s failed, reason given by server: %s\n",
+                               hostname, dirname,
+                               nfs_strerror(status.nfsv2.fhs_status));
+                       goto fail;
+               }
+               memcpy(data.root.data,
+                      (char *) status.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,
+                      NFS_FHSIZE);
+#endif
+       } else {
+#if NFS_MOUNT_VERSION >= 4
+               fhandle3 *fhandle;
+               if (status.nfsv3.fhs_status != 0) {
+                       fprintf(stderr,
+                               "mount: %s:%s failed, reason given by server: %s\n",
+                               hostname, dirname,
+                               nfs_strerror(status.nfsv3.fhs_status));
+                       goto fail;
+               }
+               fhandle = &status.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;
+               memcpy(data.root.data,
+                      (char *) fhandle->fhandle3_val,
+                      fhandle->fhandle3_len);
+
+               data.flags |= NFS_MOUNT_VER3;
+#endif
        }
-       memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
-                  sizeof(root_fhandle));
 
        /* create nfs socket for kernel */
 
        if (tcp) {
                if (nfs_mount_version < 3) {
-                       printf(_("NFS over TCP is not supported.\n"));
+                       printf(_("NFS over TCP is not supported.\n"));
                        goto fail;
                }
                fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -553,7 +787,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (port == 0) {
                server_addr.sin_port = PMAPPORT;
                port = pmap_getport(&server_addr, nfsprog, nfsvers,
-                                                       tcp ? IPPROTO_TCP : IPPROTO_UDP);
+                       tcp ? IPPROTO_TCP : IPPROTO_UDP);
                if (port == 0)
                        port = NFS_PORT;
 #ifdef NFS_MOUNT_DEBUG
@@ -565,14 +799,14 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        printf(_("using port %d for nfs deamon\n"), port);
 #endif
        server_addr.sin_port = htons(port);
-       /*
-        * connect() the socket for kernels 1.3.10 and below only,
-        * to avoid problems with multihomed hosts.
-        * --Swen
-        */
+        /*
+         * 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 *) &server_addr,
+                      sizeof (server_addr)) < 0) {
                perror(_("nfs connect"));
                goto fail;
        }
@@ -580,8 +814,6 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        /* prepare data structure for kernel */
 
        data.fd = fsock;
-       memcpy((char *) &data.root, (char *) &root_fhandle,
-                  sizeof(root_fhandle));
        memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
        strncpy(data.hostname, hostname, sizeof(data.hostname));
 
@@ -594,7 +826,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
 
        /* abort */
 
-  fail:
+fail:
        if (msock != -1) {
                if (mclient) {
                        auth_destroy(mclient->cl_auth);
@@ -605,7 +837,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (fsock != -1)
                close(fsock);
        return retval;
-}
+}      
 
 /*
  * We need to translate between nfs status return values and
@@ -624,37 +856,33 @@ static struct {
        enum nfs_stat stat;
        int errnum;
 } nfs_errtbl[] = {
-       {
-       NFS_OK, 0}, {
-       NFSERR_PERM, EPERM}, {
-       NFSERR_NOENT, ENOENT}, {
-       NFSERR_IO, EIO}, {
-       NFSERR_NXIO, ENXIO}, {
-       NFSERR_ACCES, EACCES}, {
-       NFSERR_EXIST, EEXIST}, {
-       NFSERR_NODEV, ENODEV}, {
-       NFSERR_NOTDIR, ENOTDIR}, {
-       NFSERR_ISDIR, EISDIR},
+       { NFS_OK,               0               },
+       { NFSERR_PERM,          EPERM           },
+       { NFSERR_NOENT,         ENOENT          },
+       { NFSERR_IO,            EIO             },
+       { NFSERR_NXIO,          ENXIO           },
+       { NFSERR_ACCES,         EACCES          },
+       { NFSERR_EXIST,         EEXIST          },
+       { NFSERR_NODEV,         ENODEV          },
+       { NFSERR_NOTDIR,        ENOTDIR         },
+       { NFSERR_ISDIR,         EISDIR          },
 #ifdef NFSERR_INVAL
-       {
-       NFSERR_INVAL, EINVAL},          /* that Sun forgot */
+       { NFSERR_INVAL,         EINVAL          },      /* that Sun forgot */
 #endif
-       {
-       NFSERR_FBIG, EFBIG}, {
-       NFSERR_NOSPC, ENOSPC}, {
-       NFSERR_ROFS, EROFS}, {
-       NFSERR_NAMETOOLONG, ENAMETOOLONG}, {
-       NFSERR_NOTEMPTY, ENOTEMPTY}, {
-       NFSERR_DQUOT, EDQUOT}, {
-       NFSERR_STALE, ESTALE},
+       { NFSERR_FBIG,          EFBIG           },
+       { NFSERR_NOSPC,         ENOSPC          },
+       { NFSERR_ROFS,          EROFS           },
+       { NFSERR_NAMETOOLONG,   ENAMETOOLONG    },
+       { NFSERR_NOTEMPTY,      ENOTEMPTY       },
+       { NFSERR_DQUOT,         EDQUOT          },
+       { NFSERR_STALE,         ESTALE          },
 #ifdef EWFLUSH
-       {
-       NFSERR_WFLUSH, EWFLUSH},
+       { NFSERR_WFLUSH,        EWFLUSH         },
 #endif
-               /* Throw in some NFSv3 values for even more fun (HP returns these) */
-       {
-       71, EREMOTE}, {
-       -1, EIO}
+       /* Throw in some NFSv3 values for even more fun (HP returns these) */
+       { 71,                   EREMOTE         },
+
+       { -1,                   EIO             }
 };
 
 static char *nfs_strerror(int stat)
@@ -670,621 +898,92 @@ static char *nfs_strerror(int stat)
        return buf;
 }
 
-#if 0
-int my_getport(struct in_addr server, struct timeval *timeo, ...)
+bool_t
+xdr_fhandle (XDR *xdrs, fhandle objp)
 {
-       struct sockaddr_in sin;
-       struct pmap pmap;
-       CLIENT *clnt;
-       int sock = RPC_ANYSOCK, port;
-
-       pmap.pm_prog = prog;
-       pmap.pm_vers = vers;
-       pmap.pm_prot = prot;
-       pmap.pm_port = 0;
-       sin.sin_family = AF_INET;
-       sin.sin_addr = server;
-       sin.sin_port = htons(111);
-       clnt = clntudp_create(&sin, 100000, 2, *timeo, &sock);
-       status = clnt_call(clnt, PMAP_GETPORT,
-                                          &pmap, (xdrproc_t) xdr_pmap,
-                                          &port, (xdrproc_t) xdr_uint);
-       if (status != SUCCESS) {
-               /* natter */
-               port = 0;
-       }
+       //register int32_t *buf;
 
-       clnt_destroy(clnt);
-       close(sock);
-       return port;
+        if (!xdr_opaque (xdrs, objp, FHSIZE))
+                return FALSE;
+       return TRUE;
 }
-#endif
 
-
-
-
-
-
-
-
-
-
-
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
-
-bool_t xdr_fhandle(XDR * xdrs, fhandle objp)
+bool_t
+xdr_fhstatus (XDR *xdrs, fhstatus *objp)
 {
+       //register int32_t *buf;
 
-       if (!xdr_opaque(xdrs, objp, FHSIZE)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_fhstatus(XDR * xdrs, fhstatus * objp)
-{
-
-       if (!xdr_u_int(xdrs, &objp->fhs_status)) {
-               return (FALSE);
-       }
+        if (!xdr_u_int (xdrs, &objp->fhs_status))
+                return FALSE;
        switch (objp->fhs_status) {
        case 0:
-               if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
-                       return (FALSE);
-               }
+                if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
+                        return FALSE;
                break;
        default:
                break;
        }
-       return (TRUE);
-}
-
-bool_t xdr_dirpath(XDR * xdrs, dirpath * objp)
-{
-
-       if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_name(XDR * xdrs, name * objp)
-{
-
-       if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_mountlist(XDR * xdrs, mountlist * objp)
-{
-
-       if (!xdr_pointer
-               (xdrs, (char **) objp, sizeof(struct mountbody),
-                (xdrproc_t) xdr_mountbody)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_mountbody(XDR * xdrs, mountbody * objp)
-{
-
-       if (!xdr_name(xdrs, &objp->ml_hostname)) {
-               return (FALSE);
-       }
-       if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
-               return (FALSE);
-       }
-       if (!xdr_mountlist(xdrs, &objp->ml_next)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_groups(XDR * xdrs, groups * objp)
-{
-
-       if (!xdr_pointer
-               (xdrs, (char **) objp, sizeof(struct groupnode),
-                (xdrproc_t) xdr_groupnode)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_groupnode(XDR * xdrs, groupnode * objp)
-{
-
-       if (!xdr_name(xdrs, &objp->gr_name)) {
-               return (FALSE);
-       }
-       if (!xdr_groups(xdrs, &objp->gr_next)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_exports(XDR * xdrs, exports * objp)
-{
-
-       if (!xdr_pointer
-               (xdrs, (char **) objp, sizeof(struct exportnode),
-                (xdrproc_t) xdr_exportnode)) {
-               return (FALSE);
-       }
-       return (TRUE);
+       return TRUE;
 }
 
-bool_t xdr_exportnode(XDR * xdrs, exportnode * objp)
+bool_t
+xdr_dirpath (XDR *xdrs, dirpath *objp)
 {
+       //register int32_t *buf;
 
-       if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
-               return (FALSE);
-       }
-       if (!xdr_groups(xdrs, &objp->ex_groups)) {
-               return (FALSE);
-       }
-       if (!xdr_exports(xdrs, &objp->ex_next)) {
-               return (FALSE);
-       }
-       return (TRUE);
+        if (!xdr_string (xdrs, objp, MNTPATHLEN))
+                return FALSE;
+       return TRUE;
 }
 
-bool_t xdr_ppathcnf(XDR * xdrs, ppathcnf * objp)
+bool_t
+xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
 {
+       //register int32_t *buf;
 
-       register long *buf;
-
-       int i;
-
-       if (xdrs->x_op == XDR_ENCODE) {
-               buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_int(xdrs, &objp->pc_link_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_canon)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_input)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_name_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_path_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       IXDR_PUT_LONG(buf, objp->pc_link_max);
-                       IXDR_PUT_SHORT(buf, objp->pc_max_canon);
-                       IXDR_PUT_SHORT(buf, objp->pc_max_input);
-                       IXDR_PUT_SHORT(buf, objp->pc_name_max);
-                       IXDR_PUT_SHORT(buf, objp->pc_path_max);
-                       IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
-               }
-               if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
-                       return (FALSE);
-               }
-               if (!xdr_char(xdrs, &objp->pc_xxx)) {
-                       return (FALSE);
-               }
-               buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_vector
-                               (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
-                                (xdrproc_t) xdr_short)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       {
-                               register short *genp;
-
-                               for (i = 0, genp = objp->pc_mask; i < 2; i++) {
-                                       IXDR_PUT_SHORT(buf, *genp++);
-                               }
-                       };
-               }
-
-               return (TRUE);
-       } else if (xdrs->x_op == XDR_DECODE) {
-               buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_int(xdrs, &objp->pc_link_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_canon)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_input)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_name_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_path_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       objp->pc_link_max = IXDR_GET_LONG(buf);
-                       objp->pc_max_canon = IXDR_GET_SHORT(buf);
-                       objp->pc_max_input = IXDR_GET_SHORT(buf);
-                       objp->pc_name_max = IXDR_GET_SHORT(buf);
-                       objp->pc_path_max = IXDR_GET_SHORT(buf);
-                       objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
-               }
-               if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
-                       return (FALSE);
-               }
-               if (!xdr_char(xdrs, &objp->pc_xxx)) {
-                       return (FALSE);
-               }
-               buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_vector
-                               (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
-                                (xdrproc_t) xdr_short)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       {
-                               register short *genp;
-
-                               for (i = 0, genp = objp->pc_mask; i < 2; i++) {
-                                       *genp++ = IXDR_GET_SHORT(buf);
-                               }
-                       };
-               }
-               return (TRUE);
-       }
-
-       if (!xdr_int(xdrs, &objp->pc_link_max)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_max_canon)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_max_input)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_name_max)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_path_max)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
-               return (FALSE);
-       }
-       if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
-               return (FALSE);
-       }
-       if (!xdr_char(xdrs, &objp->pc_xxx)) {
-               return (FALSE);
-       }
-       if (!xdr_vector
-               (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
-                (xdrproc_t) xdr_short)) {
-               return (FALSE);
-       }
-       return (TRUE);
+        if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+                return FALSE;
+       return TRUE;
 }
 
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
-
-#include <string.h>                            /* for memset() */
-
-/* Default timeout can be changed using clnt_control() */
-static struct timeval TIMEOUT = { 25, 0 };
-
-void *mountproc_null_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call
-               (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
-                (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-fhstatus *mountproc_mnt_1(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static fhstatus clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-mountlist *mountproc_dump_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static mountlist clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_mountlist,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-void *mountproc_umnt_1(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-void *mountproc_umntall_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
+bool_t
+xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
 {
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
+       //register int32_t *buf;
+
+        if (!xdr_fhandle3 (xdrs, &objp->fhandle))
+                return FALSE;
+        if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
+               sizeof (int), (xdrproc_t) xdr_int))
+                return FALSE;
+       return TRUE;
 }
 
-exports *mountproc_export_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
+bool_t
+xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
 {
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_exports,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
+       //register int32_t *buf;
 
-exports *mountproc_exportall_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_exports,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-void *mountproc_null_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call
-               (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
-                (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
 }
 
-fhstatus *mountproc_mnt_2(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
+bool_t
+xdr_mountres3 (XDR *xdrs, mountres3 *objp)
 {
-       static fhstatus clnt_res;
+       //register int32_t *buf;
 
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-mountlist *mountproc_dump_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static mountlist clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp,
-                                 (xdrproc_t) xdr_mountlist, (caddr_t) & clnt_res,
-                                 TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-void *mountproc_umnt_2(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-void *mountproc_umntall_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-exports *mountproc_export_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
-                                 argp, (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
-                                 TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-exports *mountproc_exportall_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp,
-                                 (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
-                                 TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
+        if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
+                return FALSE;
+       switch (objp->fhs_status) {
+       case MNT_OK:
+                if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))
+                        return FALSE;
+               break;
+       default:
+               break;
        }
-       return (&clnt_res);
+       return TRUE;
 }
 
-ppathcnf *mountproc_pathconf_2(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static ppathcnf clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_ppathcnf,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
index 64ac617c0120e5412397497e89bf41bfcdf0a408..a12de50a11b2c3d6fb2e1cf363d6cf48b792f64e 100644 (file)
@@ -9,6 +9,11 @@
 
 #include <rpc/rpc.h>
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  * unrestricted use provided that this legend is included on all tape
 /* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
 #ifndef _rpcsvc_mount_h
 #define _rpcsvc_mount_h
+#include <asm/types.h>
+#define MOUNTPORT 635
 #define MNTPATHLEN 1024
 #define MNTNAMLEN 255
 #define FHSIZE 32
+#define FHSIZE3 64
 
 typedef char fhandle[FHSIZE];
-#ifdef __cplusplus 
-extern "C" bool_t xdr_fhandle(XDR *, fhandle);
-#elif __STDC__ 
-extern  bool_t xdr_fhandle(XDR *, fhandle);
-#else /* Old Style C */ 
-bool_t xdr_fhandle();
-#endif /* Old Style C */ 
 
+typedef struct {
+       u_int fhandle3_len;
+       char *fhandle3_val;
+} fhandle3;
+
+enum mountstat3 {
+       MNT_OK = 0,
+       MNT3ERR_PERM = 1,
+       MNT3ERR_NOENT = 2,
+       MNT3ERR_IO = 5,
+       MNT3ERR_ACCES = 13,
+       MNT3ERR_NOTDIR = 20,
+       MNT3ERR_INVAL = 22,
+       MNT3ERR_NAMETOOLONG = 63,
+       MNT3ERR_NOTSUPP = 10004,
+       MNT3ERR_SERVERFAULT = 10006,
+};
+typedef enum mountstat3 mountstat3;
 
 struct fhstatus {
        u_int fhs_status;
@@ -66,44 +85,29 @@ struct fhstatus {
        } fhstatus_u;
 };
 typedef struct fhstatus fhstatus;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
-#elif __STDC__ 
-extern  bool_t xdr_fhstatus(XDR *, fhstatus*);
-#else /* Old Style C */ 
-bool_t xdr_fhstatus();
-#endif /* Old Style C */ 
 
+struct mountres3_ok {
+       fhandle3 fhandle;
+       struct {
+               u_int auth_flavours_len;
+               int *auth_flavours_val;
+       } auth_flavours;
+};
+typedef struct mountres3_ok mountres3_ok;
 
-typedef char *dirpath;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
-#elif __STDC__ 
-extern  bool_t xdr_dirpath(XDR *, dirpath*);
-#else /* Old Style C */ 
-bool_t xdr_dirpath();
-#endif /* Old Style C */ 
+struct mountres3 {
+       mountstat3 fhs_status;
+       union {
+               mountres3_ok mountinfo;
+       } mountres3_u;
+};
+typedef struct mountres3 mountres3;
 
+typedef char *dirpath;
 
 typedef char *name;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_name(XDR *, name*);
-#elif __STDC__ 
-extern  bool_t xdr_name(XDR *, name*);
-#else /* Old Style C */ 
-bool_t xdr_name();
-#endif /* Old Style C */ 
-
 
 typedef struct mountbody *mountlist;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
-#elif __STDC__ 
-extern  bool_t xdr_mountlist(XDR *, mountlist*);
-#else /* Old Style C */ 
-bool_t xdr_mountlist();
-#endif /* Old Style C */ 
-
 
 struct mountbody {
        name ml_hostname;
@@ -111,48 +115,16 @@ struct mountbody {
        mountlist ml_next;
 };
 typedef struct mountbody mountbody;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
-#elif __STDC__ 
-extern  bool_t xdr_mountbody(XDR *, mountbody*);
-#else /* Old Style C */ 
-bool_t xdr_mountbody();
-#endif /* Old Style C */ 
-
 
 typedef struct groupnode *groups;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_groups(XDR *, groups*);
-#elif __STDC__ 
-extern  bool_t xdr_groups(XDR *, groups*);
-#else /* Old Style C */ 
-bool_t xdr_groups();
-#endif /* Old Style C */ 
-
 
 struct groupnode {
        name gr_name;
        groups gr_next;
 };
 typedef struct groupnode groupnode;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
-#elif __STDC__ 
-extern  bool_t xdr_groupnode(XDR *, groupnode*);
-#else /* Old Style C */ 
-bool_t xdr_groupnode();
-#endif /* Old Style C */ 
-
 
 typedef struct exportnode *exports;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_exports(XDR *, exports*);
-#elif __STDC__ 
-extern  bool_t xdr_exports(XDR *, exports*);
-#else /* Old Style C */ 
-bool_t xdr_exports();
-#endif /* Old Style C */ 
-
 
 struct exportnode {
        dirpath ex_dir;
@@ -160,14 +132,6 @@ struct exportnode {
        exports ex_next;
 };
 typedef struct exportnode exportnode;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
-#elif __STDC__ 
-extern  bool_t xdr_exportnode(XDR *, exportnode*);
-#else /* Old Style C */ 
-bool_t xdr_exportnode();
-#endif /* Old Style C */ 
-
 
 struct ppathcnf {
        int pc_link_max;
@@ -181,110 +145,62 @@ struct ppathcnf {
        short pc_mask[2];
 };
 typedef struct ppathcnf ppathcnf;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#elif __STDC__ 
-extern  bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#else /* Old Style C */ 
-bool_t xdr_ppathcnf();
-#endif /* Old Style C */ 
-
 #endif /*!_rpcsvc_mount_h*/
 
-#define MOUNTPROG ((u_long)100005)
-#define MOUNTVERS ((u_long)1)
+#define MOUNTPROG 100005
+#define MOUNTVERS 1
 
-#ifdef __cplusplus
-#define MOUNTPROC_NULL ((u_long)0)
-extern "C" void * mountproc_null_1(void *, CLIENT *);
-extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern "C" void * mountproc_umntall_1(void *, CLIENT *);
-extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern "C" exports * mountproc_export_1(void *, CLIENT *);
-extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#elif __STDC__
-#define MOUNTPROC_NULL ((u_long)0)
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC_NULL 0
 extern  void * mountproc_null_1(void *, CLIENT *);
 extern  void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
+#define MOUNTPROC_MNT 1
 extern  fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
 extern  fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
+#define MOUNTPROC_DUMP 2
 extern  mountlist * mountproc_dump_1(void *, CLIENT *);
 extern  mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
+#define MOUNTPROC_UMNT 3
 extern  void * mountproc_umnt_1(dirpath *, CLIENT *);
 extern  void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
+#define MOUNTPROC_UMNTALL 4
 extern  void * mountproc_umntall_1(void *, CLIENT *);
 extern  void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
+#define MOUNTPROC_EXPORT 5
 extern  exports * mountproc_export_1(void *, CLIENT *);
 extern  exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
+#define MOUNTPROC_EXPORTALL 6
 extern  exports * mountproc_exportall_1(void *, CLIENT *);
 extern  exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
 
-#else /* Old Style C */ 
-#define MOUNTPROC_NULL ((u_long)0)
+#else /* K&R C */
+#define MOUNTPROC_NULL 0
 extern  void * mountproc_null_1();
 extern  void * mountproc_null_1_svc();
-#define MOUNTPROC_MNT ((u_long)1)
+#define MOUNTPROC_MNT 1
 extern  fhstatus * mountproc_mnt_1();
 extern  fhstatus * mountproc_mnt_1_svc();
-#define MOUNTPROC_DUMP ((u_long)2)
+#define MOUNTPROC_DUMP 2
 extern  mountlist * mountproc_dump_1();
 extern  mountlist * mountproc_dump_1_svc();
-#define MOUNTPROC_UMNT ((u_long)3)
+#define MOUNTPROC_UMNT 3
 extern  void * mountproc_umnt_1();
 extern  void * mountproc_umnt_1_svc();
-#define MOUNTPROC_UMNTALL ((u_long)4)
+#define MOUNTPROC_UMNTALL 4
 extern  void * mountproc_umntall_1();
 extern  void * mountproc_umntall_1_svc();
-#define MOUNTPROC_EXPORT ((u_long)5)
+#define MOUNTPROC_EXPORT 5
 extern  exports * mountproc_export_1();
 extern  exports * mountproc_export_1_svc();
-#define MOUNTPROC_EXPORTALL ((u_long)6)
+#define MOUNTPROC_EXPORTALL 6
 extern  exports * mountproc_exportall_1();
 extern  exports * mountproc_exportall_1_svc();
-#endif /* Old Style C */ 
-#define MOUNTVERS_POSIX ((u_long)2)
+extern int mountprog_1_freeresult ();
+#endif /* K&R C */
+#define MOUNTVERS_POSIX 2
 
-#ifdef __cplusplus
-extern "C" void * mountproc_null_2(void *, CLIENT *);
-extern "C" void * mountproc_null_2_svc(void *, struct svc_req *);
-extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern "C" mountlist * mountproc_dump_2(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern "C" void * mountproc_umntall_2(void *, CLIENT *);
-extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_export_2(void *, CLIENT *);
-extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_exportall_2(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#elif __STDC__
+#if defined(__STDC__) || defined(__cplusplus)
 extern  void * mountproc_null_2(void *, CLIENT *);
 extern  void * mountproc_null_2_svc(void *, struct svc_req *);
 extern  fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
@@ -299,11 +215,12 @@ extern  exports * mountproc_export_2(void *, CLIENT *);
 extern  exports * mountproc_export_2_svc(void *, struct svc_req *);
 extern  exports * mountproc_exportall_2(void *, CLIENT *);
 extern  exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
+#define MOUNTPROC_PATHCONF 7
 extern  ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
 extern  ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
+extern int mountprog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
 
-#else /* Old Style C */ 
+#else /* K&R C */
 extern  void * mountproc_null_2();
 extern  void * mountproc_null_2_svc();
 extern  fhstatus * mountproc_mnt_2();
@@ -318,9 +235,96 @@ extern  exports * mountproc_export_2();
 extern  exports * mountproc_export_2_svc();
 extern  exports * mountproc_exportall_2();
 extern  exports * mountproc_exportall_2_svc();
-#define MOUNTPROC_PATHCONF ((u_long)7)
+#define MOUNTPROC_PATHCONF 7
 extern  ppathcnf * mountproc_pathconf_2();
 extern  ppathcnf * mountproc_pathconf_2_svc();
-#endif /* Old Style C */ 
+extern int mountprog_2_freeresult ();
+#endif /* K&R C */
+#define MOUNT_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC3_NULL 0
+extern  void * mountproc3_null_3(void *, CLIENT *);
+extern  void * mountproc3_null_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_MNT 1
+extern  mountres3 * mountproc3_mnt_3(dirpath *, CLIENT *);
+extern  mountres3 * mountproc3_mnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_DUMP 2
+extern  mountlist * mountproc3_dump_3(void *, CLIENT *);
+extern  mountlist * mountproc3_dump_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_UMNT 3
+extern  void * mountproc3_umnt_3(dirpath *, CLIENT *);
+extern  void * mountproc3_umnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_UMNTALL 4
+extern  void * mountproc3_umntall_3(void *, CLIENT *);
+extern  void * mountproc3_umntall_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_EXPORT 5
+extern  exports * mountproc3_export_3(void *, CLIENT *);
+extern  exports * mountproc3_export_3_svc(void *, struct svc_req *);
+extern int mountprog_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define MOUNTPROC3_NULL 0
+extern  void * mountproc3_null_3();
+extern  void * mountproc3_null_3_svc();
+#define MOUNTPROC3_MNT 1
+extern  mountres3 * mountproc3_mnt_3();
+extern  mountres3 * mountproc3_mnt_3_svc();
+#define MOUNTPROC3_DUMP 2
+extern  mountlist * mountproc3_dump_3();
+extern  mountlist * mountproc3_dump_3_svc();
+#define MOUNTPROC3_UMNT 3
+extern  void * mountproc3_umnt_3();
+extern  void * mountproc3_umnt_3_svc();
+#define MOUNTPROC3_UMNTALL 4
+extern  void * mountproc3_umntall_3();
+extern  void * mountproc3_umntall_3_svc();
+#define MOUNTPROC3_EXPORT 5
+extern  exports * mountproc3_export_3();
+extern  exports * mountproc3_export_3_svc();
+extern int mountprog_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern  bool_t xdr_fhandle (XDR *, fhandle);
+extern  bool_t xdr_fhandle3 (XDR *, fhandle3*);
+extern  bool_t xdr_mountstat3 (XDR *, mountstat3*);
+extern  bool_t xdr_fhstatus (XDR *, fhstatus*);
+extern  bool_t xdr_mountres3_ok (XDR *, mountres3_ok*);
+extern  bool_t xdr_mountres3 (XDR *, mountres3*);
+extern  bool_t xdr_dirpath (XDR *, dirpath*);
+extern  bool_t xdr_name (XDR *, name*);
+extern  bool_t xdr_mountlist (XDR *, mountlist*);
+extern  bool_t xdr_mountbody (XDR *, mountbody*);
+extern  bool_t xdr_groups (XDR *, groups*);
+extern  bool_t xdr_groupnode (XDR *, groupnode*);
+extern  bool_t xdr_exports (XDR *, exports*);
+extern  bool_t xdr_exportnode (XDR *, exportnode*);
+extern  bool_t xdr_ppathcnf (XDR *, ppathcnf*);
+
+#else /* K&R C */
+extern bool_t xdr_fhandle ();
+extern bool_t xdr_fhandle3 ();
+extern bool_t xdr_mountstat3 ();
+extern bool_t xdr_fhstatus ();
+extern bool_t xdr_mountres3_ok ();
+extern bool_t xdr_mountres3 ();
+extern bool_t xdr_dirpath ();
+extern bool_t xdr_name ();
+extern bool_t xdr_mountlist ();
+extern bool_t xdr_mountbody ();
+extern bool_t xdr_groups ();
+extern bool_t xdr_groupnode ();
+extern bool_t xdr_exports ();
+extern bool_t xdr_exportnode ();
+extern bool_t xdr_ppathcnf ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* !_NFSMOUNT_H_RPCGEN */
index 03ce5844797b4f48d27820fca6fa84942ebeab30..8cdfebfce6d80bc4f1044ce121c4e10a5017d03d 100644 (file)
@@ -25,6 +25,8 @@
  * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
  * - added Native Language Support
  * 
+ * Modified by Olaf Kirch and Trond Myklebust for new NFS code,
+ * plus NFSv3 stuff.
  */
 
 /*
 #include <arpa/inet.h>
 
 #include "nfsmount.h"
+#include <linux/nfs.h>  /* For the kernels nfs stuff */
+
+
+/* Disable the nls stuff */
+# undef bindtextdomain
+# define bindtextdomain(Domain, Directory) /* empty */
+# undef textdomain
+# define textdomain(Domain) /* empty */
+# define _(Text) (Text)
+# define N_(Text) (Text)
+
+#define MS_MGC_VAL             0xc0ed0000 /* Magic number indicatng "new" flags */
+#define MS_RDONLY        1      /* Mount read-only */
+#define MS_NOSUID        2      /* Ignore suid and sgid bits */
+#define MS_NODEV         4      /* Disallow access to device special files */
+#define MS_NOEXEC        8      /* Disallow program execution */
+#define MS_SYNCHRONOUS  16      /* Writes are synced at once */
+#define MS_REMOUNT      32      /* Alter flags of a mounted FS */
+#define MS_MANDLOCK     64      /* Allow mandatory locks on an FS */
+#define S_QUOTA         128     /* Quota initialized for file/directory/symlink */
+#define S_APPEND        256     /* Append-only file */
+#define S_IMMUTABLE     512     /* Immutable file */
+#define MS_NOATIME      1024    /* Do not update access times. */
+#define MS_NODIRATIME   2048    /* Do not update directory access times */
 
-#include <linux/nfs.h>
-/* we suppose that libc-dev is providing NFSv3 headers (kernel >= 2.2) */
-#include <linux/nfs_mount.h>
 
-#define _
-#define HAVE_inet_aton
-#define MS_REMOUNT     32                      /* Alter flags of a mounted FS */
-#define sloppy 0
-#define EX_FAIL 1
-#define EX_BG 1
-#define xstrdup strdup
-#define xstrndup strndup
+/*
+ * We want to be able to compile mount on old kernels in such a way
+ * that the binary will work well on more recent kernels.
+ * 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).
+ */
+
+#define NFS_MOUNT_VERSION      4
 
+struct nfs2_fh {
+        char                    data[32];
+};
+struct nfs3_fh {
+        unsigned short          size;
+        unsigned char           data[64];
+};
+
+struct nfs_mount_data {
+       int             version;                /* 1 */
+       int             fd;                     /* 1 */
+       struct nfs2_fh  old_root;               /* 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 */
+       struct sockaddr_in addr;                /* 1 */
+       char            hostname[256];          /* 1 */
+       int             namlen;                 /* 2 */
+       unsigned int    bsize;                  /* 3 */
+       struct nfs3_fh  root;                   /* 4 */
+};
 
+/* bits in the flags field */
+
+#define NFS_MOUNT_SOFT         0x0001  /* 1 */
+#define NFS_MOUNT_INTR         0x0002  /* 1 */
+#define NFS_MOUNT_SECURE       0x0004  /* 1 */
+#define NFS_MOUNT_POSIX                0x0008  /* 1 */
+#define NFS_MOUNT_NOCTO                0x0010  /* 1 */
+#define NFS_MOUNT_NOAC         0x0020  /* 1 */
+#define NFS_MOUNT_TCP          0x0040  /* 2 */
+#define NFS_MOUNT_VER3         0x0080  /* 3 */
+#define NFS_MOUNT_KERBEROS     0x0100  /* 3 */
+#define NFS_MOUNT_NONLM                0x0200  /* 3 */
+
+
+#define UTIL_LINUX_VERSION "2.10m"
+#define util_linux_version "util-linux-2.10m"
+
+#define HAVE_inet_aton
+#define HAVE_scsi_h
+#define HAVE_blkpg_h
+#define HAVE_kd_h
+#define HAVE_termcap
+#define HAVE_locale_h
+#define HAVE_libintl_h
+#define ENABLE_NLS
+#define HAVE_langinfo_h
+#define HAVE_progname
+#define HAVE_openpty
+#define HAVE_nanosleep
+#define HAVE_personality
+#define HAVE_tm_gmtoff
+
+extern char *xstrdup (const char *s);
+extern char *xstrndup (const char *s, int n);
 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)
 
-static int linux_version_code(void)
-{
+#define EX_FAIL                        32       /* mount failure */
+#define EX_BG                  256       /* retry in background (internal only) */
+
+
+static int
+linux_version_code(void) {
        struct utsname my_utsname;
        int p, q, r;
 
@@ -75,15 +167,15 @@ static int linux_version_code(void)
                p = atoi(strtok(my_utsname.release, "."));
                q = atoi(strtok(NULL, "."));
                r = atoi(strtok(NULL, "."));
-               return MAKE_VERSION(p, q, r);
+               return MAKE_VERSION(p,q,r);
        }
        return 0;
 }
 
 /*
- * nfs_mount_version according to the kernel sources seen at compile time.
+ * nfs_mount_version according to the sources seen at compile time.
  */
-static int nfs_mount_version = NFS_MOUNT_VERSION;
+int nfs_mount_version = NFS_MOUNT_VERSION;
 
 /*
  * Unfortunately, the kernel prints annoying console messages
@@ -96,22 +188,77 @@ static int nfs_mount_version = NFS_MOUNT_VERSION;
  *     NFS_MOUNT_VERSION: these nfsmount sources at compile time
  *     nfs_mount_version: version this source and running kernel can handle
  */
-static void find_kernel_nfs_mount_version(void)
-{
-       int kernel_version = linux_version_code();
+static void
+find_kernel_nfs_mount_version(void) {
+       static int kernel_version = 0;
+
+       if (kernel_version)
+               return;
+
+       kernel_version = linux_version_code();
 
        if (kernel_version) {
-               if (kernel_version < MAKE_VERSION(2, 1, 32))
-                       nfs_mount_version = 1;
-               else
-                       nfs_mount_version = 3;
+            if (kernel_version < MAKE_VERSION(2,1,32))
+                 nfs_mount_version = 1;
+            else if (kernel_version < MAKE_VERSION(2,3,99))
+                 nfs_mount_version = 3;
+            else
+                 nfs_mount_version = 4; /* since 2.3.99pre4 */
        }
        if (nfs_mount_version > NFS_MOUNT_VERSION)
-               nfs_mount_version = NFS_MOUNT_VERSION;
+            nfs_mount_version = NFS_MOUNT_VERSION;
 }
 
-int nfsmount(const char *spec, const char *node, unsigned long *flags,
-                        char **extra_opts, char **mount_opts, int running_bg)
+static struct pmap *
+get_mountport(struct sockaddr_in *server_addr,
+      long unsigned prog,
+      long unsigned version,
+      long unsigned proto,
+      long unsigned port)
+{
+struct pmaplist *pmap;
+static struct pmap p = {0, 0, 0, 0};
+
+server_addr->sin_port = PMAPPORT;
+pmap = pmap_getmaps(server_addr);
+
+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;
+
+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_port)
+       p.pm_port = MOUNTPORT;
+if (!p.pm_prot)
+       p.pm_prot = IPPROTO_TCP;
+return &p;
+}
+
+int nfsmount(const char *spec, const char *node, int *flags,
+            char **extra_opts, char **mount_opts, int running_bg)
 {
        static char *prev_bg_host;
        char hostdir[1024];
@@ -119,9 +266,8 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        char *hostname;
        char *dirname;
        char *old_opts;
-       char *mounthost = NULL;
+       char *mounthost=NULL;
        char new_opts[1024];
-       fhandle root_fhandle;
        struct timeval total_timeout;
        enum clnt_stat clnt_stat;
        static struct nfs_mount_data data;
@@ -130,13 +276,18 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        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;
-       struct fhstatus status;
+       union {
+               struct fhstatus nfsv2;
+               struct mountres3 nfsv3;
+       } status;
        struct stat statbuf;
        char *s;
        int port;
        int mountport;
+       int proto;
        int bg;
        int soft;
        int intr;
@@ -162,7 +313,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        mclient = NULL;
        if (strlen(spec) >= sizeof(hostdir)) {
                fprintf(stderr, _("mount: "
-                                                 "excessively long host:dir argument\n"));
+                       "excessively long host:dir argument\n"));
                goto fail;
        }
        strcpy(hostdir, spec);
@@ -175,11 +326,11 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                if ((s = strchr(hostdir, ','))) {
                        *s = '\0';
                        fprintf(stderr, _("mount: warning: "
-                                                         "multiple hostnames not supported\n"));
+                               "multiple hostnames not supported\n"));
                }
        } else {
                fprintf(stderr, _("mount: "
-                                                 "directory to mount not in host:dir format\n"));
+                       "directory to mount not in host:dir format\n"));
                goto fail;
        }
 
@@ -190,18 +341,20 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        {
                if ((hp = gethostbyname(hostname)) == NULL) {
                        fprintf(stderr, _("mount: can't get address for %s\n"),
-                                       hostname);
+                               hostname);
                        goto fail;
                } else {
                        if (hp->h_length > sizeof(struct in_addr)) {
-                               fprintf(stderr, _("mount: got bad hp->h_length\n"));
+                               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(&server_addr.sin_addr,
+                              hp->h_addr, hp->h_length);
                }
        }
 
-       memcpy(&mount_server_addr, &server_addr, sizeof(mount_server_addr));
+       memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
 
        /* add IP address to mtab options for use when unmounting */
 
@@ -210,10 +363,12 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (!old_opts)
                old_opts = "";
        if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
-               fprintf(stderr, _("mount: " "excessively long option argument\n"));
+               fprintf(stderr, _("mount: "
+                       "excessively long option argument\n"));
                goto fail;
        }
-       sprintf(new_opts, "%s%saddr=%s", old_opts, *old_opts ? "," : "", s);
+       sprintf(new_opts, "%s%saddr=%s",
+               old_opts, *old_opts ? "," : "", s);
        *extra_opts = xstrdup(new_opts);
 
        /* Set default options.
@@ -221,13 +376,13 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
         * 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;
-       data.acdirmax = 60;
+       data.retrans    = 3;
+       data.acregmin   = 3;
+       data.acregmax   = 60;
+       data.acdirmin   = 30;
+       data.acdirmax   = 60;
 #if NFS_MOUNT_VERSION >= 2
-       data.namlen = NAME_MAX;
+       data.namlen     = NAME_MAX;
 #endif
 
        bg = 0;
@@ -237,21 +392,21 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        nocto = 0;
        nolock = 0;
        noac = 0;
-       retry = 10000;                          /* 10000 minutes ~ 1 week */
+       retry = 10000;          /* 10000 minutes ~ 1 week */
        tcp = 0;
 
        mountprog = MOUNTPROG;
-       mountvers = MOUNTVERS;
+       mountvers = 0;
        port = 0;
        mountport = 0;
        nfsprog = NFS_PROGRAM;
-       nfsvers = NFS_VERSION;
+       nfsvers = 0;
 
        /* parse options */
 
        for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
                if ((opteq = strchr(opt, '='))) {
-                       val = atoi(opteq + 1);
+                       val = atoi(opteq + 1);  
                        *opteq = '\0';
                        if (!strcmp(opt, "rsize"))
                                data.rsize = val;
@@ -274,27 +429,29 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                                data.acregmax = val;
                                data.acdirmin = val;
                                data.acdirmax = val;
-                       } else if (!strcmp(opt, "retry"))
+                       }
+                       else if (!strcmp(opt, "retry"))
                                retry = val;
                        else if (!strcmp(opt, "port"))
                                port = val;
                        else if (!strcmp(opt, "mountport"))
-                               mountport = val;
+                               mountport = val;
                        else if (!strcmp(opt, "mounthost"))
-                               mounthost = xstrndup(opteq + 1,
-                                                                        strcspn(opteq + 1, " \t\n\r,"));
+                               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"))
+                       else if (!strcmp(opt, "nfsvers") ||
+                                !strcmp(opt, "vers"))
                                nfsvers = val;
                        else if (!strcmp(opt, "proto")) {
-                               if (!strncmp(opteq + 1, "tcp", 3))
+                               if (!strncmp(opteq+1, "tcp", 3))
                                        tcp = 1;
-                               else if (!strncmp(opteq + 1, "udp", 3))
+                               else if (!strncmp(opteq+1, "udp", 3))
                                        tcp = 0;
                                else
                                        printf(_("Warning: Unrecognized proto= option.\n"));
@@ -304,24 +461,24 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                                        data.namlen = val;
                                else
 #endif
-                                       printf(_
-                                                  ("Warning: Option namlen is not supported.\n"));
+                               printf(_("Warning: Option namlen is not supported.\n"));
                        } else if (!strcmp(opt, "addr"))
-                               /* ignore */ ;
+                               /* ignore */;
                        else {
                                printf(_("unknown nfs mount parameter: "
-                                                "%s=%d\n"), opt, val);
+                                      "%s=%d\n"), opt, val);
                                goto fail;
                        }
-               } else {
+               }
+               else {
                        val = 1;
                        if (!strncmp(opt, "no", 2)) {
                                val = 0;
                                opt += 2;
                        }
-                       if (!strcmp(opt, "bg"))
+                       if (!strcmp(opt, "bg")) 
                                bg = val;
-                       else if (!strcmp(opt, "fg"))
+                       else if (!strcmp(opt, "fg")) 
                                bg = !val;
                        else if (!strcmp(opt, "soft"))
                                soft = val;
@@ -343,17 +500,16 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                                if (nfs_mount_version >= 3)
                                        nolock = !val;
                                else
-                                       printf(_
-                                                  ("Warning: option nolock is not supported.\n"));
+                                       printf(_("Warning: option nolock is not supported.\n"));
                        } else {
-                               if (!sloppy) {
-                                       printf(_("unknown nfs mount option: "
-                                                        "%s%s\n"), val ? "" : "no", opt);
-                                       goto fail;
-                               }
+                               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)
@@ -367,6 +523,19 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (nfs_mount_version >= 3)
                data.flags |= (nolock ? NFS_MOUNT_NONLM : 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)
@@ -374,21 +543,22 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
 
 #ifdef NFS_MOUNT_DEBUG
        printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
-                  data.rsize, data.wsize, data.timeo, data.retrans);
+               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);
+               data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
        printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
-                  port, bg, retry, data.flags);
+               port, bg, retry, data.flags);
        printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
-                  mountprog, mountvers, nfsprog, nfsvers);
+               mountprog, mountvers, nfsprog, nfsvers);
        printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
-                  (data.flags & NFS_MOUNT_SOFT) != 0,
-                  (data.flags & NFS_MOUNT_INTR) != 0,
-                  (data.flags & NFS_MOUNT_POSIX) != 0,
-                  (data.flags & NFS_MOUNT_NOCTO) != 0,
-                  (data.flags & NFS_MOUNT_NOAC) != 0);
+               (data.flags & NFS_MOUNT_SOFT) != 0,
+               (data.flags & NFS_MOUNT_INTR) != 0,
+               (data.flags & NFS_MOUNT_POSIX) != 0,
+               (data.flags & NFS_MOUNT_NOCTO) != 0,
+               (data.flags & NFS_MOUNT_NOAC) != 0);
 #if NFS_MOUNT_VERSION >= 2
-       printf("tcp = %d\n", (data.flags & NFS_MOUNT_TCP) != 0);
+       printf("tcp = %d\n",
+               (data.flags & NFS_MOUNT_TCP) != 0);
 #endif
 #endif
 
@@ -404,7 +574,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
         * give up immediately, to avoid the initial timeout.
         */
        if (bg && !running_bg &&
-               prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
+           prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
                if (retry > 0)
                        retval = EX_BG;
                return retval;
@@ -413,24 +583,25 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        /* 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"),
-                                               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);
-                               }
-                               mount_server_addr.sin_family = AF_INET;
-                               memcpy(&mount_server_addr.sin_addr,
-                                          hp->h_addr, hp->h_length);
-                       }
-               }
+         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"),
+                                 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);
+                         }
+                         mount_server_addr.sin_family = AF_INET;
+                         memcpy(&mount_server_addr.sin_addr,
+                                hp->h_addr, hp->h_length);
+                 }
+         }
        }
 
        /*
@@ -460,7 +631,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        for (;;) {
                if (bg && stat(node, &statbuf) == -1) {
                        if (running_bg) {
-                               sleep(val);             /* 1, 2, 4, 8, 16, 30, ... */
+                               sleep(val);     /* 1, 2, 4, 8, 16, 30, ... */
                                val *= 2;
                                if (val > 30)
                                        val = 30;
@@ -470,28 +641,60 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                        if (t - prevt < 30)
                                sleep(30);
 
+                       pm_mnt = get_mountport(&mount_server_addr,
+                                      mountprog,
+                                      mountvers,
+                                      proto,
+                                      mountport);
+
                        /* contact the mount daemon via TCP */
-                       mount_server_addr.sin_port = htons(mountport);
+                       mount_server_addr.sin_port = htons(pm_mnt->pm_port);
                        msock = RPC_ANYSOCK;
-                       mclient = clnttcp_create(&mount_server_addr,
-                                                                        mountprog, mountvers, &msock, 0, 0);
 
-                       /* if this fails, contact the mount daemon via UDP */
-                       if (!mclient) {
-                               mount_server_addr.sin_port = htons(mountport);
-                               msock = RPC_ANYSOCK;
+                       switch (pm_mnt->pm_prot) {
+                       case IPPROTO_UDP:
                                mclient = clntudp_create(&mount_server_addr,
-                                                                                mountprog, mountvers,
-                                                                                retry_timeout, &msock);
+                                                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);
+                       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);
+                                                     (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 (errno != ECONNREFUSED) {
@@ -511,7 +714,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                        prevt = t;
                }
                if (!bg)
-                       goto fail;
+                       goto fail;
                if (!running_bg) {
                        prev_bg_host = xstrdup(hostname);
                        if (retry > 0)
@@ -522,21 +725,52 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
                if (t >= timeout)
                        goto fail;
        }
+       nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
 
-       if (status.fhs_status != 0) {
-               fprintf(stderr,
-                               _("mount: %s:%s failed, reason given by server: %s\n"),
-                               hostname, dirname, nfs_strerror(status.fhs_status));
-               goto fail;
+       if (nfsvers == 2) {
+               if (status.nfsv2.fhs_status != 0) {
+                       fprintf(stderr,
+                               "mount: %s:%s failed, reason given by server: %s\n",
+                               hostname, dirname,
+                               nfs_strerror(status.nfsv2.fhs_status));
+                       goto fail;
+               }
+               memcpy(data.root.data,
+                      (char *) status.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,
+                      NFS_FHSIZE);
+#endif
+       } else {
+#if NFS_MOUNT_VERSION >= 4
+               fhandle3 *fhandle;
+               if (status.nfsv3.fhs_status != 0) {
+                       fprintf(stderr,
+                               "mount: %s:%s failed, reason given by server: %s\n",
+                               hostname, dirname,
+                               nfs_strerror(status.nfsv3.fhs_status));
+                       goto fail;
+               }
+               fhandle = &status.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;
+               memcpy(data.root.data,
+                      (char *) fhandle->fhandle3_val,
+                      fhandle->fhandle3_len);
+
+               data.flags |= NFS_MOUNT_VER3;
+#endif
        }
-       memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
-                  sizeof(root_fhandle));
 
        /* create nfs socket for kernel */
 
        if (tcp) {
                if (nfs_mount_version < 3) {
-                       printf(_("NFS over TCP is not supported.\n"));
+                       printf(_("NFS over TCP is not supported.\n"));
                        goto fail;
                }
                fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -553,7 +787,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (port == 0) {
                server_addr.sin_port = PMAPPORT;
                port = pmap_getport(&server_addr, nfsprog, nfsvers,
-                                                       tcp ? IPPROTO_TCP : IPPROTO_UDP);
+                       tcp ? IPPROTO_TCP : IPPROTO_UDP);
                if (port == 0)
                        port = NFS_PORT;
 #ifdef NFS_MOUNT_DEBUG
@@ -565,14 +799,14 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        printf(_("using port %d for nfs deamon\n"), port);
 #endif
        server_addr.sin_port = htons(port);
-       /*
-        * connect() the socket for kernels 1.3.10 and below only,
-        * to avoid problems with multihomed hosts.
-        * --Swen
-        */
+        /*
+         * 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 *) &server_addr,
+                      sizeof (server_addr)) < 0) {
                perror(_("nfs connect"));
                goto fail;
        }
@@ -580,8 +814,6 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        /* prepare data structure for kernel */
 
        data.fd = fsock;
-       memcpy((char *) &data.root, (char *) &root_fhandle,
-                  sizeof(root_fhandle));
        memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
        strncpy(data.hostname, hostname, sizeof(data.hostname));
 
@@ -594,7 +826,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
 
        /* abort */
 
-  fail:
+fail:
        if (msock != -1) {
                if (mclient) {
                        auth_destroy(mclient->cl_auth);
@@ -605,7 +837,7 @@ int nfsmount(const char *spec, const char *node, unsigned long *flags,
        if (fsock != -1)
                close(fsock);
        return retval;
-}
+}      
 
 /*
  * We need to translate between nfs status return values and
@@ -624,37 +856,33 @@ static struct {
        enum nfs_stat stat;
        int errnum;
 } nfs_errtbl[] = {
-       {
-       NFS_OK, 0}, {
-       NFSERR_PERM, EPERM}, {
-       NFSERR_NOENT, ENOENT}, {
-       NFSERR_IO, EIO}, {
-       NFSERR_NXIO, ENXIO}, {
-       NFSERR_ACCES, EACCES}, {
-       NFSERR_EXIST, EEXIST}, {
-       NFSERR_NODEV, ENODEV}, {
-       NFSERR_NOTDIR, ENOTDIR}, {
-       NFSERR_ISDIR, EISDIR},
+       { NFS_OK,               0               },
+       { NFSERR_PERM,          EPERM           },
+       { NFSERR_NOENT,         ENOENT          },
+       { NFSERR_IO,            EIO             },
+       { NFSERR_NXIO,          ENXIO           },
+       { NFSERR_ACCES,         EACCES          },
+       { NFSERR_EXIST,         EEXIST          },
+       { NFSERR_NODEV,         ENODEV          },
+       { NFSERR_NOTDIR,        ENOTDIR         },
+       { NFSERR_ISDIR,         EISDIR          },
 #ifdef NFSERR_INVAL
-       {
-       NFSERR_INVAL, EINVAL},          /* that Sun forgot */
+       { NFSERR_INVAL,         EINVAL          },      /* that Sun forgot */
 #endif
-       {
-       NFSERR_FBIG, EFBIG}, {
-       NFSERR_NOSPC, ENOSPC}, {
-       NFSERR_ROFS, EROFS}, {
-       NFSERR_NAMETOOLONG, ENAMETOOLONG}, {
-       NFSERR_NOTEMPTY, ENOTEMPTY}, {
-       NFSERR_DQUOT, EDQUOT}, {
-       NFSERR_STALE, ESTALE},
+       { NFSERR_FBIG,          EFBIG           },
+       { NFSERR_NOSPC,         ENOSPC          },
+       { NFSERR_ROFS,          EROFS           },
+       { NFSERR_NAMETOOLONG,   ENAMETOOLONG    },
+       { NFSERR_NOTEMPTY,      ENOTEMPTY       },
+       { NFSERR_DQUOT,         EDQUOT          },
+       { NFSERR_STALE,         ESTALE          },
 #ifdef EWFLUSH
-       {
-       NFSERR_WFLUSH, EWFLUSH},
+       { NFSERR_WFLUSH,        EWFLUSH         },
 #endif
-               /* Throw in some NFSv3 values for even more fun (HP returns these) */
-       {
-       71, EREMOTE}, {
-       -1, EIO}
+       /* Throw in some NFSv3 values for even more fun (HP returns these) */
+       { 71,                   EREMOTE         },
+
+       { -1,                   EIO             }
 };
 
 static char *nfs_strerror(int stat)
@@ -670,621 +898,92 @@ static char *nfs_strerror(int stat)
        return buf;
 }
 
-#if 0
-int my_getport(struct in_addr server, struct timeval *timeo, ...)
+bool_t
+xdr_fhandle (XDR *xdrs, fhandle objp)
 {
-       struct sockaddr_in sin;
-       struct pmap pmap;
-       CLIENT *clnt;
-       int sock = RPC_ANYSOCK, port;
-
-       pmap.pm_prog = prog;
-       pmap.pm_vers = vers;
-       pmap.pm_prot = prot;
-       pmap.pm_port = 0;
-       sin.sin_family = AF_INET;
-       sin.sin_addr = server;
-       sin.sin_port = htons(111);
-       clnt = clntudp_create(&sin, 100000, 2, *timeo, &sock);
-       status = clnt_call(clnt, PMAP_GETPORT,
-                                          &pmap, (xdrproc_t) xdr_pmap,
-                                          &port, (xdrproc_t) xdr_uint);
-       if (status != SUCCESS) {
-               /* natter */
-               port = 0;
-       }
+       //register int32_t *buf;
 
-       clnt_destroy(clnt);
-       close(sock);
-       return port;
+        if (!xdr_opaque (xdrs, objp, FHSIZE))
+                return FALSE;
+       return TRUE;
 }
-#endif
 
-
-
-
-
-
-
-
-
-
-
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
-
-bool_t xdr_fhandle(XDR * xdrs, fhandle objp)
+bool_t
+xdr_fhstatus (XDR *xdrs, fhstatus *objp)
 {
+       //register int32_t *buf;
 
-       if (!xdr_opaque(xdrs, objp, FHSIZE)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_fhstatus(XDR * xdrs, fhstatus * objp)
-{
-
-       if (!xdr_u_int(xdrs, &objp->fhs_status)) {
-               return (FALSE);
-       }
+        if (!xdr_u_int (xdrs, &objp->fhs_status))
+                return FALSE;
        switch (objp->fhs_status) {
        case 0:
-               if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
-                       return (FALSE);
-               }
+                if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
+                        return FALSE;
                break;
        default:
                break;
        }
-       return (TRUE);
-}
-
-bool_t xdr_dirpath(XDR * xdrs, dirpath * objp)
-{
-
-       if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_name(XDR * xdrs, name * objp)
-{
-
-       if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_mountlist(XDR * xdrs, mountlist * objp)
-{
-
-       if (!xdr_pointer
-               (xdrs, (char **) objp, sizeof(struct mountbody),
-                (xdrproc_t) xdr_mountbody)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_mountbody(XDR * xdrs, mountbody * objp)
-{
-
-       if (!xdr_name(xdrs, &objp->ml_hostname)) {
-               return (FALSE);
-       }
-       if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
-               return (FALSE);
-       }
-       if (!xdr_mountlist(xdrs, &objp->ml_next)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_groups(XDR * xdrs, groups * objp)
-{
-
-       if (!xdr_pointer
-               (xdrs, (char **) objp, sizeof(struct groupnode),
-                (xdrproc_t) xdr_groupnode)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_groupnode(XDR * xdrs, groupnode * objp)
-{
-
-       if (!xdr_name(xdrs, &objp->gr_name)) {
-               return (FALSE);
-       }
-       if (!xdr_groups(xdrs, &objp->gr_next)) {
-               return (FALSE);
-       }
-       return (TRUE);
-}
-
-bool_t xdr_exports(XDR * xdrs, exports * objp)
-{
-
-       if (!xdr_pointer
-               (xdrs, (char **) objp, sizeof(struct exportnode),
-                (xdrproc_t) xdr_exportnode)) {
-               return (FALSE);
-       }
-       return (TRUE);
+       return TRUE;
 }
 
-bool_t xdr_exportnode(XDR * xdrs, exportnode * objp)
+bool_t
+xdr_dirpath (XDR *xdrs, dirpath *objp)
 {
+       //register int32_t *buf;
 
-       if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
-               return (FALSE);
-       }
-       if (!xdr_groups(xdrs, &objp->ex_groups)) {
-               return (FALSE);
-       }
-       if (!xdr_exports(xdrs, &objp->ex_next)) {
-               return (FALSE);
-       }
-       return (TRUE);
+        if (!xdr_string (xdrs, objp, MNTPATHLEN))
+                return FALSE;
+       return TRUE;
 }
 
-bool_t xdr_ppathcnf(XDR * xdrs, ppathcnf * objp)
+bool_t
+xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
 {
+       //register int32_t *buf;
 
-       register long *buf;
-
-       int i;
-
-       if (xdrs->x_op == XDR_ENCODE) {
-               buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_int(xdrs, &objp->pc_link_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_canon)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_input)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_name_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_path_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       IXDR_PUT_LONG(buf, objp->pc_link_max);
-                       IXDR_PUT_SHORT(buf, objp->pc_max_canon);
-                       IXDR_PUT_SHORT(buf, objp->pc_max_input);
-                       IXDR_PUT_SHORT(buf, objp->pc_name_max);
-                       IXDR_PUT_SHORT(buf, objp->pc_path_max);
-                       IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
-               }
-               if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
-                       return (FALSE);
-               }
-               if (!xdr_char(xdrs, &objp->pc_xxx)) {
-                       return (FALSE);
-               }
-               buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_vector
-                               (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
-                                (xdrproc_t) xdr_short)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       {
-                               register short *genp;
-
-                               for (i = 0, genp = objp->pc_mask; i < 2; i++) {
-                                       IXDR_PUT_SHORT(buf, *genp++);
-                               }
-                       };
-               }
-
-               return (TRUE);
-       } else if (xdrs->x_op == XDR_DECODE) {
-               buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_int(xdrs, &objp->pc_link_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_canon)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_max_input)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_name_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_path_max)) {
-                               return (FALSE);
-                       }
-                       if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       objp->pc_link_max = IXDR_GET_LONG(buf);
-                       objp->pc_max_canon = IXDR_GET_SHORT(buf);
-                       objp->pc_max_input = IXDR_GET_SHORT(buf);
-                       objp->pc_name_max = IXDR_GET_SHORT(buf);
-                       objp->pc_path_max = IXDR_GET_SHORT(buf);
-                       objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
-               }
-               if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
-                       return (FALSE);
-               }
-               if (!xdr_char(xdrs, &objp->pc_xxx)) {
-                       return (FALSE);
-               }
-               buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
-               if (buf == NULL) {
-                       if (!xdr_vector
-                               (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
-                                (xdrproc_t) xdr_short)) {
-                               return (FALSE);
-                       }
-
-               } else {
-                       {
-                               register short *genp;
-
-                               for (i = 0, genp = objp->pc_mask; i < 2; i++) {
-                                       *genp++ = IXDR_GET_SHORT(buf);
-                               }
-                       };
-               }
-               return (TRUE);
-       }
-
-       if (!xdr_int(xdrs, &objp->pc_link_max)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_max_canon)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_max_input)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_name_max)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_path_max)) {
-               return (FALSE);
-       }
-       if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
-               return (FALSE);
-       }
-       if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
-               return (FALSE);
-       }
-       if (!xdr_char(xdrs, &objp->pc_xxx)) {
-               return (FALSE);
-       }
-       if (!xdr_vector
-               (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
-                (xdrproc_t) xdr_short)) {
-               return (FALSE);
-       }
-       return (TRUE);
+        if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+                return FALSE;
+       return TRUE;
 }
 
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
-
-#include <string.h>                            /* for memset() */
-
-/* Default timeout can be changed using clnt_control() */
-static struct timeval TIMEOUT = { 25, 0 };
-
-void *mountproc_null_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call
-               (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
-                (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-fhstatus *mountproc_mnt_1(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static fhstatus clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-mountlist *mountproc_dump_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static mountlist clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_mountlist,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-void *mountproc_umnt_1(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-void *mountproc_umntall_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
+bool_t
+xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
 {
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
+       //register int32_t *buf;
+
+        if (!xdr_fhandle3 (xdrs, &objp->fhandle))
+                return FALSE;
+        if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
+               sizeof (int), (xdrproc_t) xdr_int))
+                return FALSE;
+       return TRUE;
 }
 
-exports *mountproc_export_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
+bool_t
+xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
 {
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_exports,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
+       //register int32_t *buf;
 
-exports *mountproc_exportall_1(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_exports,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-void *mountproc_null_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call
-               (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
-                (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
+        if (!xdr_enum (xdrs, (enum_t *) objp))
+                return FALSE;
+       return TRUE;
 }
 
-fhstatus *mountproc_mnt_2(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
+bool_t
+xdr_mountres3 (XDR *xdrs, mountres3 *objp)
 {
-       static fhstatus clnt_res;
+       //register int32_t *buf;
 
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-mountlist *mountproc_dump_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static mountlist clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp,
-                                 (xdrproc_t) xdr_mountlist, (caddr_t) & clnt_res,
-                                 TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-void *mountproc_umnt_2(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-void *mountproc_umntall_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static char clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
-                                 (caddr_t) argp, (xdrproc_t) xdr_void,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return ((void *) &clnt_res);
-}
-
-exports *mountproc_export_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
-                                 argp, (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
-                                 TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
-
-exports *mountproc_exportall_2(argp, clnt)
-void *argp;
-CLIENT *clnt;
-{
-       static exports clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp,
-                                 (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
-                                 TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
+        if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
+                return FALSE;
+       switch (objp->fhs_status) {
+       case MNT_OK:
+                if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))
+                        return FALSE;
+               break;
+       default:
+               break;
        }
-       return (&clnt_res);
+       return TRUE;
 }
 
-ppathcnf *mountproc_pathconf_2(argp, clnt)
-dirpath *argp;
-CLIENT *clnt;
-{
-       static ppathcnf clnt_res;
-
-       memset((char *) &clnt_res, 0, sizeof(clnt_res));
-       if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath,
-                                 (caddr_t) argp, (xdrproc_t) xdr_ppathcnf,
-                                 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
-               return (NULL);
-       }
-       return (&clnt_res);
-}
index 64ac617c0120e5412397497e89bf41bfcdf0a408..a12de50a11b2c3d6fb2e1cf363d6cf48b792f64e 100644 (file)
@@ -9,6 +9,11 @@
 
 #include <rpc/rpc.h>
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  * unrestricted use provided that this legend is included on all tape
 /* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
 #ifndef _rpcsvc_mount_h
 #define _rpcsvc_mount_h
+#include <asm/types.h>
+#define MOUNTPORT 635
 #define MNTPATHLEN 1024
 #define MNTNAMLEN 255
 #define FHSIZE 32
+#define FHSIZE3 64
 
 typedef char fhandle[FHSIZE];
-#ifdef __cplusplus 
-extern "C" bool_t xdr_fhandle(XDR *, fhandle);
-#elif __STDC__ 
-extern  bool_t xdr_fhandle(XDR *, fhandle);
-#else /* Old Style C */ 
-bool_t xdr_fhandle();
-#endif /* Old Style C */ 
 
+typedef struct {
+       u_int fhandle3_len;
+       char *fhandle3_val;
+} fhandle3;
+
+enum mountstat3 {
+       MNT_OK = 0,
+       MNT3ERR_PERM = 1,
+       MNT3ERR_NOENT = 2,
+       MNT3ERR_IO = 5,
+       MNT3ERR_ACCES = 13,
+       MNT3ERR_NOTDIR = 20,
+       MNT3ERR_INVAL = 22,
+       MNT3ERR_NAMETOOLONG = 63,
+       MNT3ERR_NOTSUPP = 10004,
+       MNT3ERR_SERVERFAULT = 10006,
+};
+typedef enum mountstat3 mountstat3;
 
 struct fhstatus {
        u_int fhs_status;
@@ -66,44 +85,29 @@ struct fhstatus {
        } fhstatus_u;
 };
 typedef struct fhstatus fhstatus;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
-#elif __STDC__ 
-extern  bool_t xdr_fhstatus(XDR *, fhstatus*);
-#else /* Old Style C */ 
-bool_t xdr_fhstatus();
-#endif /* Old Style C */ 
 
+struct mountres3_ok {
+       fhandle3 fhandle;
+       struct {
+               u_int auth_flavours_len;
+               int *auth_flavours_val;
+       } auth_flavours;
+};
+typedef struct mountres3_ok mountres3_ok;
 
-typedef char *dirpath;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
-#elif __STDC__ 
-extern  bool_t xdr_dirpath(XDR *, dirpath*);
-#else /* Old Style C */ 
-bool_t xdr_dirpath();
-#endif /* Old Style C */ 
+struct mountres3 {
+       mountstat3 fhs_status;
+       union {
+               mountres3_ok mountinfo;
+       } mountres3_u;
+};
+typedef struct mountres3 mountres3;
 
+typedef char *dirpath;
 
 typedef char *name;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_name(XDR *, name*);
-#elif __STDC__ 
-extern  bool_t xdr_name(XDR *, name*);
-#else /* Old Style C */ 
-bool_t xdr_name();
-#endif /* Old Style C */ 
-
 
 typedef struct mountbody *mountlist;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
-#elif __STDC__ 
-extern  bool_t xdr_mountlist(XDR *, mountlist*);
-#else /* Old Style C */ 
-bool_t xdr_mountlist();
-#endif /* Old Style C */ 
-
 
 struct mountbody {
        name ml_hostname;
@@ -111,48 +115,16 @@ struct mountbody {
        mountlist ml_next;
 };
 typedef struct mountbody mountbody;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
-#elif __STDC__ 
-extern  bool_t xdr_mountbody(XDR *, mountbody*);
-#else /* Old Style C */ 
-bool_t xdr_mountbody();
-#endif /* Old Style C */ 
-
 
 typedef struct groupnode *groups;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_groups(XDR *, groups*);
-#elif __STDC__ 
-extern  bool_t xdr_groups(XDR *, groups*);
-#else /* Old Style C */ 
-bool_t xdr_groups();
-#endif /* Old Style C */ 
-
 
 struct groupnode {
        name gr_name;
        groups gr_next;
 };
 typedef struct groupnode groupnode;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
-#elif __STDC__ 
-extern  bool_t xdr_groupnode(XDR *, groupnode*);
-#else /* Old Style C */ 
-bool_t xdr_groupnode();
-#endif /* Old Style C */ 
-
 
 typedef struct exportnode *exports;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_exports(XDR *, exports*);
-#elif __STDC__ 
-extern  bool_t xdr_exports(XDR *, exports*);
-#else /* Old Style C */ 
-bool_t xdr_exports();
-#endif /* Old Style C */ 
-
 
 struct exportnode {
        dirpath ex_dir;
@@ -160,14 +132,6 @@ struct exportnode {
        exports ex_next;
 };
 typedef struct exportnode exportnode;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
-#elif __STDC__ 
-extern  bool_t xdr_exportnode(XDR *, exportnode*);
-#else /* Old Style C */ 
-bool_t xdr_exportnode();
-#endif /* Old Style C */ 
-
 
 struct ppathcnf {
        int pc_link_max;
@@ -181,110 +145,62 @@ struct ppathcnf {
        short pc_mask[2];
 };
 typedef struct ppathcnf ppathcnf;
-#ifdef __cplusplus 
-extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#elif __STDC__ 
-extern  bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#else /* Old Style C */ 
-bool_t xdr_ppathcnf();
-#endif /* Old Style C */ 
-
 #endif /*!_rpcsvc_mount_h*/
 
-#define MOUNTPROG ((u_long)100005)
-#define MOUNTVERS ((u_long)1)
+#define MOUNTPROG 100005
+#define MOUNTVERS 1
 
-#ifdef __cplusplus
-#define MOUNTPROC_NULL ((u_long)0)
-extern "C" void * mountproc_null_1(void *, CLIENT *);
-extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern "C" void * mountproc_umntall_1(void *, CLIENT *);
-extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern "C" exports * mountproc_export_1(void *, CLIENT *);
-extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#elif __STDC__
-#define MOUNTPROC_NULL ((u_long)0)
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC_NULL 0
 extern  void * mountproc_null_1(void *, CLIENT *);
 extern  void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
+#define MOUNTPROC_MNT 1
 extern  fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
 extern  fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
+#define MOUNTPROC_DUMP 2
 extern  mountlist * mountproc_dump_1(void *, CLIENT *);
 extern  mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
+#define MOUNTPROC_UMNT 3
 extern  void * mountproc_umnt_1(dirpath *, CLIENT *);
 extern  void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
+#define MOUNTPROC_UMNTALL 4
 extern  void * mountproc_umntall_1(void *, CLIENT *);
 extern  void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
+#define MOUNTPROC_EXPORT 5
 extern  exports * mountproc_export_1(void *, CLIENT *);
 extern  exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
+#define MOUNTPROC_EXPORTALL 6
 extern  exports * mountproc_exportall_1(void *, CLIENT *);
 extern  exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
 
-#else /* Old Style C */ 
-#define MOUNTPROC_NULL ((u_long)0)
+#else /* K&R C */
+#define MOUNTPROC_NULL 0
 extern  void * mountproc_null_1();
 extern  void * mountproc_null_1_svc();
-#define MOUNTPROC_MNT ((u_long)1)
+#define MOUNTPROC_MNT 1
 extern  fhstatus * mountproc_mnt_1();
 extern  fhstatus * mountproc_mnt_1_svc();
-#define MOUNTPROC_DUMP ((u_long)2)
+#define MOUNTPROC_DUMP 2
 extern  mountlist * mountproc_dump_1();
 extern  mountlist * mountproc_dump_1_svc();
-#define MOUNTPROC_UMNT ((u_long)3)
+#define MOUNTPROC_UMNT 3
 extern  void * mountproc_umnt_1();
 extern  void * mountproc_umnt_1_svc();
-#define MOUNTPROC_UMNTALL ((u_long)4)
+#define MOUNTPROC_UMNTALL 4
 extern  void * mountproc_umntall_1();
 extern  void * mountproc_umntall_1_svc();
-#define MOUNTPROC_EXPORT ((u_long)5)
+#define MOUNTPROC_EXPORT 5
 extern  exports * mountproc_export_1();
 extern  exports * mountproc_export_1_svc();
-#define MOUNTPROC_EXPORTALL ((u_long)6)
+#define MOUNTPROC_EXPORTALL 6
 extern  exports * mountproc_exportall_1();
 extern  exports * mountproc_exportall_1_svc();
-#endif /* Old Style C */ 
-#define MOUNTVERS_POSIX ((u_long)2)
+extern int mountprog_1_freeresult ();
+#endif /* K&R C */
+#define MOUNTVERS_POSIX 2
 
-#ifdef __cplusplus
-extern "C" void * mountproc_null_2(void *, CLIENT *);
-extern "C" void * mountproc_null_2_svc(void *, struct svc_req *);
-extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern "C" mountlist * mountproc_dump_2(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern "C" void * mountproc_umntall_2(void *, CLIENT *);
-extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_export_2(void *, CLIENT *);
-extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_exportall_2(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#elif __STDC__
+#if defined(__STDC__) || defined(__cplusplus)
 extern  void * mountproc_null_2(void *, CLIENT *);
 extern  void * mountproc_null_2_svc(void *, struct svc_req *);
 extern  fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
@@ -299,11 +215,12 @@ extern  exports * mountproc_export_2(void *, CLIENT *);
 extern  exports * mountproc_export_2_svc(void *, struct svc_req *);
 extern  exports * mountproc_exportall_2(void *, CLIENT *);
 extern  exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
+#define MOUNTPROC_PATHCONF 7
 extern  ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
 extern  ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
+extern int mountprog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
 
-#else /* Old Style C */ 
+#else /* K&R C */
 extern  void * mountproc_null_2();
 extern  void * mountproc_null_2_svc();
 extern  fhstatus * mountproc_mnt_2();
@@ -318,9 +235,96 @@ extern  exports * mountproc_export_2();
 extern  exports * mountproc_export_2_svc();
 extern  exports * mountproc_exportall_2();
 extern  exports * mountproc_exportall_2_svc();
-#define MOUNTPROC_PATHCONF ((u_long)7)
+#define MOUNTPROC_PATHCONF 7
 extern  ppathcnf * mountproc_pathconf_2();
 extern  ppathcnf * mountproc_pathconf_2_svc();
-#endif /* Old Style C */ 
+extern int mountprog_2_freeresult ();
+#endif /* K&R C */
+#define MOUNT_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC3_NULL 0
+extern  void * mountproc3_null_3(void *, CLIENT *);
+extern  void * mountproc3_null_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_MNT 1
+extern  mountres3 * mountproc3_mnt_3(dirpath *, CLIENT *);
+extern  mountres3 * mountproc3_mnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_DUMP 2
+extern  mountlist * mountproc3_dump_3(void *, CLIENT *);
+extern  mountlist * mountproc3_dump_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_UMNT 3
+extern  void * mountproc3_umnt_3(dirpath *, CLIENT *);
+extern  void * mountproc3_umnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_UMNTALL 4
+extern  void * mountproc3_umntall_3(void *, CLIENT *);
+extern  void * mountproc3_umntall_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_EXPORT 5
+extern  exports * mountproc3_export_3(void *, CLIENT *);
+extern  exports * mountproc3_export_3_svc(void *, struct svc_req *);
+extern int mountprog_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define MOUNTPROC3_NULL 0
+extern  void * mountproc3_null_3();
+extern  void * mountproc3_null_3_svc();
+#define MOUNTPROC3_MNT 1
+extern  mountres3 * mountproc3_mnt_3();
+extern  mountres3 * mountproc3_mnt_3_svc();
+#define MOUNTPROC3_DUMP 2
+extern  mountlist * mountproc3_dump_3();
+extern  mountlist * mountproc3_dump_3_svc();
+#define MOUNTPROC3_UMNT 3
+extern  void * mountproc3_umnt_3();
+extern  void * mountproc3_umnt_3_svc();
+#define MOUNTPROC3_UMNTALL 4
+extern  void * mountproc3_umntall_3();
+extern  void * mountproc3_umntall_3_svc();
+#define MOUNTPROC3_EXPORT 5
+extern  exports * mountproc3_export_3();
+extern  exports * mountproc3_export_3_svc();
+extern int mountprog_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern  bool_t xdr_fhandle (XDR *, fhandle);
+extern  bool_t xdr_fhandle3 (XDR *, fhandle3*);
+extern  bool_t xdr_mountstat3 (XDR *, mountstat3*);
+extern  bool_t xdr_fhstatus (XDR *, fhstatus*);
+extern  bool_t xdr_mountres3_ok (XDR *, mountres3_ok*);
+extern  bool_t xdr_mountres3 (XDR *, mountres3*);
+extern  bool_t xdr_dirpath (XDR *, dirpath*);
+extern  bool_t xdr_name (XDR *, name*);
+extern  bool_t xdr_mountlist (XDR *, mountlist*);
+extern  bool_t xdr_mountbody (XDR *, mountbody*);
+extern  bool_t xdr_groups (XDR *, groups*);
+extern  bool_t xdr_groupnode (XDR *, groupnode*);
+extern  bool_t xdr_exports (XDR *, exports*);
+extern  bool_t xdr_exportnode (XDR *, exportnode*);
+extern  bool_t xdr_ppathcnf (XDR *, ppathcnf*);
+
+#else /* K&R C */
+extern bool_t xdr_fhandle ();
+extern bool_t xdr_fhandle3 ();
+extern bool_t xdr_mountstat3 ();
+extern bool_t xdr_fhstatus ();
+extern bool_t xdr_mountres3_ok ();
+extern bool_t xdr_mountres3 ();
+extern bool_t xdr_dirpath ();
+extern bool_t xdr_name ();
+extern bool_t xdr_mountlist ();
+extern bool_t xdr_mountbody ();
+extern bool_t xdr_groups ();
+extern bool_t xdr_groupnode ();
+extern bool_t xdr_exports ();
+extern bool_t xdr_exportnode ();
+extern bool_t xdr_ppathcnf ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* !_NFSMOUNT_H_RPCGEN */
index ef52ce2f7142f23a8e08a68783e29aa58eece441..46907e46a1400877782f46919d2742321d50734c 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -1456,6 +1456,36 @@ extern void *xmalloc(size_t size)
        return cp;
 }
 
+#if defined BB_FEATURE_NFSMOUNT
+extern char * xstrdup (const char *s) {
+       char *t;
+
+       if (s == NULL)
+               return NULL;
+
+       t = strdup (s);
+
+       if (t == NULL)
+               fatalError(memory_exhausted, "");
+
+       return t;
+}
+
+extern char * xstrndup (const char *s, int n) {
+       char *t;
+
+       if (s == NULL)
+               fatalError("xstrndup bug");
+
+       t = xmalloc(n+1);
+       strncpy(t,s,n);
+       t[n] = 0;
+
+       return t;
+}
+#endif
+
+
 #if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT)
 extern int vdprintf(int d, const char *format, va_list ap)
 {