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
31 * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
40 #include <rpc/pmap_prot.h>
41 #include <rpc/pmap_clnt.h>
42 #include <sys/socket.h>
44 #include <sys/utsname.h>
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
51 #include <linux/nfs.h>
52 /* we suppose that libc-dev is providing NFSv3 headers (kernel >= 2.2) */
53 #include <linux/nfs_mount.h>
56 #define HAVE_inet_aton
57 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
61 #define xstrdup strdup
62 #define xstrndup strndup
65 static char *nfs_strerror(int stat);
67 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
69 static int linux_version_code(void)
71 struct utsname my_utsname;
74 if (uname(&my_utsname) == 0) {
75 p = atoi(strtok(my_utsname.release, "."));
76 q = atoi(strtok(NULL, "."));
77 r = atoi(strtok(NULL, "."));
78 return MAKE_VERSION(p, q, r);
84 * nfs_mount_version according to the kernel sources seen at compile time.
86 static int nfs_mount_version = NFS_MOUNT_VERSION;
89 * Unfortunately, the kernel prints annoying console messages
90 * in case of an unexpected nfs mount version (instead of
91 * just returning some error). Therefore we'll have to try
92 * and figure out what version the kernel expects.
95 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
96 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
97 * nfs_mount_version: version this source and running kernel can handle
99 static void find_kernel_nfs_mount_version(void)
101 int kernel_version = linux_version_code();
103 if (kernel_version) {
104 if (kernel_version < MAKE_VERSION(2, 1, 32))
105 nfs_mount_version = 1;
107 nfs_mount_version = 3;
109 if (nfs_mount_version > NFS_MOUNT_VERSION)
110 nfs_mount_version = NFS_MOUNT_VERSION;
113 int nfsmount(const char *spec, const char *node, unsigned long *flags,
114 char **extra_opts, char **mount_opts, int running_bg)
116 static char *prev_bg_host;
122 char *mounthost = NULL;
124 fhandle root_fhandle;
125 struct timeval total_timeout;
126 enum clnt_stat clnt_stat;
127 static struct nfs_mount_data data;
131 struct sockaddr_in server_addr;
132 struct sockaddr_in mount_server_addr;
134 struct timeval retry_timeout;
135 struct fhstatus status;
158 find_kernel_nfs_mount_version();
163 if (strlen(spec) >= sizeof(hostdir)) {
164 fprintf(stderr, _("mount: "
165 "excessively long host:dir argument\n"));
168 strcpy(hostdir, spec);
169 if ((s = strchr(hostdir, ':'))) {
173 /* Ignore all but first hostname in replicated mounts
174 until they can be fully supported. (mack@sgi.com) */
175 if ((s = strchr(hostdir, ','))) {
177 fprintf(stderr, _("mount: warning: "
178 "multiple hostnames not supported\n"));
181 fprintf(stderr, _("mount: "
182 "directory to mount not in host:dir format\n"));
186 server_addr.sin_family = AF_INET;
187 #ifdef HAVE_inet_aton
188 if (!inet_aton(hostname, &server_addr.sin_addr))
191 if ((hp = gethostbyname(hostname)) == NULL) {
192 fprintf(stderr, _("mount: can't get address for %s\n"),
196 if (hp->h_length > sizeof(struct in_addr)) {
197 fprintf(stderr, _("mount: got bad hp->h_length\n"));
198 hp->h_length = sizeof(struct in_addr);
200 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
204 memcpy(&mount_server_addr, &server_addr, sizeof(mount_server_addr));
206 /* add IP address to mtab options for use when unmounting */
208 s = inet_ntoa(server_addr.sin_addr);
209 old_opts = *extra_opts;
212 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
213 fprintf(stderr, _("mount: " "excessively long option argument\n"));
216 sprintf(new_opts, "%s%saddr=%s", old_opts, *old_opts ? "," : "", s);
217 *extra_opts = xstrdup(new_opts);
219 /* Set default options.
220 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
221 * let the kernel decide.
222 * timeo is filled in after we know whether it'll be TCP or UDP. */
223 memset(&data, 0, sizeof(data));
229 #if NFS_MOUNT_VERSION >= 2
230 data.namlen = NAME_MAX;
240 retry = 10000; /* 10000 minutes ~ 1 week */
243 mountprog = MOUNTPROG;
244 mountvers = MOUNTVERS;
247 nfsprog = NFS_PROGRAM;
248 nfsvers = NFS_VERSION;
252 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
253 if ((opteq = strchr(opt, '='))) {
254 val = atoi(opteq + 1);
256 if (!strcmp(opt, "rsize"))
258 else if (!strcmp(opt, "wsize"))
260 else if (!strcmp(opt, "timeo"))
262 else if (!strcmp(opt, "retrans"))
264 else if (!strcmp(opt, "acregmin"))
266 else if (!strcmp(opt, "acregmax"))
268 else if (!strcmp(opt, "acdirmin"))
270 else if (!strcmp(opt, "acdirmax"))
272 else if (!strcmp(opt, "actimeo")) {
277 } else if (!strcmp(opt, "retry"))
279 else if (!strcmp(opt, "port"))
281 else if (!strcmp(opt, "mountport"))
283 else if (!strcmp(opt, "mounthost"))
284 mounthost = xstrndup(opteq + 1,
285 strcspn(opteq + 1, " \t\n\r,"));
286 else if (!strcmp(opt, "mountprog"))
288 else if (!strcmp(opt, "mountvers"))
290 else if (!strcmp(opt, "nfsprog"))
292 else if (!strcmp(opt, "nfsvers") || !strcmp(opt, "vers"))
294 else if (!strcmp(opt, "proto")) {
295 if (!strncmp(opteq + 1, "tcp", 3))
297 else if (!strncmp(opteq + 1, "udp", 3))
300 printf(_("Warning: Unrecognized proto= option.\n"));
301 } else if (!strcmp(opt, "namlen")) {
302 #if NFS_MOUNT_VERSION >= 2
303 if (nfs_mount_version >= 2)
308 ("Warning: Option namlen is not supported.\n"));
309 } else if (!strcmp(opt, "addr"))
312 printf(_("unknown nfs mount parameter: "
313 "%s=%d\n"), opt, val);
318 if (!strncmp(opt, "no", 2)) {
322 if (!strcmp(opt, "bg"))
324 else if (!strcmp(opt, "fg"))
326 else if (!strcmp(opt, "soft"))
328 else if (!strcmp(opt, "hard"))
330 else if (!strcmp(opt, "intr"))
332 else if (!strcmp(opt, "posix"))
334 else if (!strcmp(opt, "cto"))
336 else if (!strcmp(opt, "ac"))
338 else if (!strcmp(opt, "tcp"))
340 else if (!strcmp(opt, "udp"))
342 else if (!strcmp(opt, "lock")) {
343 if (nfs_mount_version >= 3)
347 ("Warning: option nolock is not supported.\n"));
350 printf(_("unknown nfs mount option: "
351 "%s%s\n"), val ? "" : "no", opt);
357 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
358 | (intr ? NFS_MOUNT_INTR : 0)
359 | (posix ? NFS_MOUNT_POSIX : 0)
360 | (nocto ? NFS_MOUNT_NOCTO : 0)
361 | (noac ? NFS_MOUNT_NOAC : 0);
362 #if NFS_MOUNT_VERSION >= 2
363 if (nfs_mount_version >= 2)
364 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
366 #if NFS_MOUNT_VERSION >= 3
367 if (nfs_mount_version >= 3)
368 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
371 /* Adjust options if none specified */
373 data.timeo = tcp ? 70 : 7;
375 #ifdef NFS_MOUNT_DEBUG
376 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
377 data.rsize, data.wsize, data.timeo, data.retrans);
378 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
379 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
380 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
381 port, bg, retry, data.flags);
382 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
383 mountprog, mountvers, nfsprog, nfsvers);
384 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
385 (data.flags & NFS_MOUNT_SOFT) != 0,
386 (data.flags & NFS_MOUNT_INTR) != 0,
387 (data.flags & NFS_MOUNT_POSIX) != 0,
388 (data.flags & NFS_MOUNT_NOCTO) != 0,
389 (data.flags & NFS_MOUNT_NOAC) != 0);
390 #if NFS_MOUNT_VERSION >= 2
391 printf("tcp = %d\n", (data.flags & NFS_MOUNT_TCP) != 0);
395 data.version = nfs_mount_version;
396 *mount_opts = (char *) &data;
398 if (*flags & MS_REMOUNT)
402 * If the previous mount operation on the same host was
403 * backgrounded, and the "bg" for this mount is also set,
404 * give up immediately, to avoid the initial timeout.
406 if (bg && !running_bg &&
407 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
413 /* create mount deamon client */
414 /* See if the nfs host = mount host. */
416 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
417 mount_server_addr.sin_family = AF_INET;
418 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
420 if ((hp = gethostbyname(mounthost)) == NULL) {
421 fprintf(stderr, _("mount: can't get address for %s\n"),
425 if (hp->h_length > sizeof(struct in_addr)) {
426 fprintf(stderr, _("mount: got bad hp->h_length?\n"));
427 hp->h_length = sizeof(struct in_addr);
429 mount_server_addr.sin_family = AF_INET;
430 memcpy(&mount_server_addr.sin_addr,
431 hp->h_addr, hp->h_length);
437 * The following loop implements the mount retries. On the first
438 * call, "running_bg" is 0. When the mount times out, and the
439 * "bg" option is set, the exit status EX_BG will be returned.
440 * For a backgrounded mount, there will be a second call by the
441 * child process with "running_bg" set to 1.
443 * The case where the mount point is not present and the "bg"
444 * option is set, is treated as a timeout. This is done to
445 * support nested mounts.
447 * The "retry" count specified by the user is the number of
448 * minutes to retry before giving up.
450 * Only the first error message will be displayed.
452 retry_timeout.tv_sec = 3;
453 retry_timeout.tv_usec = 0;
454 total_timeout.tv_sec = 20;
455 total_timeout.tv_usec = 0;
456 timeout = time(NULL) + 60 * retry;
461 if (bg && stat(node, &statbuf) == -1) {
463 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
469 /* be careful not to use too many CPU cycles */
473 /* contact the mount daemon via TCP */
474 mount_server_addr.sin_port = htons(mountport);
476 mclient = clnttcp_create(&mount_server_addr,
477 mountprog, mountvers, &msock, 0, 0);
479 /* if this fails, contact the mount daemon via UDP */
481 mount_server_addr.sin_port = htons(mountport);
483 mclient = clntudp_create(&mount_server_addr,
484 mountprog, mountvers,
485 retry_timeout, &msock);
488 /* try to mount hostname:dirname */
489 mclient->cl_auth = authunix_create_default();
490 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
491 (xdrproc_t) xdr_dirpath,
493 (xdrproc_t) xdr_fhstatus,
494 (caddr_t) & status, total_timeout);
495 if (clnt_stat == RPC_SUCCESS)
496 break; /* we're done */
497 if (errno != ECONNREFUSED) {
498 clnt_perror(mclient, "mount");
499 goto fail; /* don't retry */
501 if (!running_bg && prevt == 0)
502 clnt_perror(mclient, "mount");
503 auth_destroy(mclient->cl_auth);
504 clnt_destroy(mclient);
508 if (!running_bg && prevt == 0)
509 clnt_pcreateerror("mount");
516 prev_bg_host = xstrdup(hostname);
526 if (status.fhs_status != 0) {
528 _("mount: %s:%s failed, reason given by server: %s\n"),
529 hostname, dirname, nfs_strerror(status.fhs_status));
532 memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
533 sizeof(root_fhandle));
535 /* create nfs socket for kernel */
538 if (nfs_mount_version < 3) {
539 printf(_("NFS over TCP is not supported.\n"));
542 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
544 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
546 perror(_("nfs socket"));
549 if (bindresvport(fsock, 0) < 0) {
550 perror(_("nfs bindresvport"));
554 server_addr.sin_port = PMAPPORT;
555 port = pmap_getport(&server_addr, nfsprog, nfsvers,
556 tcp ? IPPROTO_TCP : IPPROTO_UDP);
559 #ifdef NFS_MOUNT_DEBUG
561 printf(_("used portmapper to find NFS port\n"));
564 #ifdef NFS_MOUNT_DEBUG
565 printf(_("using port %d for nfs deamon\n"), port);
567 server_addr.sin_port = htons(port);
569 * connect() the socket for kernels 1.3.10 and below only,
570 * to avoid problems with multihomed hosts.
573 if (linux_version_code() <= 66314
574 && connect(fsock, (struct sockaddr *) &server_addr,
575 sizeof(server_addr)) < 0) {
576 perror(_("nfs connect"));
580 /* prepare data structure for kernel */
583 memcpy((char *) &data.root, (char *) &root_fhandle,
584 sizeof(root_fhandle));
585 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
586 strncpy(data.hostname, hostname, sizeof(data.hostname));
590 auth_destroy(mclient->cl_auth);
591 clnt_destroy(mclient);
600 auth_destroy(mclient->cl_auth);
601 clnt_destroy(mclient);
611 * We need to translate between nfs status return values and
612 * the local errno values which may not be the same.
614 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
615 * "after #include <errno.h> the symbol errno is reserved for any use,
616 * it cannot even be used as a struct tag or field name".
620 #define EDQUOT ENOSPC
629 NFSERR_PERM, EPERM}, {
630 NFSERR_NOENT, ENOENT}, {
632 NFSERR_NXIO, ENXIO}, {
633 NFSERR_ACCES, EACCES}, {
634 NFSERR_EXIST, EEXIST}, {
635 NFSERR_NODEV, ENODEV}, {
636 NFSERR_NOTDIR, ENOTDIR}, {
637 NFSERR_ISDIR, EISDIR},
640 NFSERR_INVAL, EINVAL}, /* that Sun forgot */
643 NFSERR_FBIG, EFBIG}, {
644 NFSERR_NOSPC, ENOSPC}, {
645 NFSERR_ROFS, EROFS}, {
646 NFSERR_NAMETOOLONG, ENAMETOOLONG}, {
647 NFSERR_NOTEMPTY, ENOTEMPTY}, {
648 NFSERR_DQUOT, EDQUOT}, {
649 NFSERR_STALE, ESTALE},
652 NFSERR_WFLUSH, EWFLUSH},
654 /* Throw in some NFSv3 values for even more fun (HP returns these) */
660 static char *nfs_strerror(int stat)
663 static char buf[256];
665 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
666 if (nfs_errtbl[i].stat == stat)
667 return strerror(nfs_errtbl[i].errnum);
669 sprintf(buf, _("unknown nfs status return value: %d"), stat);
674 int my_getport(struct in_addr server, struct timeval *timeo, ...)
676 struct sockaddr_in sin;
679 int sock = RPC_ANYSOCK, port;
685 sin.sin_family = AF_INET;
686 sin.sin_addr = server;
687 sin.sin_port = htons(111);
688 clnt = clntudp_create(&sin, 100000, 2, *timeo, &sock);
689 status = clnt_call(clnt, PMAP_GETPORT,
690 &pmap, (xdrproc_t) xdr_pmap,
691 &port, (xdrproc_t) xdr_uint);
692 if (status != SUCCESS) {
714 * Please do not edit this file.
715 * It was generated using rpcgen.
718 #include <rpc/types.h>
722 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
723 * unrestricted use provided that this legend is included on all tape
724 * media and as a part of the software program in whole or part. Users
725 * may copy or modify Sun RPC without charge, but are not authorized
726 * to license or distribute it to anyone else except as part of a product or
727 * program developed by the user or with the express written consent of
728 * Sun Microsystems, Inc.
730 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
731 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
732 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
734 * Sun RPC is provided with no support and without any obligation on the
735 * part of Sun Microsystems, Inc. to assist in its use, correction,
736 * modification or enhancement.
738 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
739 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
740 * OR ANY PART THEREOF.
742 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
743 * or profits or other special, indirect and consequential damages, even if
744 * Sun has been advised of the possibility of such damages.
746 * Sun Microsystems, Inc.
748 * Mountain View, California 94043
751 * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
754 /* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
756 bool_t xdr_fhandle(XDR * xdrs, fhandle objp)
759 if (!xdr_opaque(xdrs, objp, FHSIZE)) {
765 bool_t xdr_fhstatus(XDR * xdrs, fhstatus * objp)
768 if (!xdr_u_int(xdrs, &objp->fhs_status)) {
771 switch (objp->fhs_status) {
773 if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
783 bool_t xdr_dirpath(XDR * xdrs, dirpath * objp)
786 if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
792 bool_t xdr_name(XDR * xdrs, name * objp)
795 if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
801 bool_t xdr_mountlist(XDR * xdrs, mountlist * objp)
805 (xdrs, (char **) objp, sizeof(struct mountbody),
806 (xdrproc_t) xdr_mountbody)) {
812 bool_t xdr_mountbody(XDR * xdrs, mountbody * objp)
815 if (!xdr_name(xdrs, &objp->ml_hostname)) {
818 if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
821 if (!xdr_mountlist(xdrs, &objp->ml_next)) {
827 bool_t xdr_groups(XDR * xdrs, groups * objp)
831 (xdrs, (char **) objp, sizeof(struct groupnode),
832 (xdrproc_t) xdr_groupnode)) {
838 bool_t xdr_groupnode(XDR * xdrs, groupnode * objp)
841 if (!xdr_name(xdrs, &objp->gr_name)) {
844 if (!xdr_groups(xdrs, &objp->gr_next)) {
850 bool_t xdr_exports(XDR * xdrs, exports * objp)
854 (xdrs, (char **) objp, sizeof(struct exportnode),
855 (xdrproc_t) xdr_exportnode)) {
861 bool_t xdr_exportnode(XDR * xdrs, exportnode * objp)
864 if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
867 if (!xdr_groups(xdrs, &objp->ex_groups)) {
870 if (!xdr_exports(xdrs, &objp->ex_next)) {
876 bool_t xdr_ppathcnf(XDR * xdrs, ppathcnf * objp)
883 if (xdrs->x_op == XDR_ENCODE) {
884 buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
886 if (!xdr_int(xdrs, &objp->pc_link_max)) {
889 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
892 if (!xdr_short(xdrs, &objp->pc_max_input)) {
895 if (!xdr_short(xdrs, &objp->pc_name_max)) {
898 if (!xdr_short(xdrs, &objp->pc_path_max)) {
901 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
906 IXDR_PUT_LONG(buf, objp->pc_link_max);
907 IXDR_PUT_SHORT(buf, objp->pc_max_canon);
908 IXDR_PUT_SHORT(buf, objp->pc_max_input);
909 IXDR_PUT_SHORT(buf, objp->pc_name_max);
910 IXDR_PUT_SHORT(buf, objp->pc_path_max);
911 IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
913 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
916 if (!xdr_char(xdrs, &objp->pc_xxx)) {
919 buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
922 (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
923 (xdrproc_t) xdr_short)) {
929 register short *genp;
931 for (i = 0, genp = objp->pc_mask; i < 2; i++) {
932 IXDR_PUT_SHORT(buf, *genp++);
938 } else if (xdrs->x_op == XDR_DECODE) {
939 buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
941 if (!xdr_int(xdrs, &objp->pc_link_max)) {
944 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
947 if (!xdr_short(xdrs, &objp->pc_max_input)) {
950 if (!xdr_short(xdrs, &objp->pc_name_max)) {
953 if (!xdr_short(xdrs, &objp->pc_path_max)) {
956 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
961 objp->pc_link_max = IXDR_GET_LONG(buf);
962 objp->pc_max_canon = IXDR_GET_SHORT(buf);
963 objp->pc_max_input = IXDR_GET_SHORT(buf);
964 objp->pc_name_max = IXDR_GET_SHORT(buf);
965 objp->pc_path_max = IXDR_GET_SHORT(buf);
966 objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
968 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
971 if (!xdr_char(xdrs, &objp->pc_xxx)) {
974 buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
977 (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
978 (xdrproc_t) xdr_short)) {
984 register short *genp;
986 for (i = 0, genp = objp->pc_mask; i < 2; i++) {
987 *genp++ = IXDR_GET_SHORT(buf);
994 if (!xdr_int(xdrs, &objp->pc_link_max)) {
997 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
1000 if (!xdr_short(xdrs, &objp->pc_max_input)) {
1003 if (!xdr_short(xdrs, &objp->pc_name_max)) {
1006 if (!xdr_short(xdrs, &objp->pc_path_max)) {
1009 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
1012 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
1015 if (!xdr_char(xdrs, &objp->pc_xxx)) {
1019 (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
1020 (xdrproc_t) xdr_short)) {
1028 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
1029 * unrestricted use provided that this legend is included on all tape
1030 * media and as a part of the software program in whole or part. Users
1031 * may copy or modify Sun RPC without charge, but are not authorized
1032 * to license or distribute it to anyone else except as part of a product or
1033 * program developed by the user or with the express written consent of
1034 * Sun Microsystems, Inc.
1036 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1037 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1038 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1040 * Sun RPC is provided with no support and without any obligation on the
1041 * part of Sun Microsystems, Inc. to assist in its use, correction,
1042 * modification or enhancement.
1044 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
1045 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
1046 * OR ANY PART THEREOF.
1048 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
1049 * or profits or other special, indirect and consequential damages, even if
1050 * Sun has been advised of the possibility of such damages.
1052 * Sun Microsystems, Inc.
1053 * 2550 Garcia Avenue
1054 * Mountain View, California 94043
1057 * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
1060 /* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
1062 #include <string.h> /* for memset() */
1064 /* Default timeout can be changed using clnt_control() */
1065 static struct timeval TIMEOUT = { 25, 0 };
1067 void *mountproc_null_1(argp, clnt)
1071 static char clnt_res;
1073 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1075 (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
1076 (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1079 return ((void *) &clnt_res);
1082 fhstatus *mountproc_mnt_1(argp, clnt)
1086 static fhstatus clnt_res;
1088 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1089 if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
1090 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
1091 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1097 mountlist *mountproc_dump_1(argp, clnt)
1101 static mountlist clnt_res;
1103 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1104 if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void,
1105 (caddr_t) argp, (xdrproc_t) xdr_mountlist,
1106 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1112 void *mountproc_umnt_1(argp, clnt)
1116 static char clnt_res;
1118 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1119 if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
1120 (caddr_t) argp, (xdrproc_t) xdr_void,
1121 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1124 return ((void *) &clnt_res);
1127 void *mountproc_umntall_1(argp, clnt)
1131 static char clnt_res;
1133 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1134 if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
1135 (caddr_t) argp, (xdrproc_t) xdr_void,
1136 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1139 return ((void *) &clnt_res);
1142 exports *mountproc_export_1(argp, clnt)
1146 static exports clnt_res;
1148 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1149 if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
1150 (caddr_t) argp, (xdrproc_t) xdr_exports,
1151 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1157 exports *mountproc_exportall_1(argp, clnt)
1161 static exports clnt_res;
1163 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1164 if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void,
1165 (caddr_t) argp, (xdrproc_t) xdr_exports,
1166 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1172 void *mountproc_null_2(argp, clnt)
1176 static char clnt_res;
1178 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1180 (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
1181 (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1184 return ((void *) &clnt_res);
1187 fhstatus *mountproc_mnt_2(argp, clnt)
1191 static fhstatus clnt_res;
1193 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1194 if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
1195 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
1196 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1202 mountlist *mountproc_dump_2(argp, clnt)
1206 static mountlist clnt_res;
1208 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1209 if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp,
1210 (xdrproc_t) xdr_mountlist, (caddr_t) & clnt_res,
1211 TIMEOUT) != RPC_SUCCESS) {
1217 void *mountproc_umnt_2(argp, clnt)
1221 static char clnt_res;
1223 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1224 if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
1225 (caddr_t) argp, (xdrproc_t) xdr_void,
1226 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1229 return ((void *) &clnt_res);
1232 void *mountproc_umntall_2(argp, clnt)
1236 static char clnt_res;
1238 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1239 if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
1240 (caddr_t) argp, (xdrproc_t) xdr_void,
1241 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1244 return ((void *) &clnt_res);
1247 exports *mountproc_export_2(argp, clnt)
1251 static exports clnt_res;
1253 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1254 if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
1255 argp, (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
1256 TIMEOUT) != RPC_SUCCESS) {
1262 exports *mountproc_exportall_2(argp, clnt)
1266 static exports clnt_res;
1268 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1269 if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp,
1270 (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
1271 TIMEOUT) != RPC_SUCCESS) {
1277 ppathcnf *mountproc_pathconf_2(argp, clnt)
1281 static ppathcnf clnt_res;
1283 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1284 if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath,
1285 (caddr_t) argp, (xdrproc_t) xdr_ppathcnf,
1286 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {