2 * nfsmount.c -- Linux NFS mount
3 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * Wed Feb 8 12:51:48 1995, biro@yggdrasil.com (Ross Biro): allow all port
16 * numbers to be specified on the command line.
18 * Fri, 8 Mar 1996 18:01:39, Swen Thuemmler <swen@uni-paderborn.de>:
19 * Omit the call to connect() for Linux version 1.3.11 or later.
21 * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
22 * Implemented the "bg", "fg" and "retry" mount options for NFS.
24 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
25 * - added Native Language Support
30 * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
39 #include <rpc/pmap_prot.h>
40 #include <rpc/pmap_clnt.h>
41 #include <sys/socket.h>
43 #include <sys/utsname.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
50 #include <linux/nfs.h>
51 /* we suppose that libc-dev is providing NFSv3 headers (kernel >= 2.2) */
52 #include <linux/nfs_mount.h>
55 #define HAVE_inet_aton
56 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
60 #define xstrdup strdup
61 #define xstrndup strndup
64 static char *nfs_strerror(int stat);
66 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
69 linux_version_code(void) {
70 struct utsname my_utsname;
73 if (uname(&my_utsname) == 0) {
74 p = atoi(strtok(my_utsname.release, "."));
75 q = atoi(strtok(NULL, "."));
76 r = atoi(strtok(NULL, "."));
77 return MAKE_VERSION(p,q,r);
83 * nfs_mount_version according to the kernel sources seen at compile time.
85 static int nfs_mount_version = NFS_MOUNT_VERSION;
88 * Unfortunately, the kernel prints annoying console messages
89 * in case of an unexpected nfs mount version (instead of
90 * just returning some error). Therefore we'll have to try
91 * and figure out what version the kernel expects.
94 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
95 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
96 * nfs_mount_version: version this source and running kernel can handle
99 find_kernel_nfs_mount_version(void) {
100 int kernel_version = linux_version_code();
102 if (kernel_version) {
103 if (kernel_version < MAKE_VERSION(2,1,32))
104 nfs_mount_version = 1;
106 nfs_mount_version = 3;
108 if (nfs_mount_version > NFS_MOUNT_VERSION)
109 nfs_mount_version = NFS_MOUNT_VERSION;
112 int nfsmount(const char *spec, const char *node, unsigned long *flags,
113 char **extra_opts, char **mount_opts, int running_bg)
115 static char *prev_bg_host;
121 char *mounthost=NULL;
123 fhandle root_fhandle;
124 struct timeval total_timeout;
125 enum clnt_stat clnt_stat;
126 static struct nfs_mount_data data;
130 struct sockaddr_in server_addr;
131 struct sockaddr_in mount_server_addr;
133 struct timeval retry_timeout;
134 struct fhstatus status;
157 find_kernel_nfs_mount_version();
162 if (strlen(spec) >= sizeof(hostdir)) {
163 fprintf(stderr, _("mount: "
164 "excessively long host:dir argument\n"));
167 strcpy(hostdir, spec);
168 if ((s = strchr(hostdir, ':'))) {
172 /* Ignore all but first hostname in replicated mounts
173 until they can be fully supported. (mack@sgi.com) */
174 if ((s = strchr(hostdir, ','))) {
176 fprintf(stderr, _("mount: warning: "
177 "multiple hostnames not supported\n"));
180 fprintf(stderr, _("mount: "
181 "directory to mount not in host:dir format\n"));
185 server_addr.sin_family = AF_INET;
186 #ifdef HAVE_inet_aton
187 if (!inet_aton(hostname, &server_addr.sin_addr))
190 if ((hp = gethostbyname(hostname)) == NULL) {
191 fprintf(stderr, _("mount: can't get address for %s\n"),
195 if (hp->h_length > sizeof(struct in_addr)) {
197 _("mount: got bad hp->h_length\n"));
198 hp->h_length = sizeof(struct in_addr);
200 memcpy(&server_addr.sin_addr,
201 hp->h_addr, hp->h_length);
205 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
207 /* add IP address to mtab options for use when unmounting */
209 s = inet_ntoa(server_addr.sin_addr);
210 old_opts = *extra_opts;
213 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
214 fprintf(stderr, _("mount: "
215 "excessively long option argument\n"));
218 sprintf(new_opts, "%s%saddr=%s",
219 old_opts, *old_opts ? "," : "", s);
220 *extra_opts = xstrdup(new_opts);
222 /* Set default options.
223 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
224 * let the kernel decide.
225 * timeo is filled in after we know whether it'll be TCP or UDP. */
226 memset(&data, 0, sizeof(data));
232 #if NFS_MOUNT_VERSION >= 2
233 data.namlen = NAME_MAX;
243 retry = 10000; /* 10000 minutes ~ 1 week */
246 mountprog = MOUNTPROG;
247 mountvers = MOUNTVERS;
250 nfsprog = NFS_PROGRAM;
251 nfsvers = NFS_VERSION;
255 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
256 if ((opteq = strchr(opt, '='))) {
257 val = atoi(opteq + 1);
259 if (!strcmp(opt, "rsize"))
261 else if (!strcmp(opt, "wsize"))
263 else if (!strcmp(opt, "timeo"))
265 else if (!strcmp(opt, "retrans"))
267 else if (!strcmp(opt, "acregmin"))
269 else if (!strcmp(opt, "acregmax"))
271 else if (!strcmp(opt, "acdirmin"))
273 else if (!strcmp(opt, "acdirmax"))
275 else if (!strcmp(opt, "actimeo")) {
281 else if (!strcmp(opt, "retry"))
283 else if (!strcmp(opt, "port"))
285 else if (!strcmp(opt, "mountport"))
287 else if (!strcmp(opt, "mounthost"))
288 mounthost=xstrndup(opteq+1,
289 strcspn(opteq+1," \t\n\r,"));
290 else if (!strcmp(opt, "mountprog"))
292 else if (!strcmp(opt, "mountvers"))
294 else if (!strcmp(opt, "nfsprog"))
296 else if (!strcmp(opt, "nfsvers") ||
297 !strcmp(opt, "vers"))
299 else if (!strcmp(opt, "proto")) {
300 if (!strncmp(opteq+1, "tcp", 3))
302 else if (!strncmp(opteq+1, "udp", 3))
305 printf(_("Warning: Unrecognized proto= option.\n"));
306 } else if (!strcmp(opt, "namlen")) {
307 #if NFS_MOUNT_VERSION >= 2
308 if (nfs_mount_version >= 2)
312 printf(_("Warning: Option namlen is not supported.\n"));
313 } else if (!strcmp(opt, "addr"))
316 printf(_("unknown nfs mount parameter: "
317 "%s=%d\n"), opt, val);
323 if (!strncmp(opt, "no", 2)) {
327 if (!strcmp(opt, "bg"))
329 else if (!strcmp(opt, "fg"))
331 else if (!strcmp(opt, "soft"))
333 else if (!strcmp(opt, "hard"))
335 else if (!strcmp(opt, "intr"))
337 else if (!strcmp(opt, "posix"))
339 else if (!strcmp(opt, "cto"))
341 else if (!strcmp(opt, "ac"))
343 else if (!strcmp(opt, "tcp"))
345 else if (!strcmp(opt, "udp"))
347 else if (!strcmp(opt, "lock")) {
348 if (nfs_mount_version >= 3)
351 printf(_("Warning: option nolock is not supported.\n"));
354 printf(_("unknown nfs mount option: "
355 "%s%s\n"), val ? "" : "no", opt);
361 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
362 | (intr ? NFS_MOUNT_INTR : 0)
363 | (posix ? NFS_MOUNT_POSIX : 0)
364 | (nocto ? NFS_MOUNT_NOCTO : 0)
365 | (noac ? NFS_MOUNT_NOAC : 0);
366 #if NFS_MOUNT_VERSION >= 2
367 if (nfs_mount_version >= 2)
368 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
370 #if NFS_MOUNT_VERSION >= 3
371 if (nfs_mount_version >= 3)
372 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
375 /* Adjust options if none specified */
377 data.timeo = tcp ? 70 : 7;
379 #ifdef NFS_MOUNT_DEBUG
380 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
381 data.rsize, data.wsize, data.timeo, data.retrans);
382 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
383 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
384 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
385 port, bg, retry, data.flags);
386 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
387 mountprog, mountvers, nfsprog, nfsvers);
388 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
389 (data.flags & NFS_MOUNT_SOFT) != 0,
390 (data.flags & NFS_MOUNT_INTR) != 0,
391 (data.flags & NFS_MOUNT_POSIX) != 0,
392 (data.flags & NFS_MOUNT_NOCTO) != 0,
393 (data.flags & NFS_MOUNT_NOAC) != 0);
394 #if NFS_MOUNT_VERSION >= 2
396 (data.flags & NFS_MOUNT_TCP) != 0);
400 data.version = nfs_mount_version;
401 *mount_opts = (char *) &data;
403 if (*flags & MS_REMOUNT)
407 * If the previous mount operation on the same host was
408 * backgrounded, and the "bg" for this mount is also set,
409 * give up immediately, to avoid the initial timeout.
411 if (bg && !running_bg &&
412 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
418 /* create mount deamon client */
419 /* See if the nfs host = mount host. */
421 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
422 mount_server_addr.sin_family = AF_INET;
423 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
425 if ((hp = gethostbyname(mounthost)) == NULL) {
426 fprintf(stderr, _("mount: can't get address for %s\n"),
430 if (hp->h_length > sizeof(struct in_addr)) {
432 _("mount: got bad hp->h_length?\n"));
433 hp->h_length = sizeof(struct in_addr);
435 mount_server_addr.sin_family = AF_INET;
436 memcpy(&mount_server_addr.sin_addr,
437 hp->h_addr, hp->h_length);
443 * The following loop implements the mount retries. On the first
444 * call, "running_bg" is 0. When the mount times out, and the
445 * "bg" option is set, the exit status EX_BG will be returned.
446 * For a backgrounded mount, there will be a second call by the
447 * child process with "running_bg" set to 1.
449 * The case where the mount point is not present and the "bg"
450 * option is set, is treated as a timeout. This is done to
451 * support nested mounts.
453 * The "retry" count specified by the user is the number of
454 * minutes to retry before giving up.
456 * Only the first error message will be displayed.
458 retry_timeout.tv_sec = 3;
459 retry_timeout.tv_usec = 0;
460 total_timeout.tv_sec = 20;
461 total_timeout.tv_usec = 0;
462 timeout = time(NULL) + 60 * retry;
467 if (bg && stat(node, &statbuf) == -1) {
469 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
475 /* be careful not to use too many CPU cycles */
479 /* contact the mount daemon via TCP */
480 mount_server_addr.sin_port = htons(mountport);
482 mclient = clnttcp_create(&mount_server_addr,
483 mountprog, mountvers,
486 /* if this fails, contact the mount daemon via UDP */
488 mount_server_addr.sin_port = htons(mountport);
490 mclient = clntudp_create(&mount_server_addr,
491 mountprog, mountvers,
492 retry_timeout, &msock);
495 /* try to mount hostname:dirname */
496 mclient->cl_auth = authunix_create_default();
497 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
498 (xdrproc_t) xdr_dirpath, (caddr_t) &dirname,
499 (xdrproc_t) xdr_fhstatus, (caddr_t) &status,
501 if (clnt_stat == RPC_SUCCESS)
502 break; /* we're done */
503 if (errno != ECONNREFUSED) {
504 clnt_perror(mclient, "mount");
505 goto fail; /* don't retry */
507 if (!running_bg && prevt == 0)
508 clnt_perror(mclient, "mount");
509 auth_destroy(mclient->cl_auth);
510 clnt_destroy(mclient);
514 if (!running_bg && prevt == 0)
515 clnt_pcreateerror("mount");
522 prev_bg_host = xstrdup(hostname);
532 if (status.fhs_status != 0) {
534 _("mount: %s:%s failed, reason given by server: %s\n"),
535 hostname, dirname, nfs_strerror(status.fhs_status));
538 memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
539 sizeof (root_fhandle));
541 /* create nfs socket for kernel */
544 if (nfs_mount_version < 3) {
545 printf(_("NFS over TCP is not supported.\n"));
548 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
550 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
552 perror(_("nfs socket"));
555 if (bindresvport(fsock, 0) < 0) {
556 perror(_("nfs bindresvport"));
560 server_addr.sin_port = PMAPPORT;
561 port = pmap_getport(&server_addr, nfsprog, nfsvers,
562 tcp ? IPPROTO_TCP : IPPROTO_UDP);
565 #ifdef NFS_MOUNT_DEBUG
567 printf(_("used portmapper to find NFS port\n"));
570 #ifdef NFS_MOUNT_DEBUG
571 printf(_("using port %d for nfs deamon\n"), port);
573 server_addr.sin_port = htons(port);
575 * connect() the socket for kernels 1.3.10 and below only,
576 * to avoid problems with multihomed hosts.
579 if (linux_version_code() <= 66314
580 && connect(fsock, (struct sockaddr *) &server_addr,
581 sizeof (server_addr)) < 0) {
582 perror(_("nfs connect"));
586 /* prepare data structure for kernel */
589 memcpy((char *) &data.root, (char *) &root_fhandle,
590 sizeof (root_fhandle));
591 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
592 strncpy(data.hostname, hostname, sizeof(data.hostname));
596 auth_destroy(mclient->cl_auth);
597 clnt_destroy(mclient);
606 auth_destroy(mclient->cl_auth);
607 clnt_destroy(mclient);
617 * We need to translate between nfs status return values and
618 * the local errno values which may not be the same.
620 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
621 * "after #include <errno.h> the symbol errno is reserved for any use,
622 * it cannot even be used as a struct tag or field name".
626 #define EDQUOT ENOSPC
634 { NFSERR_PERM, EPERM },
635 { NFSERR_NOENT, ENOENT },
637 { NFSERR_NXIO, ENXIO },
638 { NFSERR_ACCES, EACCES },
639 { NFSERR_EXIST, EEXIST },
640 { NFSERR_NODEV, ENODEV },
641 { NFSERR_NOTDIR, ENOTDIR },
642 { NFSERR_ISDIR, EISDIR },
644 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
646 { NFSERR_FBIG, EFBIG },
647 { NFSERR_NOSPC, ENOSPC },
648 { NFSERR_ROFS, EROFS },
649 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
650 { NFSERR_NOTEMPTY, ENOTEMPTY },
651 { NFSERR_DQUOT, EDQUOT },
652 { NFSERR_STALE, ESTALE },
654 { NFSERR_WFLUSH, EWFLUSH },
656 /* Throw in some NFSv3 values for even more fun (HP returns these) */
662 static char *nfs_strerror(int stat)
665 static char buf[256];
667 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
668 if (nfs_errtbl[i].stat == stat)
669 return strerror(nfs_errtbl[i].errnum);
671 sprintf(buf, _("unknown nfs status return value: %d"), stat);
677 my_getport(struct in_addr server, struct timeval *timeo, ...)
679 struct sockaddr_in sin;
682 int sock = RPC_ANYSOCK, port;
688 sin.sin_family = AF_INET;
689 sin.sin_addr = server;
690 sin.sin_port = htons(111);
691 clnt = clntudp_create(&sin, 100000, 2, *timeo, &sock);
692 status = clnt_call(clnt, PMAP_GETPORT,
693 &pmap, (xdrproc_t) xdr_pmap,
694 &port, (xdrproc_t) xdr_uint);
695 if (status != SUCCESS) {
717 * Please do not edit this file.
718 * It was generated using rpcgen.
721 #include <rpc/types.h>
725 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
726 * unrestricted use provided that this legend is included on all tape
727 * media and as a part of the software program in whole or part. Users
728 * may copy or modify Sun RPC without charge, but are not authorized
729 * to license or distribute it to anyone else except as part of a product or
730 * program developed by the user or with the express written consent of
731 * Sun Microsystems, Inc.
733 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
734 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
735 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
737 * Sun RPC is provided with no support and without any obligation on the
738 * part of Sun Microsystems, Inc. to assist in its use, correction,
739 * modification or enhancement.
741 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
742 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
743 * OR ANY PART THEREOF.
745 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
746 * or profits or other special, indirect and consequential damages, even if
747 * Sun has been advised of the possibility of such damages.
749 * Sun Microsystems, Inc.
751 * Mountain View, California 94043
754 * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
757 /* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
760 xdr_fhandle(XDR *xdrs, fhandle objp)
763 if (!xdr_opaque(xdrs, objp, FHSIZE)) {
770 xdr_fhstatus(XDR *xdrs, fhstatus *objp)
773 if (!xdr_u_int(xdrs, &objp->fhs_status)) {
776 switch (objp->fhs_status) {
778 if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
789 xdr_dirpath(XDR *xdrs, dirpath *objp)
792 if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
799 xdr_name(XDR *xdrs, name *objp)
802 if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
809 xdr_mountlist(XDR *xdrs, mountlist *objp)
812 if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody), (xdrproc_t)xdr_mountbody)) {
819 xdr_mountbody(XDR *xdrs, mountbody *objp)
822 if (!xdr_name(xdrs, &objp->ml_hostname)) {
825 if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
828 if (!xdr_mountlist(xdrs, &objp->ml_next)) {
835 xdr_groups(XDR *xdrs, groups *objp)
838 if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), (xdrproc_t)xdr_groupnode)) {
845 xdr_groupnode(XDR *xdrs, groupnode *objp)
848 if (!xdr_name(xdrs, &objp->gr_name)) {
851 if (!xdr_groups(xdrs, &objp->gr_next)) {
858 xdr_exports(XDR *xdrs, exports *objp)
861 if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), (xdrproc_t)xdr_exportnode)) {
868 xdr_exportnode(XDR *xdrs, exportnode *objp)
871 if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
874 if (!xdr_groups(xdrs, &objp->ex_groups)) {
877 if (!xdr_exports(xdrs, &objp->ex_next)) {
884 xdr_ppathcnf(XDR *xdrs, ppathcnf *objp)
891 if (xdrs->x_op == XDR_ENCODE) {
892 buf = (long*)XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
894 if (!xdr_int(xdrs, &objp->pc_link_max)) {
897 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
900 if (!xdr_short(xdrs, &objp->pc_max_input)) {
903 if (!xdr_short(xdrs, &objp->pc_name_max)) {
906 if (!xdr_short(xdrs, &objp->pc_path_max)) {
909 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
915 IXDR_PUT_LONG(buf,objp->pc_link_max);
916 IXDR_PUT_SHORT(buf,objp->pc_max_canon);
917 IXDR_PUT_SHORT(buf,objp->pc_max_input);
918 IXDR_PUT_SHORT(buf,objp->pc_name_max);
919 IXDR_PUT_SHORT(buf,objp->pc_path_max);
920 IXDR_PUT_SHORT(buf,objp->pc_pipe_buf);
922 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
925 if (!xdr_char(xdrs, &objp->pc_xxx)) {
928 buf = (long*)XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
930 if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
936 { register short *genp;
937 for ( i = 0,genp=objp->pc_mask;
939 IXDR_PUT_SHORT(buf,*genp++);
945 } else if (xdrs->x_op == XDR_DECODE) {
946 buf = (long*)XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
948 if (!xdr_int(xdrs, &objp->pc_link_max)) {
951 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
954 if (!xdr_short(xdrs, &objp->pc_max_input)) {
957 if (!xdr_short(xdrs, &objp->pc_name_max)) {
960 if (!xdr_short(xdrs, &objp->pc_path_max)) {
963 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
969 objp->pc_link_max = IXDR_GET_LONG(buf);
970 objp->pc_max_canon = IXDR_GET_SHORT(buf);
971 objp->pc_max_input = IXDR_GET_SHORT(buf);
972 objp->pc_name_max = IXDR_GET_SHORT(buf);
973 objp->pc_path_max = IXDR_GET_SHORT(buf);
974 objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
976 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
979 if (!xdr_char(xdrs, &objp->pc_xxx)) {
982 buf = (long*)XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
984 if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
990 { register short *genp;
991 for ( i = 0,genp=objp->pc_mask;
993 *genp++ = IXDR_GET_SHORT(buf);
1000 if (!xdr_int(xdrs, &objp->pc_link_max)) {
1003 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
1006 if (!xdr_short(xdrs, &objp->pc_max_input)) {
1009 if (!xdr_short(xdrs, &objp->pc_name_max)) {
1012 if (!xdr_short(xdrs, &objp->pc_path_max)) {
1015 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
1018 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
1021 if (!xdr_char(xdrs, &objp->pc_xxx)) {
1024 if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
1032 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
1033 * unrestricted use provided that this legend is included on all tape
1034 * media and as a part of the software program in whole or part. Users
1035 * may copy or modify Sun RPC without charge, but are not authorized
1036 * to license or distribute it to anyone else except as part of a product or
1037 * program developed by the user or with the express written consent of
1038 * Sun Microsystems, Inc.
1040 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1041 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1042 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1044 * Sun RPC is provided with no support and without any obligation on the
1045 * part of Sun Microsystems, Inc. to assist in its use, correction,
1046 * modification or enhancement.
1048 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
1049 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
1050 * OR ANY PART THEREOF.
1052 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
1053 * or profits or other special, indirect and consequential damages, even if
1054 * Sun has been advised of the possibility of such damages.
1056 * Sun Microsystems, Inc.
1057 * 2550 Garcia Avenue
1058 * Mountain View, California 94043
1061 * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
1064 /* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
1066 #include <string.h> /* for memset() */
1068 /* Default timeout can be changed using clnt_control() */
1069 static struct timeval TIMEOUT = { 25, 0 };
1072 mountproc_null_1(argp, clnt)
1076 static char clnt_res;
1078 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1079 if (clnt_call(clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1082 return ((void *)&clnt_res);
1086 mountproc_mnt_1(argp, clnt)
1090 static fhstatus clnt_res;
1092 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1093 if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
1094 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
1095 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1102 mountproc_dump_1(argp, clnt)
1106 static mountlist clnt_res;
1108 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1109 if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void,
1110 (caddr_t) argp, (xdrproc_t) xdr_mountlist,
1111 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1118 mountproc_umnt_1(argp, clnt)
1122 static char clnt_res;
1124 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1125 if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
1126 (caddr_t) argp, (xdrproc_t) xdr_void,
1127 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1130 return ((void *)&clnt_res);
1134 mountproc_umntall_1(argp, clnt)
1138 static char clnt_res;
1140 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1141 if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
1142 (caddr_t) argp, (xdrproc_t) xdr_void,
1143 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1146 return ((void *)&clnt_res);
1150 mountproc_export_1(argp, clnt)
1154 static exports clnt_res;
1156 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1157 if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
1158 (caddr_t) argp, (xdrproc_t) xdr_exports,
1159 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1166 mountproc_exportall_1(argp, clnt)
1170 static exports clnt_res;
1172 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1173 if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void,
1174 (caddr_t) argp, (xdrproc_t) xdr_exports,
1175 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1182 mountproc_null_2(argp, clnt)
1186 static char clnt_res;
1188 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1189 if (clnt_call(clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1192 return ((void *)&clnt_res);
1196 mountproc_mnt_2(argp, clnt)
1200 static fhstatus clnt_res;
1202 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1203 if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
1204 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
1205 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1212 mountproc_dump_2(argp, clnt)
1216 static mountlist clnt_res;
1218 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1219 if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp,
1220 (xdrproc_t) xdr_mountlist, (caddr_t) &clnt_res,
1221 TIMEOUT) != RPC_SUCCESS) {
1228 mountproc_umnt_2(argp, clnt)
1232 static char clnt_res;
1234 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1235 if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
1236 (caddr_t) argp, (xdrproc_t) xdr_void,
1237 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1240 return ((void *)&clnt_res);
1244 mountproc_umntall_2(argp, clnt)
1248 static char clnt_res;
1250 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1251 if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
1252 (caddr_t) argp, (xdrproc_t) xdr_void,
1253 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
1256 return ((void *)&clnt_res);
1260 mountproc_export_2(argp, clnt)
1264 static exports clnt_res;
1266 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1267 if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
1268 argp, (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
1269 TIMEOUT) != RPC_SUCCESS) {
1276 mountproc_exportall_2(argp, clnt)
1280 static exports clnt_res;
1282 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1283 if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp,
1284 (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
1285 TIMEOUT) != RPC_SUCCESS) {
1292 mountproc_pathconf_2(argp, clnt)
1296 static ppathcnf clnt_res;
1298 memset((char *)&clnt_res, 0, sizeof(clnt_res));
1299 if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath,
1300 (caddr_t) argp, (xdrproc_t) xdr_ppathcnf,
1301 (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {