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 /* 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 stat);
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) {
187 static int kernel_version = 0;
192 nfs_mount_version = NFS_MOUNT_VERSION; /* default */
194 kernel_version = get_kernel_revision();
195 if (kernel_version) {
196 if (kernel_version < MAKE_VERSION(2,1,32))
197 nfs_mount_version = 1;
198 else if (kernel_version < MAKE_VERSION(2,3,99))
199 nfs_mount_version = 3;
201 nfs_mount_version = 4; /* since 2.3.99pre4 */
203 if (nfs_mount_version > NFS_MOUNT_VERSION)
204 nfs_mount_version = NFS_MOUNT_VERSION;
208 get_mountport(struct sockaddr_in *server_addr,
210 long unsigned version,
214 struct pmaplist *pmap;
215 static struct pmap p = {0, 0, 0, 0};
217 server_addr->sin_port = PMAPPORT;
218 pmap = pmap_getmaps(server_addr);
220 if (version > MAX_NFSPROT)
221 version = MAX_NFSPROT;
230 if (pmap->pml_map.pm_prog != prog)
232 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
234 if (version > 2 && pmap->pml_map.pm_vers != version)
236 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
238 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
239 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
240 (port && pmap->pml_map.pm_port != port))
242 memcpy(&p, &pmap->pml_map, sizeof(p));
244 pmap = pmap->pml_next;
247 p.pm_vers = MOUNTVERS;
249 p.pm_port = MOUNTPORT;
251 p.pm_prot = IPPROTO_TCP;
255 int nfsmount(const char *spec, const char *node, int *flags,
256 char **extra_opts, char **mount_opts, int running_bg)
258 static char *prev_bg_host;
264 char *mounthost=NULL;
266 struct timeval total_timeout;
267 enum clnt_stat clnt_stat;
268 static struct nfs_mount_data data;
272 struct sockaddr_in server_addr;
273 struct sockaddr_in mount_server_addr;
276 struct timeval retry_timeout;
278 struct fhstatus nfsv2;
279 struct mountres3 nfsv3;
304 find_kernel_nfs_mount_version();
309 if (strlen(spec) >= sizeof(hostdir)) {
310 error_msg("excessively long host:dir argument\n");
313 strcpy(hostdir, spec);
314 if ((s = strchr(hostdir, ':'))) {
318 /* Ignore all but first hostname in replicated mounts
319 until they can be fully supported. (mack@sgi.com) */
320 if ((s = strchr(hostdir, ','))) {
322 error_msg("warning: multiple hostnames not supported\n");
325 error_msg("directory to mount not in host:dir format\n");
329 server_addr.sin_family = AF_INET;
330 #ifdef HAVE_inet_aton
331 if (!inet_aton(hostname, &server_addr.sin_addr))
334 if ((hp = gethostbyname(hostname)) == NULL) {
335 error_msg("can't get address for %s\n", hostname);
338 if (hp->h_length > sizeof(struct in_addr)) {
339 error_msg("got bad hp->h_length\n");
340 hp->h_length = sizeof(struct in_addr);
342 memcpy(&server_addr.sin_addr,
343 hp->h_addr, hp->h_length);
347 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
349 /* add IP address to mtab options for use when unmounting */
351 s = inet_ntoa(server_addr.sin_addr);
352 old_opts = *extra_opts;
355 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
356 error_msg("excessively long option argument\n");
359 sprintf(new_opts, "%s%saddr=%s",
360 old_opts, *old_opts ? "," : "", s);
361 *extra_opts = xstrdup(new_opts);
363 /* Set default options.
364 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
365 * let the kernel decide.
366 * timeo is filled in after we know whether it'll be TCP or UDP. */
367 memset(&data, 0, sizeof(data));
373 #if NFS_MOUNT_VERSION >= 2
374 data.namlen = NAME_MAX;
384 retry = 10000; /* 10000 minutes ~ 1 week */
387 mountprog = MOUNTPROG;
391 nfsprog = NFS_PROGRAM;
396 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
397 if ((opteq = strchr(opt, '='))) {
398 val = atoi(opteq + 1);
400 if (!strcmp(opt, "rsize"))
402 else if (!strcmp(opt, "wsize"))
404 else if (!strcmp(opt, "timeo"))
406 else if (!strcmp(opt, "retrans"))
408 else if (!strcmp(opt, "acregmin"))
410 else if (!strcmp(opt, "acregmax"))
412 else if (!strcmp(opt, "acdirmin"))
414 else if (!strcmp(opt, "acdirmax"))
416 else if (!strcmp(opt, "actimeo")) {
422 else if (!strcmp(opt, "retry"))
424 else if (!strcmp(opt, "port"))
426 else if (!strcmp(opt, "mountport"))
428 else if (!strcmp(opt, "mounthost"))
429 mounthost=xstrndup(opteq+1,
430 strcspn(opteq+1," \t\n\r,"));
431 else if (!strcmp(opt, "mountprog"))
433 else if (!strcmp(opt, "mountvers"))
435 else if (!strcmp(opt, "nfsprog"))
437 else if (!strcmp(opt, "nfsvers") ||
438 !strcmp(opt, "vers"))
440 else if (!strcmp(opt, "proto")) {
441 if (!strncmp(opteq+1, "tcp", 3))
443 else if (!strncmp(opteq+1, "udp", 3))
446 printf(_("Warning: Unrecognized proto= option.\n"));
447 } else if (!strcmp(opt, "namlen")) {
448 #if NFS_MOUNT_VERSION >= 2
449 if (nfs_mount_version >= 2)
453 printf(_("Warning: Option namlen is not supported.\n"));
454 } else if (!strcmp(opt, "addr"))
457 printf(_("unknown nfs mount parameter: "
458 "%s=%d\n"), opt, val);
464 if (!strncmp(opt, "no", 2)) {
468 if (!strcmp(opt, "bg"))
470 else if (!strcmp(opt, "fg"))
472 else if (!strcmp(opt, "soft"))
474 else if (!strcmp(opt, "hard"))
476 else if (!strcmp(opt, "intr"))
478 else if (!strcmp(opt, "posix"))
480 else if (!strcmp(opt, "cto"))
482 else if (!strcmp(opt, "ac"))
484 else if (!strcmp(opt, "tcp"))
486 else if (!strcmp(opt, "udp"))
488 else if (!strcmp(opt, "lock")) {
489 if (nfs_mount_version >= 3)
492 printf(_("Warning: option nolock is not supported.\n"));
494 printf(_("unknown nfs mount option: "
495 "%s%s\n"), val ? "" : "no", opt);
500 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
502 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
503 | (intr ? NFS_MOUNT_INTR : 0)
504 | (posix ? NFS_MOUNT_POSIX : 0)
505 | (nocto ? NFS_MOUNT_NOCTO : 0)
506 | (noac ? NFS_MOUNT_NOAC : 0);
507 #if NFS_MOUNT_VERSION >= 2
508 if (nfs_mount_version >= 2)
509 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
511 #if NFS_MOUNT_VERSION >= 3
512 if (nfs_mount_version >= 3)
513 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
515 if (nfsvers > MAX_NFSPROT) {
516 error_msg("NFSv%d not supported!\n", nfsvers);
519 if (mountvers > MAX_NFSPROT) {
520 error_msg("NFSv%d not supported!\n", nfsvers);
523 if (nfsvers && !mountvers)
524 mountvers = (nfsvers < 3) ? 1 : nfsvers;
525 if (nfsvers && nfsvers < mountvers) {
529 /* Adjust options if none specified */
531 data.timeo = tcp ? 70 : 7;
533 #ifdef NFS_MOUNT_DEBUG
534 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
535 data.rsize, data.wsize, data.timeo, data.retrans);
536 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
537 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
538 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
539 port, bg, retry, data.flags);
540 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
541 mountprog, mountvers, nfsprog, nfsvers);
542 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
543 (data.flags & NFS_MOUNT_SOFT) != 0,
544 (data.flags & NFS_MOUNT_INTR) != 0,
545 (data.flags & NFS_MOUNT_POSIX) != 0,
546 (data.flags & NFS_MOUNT_NOCTO) != 0,
547 (data.flags & NFS_MOUNT_NOAC) != 0);
548 #if NFS_MOUNT_VERSION >= 2
550 (data.flags & NFS_MOUNT_TCP) != 0);
554 data.version = nfs_mount_version;
555 *mount_opts = (char *) &data;
557 if (*flags & MS_REMOUNT)
561 * If the previous mount operation on the same host was
562 * backgrounded, and the "bg" for this mount is also set,
563 * give up immediately, to avoid the initial timeout.
565 if (bg && !running_bg &&
566 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
572 /* create mount deamon client */
573 /* See if the nfs host = mount host. */
575 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
576 mount_server_addr.sin_family = AF_INET;
577 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
579 if ((hp = gethostbyname(mounthost)) == NULL) {
580 error_msg("can't get address for %s\n", hostname);
583 if (hp->h_length > sizeof(struct in_addr)) {
584 error_msg("got bad hp->h_length?\n");
585 hp->h_length = sizeof(struct in_addr);
587 mount_server_addr.sin_family = AF_INET;
588 memcpy(&mount_server_addr.sin_addr,
589 hp->h_addr, hp->h_length);
595 * The following loop implements the mount retries. On the first
596 * call, "running_bg" is 0. When the mount times out, and the
597 * "bg" option is set, the exit status EX_BG will be returned.
598 * For a backgrounded mount, there will be a second call by the
599 * child process with "running_bg" set to 1.
601 * The case where the mount point is not present and the "bg"
602 * option is set, is treated as a timeout. This is done to
603 * support nested mounts.
605 * The "retry" count specified by the user is the number of
606 * minutes to retry before giving up.
608 * Only the first error message will be displayed.
610 retry_timeout.tv_sec = 3;
611 retry_timeout.tv_usec = 0;
612 total_timeout.tv_sec = 20;
613 total_timeout.tv_usec = 0;
614 timeout = time(NULL) + 60 * retry;
619 if (bg && stat(node, &statbuf) == -1) {
621 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
627 /* be careful not to use too many CPU cycles */
631 pm_mnt = get_mountport(&mount_server_addr,
637 /* contact the mount daemon via TCP */
638 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
641 switch (pm_mnt->pm_prot) {
643 mclient = clntudp_create(&mount_server_addr,
650 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
653 mclient = clnttcp_create(&mount_server_addr,
662 /* try to mount hostname:dirname */
663 mclient->cl_auth = authunix_create_default();
665 /* make pointers in xdr_mountres3 NULL so
666 * that xdr_array allocates memory for us
668 memset(&status, 0, sizeof(status));
670 if (pm_mnt->pm_vers == 3)
671 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
672 (xdrproc_t) xdr_dirpath,
674 (xdrproc_t) xdr_mountres3,
678 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
679 (xdrproc_t) xdr_dirpath,
681 (xdrproc_t) xdr_fhstatus,
685 if (clnt_stat == RPC_SUCCESS)
686 break; /* we're done */
687 if (errno != ECONNREFUSED) {
688 clnt_perror(mclient, "mount");
689 goto fail; /* don't retry */
691 if (!running_bg && prevt == 0)
692 clnt_perror(mclient, "mount");
693 auth_destroy(mclient->cl_auth);
694 clnt_destroy(mclient);
698 if (!running_bg && prevt == 0)
699 clnt_pcreateerror("mount");
706 prev_bg_host = xstrdup(hostname);
715 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
718 if (status.nfsv2.fhs_status != 0) {
719 error_msg("%s:%s failed, reason given by server: %s\n",
721 nfs_strerror(status.nfsv2.fhs_status));
724 memcpy(data.root.data,
725 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
727 #if NFS_MOUNT_VERSION >= 4
728 data.root.size = NFS_FHSIZE;
729 memcpy(data.old_root.data,
730 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
734 #if NFS_MOUNT_VERSION >= 4
736 if (status.nfsv3.fhs_status != 0) {
737 error_msg("%s:%s failed, reason given by server: %s\n",
739 nfs_strerror(status.nfsv3.fhs_status));
742 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
743 memset(data.old_root.data, 0, NFS_FHSIZE);
744 memset(&data.root, 0, sizeof(data.root));
745 data.root.size = fhandle->fhandle3_len;
746 memcpy(data.root.data,
747 (char *) fhandle->fhandle3_val,
748 fhandle->fhandle3_len);
750 data.flags |= NFS_MOUNT_VER3;
754 /* create nfs socket for kernel */
757 if (nfs_mount_version < 3) {
758 printf(_("NFS over TCP is not supported.\n"));
761 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
763 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
765 perror(_("nfs socket"));
768 if (bindresvport(fsock, 0) < 0) {
769 perror(_("nfs bindresvport"));
773 server_addr.sin_port = PMAPPORT;
774 port = pmap_getport(&server_addr, nfsprog, nfsvers,
775 tcp ? IPPROTO_TCP : IPPROTO_UDP);
778 #ifdef NFS_MOUNT_DEBUG
780 printf(_("used portmapper to find NFS port\n"));
783 #ifdef NFS_MOUNT_DEBUG
784 printf(_("using port %d for nfs deamon\n"), port);
786 server_addr.sin_port = htons(port);
788 * connect() the socket for kernels 1.3.10 and below only,
789 * to avoid problems with multihomed hosts.
792 if (get_kernel_revision() <= 66314
793 && connect(fsock, (struct sockaddr *) &server_addr,
794 sizeof (server_addr)) < 0) {
795 perror(_("nfs connect"));
799 /* prepare data structure for kernel */
802 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
803 strncpy(data.hostname, hostname, sizeof(data.hostname));
807 auth_destroy(mclient->cl_auth);
808 clnt_destroy(mclient);
817 auth_destroy(mclient->cl_auth);
818 clnt_destroy(mclient);
828 * We need to translate between nfs status return values and
829 * the local errno values which may not be the same.
831 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
832 * "after #include <errno.h> the symbol errno is reserved for any use,
833 * it cannot even be used as a struct tag or field name".
837 #define EDQUOT ENOSPC
845 { NFSERR_PERM, EPERM },
846 { NFSERR_NOENT, ENOENT },
848 { NFSERR_NXIO, ENXIO },
849 { NFSERR_ACCES, EACCES },
850 { NFSERR_EXIST, EEXIST },
851 { NFSERR_NODEV, ENODEV },
852 { NFSERR_NOTDIR, ENOTDIR },
853 { NFSERR_ISDIR, EISDIR },
855 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
857 { NFSERR_FBIG, EFBIG },
858 { NFSERR_NOSPC, ENOSPC },
859 { NFSERR_ROFS, EROFS },
860 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
861 { NFSERR_NOTEMPTY, ENOTEMPTY },
862 { NFSERR_DQUOT, EDQUOT },
863 { NFSERR_STALE, ESTALE },
865 { NFSERR_WFLUSH, EWFLUSH },
867 /* Throw in some NFSv3 values for even more fun (HP returns these) */
873 static char *nfs_strerror(int stat)
876 static char buf[256];
878 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
879 if (nfs_errtbl[i].stat == stat)
880 return strerror(nfs_errtbl[i].errnum);
882 sprintf(buf, _("unknown nfs status return value: %d"), stat);
887 xdr_fhandle (XDR *xdrs, fhandle objp)
889 //register int32_t *buf;
891 if (!xdr_opaque (xdrs, objp, FHSIZE))
897 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
899 //register int32_t *buf;
901 if (!xdr_u_int (xdrs, &objp->fhs_status))
903 switch (objp->fhs_status) {
905 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
915 xdr_dirpath (XDR *xdrs, dirpath *objp)
917 //register int32_t *buf;
919 if (!xdr_string (xdrs, objp, MNTPATHLEN))
925 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
927 //register int32_t *buf;
929 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
935 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
937 //register int32_t *buf;
939 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
941 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
942 sizeof (int), (xdrproc_t) xdr_int))
948 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
950 //register int32_t *buf;
952 if (!xdr_enum (xdrs, (enum_t *) objp))
958 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
960 //register int32_t *buf;
962 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
964 switch (objp->fhs_status) {
966 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))