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
42 #include <rpc/pmap_prot.h>
43 #include <rpc/pmap_clnt.h>
44 #include <sys/socket.h>
46 #include <sys/utsname.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
52 #include <linux/nfs.h> /* For the kernels nfs stuff */
55 /* Disable the nls stuff */
56 # undef bindtextdomain
57 # define bindtextdomain(Domain, Directory) /* empty */
59 # define textdomain(Domain) /* empty */
60 # define _(Text) (Text)
61 # define N_(Text) (Text)
63 #define MS_MGC_VAL 0xc0ed0000 /* Magic number indicatng "new" flags */
64 #define MS_RDONLY 1 /* Mount read-only */
65 #define MS_NOSUID 2 /* Ignore suid and sgid bits */
66 #define MS_NODEV 4 /* Disallow access to device special files */
67 #define MS_NOEXEC 8 /* Disallow program execution */
68 #define MS_SYNCHRONOUS 16 /* Writes are synced at once */
69 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
70 #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
71 #define S_QUOTA 128 /* Quota initialized for file/directory/symlink */
72 #define S_APPEND 256 /* Append-only file */
73 #define S_IMMUTABLE 512 /* Immutable file */
74 #define MS_NOATIME 1024 /* Do not update access times. */
75 #define MS_NODIRATIME 2048 /* Do not update directory access times */
79 * We want to be able to compile mount on old kernels in such a way
80 * that the binary will work well on more recent kernels.
81 * Thus, if necessary we teach nfsmount.c the structure of new fields
82 * that will come later.
84 * Moreover, the new kernel includes conflict with glibc includes
85 * so it is easiest to ignore the kernel altogether (at compile time).
88 #define NFS_MOUNT_VERSION 4
95 unsigned char data[64];
98 struct nfs_mount_data {
101 struct nfs2_fh old_root; /* 1 */
107 int acregmin; /* 1 */
108 int acregmax; /* 1 */
109 int acdirmin; /* 1 */
110 int acdirmax; /* 1 */
111 struct sockaddr_in addr; /* 1 */
112 char hostname[256]; /* 1 */
114 unsigned int bsize; /* 3 */
115 struct nfs3_fh root; /* 4 */
118 /* bits in the flags field */
120 #define NFS_MOUNT_SOFT 0x0001 /* 1 */
121 #define NFS_MOUNT_INTR 0x0002 /* 1 */
122 #define NFS_MOUNT_SECURE 0x0004 /* 1 */
123 #define NFS_MOUNT_POSIX 0x0008 /* 1 */
124 #define NFS_MOUNT_NOCTO 0x0010 /* 1 */
125 #define NFS_MOUNT_NOAC 0x0020 /* 1 */
126 #define NFS_MOUNT_TCP 0x0040 /* 2 */
127 #define NFS_MOUNT_VER3 0x0080 /* 3 */
128 #define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
129 #define NFS_MOUNT_NONLM 0x0200 /* 3 */
132 #define UTIL_LINUX_VERSION "2.10m"
133 #define util_linux_version "util-linux-2.10m"
135 #define HAVE_inet_aton
140 #define HAVE_locale_h
141 #define HAVE_libintl_h
143 #define HAVE_langinfo_h
144 #define HAVE_progname
146 #define HAVE_nanosleep
147 #define HAVE_personality
148 #define HAVE_tm_gmtoff
150 extern char *xstrdup (const char *s);
151 extern char *xstrndup (const char *s, int n);
152 static char *nfs_strerror(int stat);
154 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
155 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
157 #define EX_FAIL 32 /* mount failure */
158 #define EX_BG 256 /* retry in background (internal only) */
162 linux_version_code(void) {
163 struct utsname my_utsname;
166 if (uname(&my_utsname) == 0) {
167 p = atoi(strtok(my_utsname.release, "."));
168 q = atoi(strtok(NULL, "."));
169 r = atoi(strtok(NULL, "."));
170 return MAKE_VERSION(p,q,r);
176 * nfs_mount_version according to the sources seen at compile time.
178 int nfs_mount_version = NFS_MOUNT_VERSION;
181 * Unfortunately, the kernel prints annoying console messages
182 * in case of an unexpected nfs mount version (instead of
183 * just returning some error). Therefore we'll have to try
184 * and figure out what version the kernel expects.
187 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
188 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
189 * nfs_mount_version: version this source and running kernel can handle
192 find_kernel_nfs_mount_version(void) {
193 static int kernel_version = 0;
198 kernel_version = linux_version_code();
200 if (kernel_version) {
201 if (kernel_version < MAKE_VERSION(2,1,32))
202 nfs_mount_version = 1;
203 else if (kernel_version < MAKE_VERSION(2,3,99))
204 nfs_mount_version = 3;
206 nfs_mount_version = 4; /* since 2.3.99pre4 */
208 if (nfs_mount_version > NFS_MOUNT_VERSION)
209 nfs_mount_version = NFS_MOUNT_VERSION;
213 get_mountport(struct sockaddr_in *server_addr,
215 long unsigned version,
219 struct pmaplist *pmap;
220 static struct pmap p = {0, 0, 0, 0};
222 server_addr->sin_port = PMAPPORT;
223 pmap = pmap_getmaps(server_addr);
225 if (version > MAX_NFSPROT)
226 version = MAX_NFSPROT;
235 if (pmap->pml_map.pm_prog != prog)
237 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
239 if (version > 2 && pmap->pml_map.pm_vers != version)
241 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
243 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
244 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
245 (port && pmap->pml_map.pm_port != port))
247 memcpy(&p, &pmap->pml_map, sizeof(p));
249 pmap = pmap->pml_next;
252 p.pm_vers = MOUNTVERS;
254 p.pm_port = MOUNTPORT;
256 p.pm_prot = IPPROTO_TCP;
260 int nfsmount(const char *spec, const char *node, int *flags,
261 char **extra_opts, char **mount_opts, int running_bg)
263 static char *prev_bg_host;
269 char *mounthost=NULL;
271 struct timeval total_timeout;
272 enum clnt_stat clnt_stat;
273 static struct nfs_mount_data data;
277 struct sockaddr_in server_addr;
278 struct sockaddr_in mount_server_addr;
281 struct timeval retry_timeout;
283 struct fhstatus nfsv2;
284 struct mountres3 nfsv3;
309 find_kernel_nfs_mount_version();
314 if (strlen(spec) >= sizeof(hostdir)) {
315 fprintf(stderr, _("mount: "
316 "excessively long host:dir argument\n"));
319 strcpy(hostdir, spec);
320 if ((s = strchr(hostdir, ':'))) {
324 /* Ignore all but first hostname in replicated mounts
325 until they can be fully supported. (mack@sgi.com) */
326 if ((s = strchr(hostdir, ','))) {
328 fprintf(stderr, _("mount: warning: "
329 "multiple hostnames not supported\n"));
332 fprintf(stderr, _("mount: "
333 "directory to mount not in host:dir format\n"));
337 server_addr.sin_family = AF_INET;
338 #ifdef HAVE_inet_aton
339 if (!inet_aton(hostname, &server_addr.sin_addr))
342 if ((hp = gethostbyname(hostname)) == NULL) {
343 fprintf(stderr, _("mount: can't get address for %s\n"),
347 if (hp->h_length > sizeof(struct in_addr)) {
349 _("mount: got bad hp->h_length\n"));
350 hp->h_length = sizeof(struct in_addr);
352 memcpy(&server_addr.sin_addr,
353 hp->h_addr, hp->h_length);
357 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
359 /* add IP address to mtab options for use when unmounting */
361 s = inet_ntoa(server_addr.sin_addr);
362 old_opts = *extra_opts;
365 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
366 fprintf(stderr, _("mount: "
367 "excessively long option argument\n"));
370 sprintf(new_opts, "%s%saddr=%s",
371 old_opts, *old_opts ? "," : "", s);
372 *extra_opts = xstrdup(new_opts);
374 /* Set default options.
375 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
376 * let the kernel decide.
377 * timeo is filled in after we know whether it'll be TCP or UDP. */
378 memset(&data, 0, sizeof(data));
384 #if NFS_MOUNT_VERSION >= 2
385 data.namlen = NAME_MAX;
395 retry = 10000; /* 10000 minutes ~ 1 week */
398 mountprog = MOUNTPROG;
402 nfsprog = NFS_PROGRAM;
407 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
408 if ((opteq = strchr(opt, '='))) {
409 val = atoi(opteq + 1);
411 if (!strcmp(opt, "rsize"))
413 else if (!strcmp(opt, "wsize"))
415 else if (!strcmp(opt, "timeo"))
417 else if (!strcmp(opt, "retrans"))
419 else if (!strcmp(opt, "acregmin"))
421 else if (!strcmp(opt, "acregmax"))
423 else if (!strcmp(opt, "acdirmin"))
425 else if (!strcmp(opt, "acdirmax"))
427 else if (!strcmp(opt, "actimeo")) {
433 else if (!strcmp(opt, "retry"))
435 else if (!strcmp(opt, "port"))
437 else if (!strcmp(opt, "mountport"))
439 else if (!strcmp(opt, "mounthost"))
440 mounthost=xstrndup(opteq+1,
441 strcspn(opteq+1," \t\n\r,"));
442 else if (!strcmp(opt, "mountprog"))
444 else if (!strcmp(opt, "mountvers"))
446 else if (!strcmp(opt, "nfsprog"))
448 else if (!strcmp(opt, "nfsvers") ||
449 !strcmp(opt, "vers"))
451 else if (!strcmp(opt, "proto")) {
452 if (!strncmp(opteq+1, "tcp", 3))
454 else if (!strncmp(opteq+1, "udp", 3))
457 printf(_("Warning: Unrecognized proto= option.\n"));
458 } else if (!strcmp(opt, "namlen")) {
459 #if NFS_MOUNT_VERSION >= 2
460 if (nfs_mount_version >= 2)
464 printf(_("Warning: Option namlen is not supported.\n"));
465 } else if (!strcmp(opt, "addr"))
468 printf(_("unknown nfs mount parameter: "
469 "%s=%d\n"), opt, val);
475 if (!strncmp(opt, "no", 2)) {
479 if (!strcmp(opt, "bg"))
481 else if (!strcmp(opt, "fg"))
483 else if (!strcmp(opt, "soft"))
485 else if (!strcmp(opt, "hard"))
487 else if (!strcmp(opt, "intr"))
489 else if (!strcmp(opt, "posix"))
491 else if (!strcmp(opt, "cto"))
493 else if (!strcmp(opt, "ac"))
495 else if (!strcmp(opt, "tcp"))
497 else if (!strcmp(opt, "udp"))
499 else if (!strcmp(opt, "lock")) {
500 if (nfs_mount_version >= 3)
503 printf(_("Warning: option nolock is not supported.\n"));
505 printf(_("unknown nfs mount option: "
506 "%s%s\n"), val ? "" : "no", opt);
511 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
513 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
514 | (intr ? NFS_MOUNT_INTR : 0)
515 | (posix ? NFS_MOUNT_POSIX : 0)
516 | (nocto ? NFS_MOUNT_NOCTO : 0)
517 | (noac ? NFS_MOUNT_NOAC : 0);
518 #if NFS_MOUNT_VERSION >= 2
519 if (nfs_mount_version >= 2)
520 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
522 #if NFS_MOUNT_VERSION >= 3
523 if (nfs_mount_version >= 3)
524 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
526 if (nfsvers > MAX_NFSPROT) {
527 fprintf(stderr, "NFSv%d not supported!\n", nfsvers);
530 if (mountvers > MAX_NFSPROT) {
531 fprintf(stderr, "NFSv%d not supported!\n", nfsvers);
534 if (nfsvers && !mountvers)
535 mountvers = (nfsvers < 3) ? 1 : nfsvers;
536 if (nfsvers && nfsvers < mountvers) {
540 /* Adjust options if none specified */
542 data.timeo = tcp ? 70 : 7;
544 #ifdef NFS_MOUNT_DEBUG
545 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
546 data.rsize, data.wsize, data.timeo, data.retrans);
547 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
548 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
549 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
550 port, bg, retry, data.flags);
551 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
552 mountprog, mountvers, nfsprog, nfsvers);
553 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
554 (data.flags & NFS_MOUNT_SOFT) != 0,
555 (data.flags & NFS_MOUNT_INTR) != 0,
556 (data.flags & NFS_MOUNT_POSIX) != 0,
557 (data.flags & NFS_MOUNT_NOCTO) != 0,
558 (data.flags & NFS_MOUNT_NOAC) != 0);
559 #if NFS_MOUNT_VERSION >= 2
561 (data.flags & NFS_MOUNT_TCP) != 0);
565 data.version = nfs_mount_version;
566 *mount_opts = (char *) &data;
568 if (*flags & MS_REMOUNT)
572 * If the previous mount operation on the same host was
573 * backgrounded, and the "bg" for this mount is also set,
574 * give up immediately, to avoid the initial timeout.
576 if (bg && !running_bg &&
577 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
583 /* create mount deamon client */
584 /* See if the nfs host = mount host. */
586 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
587 mount_server_addr.sin_family = AF_INET;
588 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
590 if ((hp = gethostbyname(mounthost)) == NULL) {
591 fprintf(stderr, _("mount: can't get address for %s\n"),
595 if (hp->h_length > sizeof(struct in_addr)) {
597 _("mount: got bad hp->h_length?\n"));
598 hp->h_length = sizeof(struct in_addr);
600 mount_server_addr.sin_family = AF_INET;
601 memcpy(&mount_server_addr.sin_addr,
602 hp->h_addr, hp->h_length);
608 * The following loop implements the mount retries. On the first
609 * call, "running_bg" is 0. When the mount times out, and the
610 * "bg" option is set, the exit status EX_BG will be returned.
611 * For a backgrounded mount, there will be a second call by the
612 * child process with "running_bg" set to 1.
614 * The case where the mount point is not present and the "bg"
615 * option is set, is treated as a timeout. This is done to
616 * support nested mounts.
618 * The "retry" count specified by the user is the number of
619 * minutes to retry before giving up.
621 * Only the first error message will be displayed.
623 retry_timeout.tv_sec = 3;
624 retry_timeout.tv_usec = 0;
625 total_timeout.tv_sec = 20;
626 total_timeout.tv_usec = 0;
627 timeout = time(NULL) + 60 * retry;
632 if (bg && stat(node, &statbuf) == -1) {
634 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
640 /* be careful not to use too many CPU cycles */
644 pm_mnt = get_mountport(&mount_server_addr,
650 /* contact the mount daemon via TCP */
651 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
654 switch (pm_mnt->pm_prot) {
656 mclient = clntudp_create(&mount_server_addr,
663 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
666 mclient = clnttcp_create(&mount_server_addr,
675 /* try to mount hostname:dirname */
676 mclient->cl_auth = authunix_create_default();
678 /* make pointers in xdr_mountres3 NULL so
679 * that xdr_array allocates memory for us
681 memset(&status, 0, sizeof(status));
683 if (pm_mnt->pm_vers == 3)
684 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
685 (xdrproc_t) xdr_dirpath,
687 (xdrproc_t) xdr_mountres3,
691 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
692 (xdrproc_t) xdr_dirpath,
694 (xdrproc_t) xdr_fhstatus,
698 if (clnt_stat == RPC_SUCCESS)
699 break; /* we're done */
700 if (errno != ECONNREFUSED) {
701 clnt_perror(mclient, "mount");
702 goto fail; /* don't retry */
704 if (!running_bg && prevt == 0)
705 clnt_perror(mclient, "mount");
706 auth_destroy(mclient->cl_auth);
707 clnt_destroy(mclient);
711 if (!running_bg && prevt == 0)
712 clnt_pcreateerror("mount");
719 prev_bg_host = xstrdup(hostname);
728 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
731 if (status.nfsv2.fhs_status != 0) {
733 "mount: %s:%s failed, reason given by server: %s\n",
735 nfs_strerror(status.nfsv2.fhs_status));
738 memcpy(data.root.data,
739 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
741 #if NFS_MOUNT_VERSION >= 4
742 data.root.size = NFS_FHSIZE;
743 memcpy(data.old_root.data,
744 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
748 #if NFS_MOUNT_VERSION >= 4
750 if (status.nfsv3.fhs_status != 0) {
752 "mount: %s:%s failed, reason given by server: %s\n",
754 nfs_strerror(status.nfsv3.fhs_status));
757 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
758 memset(data.old_root.data, 0, NFS_FHSIZE);
759 memset(&data.root, 0, sizeof(data.root));
760 data.root.size = fhandle->fhandle3_len;
761 memcpy(data.root.data,
762 (char *) fhandle->fhandle3_val,
763 fhandle->fhandle3_len);
765 data.flags |= NFS_MOUNT_VER3;
769 /* create nfs socket for kernel */
772 if (nfs_mount_version < 3) {
773 printf(_("NFS over TCP is not supported.\n"));
776 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
778 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
780 perror(_("nfs socket"));
783 if (bindresvport(fsock, 0) < 0) {
784 perror(_("nfs bindresvport"));
788 server_addr.sin_port = PMAPPORT;
789 port = pmap_getport(&server_addr, nfsprog, nfsvers,
790 tcp ? IPPROTO_TCP : IPPROTO_UDP);
793 #ifdef NFS_MOUNT_DEBUG
795 printf(_("used portmapper to find NFS port\n"));
798 #ifdef NFS_MOUNT_DEBUG
799 printf(_("using port %d for nfs deamon\n"), port);
801 server_addr.sin_port = htons(port);
803 * connect() the socket for kernels 1.3.10 and below only,
804 * to avoid problems with multihomed hosts.
807 if (linux_version_code() <= 66314
808 && connect(fsock, (struct sockaddr *) &server_addr,
809 sizeof (server_addr)) < 0) {
810 perror(_("nfs connect"));
814 /* prepare data structure for kernel */
817 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
818 strncpy(data.hostname, hostname, sizeof(data.hostname));
822 auth_destroy(mclient->cl_auth);
823 clnt_destroy(mclient);
832 auth_destroy(mclient->cl_auth);
833 clnt_destroy(mclient);
843 * We need to translate between nfs status return values and
844 * the local errno values which may not be the same.
846 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
847 * "after #include <errno.h> the symbol errno is reserved for any use,
848 * it cannot even be used as a struct tag or field name".
852 #define EDQUOT ENOSPC
860 { NFSERR_PERM, EPERM },
861 { NFSERR_NOENT, ENOENT },
863 { NFSERR_NXIO, ENXIO },
864 { NFSERR_ACCES, EACCES },
865 { NFSERR_EXIST, EEXIST },
866 { NFSERR_NODEV, ENODEV },
867 { NFSERR_NOTDIR, ENOTDIR },
868 { NFSERR_ISDIR, EISDIR },
870 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
872 { NFSERR_FBIG, EFBIG },
873 { NFSERR_NOSPC, ENOSPC },
874 { NFSERR_ROFS, EROFS },
875 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
876 { NFSERR_NOTEMPTY, ENOTEMPTY },
877 { NFSERR_DQUOT, EDQUOT },
878 { NFSERR_STALE, ESTALE },
880 { NFSERR_WFLUSH, EWFLUSH },
882 /* Throw in some NFSv3 values for even more fun (HP returns these) */
888 static char *nfs_strerror(int stat)
891 static char buf[256];
893 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
894 if (nfs_errtbl[i].stat == stat)
895 return strerror(nfs_errtbl[i].errnum);
897 sprintf(buf, _("unknown nfs status return value: %d"), stat);
902 xdr_fhandle (XDR *xdrs, fhandle objp)
904 //register int32_t *buf;
906 if (!xdr_opaque (xdrs, objp, FHSIZE))
912 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
914 //register int32_t *buf;
916 if (!xdr_u_int (xdrs, &objp->fhs_status))
918 switch (objp->fhs_status) {
920 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
930 xdr_dirpath (XDR *xdrs, dirpath *objp)
932 //register int32_t *buf;
934 if (!xdr_string (xdrs, objp, MNTPATHLEN))
940 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
942 //register int32_t *buf;
944 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
950 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
952 //register int32_t *buf;
954 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
956 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
957 sizeof (int), (xdrproc_t) xdr_int))
963 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
965 //register int32_t *buf;
967 if (!xdr_enum (xdrs, (enum_t *) objp))
973 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
975 //register int32_t *buf;
977 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
979 switch (objp->fhs_status) {
981 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))