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 /* Disable the nls stuff */
58 # undef bindtextdomain
59 # define bindtextdomain(Domain, Directory) /* empty */
61 # define textdomain(Domain) /* empty */
62 # define _(Text) (Text)
63 # define N_(Text) (Text)
65 #define MS_MGC_VAL 0xc0ed0000 /* Magic number indicatng "new" flags */
66 #define MS_RDONLY 1 /* Mount read-only */
67 #define MS_NOSUID 2 /* Ignore suid and sgid bits */
68 #define MS_NODEV 4 /* Disallow access to device special files */
69 #define MS_NOEXEC 8 /* Disallow program execution */
70 #define MS_SYNCHRONOUS 16 /* Writes are synced at once */
71 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
72 #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
73 #define S_QUOTA 128 /* Quota initialized for file/directory/symlink */
74 #define S_APPEND 256 /* Append-only file */
75 #define S_IMMUTABLE 512 /* Immutable file */
76 #define MS_NOATIME 1024 /* Do not update access times. */
77 #define MS_NODIRATIME 2048 /* Do not update directory access times */
81 * We want to be able to compile mount on old kernels in such a way
82 * that the binary will work well on more recent kernels.
83 * Thus, if necessary we teach nfsmount.c the structure of new fields
84 * that will come later.
86 * Moreover, the new kernel includes conflict with glibc includes
87 * so it is easiest to ignore the kernel altogether (at compile time).
90 #define NFS_MOUNT_VERSION 4
97 unsigned char data[64];
100 struct nfs_mount_data {
103 struct nfs2_fh old_root; /* 1 */
109 int acregmin; /* 1 */
110 int acregmax; /* 1 */
111 int acdirmin; /* 1 */
112 int acdirmax; /* 1 */
113 struct sockaddr_in addr; /* 1 */
114 char hostname[256]; /* 1 */
116 unsigned int bsize; /* 3 */
117 struct nfs3_fh root; /* 4 */
120 /* bits in the flags field */
122 #define NFS_MOUNT_SOFT 0x0001 /* 1 */
123 #define NFS_MOUNT_INTR 0x0002 /* 1 */
124 #define NFS_MOUNT_SECURE 0x0004 /* 1 */
125 #define NFS_MOUNT_POSIX 0x0008 /* 1 */
126 #define NFS_MOUNT_NOCTO 0x0010 /* 1 */
127 #define NFS_MOUNT_NOAC 0x0020 /* 1 */
128 #define NFS_MOUNT_TCP 0x0040 /* 2 */
129 #define NFS_MOUNT_VER3 0x0080 /* 3 */
130 #define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
131 #define NFS_MOUNT_NONLM 0x0200 /* 3 */
134 #define UTIL_LINUX_VERSION "2.10m"
135 #define util_linux_version "util-linux-2.10m"
137 #define HAVE_inet_aton
142 #define HAVE_locale_h
143 #define HAVE_libintl_h
145 #define HAVE_langinfo_h
146 #define HAVE_progname
148 #define HAVE_nanosleep
149 #define HAVE_personality
150 #define HAVE_tm_gmtoff
152 extern char *xstrdup (const char *s);
153 extern char *xstrndup (const char *s, int n);
154 static char *nfs_strerror(int stat);
156 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
157 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
159 #define EX_FAIL 32 /* mount failure */
160 #define EX_BG 256 /* retry in background (internal only) */
164 linux_version_code(void) {
165 struct utsname my_utsname;
168 if (uname(&my_utsname) == 0) {
169 p = atoi(strtok(my_utsname.release, "."));
170 q = atoi(strtok(NULL, "."));
171 r = atoi(strtok(NULL, "."));
172 return MAKE_VERSION(p,q,r);
178 * nfs_mount_version according to the sources seen at compile time.
180 int nfs_mount_version = NFS_MOUNT_VERSION;
183 * Unfortunately, the kernel prints annoying console messages
184 * in case of an unexpected nfs mount version (instead of
185 * just returning some error). Therefore we'll have to try
186 * and figure out what version the kernel expects.
189 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
190 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
191 * nfs_mount_version: version this source and running kernel can handle
194 find_kernel_nfs_mount_version(void) {
195 static int kernel_version = 0;
200 kernel_version = linux_version_code();
202 if (kernel_version) {
203 if (kernel_version < MAKE_VERSION(2,1,32))
204 nfs_mount_version = 1;
205 else if (kernel_version < MAKE_VERSION(2,3,99))
206 nfs_mount_version = 3;
208 nfs_mount_version = 4; /* since 2.3.99pre4 */
210 if (nfs_mount_version > NFS_MOUNT_VERSION)
211 nfs_mount_version = NFS_MOUNT_VERSION;
215 get_mountport(struct sockaddr_in *server_addr,
217 long unsigned version,
221 struct pmaplist *pmap;
222 static struct pmap p = {0, 0, 0, 0};
224 server_addr->sin_port = PMAPPORT;
225 pmap = pmap_getmaps(server_addr);
227 if (version > MAX_NFSPROT)
228 version = MAX_NFSPROT;
237 if (pmap->pml_map.pm_prog != prog)
239 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
241 if (version > 2 && pmap->pml_map.pm_vers != version)
243 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
245 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
246 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
247 (port && pmap->pml_map.pm_port != port))
249 memcpy(&p, &pmap->pml_map, sizeof(p));
251 pmap = pmap->pml_next;
254 p.pm_vers = MOUNTVERS;
256 p.pm_port = MOUNTPORT;
258 p.pm_prot = IPPROTO_TCP;
262 int nfsmount(const char *spec, const char *node, int *flags,
263 char **extra_opts, char **mount_opts, int running_bg)
265 static char *prev_bg_host;
271 char *mounthost=NULL;
273 struct timeval total_timeout;
274 enum clnt_stat clnt_stat;
275 static struct nfs_mount_data data;
279 struct sockaddr_in server_addr;
280 struct sockaddr_in mount_server_addr;
283 struct timeval retry_timeout;
285 struct fhstatus nfsv2;
286 struct mountres3 nfsv3;
311 find_kernel_nfs_mount_version();
316 if (strlen(spec) >= sizeof(hostdir)) {
317 errorMsg("excessively long host:dir argument\n");
320 strcpy(hostdir, spec);
321 if ((s = strchr(hostdir, ':'))) {
325 /* Ignore all but first hostname in replicated mounts
326 until they can be fully supported. (mack@sgi.com) */
327 if ((s = strchr(hostdir, ','))) {
329 errorMsg("warning: multiple hostnames not supported\n");
332 errorMsg("directory to mount not in host:dir format\n");
336 server_addr.sin_family = AF_INET;
337 #ifdef HAVE_inet_aton
338 if (!inet_aton(hostname, &server_addr.sin_addr))
341 if ((hp = gethostbyname(hostname)) == NULL) {
342 errorMsg("can't get address for %s\n", hostname);
345 if (hp->h_length > sizeof(struct in_addr)) {
346 errorMsg("got bad hp->h_length\n");
347 hp->h_length = sizeof(struct in_addr);
349 memcpy(&server_addr.sin_addr,
350 hp->h_addr, hp->h_length);
354 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
356 /* add IP address to mtab options for use when unmounting */
358 s = inet_ntoa(server_addr.sin_addr);
359 old_opts = *extra_opts;
362 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
363 errorMsg("excessively long option argument\n");
366 sprintf(new_opts, "%s%saddr=%s",
367 old_opts, *old_opts ? "," : "", s);
368 *extra_opts = xstrdup(new_opts);
370 /* Set default options.
371 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
372 * let the kernel decide.
373 * timeo is filled in after we know whether it'll be TCP or UDP. */
374 memset(&data, 0, sizeof(data));
380 #if NFS_MOUNT_VERSION >= 2
381 data.namlen = NAME_MAX;
391 retry = 10000; /* 10000 minutes ~ 1 week */
394 mountprog = MOUNTPROG;
398 nfsprog = NFS_PROGRAM;
403 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
404 if ((opteq = strchr(opt, '='))) {
405 val = atoi(opteq + 1);
407 if (!strcmp(opt, "rsize"))
409 else if (!strcmp(opt, "wsize"))
411 else if (!strcmp(opt, "timeo"))
413 else if (!strcmp(opt, "retrans"))
415 else if (!strcmp(opt, "acregmin"))
417 else if (!strcmp(opt, "acregmax"))
419 else if (!strcmp(opt, "acdirmin"))
421 else if (!strcmp(opt, "acdirmax"))
423 else if (!strcmp(opt, "actimeo")) {
429 else if (!strcmp(opt, "retry"))
431 else if (!strcmp(opt, "port"))
433 else if (!strcmp(opt, "mountport"))
435 else if (!strcmp(opt, "mounthost"))
436 mounthost=xstrndup(opteq+1,
437 strcspn(opteq+1," \t\n\r,"));
438 else if (!strcmp(opt, "mountprog"))
440 else if (!strcmp(opt, "mountvers"))
442 else if (!strcmp(opt, "nfsprog"))
444 else if (!strcmp(opt, "nfsvers") ||
445 !strcmp(opt, "vers"))
447 else if (!strcmp(opt, "proto")) {
448 if (!strncmp(opteq+1, "tcp", 3))
450 else if (!strncmp(opteq+1, "udp", 3))
453 printf(_("Warning: Unrecognized proto= option.\n"));
454 } else if (!strcmp(opt, "namlen")) {
455 #if NFS_MOUNT_VERSION >= 2
456 if (nfs_mount_version >= 2)
460 printf(_("Warning: Option namlen is not supported.\n"));
461 } else if (!strcmp(opt, "addr"))
464 printf(_("unknown nfs mount parameter: "
465 "%s=%d\n"), opt, val);
471 if (!strncmp(opt, "no", 2)) {
475 if (!strcmp(opt, "bg"))
477 else if (!strcmp(opt, "fg"))
479 else if (!strcmp(opt, "soft"))
481 else if (!strcmp(opt, "hard"))
483 else if (!strcmp(opt, "intr"))
485 else if (!strcmp(opt, "posix"))
487 else if (!strcmp(opt, "cto"))
489 else if (!strcmp(opt, "ac"))
491 else if (!strcmp(opt, "tcp"))
493 else if (!strcmp(opt, "udp"))
495 else if (!strcmp(opt, "lock")) {
496 if (nfs_mount_version >= 3)
499 printf(_("Warning: option nolock is not supported.\n"));
501 printf(_("unknown nfs mount option: "
502 "%s%s\n"), val ? "" : "no", opt);
507 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
509 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
510 | (intr ? NFS_MOUNT_INTR : 0)
511 | (posix ? NFS_MOUNT_POSIX : 0)
512 | (nocto ? NFS_MOUNT_NOCTO : 0)
513 | (noac ? NFS_MOUNT_NOAC : 0);
514 #if NFS_MOUNT_VERSION >= 2
515 if (nfs_mount_version >= 2)
516 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
518 #if NFS_MOUNT_VERSION >= 3
519 if (nfs_mount_version >= 3)
520 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
522 if (nfsvers > MAX_NFSPROT) {
523 errorMsg("NFSv%d not supported!\n", nfsvers);
526 if (mountvers > MAX_NFSPROT) {
527 errorMsg("NFSv%d not supported!\n", nfsvers);
530 if (nfsvers && !mountvers)
531 mountvers = (nfsvers < 3) ? 1 : nfsvers;
532 if (nfsvers && nfsvers < mountvers) {
536 /* Adjust options if none specified */
538 data.timeo = tcp ? 70 : 7;
540 #ifdef NFS_MOUNT_DEBUG
541 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
542 data.rsize, data.wsize, data.timeo, data.retrans);
543 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
544 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
545 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
546 port, bg, retry, data.flags);
547 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
548 mountprog, mountvers, nfsprog, nfsvers);
549 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
550 (data.flags & NFS_MOUNT_SOFT) != 0,
551 (data.flags & NFS_MOUNT_INTR) != 0,
552 (data.flags & NFS_MOUNT_POSIX) != 0,
553 (data.flags & NFS_MOUNT_NOCTO) != 0,
554 (data.flags & NFS_MOUNT_NOAC) != 0);
555 #if NFS_MOUNT_VERSION >= 2
557 (data.flags & NFS_MOUNT_TCP) != 0);
561 data.version = nfs_mount_version;
562 *mount_opts = (char *) &data;
564 if (*flags & MS_REMOUNT)
568 * If the previous mount operation on the same host was
569 * backgrounded, and the "bg" for this mount is also set,
570 * give up immediately, to avoid the initial timeout.
572 if (bg && !running_bg &&
573 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
579 /* create mount deamon client */
580 /* See if the nfs host = mount host. */
582 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
583 mount_server_addr.sin_family = AF_INET;
584 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
586 if ((hp = gethostbyname(mounthost)) == NULL) {
587 errorMsg("can't get address for %s\n", hostname);
590 if (hp->h_length > sizeof(struct in_addr)) {
591 errorMsg("got bad hp->h_length?\n");
592 hp->h_length = sizeof(struct in_addr);
594 mount_server_addr.sin_family = AF_INET;
595 memcpy(&mount_server_addr.sin_addr,
596 hp->h_addr, hp->h_length);
602 * The following loop implements the mount retries. On the first
603 * call, "running_bg" is 0. When the mount times out, and the
604 * "bg" option is set, the exit status EX_BG will be returned.
605 * For a backgrounded mount, there will be a second call by the
606 * child process with "running_bg" set to 1.
608 * The case where the mount point is not present and the "bg"
609 * option is set, is treated as a timeout. This is done to
610 * support nested mounts.
612 * The "retry" count specified by the user is the number of
613 * minutes to retry before giving up.
615 * Only the first error message will be displayed.
617 retry_timeout.tv_sec = 3;
618 retry_timeout.tv_usec = 0;
619 total_timeout.tv_sec = 20;
620 total_timeout.tv_usec = 0;
621 timeout = time(NULL) + 60 * retry;
626 if (bg && stat(node, &statbuf) == -1) {
628 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
634 /* be careful not to use too many CPU cycles */
638 pm_mnt = get_mountport(&mount_server_addr,
644 /* contact the mount daemon via TCP */
645 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
648 switch (pm_mnt->pm_prot) {
650 mclient = clntudp_create(&mount_server_addr,
657 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
660 mclient = clnttcp_create(&mount_server_addr,
669 /* try to mount hostname:dirname */
670 mclient->cl_auth = authunix_create_default();
672 /* make pointers in xdr_mountres3 NULL so
673 * that xdr_array allocates memory for us
675 memset(&status, 0, sizeof(status));
677 if (pm_mnt->pm_vers == 3)
678 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
679 (xdrproc_t) xdr_dirpath,
681 (xdrproc_t) xdr_mountres3,
685 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
686 (xdrproc_t) xdr_dirpath,
688 (xdrproc_t) xdr_fhstatus,
692 if (clnt_stat == RPC_SUCCESS)
693 break; /* we're done */
694 if (errno != ECONNREFUSED) {
695 clnt_perror(mclient, "mount");
696 goto fail; /* don't retry */
698 if (!running_bg && prevt == 0)
699 clnt_perror(mclient, "mount");
700 auth_destroy(mclient->cl_auth);
701 clnt_destroy(mclient);
705 if (!running_bg && prevt == 0)
706 clnt_pcreateerror("mount");
713 prev_bg_host = xstrdup(hostname);
722 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
725 if (status.nfsv2.fhs_status != 0) {
726 errorMsg("%s:%s failed, reason given by server: %s\n",
728 nfs_strerror(status.nfsv2.fhs_status));
731 memcpy(data.root.data,
732 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
734 #if NFS_MOUNT_VERSION >= 4
735 data.root.size = NFS_FHSIZE;
736 memcpy(data.old_root.data,
737 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
741 #if NFS_MOUNT_VERSION >= 4
743 if (status.nfsv3.fhs_status != 0) {
744 errorMsg("%s:%s failed, reason given by server: %s\n",
746 nfs_strerror(status.nfsv3.fhs_status));
749 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
750 memset(data.old_root.data, 0, NFS_FHSIZE);
751 memset(&data.root, 0, sizeof(data.root));
752 data.root.size = fhandle->fhandle3_len;
753 memcpy(data.root.data,
754 (char *) fhandle->fhandle3_val,
755 fhandle->fhandle3_len);
757 data.flags |= NFS_MOUNT_VER3;
761 /* create nfs socket for kernel */
764 if (nfs_mount_version < 3) {
765 printf(_("NFS over TCP is not supported.\n"));
768 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
770 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
772 perror(_("nfs socket"));
775 if (bindresvport(fsock, 0) < 0) {
776 perror(_("nfs bindresvport"));
780 server_addr.sin_port = PMAPPORT;
781 port = pmap_getport(&server_addr, nfsprog, nfsvers,
782 tcp ? IPPROTO_TCP : IPPROTO_UDP);
785 #ifdef NFS_MOUNT_DEBUG
787 printf(_("used portmapper to find NFS port\n"));
790 #ifdef NFS_MOUNT_DEBUG
791 printf(_("using port %d for nfs deamon\n"), port);
793 server_addr.sin_port = htons(port);
795 * connect() the socket for kernels 1.3.10 and below only,
796 * to avoid problems with multihomed hosts.
799 if (linux_version_code() <= 66314
800 && connect(fsock, (struct sockaddr *) &server_addr,
801 sizeof (server_addr)) < 0) {
802 perror(_("nfs connect"));
806 /* prepare data structure for kernel */
809 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
810 strncpy(data.hostname, hostname, sizeof(data.hostname));
814 auth_destroy(mclient->cl_auth);
815 clnt_destroy(mclient);
824 auth_destroy(mclient->cl_auth);
825 clnt_destroy(mclient);
835 * We need to translate between nfs status return values and
836 * the local errno values which may not be the same.
838 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
839 * "after #include <errno.h> the symbol errno is reserved for any use,
840 * it cannot even be used as a struct tag or field name".
844 #define EDQUOT ENOSPC
852 { NFSERR_PERM, EPERM },
853 { NFSERR_NOENT, ENOENT },
855 { NFSERR_NXIO, ENXIO },
856 { NFSERR_ACCES, EACCES },
857 { NFSERR_EXIST, EEXIST },
858 { NFSERR_NODEV, ENODEV },
859 { NFSERR_NOTDIR, ENOTDIR },
860 { NFSERR_ISDIR, EISDIR },
862 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
864 { NFSERR_FBIG, EFBIG },
865 { NFSERR_NOSPC, ENOSPC },
866 { NFSERR_ROFS, EROFS },
867 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
868 { NFSERR_NOTEMPTY, ENOTEMPTY },
869 { NFSERR_DQUOT, EDQUOT },
870 { NFSERR_STALE, ESTALE },
872 { NFSERR_WFLUSH, EWFLUSH },
874 /* Throw in some NFSv3 values for even more fun (HP returns these) */
880 static char *nfs_strerror(int stat)
883 static char buf[256];
885 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
886 if (nfs_errtbl[i].stat == stat)
887 return strerror(nfs_errtbl[i].errnum);
889 sprintf(buf, _("unknown nfs status return value: %d"), stat);
894 xdr_fhandle (XDR *xdrs, fhandle objp)
896 //register int32_t *buf;
898 if (!xdr_opaque (xdrs, objp, FHSIZE))
904 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
906 //register int32_t *buf;
908 if (!xdr_u_int (xdrs, &objp->fhs_status))
910 switch (objp->fhs_status) {
912 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
922 xdr_dirpath (XDR *xdrs, dirpath *objp)
924 //register int32_t *buf;
926 if (!xdr_string (xdrs, objp, MNTPATHLEN))
932 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
934 //register int32_t *buf;
936 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
942 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
944 //register int32_t *buf;
946 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
948 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
949 sizeof (int), (xdrproc_t) xdr_int))
955 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
957 //register int32_t *buf;
959 if (!xdr_enum (xdrs, (enum_t *) objp))
965 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
967 //register int32_t *buf;
969 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
971 switch (objp->fhs_status) {
973 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))