blob: 03ce5844797b4f48d27820fca6fa84942ebeab30 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersen1c43d0c1999-11-18 07:58:07 +00002/*
3 * nfsmount.c -- Linux NFS mount
4 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
5 *
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)
9 * any later version.
10 *
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.
15 *
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.
18 *
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.
21 *
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.
24 *
25 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
26 * - added Native Language Support
27 *
28 */
29
30/*
31 * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
32 */
33
34#include <unistd.h>
35#include <stdio.h>
36#include <string.h>
37#include <errno.h>
38#include <netdb.h>
39#include <rpc/rpc.h>
40#include <rpc/pmap_prot.h>
41#include <rpc/pmap_clnt.h>
42#include <sys/socket.h>
43#include <sys/time.h>
44#include <sys/utsname.h>
45#include <sys/stat.h>
46#include <netinet/in.h>
47#include <arpa/inet.h>
48
49#include "nfsmount.h"
50
51#include <linux/nfs.h>
52/* we suppose that libc-dev is providing NFSv3 headers (kernel >= 2.2) */
53#include <linux/nfs_mount.h>
54
55#define _
56#define HAVE_inet_aton
Erik Andersene49d5ec2000-02-08 19:58:47 +000057#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
Eric Andersen1c43d0c1999-11-18 07:58:07 +000058#define sloppy 0
59#define EX_FAIL 1
60#define EX_BG 1
61#define xstrdup strdup
62#define xstrndup strndup
63
64
65static char *nfs_strerror(int stat);
66
67#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
68
Erik Andersene49d5ec2000-02-08 19:58:47 +000069static int linux_version_code(void)
70{
Eric Andersen1c43d0c1999-11-18 07:58:07 +000071 struct utsname my_utsname;
72 int p, q, r;
73
74 if (uname(&my_utsname) == 0) {
75 p = atoi(strtok(my_utsname.release, "."));
76 q = atoi(strtok(NULL, "."));
77 r = atoi(strtok(NULL, "."));
Erik Andersene49d5ec2000-02-08 19:58:47 +000078 return MAKE_VERSION(p, q, r);
Eric Andersen1c43d0c1999-11-18 07:58:07 +000079 }
80 return 0;
81}
82
83/*
84 * nfs_mount_version according to the kernel sources seen at compile time.
85 */
86static int nfs_mount_version = NFS_MOUNT_VERSION;
87
88/*
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.
93 *
94 * Variables:
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
98 */
Erik Andersene49d5ec2000-02-08 19:58:47 +000099static void find_kernel_nfs_mount_version(void)
100{
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000101 int kernel_version = linux_version_code();
102
103 if (kernel_version) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000104 if (kernel_version < MAKE_VERSION(2, 1, 32))
105 nfs_mount_version = 1;
106 else
107 nfs_mount_version = 3;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000108 }
109 if (nfs_mount_version > NFS_MOUNT_VERSION)
Erik Andersene49d5ec2000-02-08 19:58:47 +0000110 nfs_mount_version = NFS_MOUNT_VERSION;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000111}
112
113int nfsmount(const char *spec, const char *node, unsigned long *flags,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000114 char **extra_opts, char **mount_opts, int running_bg)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000115{
116 static char *prev_bg_host;
117 char hostdir[1024];
118 CLIENT *mclient;
119 char *hostname;
120 char *dirname;
121 char *old_opts;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000122 char *mounthost = NULL;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000123 char new_opts[1024];
124 fhandle root_fhandle;
125 struct timeval total_timeout;
126 enum clnt_stat clnt_stat;
127 static struct nfs_mount_data data;
128 char *opt, *opteq;
129 int val;
130 struct hostent *hp;
131 struct sockaddr_in server_addr;
132 struct sockaddr_in mount_server_addr;
133 int msock, fsock;
134 struct timeval retry_timeout;
135 struct fhstatus status;
136 struct stat statbuf;
137 char *s;
138 int port;
139 int mountport;
140 int bg;
141 int soft;
142 int intr;
143 int posix;
144 int nocto;
145 int noac;
146 int nolock;
147 int retry;
148 int tcp;
149 int mountprog;
150 int mountvers;
151 int nfsprog;
152 int nfsvers;
153 int retval;
154 time_t t;
155 time_t prevt;
156 time_t timeout;
157
158 find_kernel_nfs_mount_version();
159
160 retval = EX_FAIL;
161 msock = fsock = -1;
162 mclient = NULL;
163 if (strlen(spec) >= sizeof(hostdir)) {
164 fprintf(stderr, _("mount: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000165 "excessively long host:dir argument\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000166 goto fail;
167 }
168 strcpy(hostdir, spec);
169 if ((s = strchr(hostdir, ':'))) {
170 hostname = hostdir;
171 dirname = s + 1;
172 *s = '\0';
173 /* Ignore all but first hostname in replicated mounts
174 until they can be fully supported. (mack@sgi.com) */
175 if ((s = strchr(hostdir, ','))) {
176 *s = '\0';
177 fprintf(stderr, _("mount: warning: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000178 "multiple hostnames not supported\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000179 }
180 } else {
181 fprintf(stderr, _("mount: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000182 "directory to mount not in host:dir format\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000183 goto fail;
184 }
185
186 server_addr.sin_family = AF_INET;
187#ifdef HAVE_inet_aton
188 if (!inet_aton(hostname, &server_addr.sin_addr))
189#endif
190 {
191 if ((hp = gethostbyname(hostname)) == NULL) {
192 fprintf(stderr, _("mount: can't get address for %s\n"),
Erik Andersene49d5ec2000-02-08 19:58:47 +0000193 hostname);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000194 goto fail;
195 } else {
196 if (hp->h_length > sizeof(struct in_addr)) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000197 fprintf(stderr, _("mount: got bad hp->h_length\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000198 hp->h_length = sizeof(struct in_addr);
199 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000200 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000201 }
202 }
203
Erik Andersene49d5ec2000-02-08 19:58:47 +0000204 memcpy(&mount_server_addr, &server_addr, sizeof(mount_server_addr));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000205
206 /* add IP address to mtab options for use when unmounting */
207
208 s = inet_ntoa(server_addr.sin_addr);
209 old_opts = *extra_opts;
210 if (!old_opts)
211 old_opts = "";
212 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000213 fprintf(stderr, _("mount: " "excessively long option argument\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000214 goto fail;
215 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000216 sprintf(new_opts, "%s%saddr=%s", old_opts, *old_opts ? "," : "", s);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000217 *extra_opts = xstrdup(new_opts);
218
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));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000224 data.retrans = 3;
225 data.acregmin = 3;
226 data.acregmax = 60;
227 data.acdirmin = 30;
228 data.acdirmax = 60;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000229#if NFS_MOUNT_VERSION >= 2
Erik Andersene49d5ec2000-02-08 19:58:47 +0000230 data.namlen = NAME_MAX;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000231#endif
232
233 bg = 0;
234 soft = 0;
235 intr = 0;
236 posix = 0;
237 nocto = 0;
238 nolock = 0;
239 noac = 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000240 retry = 10000; /* 10000 minutes ~ 1 week */
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000241 tcp = 0;
242
243 mountprog = MOUNTPROG;
244 mountvers = MOUNTVERS;
245 port = 0;
246 mountport = 0;
247 nfsprog = NFS_PROGRAM;
248 nfsvers = NFS_VERSION;
249
250 /* parse options */
251
252 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
253 if ((opteq = strchr(opt, '='))) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000254 val = atoi(opteq + 1);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000255 *opteq = '\0';
256 if (!strcmp(opt, "rsize"))
257 data.rsize = val;
258 else if (!strcmp(opt, "wsize"))
259 data.wsize = val;
260 else if (!strcmp(opt, "timeo"))
261 data.timeo = val;
262 else if (!strcmp(opt, "retrans"))
263 data.retrans = val;
264 else if (!strcmp(opt, "acregmin"))
265 data.acregmin = val;
266 else if (!strcmp(opt, "acregmax"))
267 data.acregmax = val;
268 else if (!strcmp(opt, "acdirmin"))
269 data.acdirmin = val;
270 else if (!strcmp(opt, "acdirmax"))
271 data.acdirmax = val;
272 else if (!strcmp(opt, "actimeo")) {
273 data.acregmin = val;
274 data.acregmax = val;
275 data.acdirmin = val;
276 data.acdirmax = val;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000277 } else if (!strcmp(opt, "retry"))
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000278 retry = val;
279 else if (!strcmp(opt, "port"))
280 port = val;
281 else if (!strcmp(opt, "mountport"))
Erik Andersene49d5ec2000-02-08 19:58:47 +0000282 mountport = val;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000283 else if (!strcmp(opt, "mounthost"))
Erik Andersene49d5ec2000-02-08 19:58:47 +0000284 mounthost = xstrndup(opteq + 1,
285 strcspn(opteq + 1, " \t\n\r,"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000286 else if (!strcmp(opt, "mountprog"))
287 mountprog = val;
288 else if (!strcmp(opt, "mountvers"))
289 mountvers = val;
290 else if (!strcmp(opt, "nfsprog"))
291 nfsprog = val;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000292 else if (!strcmp(opt, "nfsvers") || !strcmp(opt, "vers"))
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000293 nfsvers = val;
294 else if (!strcmp(opt, "proto")) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000295 if (!strncmp(opteq + 1, "tcp", 3))
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000296 tcp = 1;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000297 else if (!strncmp(opteq + 1, "udp", 3))
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000298 tcp = 0;
299 else
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)
304 data.namlen = val;
305 else
306#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000307 printf(_
308 ("Warning: Option namlen is not supported.\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000309 } else if (!strcmp(opt, "addr"))
Erik Andersene49d5ec2000-02-08 19:58:47 +0000310 /* ignore */ ;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000311 else {
312 printf(_("unknown nfs mount parameter: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000313 "%s=%d\n"), opt, val);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000314 goto fail;
315 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000316 } else {
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000317 val = 1;
318 if (!strncmp(opt, "no", 2)) {
319 val = 0;
320 opt += 2;
321 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000322 if (!strcmp(opt, "bg"))
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000323 bg = val;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000324 else if (!strcmp(opt, "fg"))
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000325 bg = !val;
326 else if (!strcmp(opt, "soft"))
327 soft = val;
328 else if (!strcmp(opt, "hard"))
329 soft = !val;
330 else if (!strcmp(opt, "intr"))
331 intr = val;
332 else if (!strcmp(opt, "posix"))
333 posix = val;
334 else if (!strcmp(opt, "cto"))
335 nocto = !val;
336 else if (!strcmp(opt, "ac"))
337 noac = !val;
338 else if (!strcmp(opt, "tcp"))
339 tcp = val;
340 else if (!strcmp(opt, "udp"))
341 tcp = !val;
342 else if (!strcmp(opt, "lock")) {
343 if (nfs_mount_version >= 3)
344 nolock = !val;
345 else
Erik Andersene49d5ec2000-02-08 19:58:47 +0000346 printf(_
347 ("Warning: option nolock is not supported.\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000348 } else {
349 if (!sloppy) {
350 printf(_("unknown nfs mount option: "
Erik Andersene49d5ec2000-02-08 19:58:47 +0000351 "%s%s\n"), val ? "" : "no", opt);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000352 goto fail;
353 }
354 }
355 }
356 }
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);
365#endif
366#if NFS_MOUNT_VERSION >= 3
367 if (nfs_mount_version >= 3)
368 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
369#endif
370
371 /* Adjust options if none specified */
372 if (!data.timeo)
373 data.timeo = tcp ? 70 : 7;
374
375#ifdef NFS_MOUNT_DEBUG
376 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
Erik Andersene49d5ec2000-02-08 19:58:47 +0000377 data.rsize, data.wsize, data.timeo, data.retrans);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000378 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
Erik Andersene49d5ec2000-02-08 19:58:47 +0000379 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000380 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
Erik Andersene49d5ec2000-02-08 19:58:47 +0000381 port, bg, retry, data.flags);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000382 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
Erik Andersene49d5ec2000-02-08 19:58:47 +0000383 mountprog, mountvers, nfsprog, nfsvers);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000384 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
Erik Andersene49d5ec2000-02-08 19:58:47 +0000385 (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);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000390#if NFS_MOUNT_VERSION >= 2
Erik Andersene49d5ec2000-02-08 19:58:47 +0000391 printf("tcp = %d\n", (data.flags & NFS_MOUNT_TCP) != 0);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000392#endif
393#endif
394
395 data.version = nfs_mount_version;
396 *mount_opts = (char *) &data;
397
398 if (*flags & MS_REMOUNT)
399 return 0;
400
401 /*
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.
405 */
406 if (bg && !running_bg &&
Erik Andersene49d5ec2000-02-08 19:58:47 +0000407 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000408 if (retry > 0)
409 retval = EX_BG;
410 return retval;
411 }
412
413 /* create mount deamon client */
414 /* See if the nfs host = mount host. */
415 if (mounthost) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000416 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);
419 } else {
420 if ((hp = gethostbyname(mounthost)) == NULL) {
421 fprintf(stderr, _("mount: can't get address for %s\n"),
422 hostname);
423 goto fail;
424 } else {
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);
428 }
429 mount_server_addr.sin_family = AF_INET;
430 memcpy(&mount_server_addr.sin_addr,
431 hp->h_addr, hp->h_length);
432 }
433 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000434 }
435
436 /*
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.
442 *
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.
446 *
447 * The "retry" count specified by the user is the number of
448 * minutes to retry before giving up.
449 *
450 * Only the first error message will be displayed.
451 */
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;
457 prevt = 0;
458 t = 30;
459 val = 1;
460 for (;;) {
461 if (bg && stat(node, &statbuf) == -1) {
462 if (running_bg) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000463 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000464 val *= 2;
465 if (val > 30)
466 val = 30;
467 }
468 } else {
469 /* be careful not to use too many CPU cycles */
470 if (t - prevt < 30)
471 sleep(30);
472
473 /* contact the mount daemon via TCP */
474 mount_server_addr.sin_port = htons(mountport);
475 msock = RPC_ANYSOCK;
476 mclient = clnttcp_create(&mount_server_addr,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000477 mountprog, mountvers, &msock, 0, 0);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000478
479 /* if this fails, contact the mount daemon via UDP */
480 if (!mclient) {
481 mount_server_addr.sin_port = htons(mountport);
482 msock = RPC_ANYSOCK;
483 mclient = clntudp_create(&mount_server_addr,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000484 mountprog, mountvers,
485 retry_timeout, &msock);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000486 }
487 if (mclient) {
488 /* try to mount hostname:dirname */
489 mclient->cl_auth = authunix_create_default();
490 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000491 (xdrproc_t) xdr_dirpath,
492 (caddr_t) & dirname,
493 (xdrproc_t) xdr_fhstatus,
494 (caddr_t) & status, total_timeout);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000495 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 */
500 }
501 if (!running_bg && prevt == 0)
502 clnt_perror(mclient, "mount");
503 auth_destroy(mclient->cl_auth);
504 clnt_destroy(mclient);
505 mclient = 0;
506 close(msock);
507 } else {
508 if (!running_bg && prevt == 0)
509 clnt_pcreateerror("mount");
510 }
511 prevt = t;
512 }
513 if (!bg)
Erik Andersene49d5ec2000-02-08 19:58:47 +0000514 goto fail;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000515 if (!running_bg) {
516 prev_bg_host = xstrdup(hostname);
517 if (retry > 0)
518 retval = EX_BG;
519 goto fail;
520 }
521 t = time(NULL);
522 if (t >= timeout)
523 goto fail;
524 }
525
526 if (status.fhs_status != 0) {
527 fprintf(stderr,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000528 _("mount: %s:%s failed, reason given by server: %s\n"),
529 hostname, dirname, nfs_strerror(status.fhs_status));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000530 goto fail;
531 }
532 memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000533 sizeof(root_fhandle));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000534
535 /* create nfs socket for kernel */
536
537 if (tcp) {
538 if (nfs_mount_version < 3) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000539 printf(_("NFS over TCP is not supported.\n"));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000540 goto fail;
541 }
542 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
543 } else
544 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
545 if (fsock < 0) {
546 perror(_("nfs socket"));
547 goto fail;
548 }
549 if (bindresvport(fsock, 0) < 0) {
550 perror(_("nfs bindresvport"));
551 goto fail;
552 }
553 if (port == 0) {
554 server_addr.sin_port = PMAPPORT;
555 port = pmap_getport(&server_addr, nfsprog, nfsvers,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000556 tcp ? IPPROTO_TCP : IPPROTO_UDP);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000557 if (port == 0)
558 port = NFS_PORT;
559#ifdef NFS_MOUNT_DEBUG
560 else
561 printf(_("used portmapper to find NFS port\n"));
562#endif
563 }
564#ifdef NFS_MOUNT_DEBUG
565 printf(_("using port %d for nfs deamon\n"), port);
566#endif
567 server_addr.sin_port = htons(port);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000568 /*
569 * connect() the socket for kernels 1.3.10 and below only,
570 * to avoid problems with multihomed hosts.
571 * --Swen
572 */
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000573 if (linux_version_code() <= 66314
Erik Andersene49d5ec2000-02-08 19:58:47 +0000574 && connect(fsock, (struct sockaddr *) &server_addr,
575 sizeof(server_addr)) < 0) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000576 perror(_("nfs connect"));
577 goto fail;
578 }
579
580 /* prepare data structure for kernel */
581
582 data.fd = fsock;
583 memcpy((char *) &data.root, (char *) &root_fhandle,
Erik Andersene49d5ec2000-02-08 19:58:47 +0000584 sizeof(root_fhandle));
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000585 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
586 strncpy(data.hostname, hostname, sizeof(data.hostname));
587
588 /* clean up */
589
590 auth_destroy(mclient->cl_auth);
591 clnt_destroy(mclient);
592 close(msock);
593 return 0;
594
595 /* abort */
596
Erik Andersene49d5ec2000-02-08 19:58:47 +0000597 fail:
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000598 if (msock != -1) {
599 if (mclient) {
600 auth_destroy(mclient->cl_auth);
601 clnt_destroy(mclient);
602 }
603 close(msock);
604 }
605 if (fsock != -1)
606 close(fsock);
607 return retval;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000608}
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000609
610/*
611 * We need to translate between nfs status return values and
612 * the local errno values which may not be the same.
613 *
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".
617 */
618
619#ifndef EDQUOT
620#define EDQUOT ENOSPC
621#endif
622
623static struct {
624 enum nfs_stat stat;
625 int errnum;
626} nfs_errtbl[] = {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000627 {
628 NFS_OK, 0}, {
629 NFSERR_PERM, EPERM}, {
630 NFSERR_NOENT, ENOENT}, {
631 NFSERR_IO, EIO}, {
632 NFSERR_NXIO, ENXIO}, {
633 NFSERR_ACCES, EACCES}, {
634 NFSERR_EXIST, EEXIST}, {
635 NFSERR_NODEV, ENODEV}, {
636 NFSERR_NOTDIR, ENOTDIR}, {
637 NFSERR_ISDIR, EISDIR},
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000638#ifdef NFSERR_INVAL
Erik Andersene49d5ec2000-02-08 19:58:47 +0000639 {
640 NFSERR_INVAL, EINVAL}, /* that Sun forgot */
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000641#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000642 {
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},
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000650#ifdef EWFLUSH
Erik Andersene49d5ec2000-02-08 19:58:47 +0000651 {
652 NFSERR_WFLUSH, EWFLUSH},
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000653#endif
Erik Andersene49d5ec2000-02-08 19:58:47 +0000654 /* Throw in some NFSv3 values for even more fun (HP returns these) */
655 {
656 71, EREMOTE}, {
657 -1, EIO}
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000658};
659
660static char *nfs_strerror(int stat)
661{
662 int i;
663 static char buf[256];
664
665 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
666 if (nfs_errtbl[i].stat == stat)
667 return strerror(nfs_errtbl[i].errnum);
668 }
669 sprintf(buf, _("unknown nfs status return value: %d"), stat);
670 return buf;
671}
672
673#if 0
Erik Andersene49d5ec2000-02-08 19:58:47 +0000674int my_getport(struct in_addr server, struct timeval *timeo, ...)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000675{
Erik Andersene49d5ec2000-02-08 19:58:47 +0000676 struct sockaddr_in sin;
677 struct pmap pmap;
678 CLIENT *clnt;
679 int sock = RPC_ANYSOCK, port;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000680
Erik Andersene49d5ec2000-02-08 19:58:47 +0000681 pmap.pm_prog = prog;
682 pmap.pm_vers = vers;
683 pmap.pm_prot = prot;
684 pmap.pm_port = 0;
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) {
693 /* natter */
694 port = 0;
695 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000696
Erik Andersene49d5ec2000-02-08 19:58:47 +0000697 clnt_destroy(clnt);
698 close(sock);
699 return port;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000700}
701#endif
702
703
704
705
706
707
708
709
710
711
712
713/*
714 * Please do not edit this file.
715 * It was generated using rpcgen.
716 */
717
718#include <rpc/types.h>
719#include <rpc/xdr.h>
720
721/*
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.
729 *
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.
733 *
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.
737 *
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.
741 *
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.
745 *
746 * Sun Microsystems, Inc.
747 * 2550 Garcia Avenue
748 * Mountain View, California 94043
749 */
750/*
751 * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
752 */
753
754/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
755
Erik Andersene49d5ec2000-02-08 19:58:47 +0000756bool_t xdr_fhandle(XDR * xdrs, fhandle objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000757{
758
Erik Andersene49d5ec2000-02-08 19:58:47 +0000759 if (!xdr_opaque(xdrs, objp, FHSIZE)) {
760 return (FALSE);
761 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000762 return (TRUE);
763}
764
Erik Andersene49d5ec2000-02-08 19:58:47 +0000765bool_t xdr_fhstatus(XDR * xdrs, fhstatus * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000766{
767
Erik Andersene49d5ec2000-02-08 19:58:47 +0000768 if (!xdr_u_int(xdrs, &objp->fhs_status)) {
769 return (FALSE);
770 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000771 switch (objp->fhs_status) {
772 case 0:
Erik Andersene49d5ec2000-02-08 19:58:47 +0000773 if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
774 return (FALSE);
775 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000776 break;
777 default:
778 break;
779 }
780 return (TRUE);
781}
782
Erik Andersene49d5ec2000-02-08 19:58:47 +0000783bool_t xdr_dirpath(XDR * xdrs, dirpath * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000784{
785
Erik Andersene49d5ec2000-02-08 19:58:47 +0000786 if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
787 return (FALSE);
788 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000789 return (TRUE);
790}
791
Erik Andersene49d5ec2000-02-08 19:58:47 +0000792bool_t xdr_name(XDR * xdrs, name * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000793{
794
Erik Andersene49d5ec2000-02-08 19:58:47 +0000795 if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
796 return (FALSE);
797 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000798 return (TRUE);
799}
800
Erik Andersene49d5ec2000-02-08 19:58:47 +0000801bool_t xdr_mountlist(XDR * xdrs, mountlist * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000802{
803
Erik Andersene49d5ec2000-02-08 19:58:47 +0000804 if (!xdr_pointer
805 (xdrs, (char **) objp, sizeof(struct mountbody),
806 (xdrproc_t) xdr_mountbody)) {
807 return (FALSE);
808 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000809 return (TRUE);
810}
811
Erik Andersene49d5ec2000-02-08 19:58:47 +0000812bool_t xdr_mountbody(XDR * xdrs, mountbody * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000813{
814
Erik Andersene49d5ec2000-02-08 19:58:47 +0000815 if (!xdr_name(xdrs, &objp->ml_hostname)) {
816 return (FALSE);
817 }
818 if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
819 return (FALSE);
820 }
821 if (!xdr_mountlist(xdrs, &objp->ml_next)) {
822 return (FALSE);
823 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000824 return (TRUE);
825}
826
Erik Andersene49d5ec2000-02-08 19:58:47 +0000827bool_t xdr_groups(XDR * xdrs, groups * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000828{
829
Erik Andersene49d5ec2000-02-08 19:58:47 +0000830 if (!xdr_pointer
831 (xdrs, (char **) objp, sizeof(struct groupnode),
832 (xdrproc_t) xdr_groupnode)) {
833 return (FALSE);
834 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000835 return (TRUE);
836}
837
Erik Andersene49d5ec2000-02-08 19:58:47 +0000838bool_t xdr_groupnode(XDR * xdrs, groupnode * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000839{
840
Erik Andersene49d5ec2000-02-08 19:58:47 +0000841 if (!xdr_name(xdrs, &objp->gr_name)) {
842 return (FALSE);
843 }
844 if (!xdr_groups(xdrs, &objp->gr_next)) {
845 return (FALSE);
846 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000847 return (TRUE);
848}
849
Erik Andersene49d5ec2000-02-08 19:58:47 +0000850bool_t xdr_exports(XDR * xdrs, exports * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000851{
852
Erik Andersene49d5ec2000-02-08 19:58:47 +0000853 if (!xdr_pointer
854 (xdrs, (char **) objp, sizeof(struct exportnode),
855 (xdrproc_t) xdr_exportnode)) {
856 return (FALSE);
857 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000858 return (TRUE);
859}
860
Erik Andersene49d5ec2000-02-08 19:58:47 +0000861bool_t xdr_exportnode(XDR * xdrs, exportnode * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000862{
863
Erik Andersene49d5ec2000-02-08 19:58:47 +0000864 if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
865 return (FALSE);
866 }
867 if (!xdr_groups(xdrs, &objp->ex_groups)) {
868 return (FALSE);
869 }
870 if (!xdr_exports(xdrs, &objp->ex_next)) {
871 return (FALSE);
872 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000873 return (TRUE);
874}
875
Erik Andersene49d5ec2000-02-08 19:58:47 +0000876bool_t xdr_ppathcnf(XDR * xdrs, ppathcnf * objp)
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000877{
878
Erik Andersene49d5ec2000-02-08 19:58:47 +0000879 register long *buf;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000880
Erik Andersene49d5ec2000-02-08 19:58:47 +0000881 int i;
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000882
Erik Andersene49d5ec2000-02-08 19:58:47 +0000883 if (xdrs->x_op == XDR_ENCODE) {
884 buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000885 if (buf == NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000886 if (!xdr_int(xdrs, &objp->pc_link_max)) {
887 return (FALSE);
888 }
889 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
890 return (FALSE);
891 }
892 if (!xdr_short(xdrs, &objp->pc_max_input)) {
893 return (FALSE);
894 }
895 if (!xdr_short(xdrs, &objp->pc_name_max)) {
896 return (FALSE);
897 }
898 if (!xdr_short(xdrs, &objp->pc_path_max)) {
899 return (FALSE);
900 }
901 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
902 return (FALSE);
903 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000904
Erik Andersene49d5ec2000-02-08 19:58:47 +0000905 } else {
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);
912 }
913 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
914 return (FALSE);
915 }
916 if (!xdr_char(xdrs, &objp->pc_xxx)) {
917 return (FALSE);
918 }
919 buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
920 if (buf == NULL) {
921 if (!xdr_vector
922 (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
923 (xdrproc_t) xdr_short)) {
924 return (FALSE);
925 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000926
Erik Andersene49d5ec2000-02-08 19:58:47 +0000927 } else {
928 {
929 register short *genp;
930
931 for (i = 0, genp = objp->pc_mask; i < 2; i++) {
932 IXDR_PUT_SHORT(buf, *genp++);
933 }
934 };
935 }
936
937 return (TRUE);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000938 } else if (xdrs->x_op == XDR_DECODE) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000939 buf = (long *) XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000940 if (buf == NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000941 if (!xdr_int(xdrs, &objp->pc_link_max)) {
942 return (FALSE);
943 }
944 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
945 return (FALSE);
946 }
947 if (!xdr_short(xdrs, &objp->pc_max_input)) {
948 return (FALSE);
949 }
950 if (!xdr_short(xdrs, &objp->pc_name_max)) {
951 return (FALSE);
952 }
953 if (!xdr_short(xdrs, &objp->pc_path_max)) {
954 return (FALSE);
955 }
956 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
957 return (FALSE);
958 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000959
Erik Andersene49d5ec2000-02-08 19:58:47 +0000960 } else {
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);
967 }
968 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
969 return (FALSE);
970 }
971 if (!xdr_char(xdrs, &objp->pc_xxx)) {
972 return (FALSE);
973 }
974 buf = (long *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
975 if (buf == NULL) {
976 if (!xdr_vector
977 (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
978 (xdrproc_t) xdr_short)) {
979 return (FALSE);
980 }
981
982 } else {
983 {
984 register short *genp;
985
986 for (i = 0, genp = objp->pc_mask; i < 2; i++) {
987 *genp++ = IXDR_GET_SHORT(buf);
988 }
989 };
990 }
991 return (TRUE);
Eric Andersen1c43d0c1999-11-18 07:58:07 +0000992 }
993
Erik Andersene49d5ec2000-02-08 19:58:47 +0000994 if (!xdr_int(xdrs, &objp->pc_link_max)) {
995 return (FALSE);
996 }
997 if (!xdr_short(xdrs, &objp->pc_max_canon)) {
998 return (FALSE);
999 }
1000 if (!xdr_short(xdrs, &objp->pc_max_input)) {
1001 return (FALSE);
1002 }
1003 if (!xdr_short(xdrs, &objp->pc_name_max)) {
1004 return (FALSE);
1005 }
1006 if (!xdr_short(xdrs, &objp->pc_path_max)) {
1007 return (FALSE);
1008 }
1009 if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
1010 return (FALSE);
1011 }
1012 if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
1013 return (FALSE);
1014 }
1015 if (!xdr_char(xdrs, &objp->pc_xxx)) {
1016 return (FALSE);
1017 }
1018 if (!xdr_vector
1019 (xdrs, (char *) objp->pc_mask, 2, sizeof(short),
1020 (xdrproc_t) xdr_short)) {
1021 return (FALSE);
1022 }
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001023 return (TRUE);
1024}
1025
1026
1027/*
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.
1035 *
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.
1039 *
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.
1043 *
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.
1047 *
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.
1051 *
1052 * Sun Microsystems, Inc.
1053 * 2550 Garcia Avenue
1054 * Mountain View, California 94043
1055 */
1056/*
1057 * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
1058 */
1059
1060/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
1061
Erik Andersene49d5ec2000-02-08 19:58:47 +00001062#include <string.h> /* for memset() */
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001063
1064/* Default timeout can be changed using clnt_control() */
1065static struct timeval TIMEOUT = { 25, 0 };
1066
Erik Andersene49d5ec2000-02-08 19:58:47 +00001067void *mountproc_null_1(argp, clnt)
1068void *argp;
1069CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001070{
1071 static char clnt_res;
1072
Erik Andersene49d5ec2000-02-08 19:58:47 +00001073 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1074 if (clnt_call
1075 (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
1076 (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001077 return (NULL);
1078 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00001079 return ((void *) &clnt_res);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001080}
1081
Erik Andersene49d5ec2000-02-08 19:58:47 +00001082fhstatus *mountproc_mnt_1(argp, clnt)
1083dirpath *argp;
1084CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001085{
1086 static fhstatus clnt_res;
1087
Erik Andersene49d5ec2000-02-08 19:58:47 +00001088 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001089 if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001090 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
1091 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001092 return (NULL);
1093 }
1094 return (&clnt_res);
1095}
1096
Erik Andersene49d5ec2000-02-08 19:58:47 +00001097mountlist *mountproc_dump_1(argp, clnt)
1098void *argp;
1099CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001100{
1101 static mountlist clnt_res;
1102
Erik Andersene49d5ec2000-02-08 19:58:47 +00001103 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001104 if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001105 (caddr_t) argp, (xdrproc_t) xdr_mountlist,
1106 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001107 return (NULL);
1108 }
1109 return (&clnt_res);
1110}
1111
Erik Andersene49d5ec2000-02-08 19:58:47 +00001112void *mountproc_umnt_1(argp, clnt)
1113dirpath *argp;
1114CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001115{
1116 static char clnt_res;
1117
Erik Andersene49d5ec2000-02-08 19:58:47 +00001118 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001119 if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001120 (caddr_t) argp, (xdrproc_t) xdr_void,
1121 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001122 return (NULL);
1123 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00001124 return ((void *) &clnt_res);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001125}
1126
Erik Andersene49d5ec2000-02-08 19:58:47 +00001127void *mountproc_umntall_1(argp, clnt)
1128void *argp;
1129CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001130{
1131 static char clnt_res;
1132
Erik Andersene49d5ec2000-02-08 19:58:47 +00001133 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001134 if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001135 (caddr_t) argp, (xdrproc_t) xdr_void,
1136 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001137 return (NULL);
1138 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00001139 return ((void *) &clnt_res);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001140}
1141
Erik Andersene49d5ec2000-02-08 19:58:47 +00001142exports *mountproc_export_1(argp, clnt)
1143void *argp;
1144CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001145{
1146 static exports clnt_res;
1147
Erik Andersene49d5ec2000-02-08 19:58:47 +00001148 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001149 if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001150 (caddr_t) argp, (xdrproc_t) xdr_exports,
1151 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001152 return (NULL);
1153 }
1154 return (&clnt_res);
1155}
1156
Erik Andersene49d5ec2000-02-08 19:58:47 +00001157exports *mountproc_exportall_1(argp, clnt)
1158void *argp;
1159CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001160{
1161 static exports clnt_res;
1162
Erik Andersene49d5ec2000-02-08 19:58:47 +00001163 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001164 if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001165 (caddr_t) argp, (xdrproc_t) xdr_exports,
1166 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
1167 return (NULL);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001168 }
1169 return (&clnt_res);
1170}
1171
Erik Andersene49d5ec2000-02-08 19:58:47 +00001172void *mountproc_null_2(argp, clnt)
1173void *argp;
1174CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001175{
1176 static char clnt_res;
1177
Erik Andersene49d5ec2000-02-08 19:58:47 +00001178 memset((char *) &clnt_res, 0, sizeof(clnt_res));
1179 if (clnt_call
1180 (clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp,
1181 (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001182 return (NULL);
1183 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00001184 return ((void *) &clnt_res);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001185}
1186
Erik Andersene49d5ec2000-02-08 19:58:47 +00001187fhstatus *mountproc_mnt_2(argp, clnt)
1188dirpath *argp;
1189CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001190{
1191 static fhstatus clnt_res;
1192
Erik Andersene49d5ec2000-02-08 19:58:47 +00001193 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001194 if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001195 (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
1196 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001197 return (NULL);
1198 }
1199 return (&clnt_res);
1200}
1201
Erik Andersene49d5ec2000-02-08 19:58:47 +00001202mountlist *mountproc_dump_2(argp, clnt)
1203void *argp;
1204CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001205{
1206 static mountlist clnt_res;
1207
Erik Andersene49d5ec2000-02-08 19:58:47 +00001208 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001209 if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001210 (xdrproc_t) xdr_mountlist, (caddr_t) & clnt_res,
1211 TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001212 return (NULL);
1213 }
1214 return (&clnt_res);
1215}
1216
Erik Andersene49d5ec2000-02-08 19:58:47 +00001217void *mountproc_umnt_2(argp, clnt)
1218dirpath *argp;
1219CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001220{
1221 static char clnt_res;
1222
Erik Andersene49d5ec2000-02-08 19:58:47 +00001223 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001224 if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001225 (caddr_t) argp, (xdrproc_t) xdr_void,
1226 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001227 return (NULL);
1228 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00001229 return ((void *) &clnt_res);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001230}
1231
Erik Andersene49d5ec2000-02-08 19:58:47 +00001232void *mountproc_umntall_2(argp, clnt)
1233void *argp;
1234CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001235{
1236 static char clnt_res;
1237
Erik Andersene49d5ec2000-02-08 19:58:47 +00001238 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001239 if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001240 (caddr_t) argp, (xdrproc_t) xdr_void,
1241 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001242 return (NULL);
1243 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00001244 return ((void *) &clnt_res);
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001245}
1246
Erik Andersene49d5ec2000-02-08 19:58:47 +00001247exports *mountproc_export_2(argp, clnt)
1248void *argp;
1249CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001250{
1251 static exports clnt_res;
1252
Erik Andersene49d5ec2000-02-08 19:58:47 +00001253 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001254 if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001255 argp, (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
1256 TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001257 return (NULL);
1258 }
1259 return (&clnt_res);
1260}
1261
Erik Andersene49d5ec2000-02-08 19:58:47 +00001262exports *mountproc_exportall_2(argp, clnt)
1263void *argp;
1264CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001265{
1266 static exports clnt_res;
1267
Erik Andersene49d5ec2000-02-08 19:58:47 +00001268 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001269 if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001270 (xdrproc_t) xdr_exports, (caddr_t) & clnt_res,
1271 TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001272 return (NULL);
1273 }
1274 return (&clnt_res);
1275}
1276
Erik Andersene49d5ec2000-02-08 19:58:47 +00001277ppathcnf *mountproc_pathconf_2(argp, clnt)
1278dirpath *argp;
1279CLIENT *clnt;
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001280{
1281 static ppathcnf clnt_res;
1282
Erik Andersene49d5ec2000-02-08 19:58:47 +00001283 memset((char *) &clnt_res, 0, sizeof(clnt_res));
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001284 if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath,
Erik Andersene49d5ec2000-02-08 19:58:47 +00001285 (caddr_t) argp, (xdrproc_t) xdr_ppathcnf,
1286 (caddr_t) & clnt_res, TIMEOUT) != RPC_SUCCESS) {
Eric Andersen1c43d0c1999-11-18 07:58:07 +00001287 return (NULL);
1288 }
1289 return (&clnt_res);
1290}