1 /* vi: set sw=4 ts=4: */
3 * nfsmount.c -- Linux NFS mount
4 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * Wed Feb 8 12:51:48 1995, biro@yggdrasil.com (Ross Biro): allow all port
17 * numbers to be specified on the command line.
19 * Fri, 8 Mar 1996 18:01:39, Swen Thuemmler <swen@uni-paderborn.de>:
20 * Omit the call to connect() for Linux version 1.3.11 or later.
22 * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
23 * Implemented the "bg", "fg" and "retry" mount options for NFS.
25 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
26 * - added Native Language Support
28 * Modified by Olaf Kirch and Trond Myklebust for new NFS code,
33 * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
45 #include <rpc/pmap_prot.h>
46 #include <rpc/pmap_clnt.h>
47 #include <sys/socket.h>
49 #include <sys/utsname.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
54 #include <linux/nfs.h> /* For the kernels nfs stuff */
57 static const int NFS_FHSIZE = 32;
60 static const int NFS_PORT = 2049;
63 /* Disable the nls stuff */
64 # undef bindtextdomain
65 # define bindtextdomain(Domain, Directory) /* empty */
67 # define textdomain(Domain) /* empty */
68 # define _(Text) (Text)
69 # define N_(Text) (Text)
71 static const int MS_MGC_VAL = 0xc0ed0000; /* Magic number indicatng "new" flags */
72 static const int MS_RDONLY = 1; /* Mount read-only */
73 static const int MS_NOSUID = 2; /* Ignore suid and sgid bits */
74 static const int MS_NODEV = 4; /* Disallow access to device special files */
75 static const int MS_NOEXEC = 8; /* Disallow program execution */
76 static const int MS_SYNCHRONOUS = 16; /* Writes are synced at once */
77 static const int MS_REMOUNT = 32; /* Alter flags of a mounted FS */
78 static const int MS_MANDLOCK = 64; /* Allow mandatory locks on an FS */
79 static const int S_QUOTA = 128; /* Quota initialized for file/directory/symlink */
80 static const int S_APPEND = 256; /* Append-only file */
81 static const int S_IMMUTABLE = 512; /* Immutable file */
82 static const int MS_NOATIME = 1024; /* Do not update access times. */
83 static const int MS_NODIRATIME = 2048; /* Do not update directory access times */
87 * We want to be able to compile mount on old kernels in such a way
88 * that the binary will work well on more recent kernels.
89 * Thus, if necessary we teach nfsmount.c the structure of new fields
90 * that will come later.
92 * Moreover, the new kernel includes conflict with glibc includes
93 * so it is easiest to ignore the kernel altogether (at compile time).
96 static const int NFS_MOUNT_VERSION = 4;
103 unsigned char data[64];
106 struct nfs_mount_data {
109 struct nfs2_fh old_root; /* 1 */
115 int acregmin; /* 1 */
116 int acregmax; /* 1 */
117 int acdirmin; /* 1 */
118 int acdirmax; /* 1 */
119 struct sockaddr_in addr; /* 1 */
120 char hostname[256]; /* 1 */
122 unsigned int bsize; /* 3 */
123 struct nfs3_fh root; /* 4 */
126 /* bits in the flags field */
128 static const int NFS_MOUNT_SOFT = 0x0001; /* 1 */
129 static const int NFS_MOUNT_INTR = 0x0002; /* 1 */
130 static const int NFS_MOUNT_SECURE = 0x0004; /* 1 */
131 static const int NFS_MOUNT_POSIX = 0x0008; /* 1 */
132 static const int NFS_MOUNT_NOCTO = 0x0010; /* 1 */
133 static const int NFS_MOUNT_NOAC = 0x0020; /* 1 */
134 static const int NFS_MOUNT_TCP = 0x0040; /* 2 */
135 static const int NFS_MOUNT_VER3 = 0x0080; /* 3 */
136 static const int NFS_MOUNT_KERBEROS = 0x0100; /* 3 */
137 static const int NFS_MOUNT_NONLM = 0x0200; /* 3 */
140 #define UTIL_LINUX_VERSION "2.10m"
141 #define util_linux_version "util-linux-2.10m"
143 #define HAVE_inet_aton
148 #define HAVE_locale_h
149 #define HAVE_libintl_h
151 #define HAVE_langinfo_h
152 #define HAVE_progname
154 #define HAVE_nanosleep
155 #define HAVE_personality
156 #define HAVE_tm_gmtoff
158 static char *nfs_strerror(int stat);
160 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
161 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
163 static const int EX_FAIL = 32; /* mount failure */
164 static const int EX_BG = 256; /* retry in background (internal only) */
168 * nfs_mount_version according to the sources seen at compile time.
170 static int nfs_mount_version;
173 * Unfortunately, the kernel prints annoying console messages
174 * in case of an unexpected nfs mount version (instead of
175 * just returning some error). Therefore we'll have to try
176 * and figure out what version the kernel expects.
179 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
180 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
181 * nfs_mount_version: version this source and running kernel can handle
184 find_kernel_nfs_mount_version(void) {
185 static int kernel_version = 0;
190 nfs_mount_version = NFS_MOUNT_VERSION; /* default */
192 kernel_version = get_kernel_revision();
193 if (kernel_version) {
194 if (kernel_version < MAKE_VERSION(2,1,32))
195 nfs_mount_version = 1;
196 else if (kernel_version < MAKE_VERSION(2,3,99))
197 nfs_mount_version = 3;
199 nfs_mount_version = 4; /* since 2.3.99pre4 */
201 if (nfs_mount_version > NFS_MOUNT_VERSION)
202 nfs_mount_version = NFS_MOUNT_VERSION;
206 get_mountport(struct sockaddr_in *server_addr,
208 long unsigned version,
212 struct pmaplist *pmap;
213 static struct pmap p = {0, 0, 0, 0};
215 server_addr->sin_port = PMAPPORT;
216 pmap = pmap_getmaps(server_addr);
218 if (version > MAX_NFSPROT)
219 version = MAX_NFSPROT;
228 if (pmap->pml_map.pm_prog != prog)
230 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
232 if (version > 2 && pmap->pml_map.pm_vers != version)
234 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
236 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
237 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
238 (port && pmap->pml_map.pm_port != port))
240 memcpy(&p, &pmap->pml_map, sizeof(p));
242 pmap = pmap->pml_next;
245 p.pm_vers = MOUNTVERS;
247 p.pm_port = MOUNTPORT;
249 p.pm_prot = IPPROTO_TCP;
253 int nfsmount(const char *spec, const char *node, int *flags,
254 char **extra_opts, char **mount_opts, int running_bg)
256 static char *prev_bg_host;
262 char *mounthost=NULL;
264 struct timeval total_timeout;
265 enum clnt_stat clnt_stat;
266 static struct nfs_mount_data data;
270 struct sockaddr_in server_addr;
271 struct sockaddr_in mount_server_addr;
274 struct timeval retry_timeout;
276 struct fhstatus nfsv2;
277 struct mountres3 nfsv3;
302 find_kernel_nfs_mount_version();
307 if (strlen(spec) >= sizeof(hostdir)) {
308 error_msg("excessively long host:dir argument\n");
311 strcpy(hostdir, spec);
312 if ((s = strchr(hostdir, ':'))) {
316 /* Ignore all but first hostname in replicated mounts
317 until they can be fully supported. (mack@sgi.com) */
318 if ((s = strchr(hostdir, ','))) {
320 error_msg("warning: multiple hostnames not supported\n");
323 error_msg("directory to mount not in host:dir format\n");
327 server_addr.sin_family = AF_INET;
328 #ifdef HAVE_inet_aton
329 if (!inet_aton(hostname, &server_addr.sin_addr))
332 if ((hp = gethostbyname(hostname)) == NULL) {
333 error_msg("can't get address for %s\n", hostname);
336 if (hp->h_length > sizeof(struct in_addr)) {
337 error_msg("got bad hp->h_length\n");
338 hp->h_length = sizeof(struct in_addr);
340 memcpy(&server_addr.sin_addr,
341 hp->h_addr, hp->h_length);
345 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
347 /* add IP address to mtab options for use when unmounting */
349 s = inet_ntoa(server_addr.sin_addr);
350 old_opts = *extra_opts;
353 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
354 error_msg("excessively long option argument\n");
357 sprintf(new_opts, "%s%saddr=%s",
358 old_opts, *old_opts ? "," : "", s);
359 *extra_opts = xstrdup(new_opts);
361 /* Set default options.
362 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
363 * let the kernel decide.
364 * timeo is filled in after we know whether it'll be TCP or UDP. */
365 memset(&data, 0, sizeof(data));
371 #if NFS_MOUNT_VERSION >= 2
372 data.namlen = NAME_MAX;
382 retry = 10000; /* 10000 minutes ~ 1 week */
385 mountprog = MOUNTPROG;
389 nfsprog = NFS_PROGRAM;
394 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
395 if ((opteq = strchr(opt, '='))) {
396 val = atoi(opteq + 1);
398 if (!strcmp(opt, "rsize"))
400 else if (!strcmp(opt, "wsize"))
402 else if (!strcmp(opt, "timeo"))
404 else if (!strcmp(opt, "retrans"))
406 else if (!strcmp(opt, "acregmin"))
408 else if (!strcmp(opt, "acregmax"))
410 else if (!strcmp(opt, "acdirmin"))
412 else if (!strcmp(opt, "acdirmax"))
414 else if (!strcmp(opt, "actimeo")) {
420 else if (!strcmp(opt, "retry"))
422 else if (!strcmp(opt, "port"))
424 else if (!strcmp(opt, "mountport"))
426 else if (!strcmp(opt, "mounthost"))
427 mounthost=xstrndup(opteq+1,
428 strcspn(opteq+1," \t\n\r,"));
429 else if (!strcmp(opt, "mountprog"))
431 else if (!strcmp(opt, "mountvers"))
433 else if (!strcmp(opt, "nfsprog"))
435 else if (!strcmp(opt, "nfsvers") ||
436 !strcmp(opt, "vers"))
438 else if (!strcmp(opt, "proto")) {
439 if (!strncmp(opteq+1, "tcp", 3))
441 else if (!strncmp(opteq+1, "udp", 3))
444 printf(_("Warning: Unrecognized proto= option.\n"));
445 } else if (!strcmp(opt, "namlen")) {
446 #if NFS_MOUNT_VERSION >= 2
447 if (nfs_mount_version >= 2)
451 printf(_("Warning: Option namlen is not supported.\n"));
452 } else if (!strcmp(opt, "addr"))
455 printf(_("unknown nfs mount parameter: "
456 "%s=%d\n"), opt, val);
462 if (!strncmp(opt, "no", 2)) {
466 if (!strcmp(opt, "bg"))
468 else if (!strcmp(opt, "fg"))
470 else if (!strcmp(opt, "soft"))
472 else if (!strcmp(opt, "hard"))
474 else if (!strcmp(opt, "intr"))
476 else if (!strcmp(opt, "posix"))
478 else if (!strcmp(opt, "cto"))
480 else if (!strcmp(opt, "ac"))
482 else if (!strcmp(opt, "tcp"))
484 else if (!strcmp(opt, "udp"))
486 else if (!strcmp(opt, "lock")) {
487 if (nfs_mount_version >= 3)
490 printf(_("Warning: option nolock is not supported.\n"));
492 printf(_("unknown nfs mount option: "
493 "%s%s\n"), val ? "" : "no", opt);
498 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
500 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
501 | (intr ? NFS_MOUNT_INTR : 0)
502 | (posix ? NFS_MOUNT_POSIX : 0)
503 | (nocto ? NFS_MOUNT_NOCTO : 0)
504 | (noac ? NFS_MOUNT_NOAC : 0);
505 #if NFS_MOUNT_VERSION >= 2
506 if (nfs_mount_version >= 2)
507 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
509 #if NFS_MOUNT_VERSION >= 3
510 if (nfs_mount_version >= 3)
511 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
513 if (nfsvers > MAX_NFSPROT) {
514 error_msg("NFSv%d not supported!\n", nfsvers);
517 if (mountvers > MAX_NFSPROT) {
518 error_msg("NFSv%d not supported!\n", nfsvers);
521 if (nfsvers && !mountvers)
522 mountvers = (nfsvers < 3) ? 1 : nfsvers;
523 if (nfsvers && nfsvers < mountvers) {
527 /* Adjust options if none specified */
529 data.timeo = tcp ? 70 : 7;
531 #ifdef NFS_MOUNT_DEBUG
532 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
533 data.rsize, data.wsize, data.timeo, data.retrans);
534 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
535 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
536 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
537 port, bg, retry, data.flags);
538 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
539 mountprog, mountvers, nfsprog, nfsvers);
540 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
541 (data.flags & NFS_MOUNT_SOFT) != 0,
542 (data.flags & NFS_MOUNT_INTR) != 0,
543 (data.flags & NFS_MOUNT_POSIX) != 0,
544 (data.flags & NFS_MOUNT_NOCTO) != 0,
545 (data.flags & NFS_MOUNT_NOAC) != 0);
546 #if NFS_MOUNT_VERSION >= 2
548 (data.flags & NFS_MOUNT_TCP) != 0);
552 data.version = nfs_mount_version;
553 *mount_opts = (char *) &data;
555 if (*flags & MS_REMOUNT)
559 * If the previous mount operation on the same host was
560 * backgrounded, and the "bg" for this mount is also set,
561 * give up immediately, to avoid the initial timeout.
563 if (bg && !running_bg &&
564 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
570 /* create mount deamon client */
571 /* See if the nfs host = mount host. */
573 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
574 mount_server_addr.sin_family = AF_INET;
575 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
577 if ((hp = gethostbyname(mounthost)) == NULL) {
578 error_msg("can't get address for %s\n", hostname);
581 if (hp->h_length > sizeof(struct in_addr)) {
582 error_msg("got bad hp->h_length?\n");
583 hp->h_length = sizeof(struct in_addr);
585 mount_server_addr.sin_family = AF_INET;
586 memcpy(&mount_server_addr.sin_addr,
587 hp->h_addr, hp->h_length);
593 * The following loop implements the mount retries. On the first
594 * call, "running_bg" is 0. When the mount times out, and the
595 * "bg" option is set, the exit status EX_BG will be returned.
596 * For a backgrounded mount, there will be a second call by the
597 * child process with "running_bg" set to 1.
599 * The case where the mount point is not present and the "bg"
600 * option is set, is treated as a timeout. This is done to
601 * support nested mounts.
603 * The "retry" count specified by the user is the number of
604 * minutes to retry before giving up.
606 * Only the first error message will be displayed.
608 retry_timeout.tv_sec = 3;
609 retry_timeout.tv_usec = 0;
610 total_timeout.tv_sec = 20;
611 total_timeout.tv_usec = 0;
612 timeout = time(NULL) + 60 * retry;
617 if (bg && stat(node, &statbuf) == -1) {
619 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
625 /* be careful not to use too many CPU cycles */
629 pm_mnt = get_mountport(&mount_server_addr,
635 /* contact the mount daemon via TCP */
636 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
639 switch (pm_mnt->pm_prot) {
641 mclient = clntudp_create(&mount_server_addr,
648 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
651 mclient = clnttcp_create(&mount_server_addr,
660 /* try to mount hostname:dirname */
661 mclient->cl_auth = authunix_create_default();
663 /* make pointers in xdr_mountres3 NULL so
664 * that xdr_array allocates memory for us
666 memset(&status, 0, sizeof(status));
668 if (pm_mnt->pm_vers == 3)
669 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
670 (xdrproc_t) xdr_dirpath,
672 (xdrproc_t) xdr_mountres3,
676 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
677 (xdrproc_t) xdr_dirpath,
679 (xdrproc_t) xdr_fhstatus,
683 if (clnt_stat == RPC_SUCCESS)
684 break; /* we're done */
685 if (errno != ECONNREFUSED) {
686 clnt_perror(mclient, "mount");
687 goto fail; /* don't retry */
689 if (!running_bg && prevt == 0)
690 clnt_perror(mclient, "mount");
691 auth_destroy(mclient->cl_auth);
692 clnt_destroy(mclient);
696 if (!running_bg && prevt == 0)
697 clnt_pcreateerror("mount");
704 prev_bg_host = xstrdup(hostname);
713 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
716 if (status.nfsv2.fhs_status != 0) {
717 error_msg("%s:%s failed, reason given by server: %s\n",
719 nfs_strerror(status.nfsv2.fhs_status));
722 memcpy(data.root.data,
723 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
725 #if NFS_MOUNT_VERSION >= 4
726 data.root.size = NFS_FHSIZE;
727 memcpy(data.old_root.data,
728 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
732 #if NFS_MOUNT_VERSION >= 4
734 if (status.nfsv3.fhs_status != 0) {
735 error_msg("%s:%s failed, reason given by server: %s\n",
737 nfs_strerror(status.nfsv3.fhs_status));
740 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
741 memset(data.old_root.data, 0, NFS_FHSIZE);
742 memset(&data.root, 0, sizeof(data.root));
743 data.root.size = fhandle->fhandle3_len;
744 memcpy(data.root.data,
745 (char *) fhandle->fhandle3_val,
746 fhandle->fhandle3_len);
748 data.flags |= NFS_MOUNT_VER3;
752 /* create nfs socket for kernel */
755 if (nfs_mount_version < 3) {
756 printf(_("NFS over TCP is not supported.\n"));
759 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
761 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
763 perror(_("nfs socket"));
766 if (bindresvport(fsock, 0) < 0) {
767 perror(_("nfs bindresvport"));
771 server_addr.sin_port = PMAPPORT;
772 port = pmap_getport(&server_addr, nfsprog, nfsvers,
773 tcp ? IPPROTO_TCP : IPPROTO_UDP);
776 #ifdef NFS_MOUNT_DEBUG
778 printf(_("used portmapper to find NFS port\n"));
781 #ifdef NFS_MOUNT_DEBUG
782 printf(_("using port %d for nfs deamon\n"), port);
784 server_addr.sin_port = htons(port);
786 * connect() the socket for kernels 1.3.10 and below only,
787 * to avoid problems with multihomed hosts.
790 if (get_kernel_revision() <= 66314
791 && connect(fsock, (struct sockaddr *) &server_addr,
792 sizeof (server_addr)) < 0) {
793 perror(_("nfs connect"));
797 /* prepare data structure for kernel */
800 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
801 strncpy(data.hostname, hostname, sizeof(data.hostname));
805 auth_destroy(mclient->cl_auth);
806 clnt_destroy(mclient);
815 auth_destroy(mclient->cl_auth);
816 clnt_destroy(mclient);
826 * We need to translate between nfs status return values and
827 * the local errno values which may not be the same.
829 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
830 * "after #include <errno.h> the symbol errno is reserved for any use,
831 * it cannot even be used as a struct tag or field name".
835 #define EDQUOT ENOSPC
843 { NFSERR_PERM, EPERM },
844 { NFSERR_NOENT, ENOENT },
846 { NFSERR_NXIO, ENXIO },
847 { NFSERR_ACCES, EACCES },
848 { NFSERR_EXIST, EEXIST },
849 { NFSERR_NODEV, ENODEV },
850 { NFSERR_NOTDIR, ENOTDIR },
851 { NFSERR_ISDIR, EISDIR },
853 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
855 { NFSERR_FBIG, EFBIG },
856 { NFSERR_NOSPC, ENOSPC },
857 { NFSERR_ROFS, EROFS },
858 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
859 { NFSERR_NOTEMPTY, ENOTEMPTY },
860 { NFSERR_DQUOT, EDQUOT },
861 { NFSERR_STALE, ESTALE },
863 { NFSERR_WFLUSH, EWFLUSH },
865 /* Throw in some NFSv3 values for even more fun (HP returns these) */
871 static char *nfs_strerror(int stat)
874 static char buf[256];
876 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
877 if (nfs_errtbl[i].stat == stat)
878 return strerror(nfs_errtbl[i].errnum);
880 sprintf(buf, _("unknown nfs status return value: %d"), stat);
885 xdr_fhandle (XDR *xdrs, fhandle objp)
887 //register int32_t *buf;
889 if (!xdr_opaque (xdrs, objp, FHSIZE))
895 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
897 //register int32_t *buf;
899 if (!xdr_u_int (xdrs, &objp->fhs_status))
901 switch (objp->fhs_status) {
903 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
913 xdr_dirpath (XDR *xdrs, dirpath *objp)
915 //register int32_t *buf;
917 if (!xdr_string (xdrs, objp, MNTPATHLEN))
923 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
925 //register int32_t *buf;
927 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
933 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
935 //register int32_t *buf;
937 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
939 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
940 sizeof (int), (xdrproc_t) xdr_int))
946 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
948 //register int32_t *buf;
950 if (!xdr_enum (xdrs, (enum_t *) objp))
956 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
958 //register int32_t *buf;
960 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
962 switch (objp->fhs_status) {
964 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))