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/time.h>
50 #include <sys/utsname.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
55 #include <linux/nfs.h> /* For the kernels nfs stuff */
58 static const int NFS_FHSIZE = 32;
61 static const int NFS_PORT = 2049;
64 /* Disable the nls stuff */
65 # undef bindtextdomain
66 # define bindtextdomain(Domain, Directory) /* empty */
68 # define textdomain(Domain) /* empty */
69 # define _(Text) (Text)
70 # define N_(Text) (Text)
72 static const int MS_MGC_VAL = 0xc0ed0000; /* Magic number indicatng "new" flags */
73 static const int MS_RDONLY = 1; /* Mount read-only */
74 static const int MS_NOSUID = 2; /* Ignore suid and sgid bits */
75 static const int MS_NODEV = 4; /* Disallow access to device special files */
76 static const int MS_NOEXEC = 8; /* Disallow program execution */
77 static const int MS_SYNCHRONOUS = 16; /* Writes are synced at once */
78 static const int MS_REMOUNT = 32; /* Alter flags of a mounted FS */
79 static const int MS_MANDLOCK = 64; /* Allow mandatory locks on an FS */
80 static const int S_QUOTA = 128; /* Quota initialized for file/directory/symlink */
81 static const int S_APPEND = 256; /* Append-only file */
82 static const int S_IMMUTABLE = 512; /* Immutable file */
83 static const int MS_NOATIME = 1024; /* Do not update access times. */
84 static const int MS_NODIRATIME = 2048; /* Do not update directory access times */
88 * We want to be able to compile mount on old kernels in such a way
89 * that the binary will work well on more recent kernels.
90 * Thus, if necessary we teach nfsmount.c the structure of new fields
91 * that will come later.
93 * Moreover, the new kernel includes conflict with glibc includes
94 * so it is easiest to ignore the kernel altogether (at compile time).
97 /* NOTE: Do not make this into a 'static const int' because the pre-processor
98 * needs to test this value in some #if statements. */
99 #define NFS_MOUNT_VERSION 4
106 unsigned char data[64];
109 struct nfs_mount_data {
112 struct nfs2_fh old_root; /* 1 */
118 int acregmin; /* 1 */
119 int acregmax; /* 1 */
120 int acdirmin; /* 1 */
121 int acdirmax; /* 1 */
122 struct sockaddr_in addr; /* 1 */
123 char hostname[256]; /* 1 */
125 unsigned int bsize; /* 3 */
126 struct nfs3_fh root; /* 4 */
129 /* bits in the flags field */
131 static const int NFS_MOUNT_SOFT = 0x0001; /* 1 */
132 static const int NFS_MOUNT_INTR = 0x0002; /* 1 */
133 static const int NFS_MOUNT_SECURE = 0x0004; /* 1 */
134 static const int NFS_MOUNT_POSIX = 0x0008; /* 1 */
135 static const int NFS_MOUNT_NOCTO = 0x0010; /* 1 */
136 static const int NFS_MOUNT_NOAC = 0x0020; /* 1 */
137 static const int NFS_MOUNT_TCP = 0x0040; /* 2 */
138 static const int NFS_MOUNT_VER3 = 0x0080; /* 3 */
139 static const int NFS_MOUNT_KERBEROS = 0x0100; /* 3 */
140 static const int NFS_MOUNT_NONLM = 0x0200; /* 3 */
143 #define UTIL_LINUX_VERSION "2.10m"
144 #define util_linux_version "util-linux-2.10m"
146 #define HAVE_inet_aton
151 #define HAVE_locale_h
152 #define HAVE_libintl_h
154 #define HAVE_langinfo_h
155 #define HAVE_progname
157 #define HAVE_nanosleep
158 #define HAVE_personality
159 #define HAVE_tm_gmtoff
161 static char *nfs_strerror(int stat);
163 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
164 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
166 static const int EX_FAIL = 32; /* mount failure */
167 static const int EX_BG = 256; /* retry in background (internal only) */
171 * nfs_mount_version according to the sources seen at compile time.
173 static int nfs_mount_version;
176 * Unfortunately, the kernel prints annoying console messages
177 * in case of an unexpected nfs mount version (instead of
178 * just returning some error). Therefore we'll have to try
179 * and figure out what version the kernel expects.
182 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
183 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
184 * nfs_mount_version: version this source and running kernel can handle
187 find_kernel_nfs_mount_version(void)
189 static int kernel_version = 0;
194 nfs_mount_version = NFS_MOUNT_VERSION; /* default */
196 kernel_version = get_kernel_revision();
197 if (kernel_version) {
198 if (kernel_version < MAKE_VERSION(2,1,32))
199 nfs_mount_version = 1;
200 else if (kernel_version < MAKE_VERSION(2,2,18) ||
201 (kernel_version >= MAKE_VERSION(2,3,0) &&
202 kernel_version < MAKE_VERSION(2,3,99)))
203 nfs_mount_version = 3;
205 nfs_mount_version = 4; /* since 2.3.99pre4 */
207 if (nfs_mount_version > NFS_MOUNT_VERSION)
208 nfs_mount_version = NFS_MOUNT_VERSION;
212 get_mountport(struct sockaddr_in *server_addr,
214 long unsigned version,
218 struct pmaplist *pmap;
219 static struct pmap p = {0, 0, 0, 0};
221 server_addr->sin_port = PMAPPORT;
222 pmap = pmap_getmaps(server_addr);
224 if (version > MAX_NFSPROT)
225 version = MAX_NFSPROT;
234 if (pmap->pml_map.pm_prog != prog)
236 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
238 if (version > 2 && pmap->pml_map.pm_vers != version)
240 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
242 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
243 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
244 (port && pmap->pml_map.pm_port != port))
246 memcpy(&p, &pmap->pml_map, sizeof(p));
248 pmap = pmap->pml_next;
251 p.pm_vers = MOUNTVERS;
253 p.pm_port = MOUNTPORT;
255 p.pm_prot = IPPROTO_TCP;
259 int nfsmount(const char *spec, const char *node, int *flags,
260 char **extra_opts, char **mount_opts, int running_bg)
262 static char *prev_bg_host;
268 char *mounthost=NULL;
270 struct timeval total_timeout;
271 enum clnt_stat clnt_stat;
272 static struct nfs_mount_data data;
276 struct sockaddr_in server_addr;
277 struct sockaddr_in mount_server_addr;
280 struct timeval retry_timeout;
282 struct fhstatus nfsv2;
283 struct mountres3 nfsv3;
308 find_kernel_nfs_mount_version();
313 if (strlen(spec) >= sizeof(hostdir)) {
314 error_msg("excessively long host:dir argument");
317 strcpy(hostdir, spec);
318 if ((s = strchr(hostdir, ':'))) {
322 /* Ignore all but first hostname in replicated mounts
323 until they can be fully supported. (mack@sgi.com) */
324 if ((s = strchr(hostdir, ','))) {
326 error_msg("warning: multiple hostnames not supported");
329 error_msg("directory to mount not in host:dir format");
333 server_addr.sin_family = AF_INET;
334 #ifdef HAVE_inet_aton
335 if (!inet_aton(hostname, &server_addr.sin_addr))
338 if ((hp = gethostbyname(hostname)) == NULL) {
339 error_msg("can't get address for %s", hostname);
342 if (hp->h_length > sizeof(struct in_addr)) {
343 error_msg("got bad hp->h_length");
344 hp->h_length = sizeof(struct in_addr);
346 memcpy(&server_addr.sin_addr,
347 hp->h_addr, hp->h_length);
351 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
353 /* add IP address to mtab options for use when unmounting */
355 s = inet_ntoa(server_addr.sin_addr);
356 old_opts = *extra_opts;
359 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
360 error_msg("excessively long option argument");
363 sprintf(new_opts, "%s%saddr=%s",
364 old_opts, *old_opts ? "," : "", s);
365 *extra_opts = xstrdup(new_opts);
367 /* Set default options.
368 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
369 * let the kernel decide.
370 * timeo is filled in after we know whether it'll be TCP or UDP. */
371 memset(&data, 0, sizeof(data));
377 #if NFS_MOUNT_VERSION >= 2
378 data.namlen = NAME_MAX;
388 retry = 10000; /* 10000 minutes ~ 1 week */
391 mountprog = MOUNTPROG;
395 nfsprog = NFS_PROGRAM;
400 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
401 if ((opteq = strchr(opt, '='))) {
402 val = atoi(opteq + 1);
404 if (!strcmp(opt, "rsize"))
406 else if (!strcmp(opt, "wsize"))
408 else if (!strcmp(opt, "timeo"))
410 else if (!strcmp(opt, "retrans"))
412 else if (!strcmp(opt, "acregmin"))
414 else if (!strcmp(opt, "acregmax"))
416 else if (!strcmp(opt, "acdirmin"))
418 else if (!strcmp(opt, "acdirmax"))
420 else if (!strcmp(opt, "actimeo")) {
426 else if (!strcmp(opt, "retry"))
428 else if (!strcmp(opt, "port"))
430 else if (!strcmp(opt, "mountport"))
432 else if (!strcmp(opt, "mounthost"))
433 mounthost=xstrndup(opteq+1,
434 strcspn(opteq+1," \t\n\r,"));
435 else if (!strcmp(opt, "mountprog"))
437 else if (!strcmp(opt, "mountvers"))
439 else if (!strcmp(opt, "nfsprog"))
441 else if (!strcmp(opt, "nfsvers") ||
442 !strcmp(opt, "vers"))
444 else if (!strcmp(opt, "proto")) {
445 if (!strncmp(opteq+1, "tcp", 3))
447 else if (!strncmp(opteq+1, "udp", 3))
450 printf(_("Warning: Unrecognized proto= option.\n"));
451 } else if (!strcmp(opt, "namlen")) {
452 #if NFS_MOUNT_VERSION >= 2
453 if (nfs_mount_version >= 2)
457 printf(_("Warning: Option namlen is not supported.\n"));
458 } else if (!strcmp(opt, "addr"))
461 printf(_("unknown nfs mount parameter: "
462 "%s=%d\n"), opt, val);
468 if (!strncmp(opt, "no", 2)) {
472 if (!strcmp(opt, "bg"))
474 else if (!strcmp(opt, "fg"))
476 else if (!strcmp(opt, "soft"))
478 else if (!strcmp(opt, "hard"))
480 else if (!strcmp(opt, "intr"))
482 else if (!strcmp(opt, "posix"))
484 else if (!strcmp(opt, "cto"))
486 else if (!strcmp(opt, "ac"))
488 else if (!strcmp(opt, "tcp"))
490 else if (!strcmp(opt, "udp"))
492 else if (!strcmp(opt, "lock")) {
493 if (nfs_mount_version >= 3)
496 printf(_("Warning: option nolock is not supported.\n"));
498 printf(_("unknown nfs mount option: "
499 "%s%s\n"), val ? "" : "no", opt);
504 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
506 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
507 | (intr ? NFS_MOUNT_INTR : 0)
508 | (posix ? NFS_MOUNT_POSIX : 0)
509 | (nocto ? NFS_MOUNT_NOCTO : 0)
510 | (noac ? NFS_MOUNT_NOAC : 0);
511 #if NFS_MOUNT_VERSION >= 2
512 if (nfs_mount_version >= 2)
513 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
515 #if NFS_MOUNT_VERSION >= 3
516 if (nfs_mount_version >= 3)
517 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
519 if (nfsvers > MAX_NFSPROT) {
520 error_msg("NFSv%d not supported!", nfsvers);
523 if (mountvers > MAX_NFSPROT) {
524 error_msg("NFSv%d not supported!", nfsvers);
527 if (nfsvers && !mountvers)
528 mountvers = (nfsvers < 3) ? 1 : nfsvers;
529 if (nfsvers && nfsvers < mountvers) {
533 /* Adjust options if none specified */
535 data.timeo = tcp ? 70 : 7;
537 #ifdef NFS_MOUNT_DEBUG
538 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
539 data.rsize, data.wsize, data.timeo, data.retrans);
540 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
541 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
542 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
543 port, bg, retry, data.flags);
544 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
545 mountprog, mountvers, nfsprog, nfsvers);
546 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
547 (data.flags & NFS_MOUNT_SOFT) != 0,
548 (data.flags & NFS_MOUNT_INTR) != 0,
549 (data.flags & NFS_MOUNT_POSIX) != 0,
550 (data.flags & NFS_MOUNT_NOCTO) != 0,
551 (data.flags & NFS_MOUNT_NOAC) != 0);
552 #if NFS_MOUNT_VERSION >= 2
554 (data.flags & NFS_MOUNT_TCP) != 0);
558 data.version = nfs_mount_version;
559 *mount_opts = (char *) &data;
561 if (*flags & MS_REMOUNT)
565 * If the previous mount operation on the same host was
566 * backgrounded, and the "bg" for this mount is also set,
567 * give up immediately, to avoid the initial timeout.
569 if (bg && !running_bg &&
570 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
576 /* create mount deamon client */
577 /* See if the nfs host = mount host. */
579 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
580 mount_server_addr.sin_family = AF_INET;
581 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
583 if ((hp = gethostbyname(mounthost)) == NULL) {
584 error_msg("can't get address for %s", hostname);
587 if (hp->h_length > sizeof(struct in_addr)) {
588 error_msg("got bad hp->h_length?");
589 hp->h_length = sizeof(struct in_addr);
591 mount_server_addr.sin_family = AF_INET;
592 memcpy(&mount_server_addr.sin_addr,
593 hp->h_addr, hp->h_length);
599 * The following loop implements the mount retries. On the first
600 * call, "running_bg" is 0. When the mount times out, and the
601 * "bg" option is set, the exit status EX_BG will be returned.
602 * For a backgrounded mount, there will be a second call by the
603 * child process with "running_bg" set to 1.
605 * The case where the mount point is not present and the "bg"
606 * option is set, is treated as a timeout. This is done to
607 * support nested mounts.
609 * The "retry" count specified by the user is the number of
610 * minutes to retry before giving up.
612 * Only the first error message will be displayed.
614 retry_timeout.tv_sec = 3;
615 retry_timeout.tv_usec = 0;
616 total_timeout.tv_sec = 20;
617 total_timeout.tv_usec = 0;
618 timeout = time(NULL) + 60 * retry;
623 if (bg && stat(node, &statbuf) == -1) {
625 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
631 /* be careful not to use too many CPU cycles */
635 pm_mnt = get_mountport(&mount_server_addr,
641 /* contact the mount daemon via TCP */
642 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
645 switch (pm_mnt->pm_prot) {
647 mclient = clntudp_create(&mount_server_addr,
654 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
657 mclient = clnttcp_create(&mount_server_addr,
666 /* try to mount hostname:dirname */
667 mclient->cl_auth = authunix_create_default();
669 /* make pointers in xdr_mountres3 NULL so
670 * that xdr_array allocates memory for us
672 memset(&status, 0, sizeof(status));
674 if (pm_mnt->pm_vers == 3)
675 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
676 (xdrproc_t) xdr_dirpath,
678 (xdrproc_t) xdr_mountres3,
682 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
683 (xdrproc_t) xdr_dirpath,
685 (xdrproc_t) xdr_fhstatus,
689 if (clnt_stat == RPC_SUCCESS)
690 break; /* we're done */
691 if (errno != ECONNREFUSED) {
692 clnt_perror(mclient, "mount");
693 goto fail; /* don't retry */
695 if (!running_bg && prevt == 0)
696 clnt_perror(mclient, "mount");
697 auth_destroy(mclient->cl_auth);
698 clnt_destroy(mclient);
702 if (!running_bg && prevt == 0)
703 clnt_pcreateerror("mount");
710 prev_bg_host = xstrdup(hostname);
719 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
722 if (status.nfsv2.fhs_status != 0) {
723 error_msg("%s:%s failed, reason given by server: %s",
725 nfs_strerror(status.nfsv2.fhs_status));
728 memcpy(data.root.data,
729 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
731 #if NFS_MOUNT_VERSION >= 4
732 data.root.size = NFS_FHSIZE;
733 memcpy(data.old_root.data,
734 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
738 #if NFS_MOUNT_VERSION >= 4
740 if (status.nfsv3.fhs_status != 0) {
741 error_msg("%s:%s failed, reason given by server: %s",
743 nfs_strerror(status.nfsv3.fhs_status));
746 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
747 memset(data.old_root.data, 0, NFS_FHSIZE);
748 memset(&data.root, 0, sizeof(data.root));
749 data.root.size = fhandle->fhandle3_len;
750 memcpy(data.root.data,
751 (char *) fhandle->fhandle3_val,
752 fhandle->fhandle3_len);
754 data.flags |= NFS_MOUNT_VER3;
758 /* create nfs socket for kernel */
761 if (nfs_mount_version < 3) {
762 printf(_("NFS over TCP is not supported.\n"));
765 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
767 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
769 perror(_("nfs socket"));
772 if (bindresvport(fsock, 0) < 0) {
773 perror(_("nfs bindresvport"));
777 server_addr.sin_port = PMAPPORT;
778 port = pmap_getport(&server_addr, nfsprog, nfsvers,
779 tcp ? IPPROTO_TCP : IPPROTO_UDP);
782 #ifdef NFS_MOUNT_DEBUG
784 printf(_("used portmapper to find NFS port\n"));
787 #ifdef NFS_MOUNT_DEBUG
788 printf(_("using port %d for nfs deamon\n"), port);
790 server_addr.sin_port = htons(port);
792 * connect() the socket for kernels 1.3.10 and below only,
793 * to avoid problems with multihomed hosts.
796 if (get_kernel_revision() <= 66314
797 && connect(fsock, (struct sockaddr *) &server_addr,
798 sizeof (server_addr)) < 0) {
799 perror(_("nfs connect"));
803 /* prepare data structure for kernel */
806 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
807 strncpy(data.hostname, hostname, sizeof(data.hostname));
811 auth_destroy(mclient->cl_auth);
812 clnt_destroy(mclient);
821 auth_destroy(mclient->cl_auth);
822 clnt_destroy(mclient);
832 * We need to translate between nfs status return values and
833 * the local errno values which may not be the same.
835 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
836 * "after #include <errno.h> the symbol errno is reserved for any use,
837 * it cannot even be used as a struct tag or field name".
841 #define EDQUOT ENOSPC
849 { NFSERR_PERM, EPERM },
850 { NFSERR_NOENT, ENOENT },
852 { NFSERR_NXIO, ENXIO },
853 { NFSERR_ACCES, EACCES },
854 { NFSERR_EXIST, EEXIST },
855 { NFSERR_NODEV, ENODEV },
856 { NFSERR_NOTDIR, ENOTDIR },
857 { NFSERR_ISDIR, EISDIR },
859 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
861 { NFSERR_FBIG, EFBIG },
862 { NFSERR_NOSPC, ENOSPC },
863 { NFSERR_ROFS, EROFS },
864 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
865 { NFSERR_NOTEMPTY, ENOTEMPTY },
866 { NFSERR_DQUOT, EDQUOT },
867 { NFSERR_STALE, ESTALE },
869 { NFSERR_WFLUSH, EWFLUSH },
871 /* Throw in some NFSv3 values for even more fun (HP returns these) */
877 static char *nfs_strerror(int stat)
880 static char buf[256];
882 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
883 if (nfs_errtbl[i].stat == stat)
884 return strerror(nfs_errtbl[i].errnum);
886 sprintf(buf, _("unknown nfs status return value: %d"), stat);
891 xdr_fhandle (XDR *xdrs, fhandle objp)
893 //register int32_t *buf;
895 if (!xdr_opaque (xdrs, objp, FHSIZE))
901 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
903 //register int32_t *buf;
905 if (!xdr_u_int (xdrs, &objp->fhs_status))
907 switch (objp->fhs_status) {
909 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
919 xdr_dirpath (XDR *xdrs, dirpath *objp)
921 //register int32_t *buf;
923 if (!xdr_string (xdrs, objp, MNTPATHLEN))
929 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
931 //register int32_t *buf;
933 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
939 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
941 //register int32_t *buf;
943 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
945 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
946 sizeof (int), (xdrproc_t) xdr_int))
952 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
954 //register int32_t *buf;
956 if (!xdr_enum (xdrs, (enum_t *) objp))
962 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
964 //register int32_t *buf;
966 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
968 switch (objp->fhs_status) {
970 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))