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
41 #include <sys/socket.h>
43 #include <sys/utsname.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
51 #include <rpc/pmap_prot.h>
52 #include <rpc/pmap_clnt.h>
53 #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 /* NOTE: Do not make this into a 'static const int' because the pre-processor
97 * needs to test this value in some #if statements. */
98 #define NFS_MOUNT_VERSION 4
105 unsigned char data[64];
108 struct nfs_mount_data {
111 struct nfs2_fh old_root; /* 1 */
117 int acregmin; /* 1 */
118 int acregmax; /* 1 */
119 int acdirmin; /* 1 */
120 int acdirmax; /* 1 */
121 struct sockaddr_in addr; /* 1 */
122 char hostname[256]; /* 1 */
124 unsigned int bsize; /* 3 */
125 struct nfs3_fh root; /* 4 */
128 /* bits in the flags field */
130 static const int NFS_MOUNT_SOFT = 0x0001; /* 1 */
131 static const int NFS_MOUNT_INTR = 0x0002; /* 1 */
132 static const int NFS_MOUNT_SECURE = 0x0004; /* 1 */
133 static const int NFS_MOUNT_POSIX = 0x0008; /* 1 */
134 static const int NFS_MOUNT_NOCTO = 0x0010; /* 1 */
135 static const int NFS_MOUNT_NOAC = 0x0020; /* 1 */
136 static const int NFS_MOUNT_TCP = 0x0040; /* 2 */
137 static const int NFS_MOUNT_VER3 = 0x0080; /* 3 */
138 static const int NFS_MOUNT_KERBEROS = 0x0100; /* 3 */
139 static const int NFS_MOUNT_NONLM = 0x0200; /* 3 */
142 #define UTIL_LINUX_VERSION "2.10m"
143 #define util_linux_version "util-linux-2.10m"
145 #define HAVE_inet_aton
150 #define HAVE_locale_h
151 #define HAVE_libintl_h
153 #define HAVE_langinfo_h
154 #define HAVE_progname
156 #define HAVE_nanosleep
157 #define HAVE_personality
158 #define HAVE_tm_gmtoff
160 static char *nfs_strerror(int status);
162 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
163 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
165 static const int EX_FAIL = 32; /* mount failure */
166 static const int EX_BG = 256; /* retry in background (internal only) */
170 * nfs_mount_version according to the sources seen at compile time.
172 static int nfs_mount_version;
175 * Unfortunately, the kernel prints annoying console messages
176 * in case of an unexpected nfs mount version (instead of
177 * just returning some error). Therefore we'll have to try
178 * and figure out what version the kernel expects.
181 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
182 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
183 * nfs_mount_version: version this source and running kernel can handle
186 find_kernel_nfs_mount_version(void)
188 static int kernel_version = 0;
193 nfs_mount_version = NFS_MOUNT_VERSION; /* default */
195 kernel_version = get_kernel_revision();
196 if (kernel_version) {
197 if (kernel_version < MAKE_VERSION(2,1,32))
198 nfs_mount_version = 1;
199 else if (kernel_version < MAKE_VERSION(2,2,18) ||
200 (kernel_version >= MAKE_VERSION(2,3,0) &&
201 kernel_version < MAKE_VERSION(2,3,99)))
202 nfs_mount_version = 3;
204 nfs_mount_version = 4; /* since 2.3.99pre4 */
206 if (nfs_mount_version > NFS_MOUNT_VERSION)
207 nfs_mount_version = NFS_MOUNT_VERSION;
211 get_mountport(struct sockaddr_in *server_addr,
213 long unsigned version,
217 struct pmaplist *pmap;
218 static struct pmap p = {0, 0, 0, 0};
220 server_addr->sin_port = PMAPPORT;
221 pmap = pmap_getmaps(server_addr);
223 if (version > MAX_NFSPROT)
224 version = MAX_NFSPROT;
233 if (pmap->pml_map.pm_prog != prog)
235 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
237 if (version > 2 && pmap->pml_map.pm_vers != version)
239 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
241 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
242 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
243 (port && pmap->pml_map.pm_port != port))
245 memcpy(&p, &pmap->pml_map, sizeof(p));
247 pmap = pmap->pml_next;
250 p.pm_vers = MOUNTVERS;
252 p.pm_port = MOUNTPORT;
254 p.pm_prot = IPPROTO_TCP;
258 int nfsmount(const char *spec, const char *node, int *flags,
259 char **extra_opts, char **mount_opts, int running_bg)
261 static char *prev_bg_host;
267 char *mounthost=NULL;
269 struct timeval total_timeout;
270 enum clnt_stat clnt_stat;
271 static struct nfs_mount_data data;
275 struct sockaddr_in server_addr;
276 struct sockaddr_in mount_server_addr;
279 struct timeval retry_timeout;
281 struct fhstatus nfsv2;
282 struct mountres3 nfsv3;
307 find_kernel_nfs_mount_version();
312 if (strlen(spec) >= sizeof(hostdir)) {
313 error_msg("excessively long host:dir argument");
316 strcpy(hostdir, spec);
317 if ((s = strchr(hostdir, ':'))) {
321 /* Ignore all but first hostname in replicated mounts
322 until they can be fully supported. (mack@sgi.com) */
323 if ((s = strchr(hostdir, ','))) {
325 error_msg("warning: multiple hostnames not supported");
328 error_msg("directory to mount not in host:dir format");
332 server_addr.sin_family = AF_INET;
333 #ifdef HAVE_inet_aton
334 if (!inet_aton(hostname, &server_addr.sin_addr))
337 if ((hp = gethostbyname(hostname)) == NULL) {
338 herror_msg("%s", hostname);
341 if (hp->h_length > sizeof(struct in_addr)) {
342 error_msg("got bad hp->h_length");
343 hp->h_length = sizeof(struct in_addr);
345 memcpy(&server_addr.sin_addr,
346 hp->h_addr, hp->h_length);
350 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
352 /* add IP address to mtab options for use when unmounting */
354 s = inet_ntoa(server_addr.sin_addr);
355 old_opts = *extra_opts;
358 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
359 error_msg("excessively long option argument");
362 sprintf(new_opts, "%s%saddr=%s",
363 old_opts, *old_opts ? "," : "", s);
364 *extra_opts = xstrdup(new_opts);
366 /* Set default options.
367 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
368 * let the kernel decide.
369 * timeo is filled in after we know whether it'll be TCP or UDP. */
370 memset(&data, 0, sizeof(data));
376 #if NFS_MOUNT_VERSION >= 2
377 data.namlen = NAME_MAX;
387 retry = 10000; /* 10000 minutes ~ 1 week */
390 mountprog = MOUNTPROG;
394 nfsprog = NFS_PROGRAM;
399 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
400 if ((opteq = strchr(opt, '='))) {
401 val = atoi(opteq + 1);
403 if (!strcmp(opt, "rsize"))
405 else if (!strcmp(opt, "wsize"))
407 else if (!strcmp(opt, "timeo"))
409 else if (!strcmp(opt, "retrans"))
411 else if (!strcmp(opt, "acregmin"))
413 else if (!strcmp(opt, "acregmax"))
415 else if (!strcmp(opt, "acdirmin"))
417 else if (!strcmp(opt, "acdirmax"))
419 else if (!strcmp(opt, "actimeo")) {
425 else if (!strcmp(opt, "retry"))
427 else if (!strcmp(opt, "port"))
429 else if (!strcmp(opt, "mountport"))
431 else if (!strcmp(opt, "mounthost"))
432 mounthost=xstrndup(opteq+1,
433 strcspn(opteq+1," \t\n\r,"));
434 else if (!strcmp(opt, "mountprog"))
436 else if (!strcmp(opt, "mountvers"))
438 else if (!strcmp(opt, "nfsprog"))
440 else if (!strcmp(opt, "nfsvers") ||
441 !strcmp(opt, "vers"))
443 else if (!strcmp(opt, "proto")) {
444 if (!strncmp(opteq+1, "tcp", 3))
446 else if (!strncmp(opteq+1, "udp", 3))
449 printf(_("Warning: Unrecognized proto= option.\n"));
450 } else if (!strcmp(opt, "namlen")) {
451 #if NFS_MOUNT_VERSION >= 2
452 if (nfs_mount_version >= 2)
456 printf(_("Warning: Option namlen is not supported.\n"));
457 } else if (!strcmp(opt, "addr"))
460 printf(_("unknown nfs mount parameter: "
461 "%s=%d\n"), opt, val);
467 if (!strncmp(opt, "no", 2)) {
471 if (!strcmp(opt, "bg"))
473 else if (!strcmp(opt, "fg"))
475 else if (!strcmp(opt, "soft"))
477 else if (!strcmp(opt, "hard"))
479 else if (!strcmp(opt, "intr"))
481 else if (!strcmp(opt, "posix"))
483 else if (!strcmp(opt, "cto"))
485 else if (!strcmp(opt, "ac"))
487 else if (!strcmp(opt, "tcp"))
489 else if (!strcmp(opt, "udp"))
491 else if (!strcmp(opt, "lock")) {
492 if (nfs_mount_version >= 3)
495 printf(_("Warning: option nolock is not supported.\n"));
497 printf(_("unknown nfs mount option: "
498 "%s%s\n"), val ? "" : "no", opt);
503 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
505 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
506 | (intr ? NFS_MOUNT_INTR : 0)
507 | (posix ? NFS_MOUNT_POSIX : 0)
508 | (nocto ? NFS_MOUNT_NOCTO : 0)
509 | (noac ? NFS_MOUNT_NOAC : 0);
510 #if NFS_MOUNT_VERSION >= 2
511 if (nfs_mount_version >= 2)
512 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
514 #if NFS_MOUNT_VERSION >= 3
515 if (nfs_mount_version >= 3)
516 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
518 if (nfsvers > MAX_NFSPROT) {
519 error_msg("NFSv%d not supported!", nfsvers);
522 if (mountvers > MAX_NFSPROT) {
523 error_msg("NFSv%d not supported!", nfsvers);
526 if (nfsvers && !mountvers)
527 mountvers = (nfsvers < 3) ? 1 : nfsvers;
528 if (nfsvers && nfsvers < mountvers) {
532 /* Adjust options if none specified */
534 data.timeo = tcp ? 70 : 7;
536 #ifdef NFS_MOUNT_DEBUG
537 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
538 data.rsize, data.wsize, data.timeo, data.retrans);
539 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
540 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
541 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
542 port, bg, retry, data.flags);
543 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
544 mountprog, mountvers, nfsprog, nfsvers);
545 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
546 (data.flags & NFS_MOUNT_SOFT) != 0,
547 (data.flags & NFS_MOUNT_INTR) != 0,
548 (data.flags & NFS_MOUNT_POSIX) != 0,
549 (data.flags & NFS_MOUNT_NOCTO) != 0,
550 (data.flags & NFS_MOUNT_NOAC) != 0);
551 #if NFS_MOUNT_VERSION >= 2
553 (data.flags & NFS_MOUNT_TCP) != 0);
557 data.version = nfs_mount_version;
558 *mount_opts = (char *) &data;
560 if (*flags & MS_REMOUNT)
564 * If the previous mount operation on the same host was
565 * backgrounded, and the "bg" for this mount is also set,
566 * give up immediately, to avoid the initial timeout.
568 if (bg && !running_bg &&
569 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
575 /* create mount deamon client */
576 /* See if the nfs host = mount host. */
578 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
579 mount_server_addr.sin_family = AF_INET;
580 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
582 if ((hp = gethostbyname(mounthost)) == NULL) {
583 herror_msg("%s", mounthost);
586 if (hp->h_length > sizeof(struct in_addr)) {
587 error_msg("got bad hp->h_length?");
588 hp->h_length = sizeof(struct in_addr);
590 mount_server_addr.sin_family = AF_INET;
591 memcpy(&mount_server_addr.sin_addr,
592 hp->h_addr, hp->h_length);
598 * The following loop implements the mount retries. On the first
599 * call, "running_bg" is 0. When the mount times out, and the
600 * "bg" option is set, the exit status EX_BG will be returned.
601 * For a backgrounded mount, there will be a second call by the
602 * child process with "running_bg" set to 1.
604 * The case where the mount point is not present and the "bg"
605 * option is set, is treated as a timeout. This is done to
606 * support nested mounts.
608 * The "retry" count specified by the user is the number of
609 * minutes to retry before giving up.
611 * Only the first error message will be displayed.
613 retry_timeout.tv_sec = 3;
614 retry_timeout.tv_usec = 0;
615 total_timeout.tv_sec = 20;
616 total_timeout.tv_usec = 0;
617 timeout = time(NULL) + 60 * retry;
622 if (bg && stat(node, &statbuf) == -1) {
624 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
630 /* be careful not to use too many CPU cycles */
634 pm_mnt = get_mountport(&mount_server_addr,
640 /* contact the mount daemon via TCP */
641 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
644 switch (pm_mnt->pm_prot) {
646 mclient = clntudp_create(&mount_server_addr,
653 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
656 mclient = clnttcp_create(&mount_server_addr,
665 /* try to mount hostname:pathname */
666 mclient->cl_auth = authunix_create_default();
668 /* make pointers in xdr_mountres3 NULL so
669 * that xdr_array allocates memory for us
671 memset(&status, 0, sizeof(status));
673 if (pm_mnt->pm_vers == 3)
674 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
675 (xdrproc_t) xdr_dirpath,
677 (xdrproc_t) xdr_mountres3,
681 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
682 (xdrproc_t) xdr_dirpath,
684 (xdrproc_t) xdr_fhstatus,
688 if (clnt_stat == RPC_SUCCESS)
689 break; /* we're done */
690 if (errno != ECONNREFUSED) {
691 clnt_perror(mclient, "mount");
692 goto fail; /* don't retry */
694 if (!running_bg && prevt == 0)
695 clnt_perror(mclient, "mount");
696 auth_destroy(mclient->cl_auth);
697 clnt_destroy(mclient);
701 if (!running_bg && prevt == 0)
702 clnt_pcreateerror("mount");
709 prev_bg_host = xstrdup(hostname);
718 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
721 if (status.nfsv2.fhs_status != 0) {
722 error_msg("%s:%s failed, reason given by server: %s",
724 nfs_strerror(status.nfsv2.fhs_status));
727 memcpy(data.root.data,
728 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
730 #if NFS_MOUNT_VERSION >= 4
731 data.root.size = NFS_FHSIZE;
732 memcpy(data.old_root.data,
733 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
737 #if NFS_MOUNT_VERSION >= 4
738 fhandle3 *my_fhandle;
739 if (status.nfsv3.fhs_status != 0) {
740 error_msg("%s:%s failed, reason given by server: %s",
742 nfs_strerror(status.nfsv3.fhs_status));
745 my_fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
746 memset(data.old_root.data, 0, NFS_FHSIZE);
747 memset(&data.root, 0, sizeof(data.root));
748 data.root.size = my_fhandle->fhandle3_len;
749 memcpy(data.root.data,
750 (char *) my_fhandle->fhandle3_val,
751 my_fhandle->fhandle3_len);
753 data.flags |= NFS_MOUNT_VER3;
757 /* create nfs socket for kernel */
760 if (nfs_mount_version < 3) {
761 printf(_("NFS over TCP is not supported.\n"));
764 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
766 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
768 perror(_("nfs socket"));
771 if (bindresvport(fsock, 0) < 0) {
772 perror(_("nfs bindresvport"));
776 server_addr.sin_port = PMAPPORT;
777 port = pmap_getport(&server_addr, nfsprog, nfsvers,
778 tcp ? IPPROTO_TCP : IPPROTO_UDP);
781 #ifdef NFS_MOUNT_DEBUG
783 printf(_("used portmapper to find NFS port\n"));
786 #ifdef NFS_MOUNT_DEBUG
787 printf(_("using port %d for nfs deamon\n"), port);
789 server_addr.sin_port = htons(port);
791 * connect() the socket for kernels 1.3.10 and below only,
792 * to avoid problems with multihomed hosts.
795 if (get_kernel_revision() <= 66314
796 && connect(fsock, (struct sockaddr *) &server_addr,
797 sizeof (server_addr)) < 0) {
798 perror(_("nfs connect"));
802 /* prepare data structure for kernel */
805 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
806 strncpy(data.hostname, hostname, sizeof(data.hostname));
810 auth_destroy(mclient->cl_auth);
811 clnt_destroy(mclient);
820 auth_destroy(mclient->cl_auth);
821 clnt_destroy(mclient);
831 * We need to translate between nfs status return values and
832 * the local errno values which may not be the same.
834 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
835 * "after #include <errno.h> the symbol errno is reserved for any use,
836 * it cannot even be used as a struct tag or field name".
840 #define EDQUOT ENOSPC
848 { NFSERR_PERM, EPERM },
849 { NFSERR_NOENT, ENOENT },
851 { NFSERR_NXIO, ENXIO },
852 { NFSERR_ACCES, EACCES },
853 { NFSERR_EXIST, EEXIST },
854 { NFSERR_NODEV, ENODEV },
855 { NFSERR_NOTDIR, ENOTDIR },
856 { NFSERR_ISDIR, EISDIR },
858 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
860 { NFSERR_FBIG, EFBIG },
861 { NFSERR_NOSPC, ENOSPC },
862 { NFSERR_ROFS, EROFS },
863 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
864 { NFSERR_NOTEMPTY, ENOTEMPTY },
865 { NFSERR_DQUOT, EDQUOT },
866 { NFSERR_STALE, ESTALE },
868 { NFSERR_WFLUSH, EWFLUSH },
870 /* Throw in some NFSv3 values for even more fun (HP returns these) */
876 static char *nfs_strerror(int status)
879 static char buf[256];
881 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
882 if (nfs_errtbl[i].stat == status)
883 return strerror(nfs_errtbl[i].errnum);
885 sprintf(buf, _("unknown nfs status return value: %d"), status);
890 xdr_fhandle (XDR *xdrs, fhandle objp)
892 //register int32_t *buf;
894 if (!xdr_opaque (xdrs, objp, FHSIZE))
900 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
902 //register int32_t *buf;
904 if (!xdr_u_int (xdrs, &objp->fhs_status))
906 switch (objp->fhs_status) {
908 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
918 xdr_dirpath (XDR *xdrs, dirpath *objp)
920 //register int32_t *buf;
922 if (!xdr_string (xdrs, objp, MNTPATHLEN))
928 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
930 //register int32_t *buf;
932 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
938 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
940 //register int32_t *buf;
942 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
944 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
945 sizeof (int), (xdrproc_t) xdr_int))
951 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
953 //register int32_t *buf;
955 if (!xdr_enum (xdrs, (enum_t *) objp))
961 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
963 //register int32_t *buf;
965 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
967 switch (objp->fhs_status) {
969 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))