Commit | Line | Data |
---|---|---|
c882a0dc | 1 | /* |
79ae9f1e | 2 | * Copyright (c) 1992, 1993, 1994 |
1ca341e6 | 3 | * The Regents of the University of California. All rights reserved. |
c882a0dc KM |
4 | * |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Rick Macklem at The University of Guelph. | |
7 | * | |
8 | * %sccs.include.redist.c% | |
9 | */ | |
10 | ||
11 | #ifndef lint | |
1ca341e6 | 12 | static char copyright[] = |
79ae9f1e | 13 | "@(#) Copyright (c) 1992, 1993, 1994\n\ |
1ca341e6 | 14 | The Regents of the University of California. All rights reserved.\n"; |
c882a0dc KM |
15 | #endif /* not lint */ |
16 | ||
17 | #ifndef lint | |
d56c93e6 | 18 | static char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) %G%"; |
c882a0dc KM |
19 | #endif /* not lint */ |
20 | ||
c882a0dc | 21 | #include <sys/param.h> |
c882a0dc KM |
22 | #include <sys/mount.h> |
23 | #include <sys/socket.h> | |
24 | #include <sys/socketvar.h> | |
5c60eb94 KB |
25 | #include <sys/stat.h> |
26 | #include <sys/syslog.h> | |
27 | ||
c882a0dc KM |
28 | #include <rpc/rpc.h> |
29 | #include <rpc/pmap_clnt.h> | |
30 | #include <rpc/pmap_prot.h> | |
5c60eb94 | 31 | |
c882a0dc KM |
32 | #ifdef ISO |
33 | #include <netiso/iso.h> | |
34 | #endif | |
5c60eb94 | 35 | |
c882a0dc | 36 | #ifdef KERBEROS |
dbbed105 | 37 | #include <kerberosIV/des.h> |
c882a0dc KM |
38 | #include <kerberosIV/krb.h> |
39 | #endif | |
5c60eb94 | 40 | |
c882a0dc KM |
41 | #include <nfs/rpcv2.h> |
42 | #include <nfs/nfsv2.h> | |
5c60eb94 | 43 | #define KERNEL |
c882a0dc | 44 | #include <nfs/nfs.h> |
5c60eb94 | 45 | #undef KERNEL |
c882a0dc KM |
46 | #include <nfs/nqnfs.h> |
47 | ||
5c60eb94 KB |
48 | #include <arpa/inet.h> |
49 | ||
50 | #include <ctype.h> | |
79ae9f1e | 51 | #include <err.h> |
5c60eb94 KB |
52 | #include <errno.h> |
53 | #include <fcntl.h> | |
54 | #include <netdb.h> | |
55 | #include <signal.h> | |
56 | #include <stdio.h> | |
57 | #include <stdlib.h> | |
58 | #include <strings.h> | |
59 | #include <unistd.h> | |
60 | ||
79ae9f1e KB |
61 | #include "mntopts.h" |
62 | ||
79ae9f1e KB |
63 | struct mntopt mopts[] = { |
64 | MOPT_STDOPTS, | |
79ae9f1e | 65 | MOPT_FORCE, |
79ae9f1e KB |
66 | MOPT_UPDATE, |
67 | { NULL } | |
68 | }; | |
69 | ||
c882a0dc KM |
70 | struct nfs_args nfsdefargs = { |
71 | (struct sockaddr *)0, | |
72 | sizeof (struct sockaddr_in), | |
73 | SOCK_DGRAM, | |
74 | 0, | |
75 | (nfsv2fh_t *)0, | |
76 | 0, | |
77 | NFS_WSIZE, | |
78 | NFS_RSIZE, | |
79 | NFS_TIMEO, | |
80 | NFS_RETRANS, | |
81 | NFS_MAXGRPS, | |
82 | NFS_DEFRAHEAD, | |
83 | NQ_DEFLEASE, | |
84 | NQ_DEADTHRESH, | |
85 | (char *)0, | |
86 | }; | |
87 | ||
88 | struct nfhret { | |
89 | u_long stat; | |
90 | nfsv2fh_t nfh; | |
91 | }; | |
92 | #define DEF_RETRY 10000 | |
93 | #define BGRND 1 | |
94 | #define ISBGRND 2 | |
95 | int retrycnt = DEF_RETRY; | |
96 | int opflags = 0; | |
c882a0dc KM |
97 | |
98 | #ifdef KERBEROS | |
99 | char inst[INST_SZ]; | |
100 | char realm[REALM_SZ]; | |
101 | KTEXT_ST kt; | |
102 | #endif | |
103 | ||
5c60eb94 KB |
104 | int getnfsargs __P((char *, struct nfs_args *)); |
105 | #ifdef ISO | |
106 | struct iso_addr *iso_addr __P((const char *)); | |
107 | #endif | |
108 | void set_rpc_maxgrouplist __P((int)); | |
109 | __dead void usage __P((void)); | |
5c60eb94 KB |
110 | int xdr_dir __P((XDR *, char *)); |
111 | int xdr_fh __P((XDR *, struct nfhret *)); | |
112 | ||
113 | int | |
114 | main(argc, argv) | |
c882a0dc | 115 | int argc; |
5c60eb94 | 116 | char *argv[]; |
c882a0dc | 117 | { |
c882a0dc | 118 | register int c; |
5c60eb94 KB |
119 | register struct nfs_args *nfsargsp; |
120 | struct nfs_args nfsargs; | |
c882a0dc | 121 | struct nfsd_cargs ncd; |
79ae9f1e | 122 | int mntflags, i, nfssvc_flag, num; |
5c60eb94 | 123 | char *name, *p, *spec; |
79ae9f1e | 124 | int error = 0; |
5c60eb94 KB |
125 | #ifdef KERBEROS |
126 | uid_t last_ruid; | |
127 | #endif | |
c882a0dc KM |
128 | |
129 | #ifdef KERBEROS | |
5c60eb94 KB |
130 | last_ruid = -1; |
131 | (void)strcpy(realm, KRB_REALM); | |
c882a0dc | 132 | #endif |
c882a0dc | 133 | retrycnt = DEF_RETRY; |
5c60eb94 | 134 | |
79ae9f1e | 135 | mntflags = 0; |
5c60eb94 KB |
136 | nfsargs = nfsdefargs; |
137 | nfsargsp = &nfsargs; | |
138 | while ((c = getopt(argc, argv, | |
79ae9f1e | 139 | "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF) |
c882a0dc | 140 | switch (c) { |
5c60eb94 KB |
141 | case 'a': |
142 | num = strtol(optarg, &p, 10); | |
143 | if (*p || num < 0) | |
79ae9f1e | 144 | errx(1, "illegal -a value -- %s", optarg); |
5c60eb94 KB |
145 | nfsargsp->readahead = num; |
146 | nfsargsp->flags |= NFSMNT_READAHEAD; | |
147 | break; | |
c882a0dc KM |
148 | case 'b': |
149 | opflags |= BGRND; | |
150 | break; | |
5c60eb94 KB |
151 | case 'c': |
152 | nfsargsp->flags |= NFSMNT_NOCONN; | |
153 | break; | |
154 | case 'D': | |
155 | num = strtol(optarg, &p, 10); | |
156 | if (*p || num <= 0) | |
79ae9f1e | 157 | errx(1, "illegal -D value -- %s", optarg); |
5c60eb94 KB |
158 | nfsargsp->deadthresh = num; |
159 | nfsargsp->flags |= NFSMNT_DEADTHRESH; | |
160 | break; | |
161 | case 'd': | |
162 | nfsargsp->flags |= NFSMNT_DUMBTIMR; | |
163 | break; | |
5c60eb94 KB |
164 | case 'g': |
165 | num = strtol(optarg, &p, 10); | |
efdcf411 | 166 | if (*p || num <= 0) |
79ae9f1e | 167 | errx(1, "illegal -g value -- %s", optarg); |
5c60eb94 KB |
168 | set_rpc_maxgrouplist(num); |
169 | nfsargsp->maxgrouplist = num; | |
170 | nfsargsp->flags |= NFSMNT_MAXGRPS; | |
c882a0dc KM |
171 | break; |
172 | case 'i': | |
173 | nfsargsp->flags |= NFSMNT_INT; | |
174 | break; | |
5c60eb94 KB |
175 | #ifdef KERBEROS |
176 | case 'K': | |
177 | nfsargsp->flags |= NFSMNT_KERB; | |
c882a0dc KM |
178 | break; |
179 | #endif | |
5c60eb94 KB |
180 | case 'k': |
181 | nfsargsp->flags |= NFSMNT_NQLOOKLEASE; | |
182 | break; | |
183 | case 'L': | |
184 | num = strtol(optarg, &p, 10); | |
185 | if (*p || num < 2) | |
79ae9f1e | 186 | errx(1, "illegal -L value -- %s", optarg); |
5c60eb94 KB |
187 | nfsargsp->leaseterm = num; |
188 | nfsargsp->flags |= NFSMNT_LEASETERM; | |
c882a0dc KM |
189 | break; |
190 | case 'l': | |
191 | nfsargsp->flags |= NFSMNT_RDIRALOOK; | |
192 | break; | |
5c60eb94 KB |
193 | case 'M': |
194 | nfsargsp->flags |= NFSMNT_MYWRITE; | |
c882a0dc | 195 | break; |
5c60eb94 KB |
196 | #ifdef KERBEROS |
197 | case 'm': | |
198 | (void)strncpy(realm, optarg, REALM_SZ - 1); | |
199 | realm[REALM_SZ - 1] = '\0'; | |
c882a0dc | 200 | break; |
5c60eb94 | 201 | #endif |
79ae9f1e KB |
202 | case 'o': |
203 | getmntopts(optarg, mopts, &mntflags); | |
204 | break; | |
2bb04e15 KM |
205 | case 'P': |
206 | nfsargsp->flags |= NFSMNT_RESVPORT; | |
207 | break; | |
5c60eb94 KB |
208 | #ifdef ISO |
209 | case 'p': | |
210 | nfsargsp->sotype = SOCK_SEQPACKET; | |
211 | break; | |
212 | #endif | |
213 | case 'q': | |
214 | nfsargsp->flags |= NFSMNT_NQNFS; | |
c882a0dc KM |
215 | break; |
216 | case 'R': | |
5c60eb94 KB |
217 | num = strtol(optarg, &p, 10); |
218 | if (*p || num <= 0) | |
79ae9f1e | 219 | errx(1, "illegal -R value -- %s", optarg); |
5c60eb94 | 220 | retrycnt = num; |
c882a0dc KM |
221 | break; |
222 | case 'r': | |
5c60eb94 KB |
223 | num = strtol(optarg, &p, 10); |
224 | if (*p || num <= 0) | |
79ae9f1e | 225 | errx(1, "illegal -r value -- %s", optarg); |
5c60eb94 KB |
226 | nfsargsp->rsize = num; |
227 | nfsargsp->flags |= NFSMNT_RSIZE; | |
c882a0dc | 228 | break; |
5c60eb94 KB |
229 | case 's': |
230 | nfsargsp->flags |= NFSMNT_SOFT; | |
c882a0dc | 231 | break; |
5c60eb94 KB |
232 | case 'T': |
233 | nfsargsp->sotype = SOCK_STREAM; | |
c882a0dc | 234 | break; |
5c60eb94 KB |
235 | case 't': |
236 | num = strtol(optarg, &p, 10); | |
237 | if (*p || num <= 0) | |
79ae9f1e | 238 | errx(1, "illegal -t value -- %s", optarg); |
5c60eb94 KB |
239 | nfsargsp->timeo = num; |
240 | nfsargsp->flags |= NFSMNT_TIMEO; | |
c882a0dc | 241 | break; |
5c60eb94 KB |
242 | case 'w': |
243 | num = strtol(optarg, &p, 10); | |
244 | if (*p || num <= 0) | |
79ae9f1e | 245 | errx(1, "illegal -w value -- %s", optarg); |
5c60eb94 KB |
246 | nfsargsp->wsize = num; |
247 | nfsargsp->flags |= NFSMNT_WSIZE; | |
c882a0dc | 248 | break; |
5c60eb94 KB |
249 | case 'x': |
250 | num = strtol(optarg, &p, 10); | |
251 | if (*p || num <= 0) | |
79ae9f1e | 252 | errx(1, "illegal -x value -- %s", optarg); |
5c60eb94 KB |
253 | nfsargsp->retrans = num; |
254 | nfsargsp->flags |= NFSMNT_RETRANS; | |
c882a0dc | 255 | break; |
c882a0dc | 256 | default: |
5c60eb94 | 257 | usage(); |
79ae9f1e KB |
258 | break; |
259 | } | |
260 | argc -= optind; | |
261 | argv += optind; | |
5c60eb94 | 262 | |
79ae9f1e KB |
263 | if (argc != 2) |
264 | error = 1; | |
5c60eb94 | 265 | |
79ae9f1e KB |
266 | spec = *argv++; |
267 | name = *argv; | |
5c60eb94 KB |
268 | |
269 | if (!getnfsargs(spec, nfsargsp)) | |
270 | exit(1); | |
79ae9f1e KB |
271 | if (mount(MOUNT_NFS, name, mntflags, nfsargsp)) |
272 | err(1, "%s", name); | |
5c60eb94 KB |
273 | if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) { |
274 | if ((opflags & ISBGRND) == 0) { | |
275 | if (i = fork()) { | |
276 | if (i == -1) | |
79ae9f1e | 277 | err(1, "nqnfs 1"); |
5c60eb94 KB |
278 | exit(0); |
279 | } | |
280 | (void) setsid(); | |
281 | (void) close(STDIN_FILENO); | |
282 | (void) close(STDOUT_FILENO); | |
283 | (void) close(STDERR_FILENO); | |
284 | (void) chdir("/"); | |
285 | } | |
286 | openlog("mount_nfs:", LOG_PID, LOG_DAEMON); | |
287 | nfssvc_flag = NFSSVC_MNTD; | |
288 | ncd.ncd_dirp = name; | |
289 | while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) { | |
290 | if (errno != ENEEDAUTH) { | |
291 | syslog(LOG_ERR, "nfssvc err %m"); | |
292 | continue; | |
c882a0dc | 293 | } |
5c60eb94 KB |
294 | nfssvc_flag = |
295 | NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL; | |
c882a0dc | 296 | #ifdef KERBEROS |
5c60eb94 KB |
297 | /* |
298 | * Set up as ncd_authuid for the kerberos call. | |
299 | * Must set ruid to ncd_authuid and reset the | |
300 | * ticket name iff ncd_authuid is not the same | |
301 | * as last time, so that the right ticket file | |
302 | * is found. | |
303 | */ | |
304 | if (ncd.ncd_authuid != last_ruid) { | |
305 | krb_set_tkt_string(""); | |
306 | last_ruid = ncd.ncd_authuid; | |
307 | } | |
308 | setreuid(ncd.ncd_authuid, 0); | |
309 | if (krb_mk_req(&kt, "rcmd", inst, realm, 0) == | |
310 | KSUCCESS && | |
311 | kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) { | |
5c60eb94 KB |
312 | ncd.ncd_authtype = RPCAUTH_NQNFS; |
313 | ncd.ncd_authlen = kt.length; | |
314 | ncd.ncd_authstr = (char *)kt.dat; | |
315 | nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH; | |
c882a0dc | 316 | } |
5c60eb94 | 317 | setreuid(0, 0); |
5c60eb94 | 318 | #endif /* KERBEROS */ |
c882a0dc | 319 | } |
5c60eb94 KB |
320 | } |
321 | exit(0); | |
c882a0dc KM |
322 | } |
323 | ||
5c60eb94 | 324 | int |
c882a0dc KM |
325 | getnfsargs(spec, nfsargsp) |
326 | char *spec; | |
327 | struct nfs_args *nfsargsp; | |
328 | { | |
329 | register CLIENT *clp; | |
330 | struct hostent *hp; | |
331 | static struct sockaddr_in saddr; | |
332 | #ifdef ISO | |
333 | static struct sockaddr_iso isoaddr; | |
334 | struct iso_addr *isop; | |
5c60eb94 | 335 | int isoflag = 0; |
c882a0dc KM |
336 | #endif |
337 | struct timeval pertry, try; | |
338 | enum clnt_stat clnt_stat; | |
5c60eb94 KB |
339 | int so = RPC_ANYSOCK, i; |
340 | char *hostp, *delimp; | |
341 | #ifdef KERBEROS | |
342 | char *cp; | |
343 | #endif | |
c882a0dc KM |
344 | u_short tport; |
345 | static struct nfhret nfhret; | |
346 | static char nam[MNAMELEN + 1]; | |
347 | ||
348 | strncpy(nam, spec, MNAMELEN); | |
349 | nam[MNAMELEN] = '\0'; | |
79ae9f1e | 350 | if ((delimp = strchr(spec, '@')) != NULL) { |
c882a0dc | 351 | hostp = delimp + 1; |
79ae9f1e | 352 | } else if ((delimp = strchr(spec, ':')) != NULL) { |
c882a0dc KM |
353 | hostp = spec; |
354 | spec = delimp + 1; | |
355 | } else { | |
79ae9f1e | 356 | warnx("no <host>:<dirpath> or <dirpath>@<host> spec"); |
c882a0dc KM |
357 | return (0); |
358 | } | |
359 | *delimp = '\0'; | |
360 | /* | |
361 | * DUMB!! Until the mount protocol works on iso transport, we must | |
362 | * supply both an iso and an inet address for the host. | |
363 | */ | |
364 | #ifdef ISO | |
365 | if (!strncmp(hostp, "iso=", 4)) { | |
366 | u_short isoport; | |
367 | ||
368 | hostp += 4; | |
369 | isoflag++; | |
79ae9f1e KB |
370 | if ((delimp = strchr(hostp, '+')) == NULL) { |
371 | warnx("no iso+inet address"); | |
c882a0dc KM |
372 | return (0); |
373 | } | |
374 | *delimp = '\0'; | |
375 | if ((isop = iso_addr(hostp)) == NULL) { | |
79ae9f1e | 376 | warnx("bad ISO address"); |
c882a0dc KM |
377 | return (0); |
378 | } | |
379 | bzero((caddr_t)&isoaddr, sizeof (isoaddr)); | |
380 | bcopy((caddr_t)isop, (caddr_t)&isoaddr.siso_addr, | |
381 | sizeof (struct iso_addr)); | |
382 | isoaddr.siso_len = sizeof (isoaddr); | |
383 | isoaddr.siso_family = AF_ISO; | |
384 | isoaddr.siso_tlen = 2; | |
385 | isoport = htons(NFS_PORT); | |
386 | bcopy((caddr_t)&isoport, TSEL(&isoaddr), isoaddr.siso_tlen); | |
387 | hostp = delimp + 1; | |
388 | } | |
389 | #endif /* ISO */ | |
390 | ||
391 | /* | |
392 | * Handle an internet host address and reverse resolve it if | |
393 | * doing Kerberos. | |
394 | */ | |
395 | if (isdigit(*hostp)) { | |
396 | if ((saddr.sin_addr.s_addr = inet_addr(hostp)) == -1) { | |
79ae9f1e | 397 | warnx("bad net address %s", hostp); |
c882a0dc KM |
398 | return (0); |
399 | } | |
400 | if ((nfsargsp->flags & NFSMNT_KERB) && | |
401 | (hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr, | |
5c60eb94 | 402 | sizeof (u_long), AF_INET)) == (struct hostent *)0) { |
79ae9f1e | 403 | warnx("can't reverse resolve net address"); |
c882a0dc KM |
404 | return (0); |
405 | } | |
406 | } else if ((hp = gethostbyname(hostp)) == NULL) { | |
79ae9f1e | 407 | warnx("can't get net id for host"); |
c882a0dc KM |
408 | return (0); |
409 | } | |
410 | #ifdef KERBEROS | |
411 | if (nfsargsp->flags & NFSMNT_KERB) { | |
412 | strncpy(inst, hp->h_name, INST_SZ); | |
413 | inst[INST_SZ - 1] = '\0'; | |
79ae9f1e | 414 | if (cp = strchr(inst, '.')) |
c882a0dc KM |
415 | *cp = '\0'; |
416 | } | |
417 | #endif /* KERBEROS */ | |
418 | ||
419 | bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); | |
420 | nfhret.stat = EACCES; /* Mark not yet successful */ | |
421 | while (retrycnt > 0) { | |
422 | saddr.sin_family = AF_INET; | |
423 | saddr.sin_port = htons(PMAPPORT); | |
424 | if ((tport = pmap_getport(&saddr, RPCPROG_NFS, | |
425 | NFS_VER2, IPPROTO_UDP)) == 0) { | |
426 | if ((opflags & ISBGRND) == 0) | |
427 | clnt_pcreateerror("NFS Portmap"); | |
428 | } else { | |
429 | saddr.sin_port = 0; | |
430 | pertry.tv_sec = 10; | |
431 | pertry.tv_usec = 0; | |
432 | if ((clp = clntudp_create(&saddr, RPCPROG_MNT, | |
433 | RPCMNT_VER1, pertry, &so)) == NULL) { | |
434 | if ((opflags & ISBGRND) == 0) | |
435 | clnt_pcreateerror("Cannot MNT PRC"); | |
436 | } else { | |
437 | clp->cl_auth = authunix_create_default(); | |
438 | try.tv_sec = 10; | |
439 | try.tv_usec = 0; | |
440 | clnt_stat = clnt_call(clp, RPCMNT_MOUNT, | |
441 | xdr_dir, spec, xdr_fh, &nfhret, try); | |
442 | if (clnt_stat != RPC_SUCCESS) { | |
79ae9f1e KB |
443 | if ((opflags & ISBGRND) == 0) |
444 | warnx("%s", clnt_sperror(clp, | |
5c60eb94 | 445 | "bad MNT RPC")); |
c882a0dc KM |
446 | } else { |
447 | auth_destroy(clp->cl_auth); | |
448 | clnt_destroy(clp); | |
449 | retrycnt = 0; | |
450 | } | |
451 | } | |
452 | } | |
453 | if (--retrycnt > 0) { | |
454 | if (opflags & BGRND) { | |
455 | opflags &= ~BGRND; | |
456 | if (i = fork()) { | |
5c60eb94 | 457 | if (i == -1) |
79ae9f1e | 458 | err(1, "nqnfs 2"); |
7cd40046 | 459 | exit(0); |
c882a0dc KM |
460 | } |
461 | (void) setsid(); | |
5c60eb94 KB |
462 | (void) close(STDIN_FILENO); |
463 | (void) close(STDOUT_FILENO); | |
464 | (void) close(STDERR_FILENO); | |
c882a0dc KM |
465 | (void) chdir("/"); |
466 | opflags |= ISBGRND; | |
5c60eb94 | 467 | } |
c882a0dc KM |
468 | sleep(60); |
469 | } | |
470 | } | |
471 | if (nfhret.stat) { | |
472 | if (opflags & ISBGRND) | |
473 | exit(1); | |
79ae9f1e | 474 | warn("can't access %s", spec); |
c882a0dc KM |
475 | return (0); |
476 | } | |
477 | saddr.sin_port = htons(tport); | |
478 | #ifdef ISO | |
479 | if (isoflag) { | |
480 | nfsargsp->addr = (struct sockaddr *) &isoaddr; | |
481 | nfsargsp->addrlen = sizeof (isoaddr); | |
482 | } else | |
483 | #endif /* ISO */ | |
484 | { | |
485 | nfsargsp->addr = (struct sockaddr *) &saddr; | |
486 | nfsargsp->addrlen = sizeof (saddr); | |
487 | } | |
488 | nfsargsp->fh = &nfhret.nfh; | |
489 | nfsargsp->hostname = nam; | |
490 | return (1); | |
491 | } | |
492 | ||
493 | /* | |
494 | * xdr routines for mount rpc's | |
495 | */ | |
5c60eb94 | 496 | int |
c882a0dc KM |
497 | xdr_dir(xdrsp, dirp) |
498 | XDR *xdrsp; | |
499 | char *dirp; | |
500 | { | |
501 | return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); | |
502 | } | |
503 | ||
5c60eb94 | 504 | int |
c882a0dc KM |
505 | xdr_fh(xdrsp, np) |
506 | XDR *xdrsp; | |
507 | struct nfhret *np; | |
508 | { | |
509 | if (!xdr_u_long(xdrsp, &(np->stat))) | |
510 | return (0); | |
511 | if (np->stat) | |
512 | return (1); | |
513 | return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); | |
514 | } | |
515 | ||
5c60eb94 KB |
516 | __dead void |
517 | usage() | |
c882a0dc | 518 | { |
5c60eb94 KB |
519 | (void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n", |
520 | "[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]", | |
79ae9f1e | 521 | "\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]", |
5c60eb94 KB |
522 | "\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]", |
523 | "\trhost:path node"); | |
524 | exit(1); | |
525 | } |