|
|
1.1 root 1: /*
2: * Copyright (c) 1980, 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)mount.c 5.39 (Berkeley) 6/22/90";
28: #endif /* not lint */
29:
30: #include "pathnames.h"
31: #include <sys/param.h>
32: #include <sys/file.h>
33: #include <sys/time.h>
34: #include <sys/wait.h>
35: #include <fstab.h>
36: #include <errno.h>
37: #include <stdio.h>
38: #include <signal.h>
39: #include <string.h>
40: #include <sys/mount.h>
41: #ifdef NFS
42: #include <sys/socket.h>
43: #include <sys/socketvar.h>
44: #include <netdb.h>
45: #include <rpc/rpc.h>
46: #include <rpc/pmap_clnt.h>
47: #include <rpc/pmap_prot.h>
48: #include <nfs/rpcv2.h>
49: #include <nfs/nfsv2.h>
50: #include <nfs/nfs.h>
51: #endif
52:
53: #define DEFAULT_ROOTUID -2
54:
55: #define BADTYPE(type) \
56: (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \
57: strcmp(type, FSTAB_RQ))
58: #define SETTYPE(type) \
59: (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ))
60:
61: int fake, verbose, updateflg, mnttype;
62: char *mntname, **envp;
63: char **vfslist, **makevfslist();
64:
65: #ifdef NFS
66: int xdr_dir(), xdr_fh();
67: char *getnfsargs();
68: struct nfs_args nfsdefargs = {
69: (struct sockaddr *)0,
70: SOCK_DGRAM,
71: 0,
72: (nfsv2fh_t *)0,
73: 0,
74: NFS_WSIZE,
75: NFS_RSIZE,
76: NFS_TIMEO,
77: NFS_RETRANS,
78: (char *)0,
79: };
80:
81: struct nfhret {
82: u_long stat;
83: nfsv2fh_t nfh;
84: };
85: #define DEF_RETRY 10000
86: int retrycnt;
87: #define BGRND 1
88: #define ISBGRND 2
89: int opflags = 0;
90: #endif
91:
92: main(argc, argv, arge)
93: int argc;
94: char **argv;
95: char **arge;
96: {
97: extern char *optarg;
98: extern int optind;
99: register struct fstab *fs;
100: int all, ch, rval, flags, ret, pid, i;
101: long mntsize;
102: struct statfs *mntbuf, *getmntpt();
103: char *type, *options = NULL;
104: FILE *pidfile;
105:
106: envp = arge;
107: all = 0;
108: type = NULL;
109: mnttype = MOUNT_UFS;
110: mntname = "ufs";
111: while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF)
112: switch((char)ch) {
113: case 'a':
114: all = 1;
115: break;
116: case 'f':
117: fake = 1;
118: break;
119: case 'r':
120: type = FSTAB_RO;
121: break;
122: case 'u':
123: updateflg = MNT_UPDATE;
124: break;
125: case 'v':
126: verbose = 1;
127: break;
128: case 'w':
129: type = FSTAB_RW;
130: break;
131: case 'o':
132: options = optarg;
133: break;
134: case 't':
135: vfslist = makevfslist(optarg);
136: mnttype = getmnttype(optarg);
137: break;
138: case '?':
139: default:
140: usage();
141: /* NOTREACHED */
142: }
143: argc -= optind;
144: argv += optind;
145:
146: /* NOSTRICT */
147:
148: if (all) {
149: rval = 0;
150: while (fs = getfsent()) {
151: if (BADTYPE(fs->fs_type))
152: continue;
153: if (badvfsname(fs->fs_vfstype, vfslist))
154: continue;
155: /* `/' is special, it's always mounted */
156: if (!strcmp(fs->fs_file, "/"))
157: flags = MNT_UPDATE;
158: else
159: flags = updateflg;
160: mnttype = getmnttype(fs->fs_vfstype);
161: rval |= mountfs(fs->fs_spec, fs->fs_file, flags,
162: type, options, fs->fs_mntops);
163: }
164: exit(rval);
165: }
166:
167: if (argc == 0) {
168: if (verbose || fake || type)
169: usage();
170: if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
171: fprintf(stderr,
172: "mount: cannot get mount information\n");
173: exit(1);
174: }
175: for (i = 0; i < mntsize; i++) {
176: if (badvfstype(mntbuf[i].f_type, vfslist))
177: continue;
178: prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname,
179: mntbuf[i].f_flags);
180: }
181: exit(0);
182: }
183:
184: if (argc == 1 && updateflg) {
185: if ((mntbuf = getmntpt(*argv)) == NULL) {
186: fprintf(stderr,
187: "mount: unknown special file or file system %s.\n",
188: *argv);
189: exit(1);
190: }
191: mnttype = mntbuf->f_type;
192: if (!strcmp(mntbuf->f_mntfromname, "root_device")) {
193: fs = getfsfile("/");
194: strcpy(mntbuf->f_mntfromname, fs->fs_spec);
195: }
196: ret = mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname,
197: updateflg, type, options, (char *)NULL);
198: } else if (argc == 1) {
199: if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) {
200: fprintf(stderr,
201: "mount: unknown special file or file system %s.\n",
202: *argv);
203: exit(1);
204: }
205: if (BADTYPE(fs->fs_type)) {
206: fprintf(stderr,
207: "mount: %s has unknown file system type.\n", *argv);
208: exit(1);
209: }
210: mnttype = getmnttype(fs->fs_vfstype);
211: ret = mountfs(fs->fs_spec, fs->fs_file, updateflg,
212: type, options, fs->fs_mntops);
213: } else if (argc != 2) {
214: usage();
215: ret = 1;
216: } else {
217: /*
218: * If -t flag has not been specified, and spec
219: * contains either a ':' or a '@' then assume that
220: * an NFS filesystem is being specified ala Sun.
221: */
222: if (vfslist == (char **)0 &&
223: (index(argv[0], ':') || index(argv[0], '@')))
224: mnttype = MOUNT_NFS;
225: ret = mountfs(argv[0], argv[1], updateflg, type, options,
226: (char *)NULL);
227: }
228: if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) {
229: pid = 0;
230: fscanf(pidfile, "%d", &pid);
231: fclose(pidfile);
232: if (pid > 0)
233: kill(pid, SIGHUP);
234: }
235: exit (ret);
236: }
237:
238: mountfs(spec, name, flags, type, options, mntopts)
239: char *spec, *name, *type, *options, *mntopts;
240: int flags;
241: {
242: extern int errno;
243: union wait status;
244: pid_t pid;
245: int argc, i;
246: struct ufs_args args;
247: struct nfs_args nfsargs;
248: char *argp, *argv[50];
249: char execname[MAXPATHLEN + 1], flagval[12];
250:
251: nfsargs = nfsdefargs;
252: if (mntopts)
253: getstdopts(mntopts, &flags);
254: if (options)
255: getstdopts(options, &flags);
256: if (type)
257: getstdopts(type, &flags);
258: switch (mnttype) {
259: case MOUNT_UFS:
260: if (mntopts)
261: getufsopts(mntopts, &flags);
262: if (options)
263: getufsopts(options, &flags);
264: args.fspec = spec;
265: args.exroot = DEFAULT_ROOTUID;
266: if (flags & MNT_RDONLY)
267: args.exflags = MNT_EXRDONLY;
268: else
269: args.exflags = 0;
270: argp = (caddr_t)&args;
271: break;
272:
273: #ifdef NFS
274: case MOUNT_NFS:
275: retrycnt = DEF_RETRY;
276: if (mntopts)
277: getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt);
278: if (options)
279: getnfsopts(options, &nfsargs, &opflags, &retrycnt);
280: if (argp = getnfsargs(spec, &nfsargs))
281: break;
282: return (1);
283: #endif /* NFS */
284:
285: case MOUNT_MFS:
286: default:
287: argv[0] = mntname;
288: argc = 1;
289: if (flags) {
290: argv[argc++] = "-F";
291: sprintf(flagval, "%d", flags);
292: argv[argc++] = flagval;
293: }
294: if (mntopts)
295: argc += getexecopts(mntopts, &argv[argc]);
296: if (options)
297: argc += getexecopts(options, &argv[argc]);
298: argv[argc++] = spec;
299: argv[argc++] = name;
300: argv[argc++] = NULL;
301: sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname);
302: if (verbose) {
303: (void)printf("exec: %s", execname);
304: for (i = 1; i < argc - 1; i++)
305: (void)printf(" %s", argv[i]);
306: (void)printf("\n");
307: }
308: if (fake)
309: break;
310: if (pid = vfork()) {
311: if (pid == -1) {
312: perror("mount: vfork starting file system");
313: return (1);
314: }
315: if (waitpid(pid, &status, 0) != -1 &&
316: WIFEXITED(status) &&
317: WEXITSTATUS(status) != 0)
318: return (WEXITSTATUS(status));
319: spec = mntname;
320: goto out;
321: }
322: execve(execname, argv, envp);
323: fprintf(stderr, "mount: cannot exec %s for %s: ",
324: execname, name);
325: perror((char *)NULL);
326: exit (1);
327: /* NOTREACHED */
328:
329: }
330: if (!fake && mount(mnttype, name, flags, argp)) {
331: if (opflags & ISBGRND)
332: exit(1);
333: fprintf(stderr, "%s on %s: ", spec, name);
334: switch (errno) {
335: case EMFILE:
336: fprintf(stderr, "Mount table full\n");
337: break;
338: case EINVAL:
339: if (flags & MNT_UPDATE)
340: fprintf(stderr, "Specified device does %s\n",
341: "not match mounted device");
342: else
343: fprintf(stderr, "Bogus super block\n");
344: break;
345: case EOPNOTSUPP:
346: fprintf(stderr, "Operation not supported\n");
347: break;
348: default:
349: perror((char *)NULL);
350: break;
351: }
352: return(1);
353: }
354:
355: out:
356: if (verbose)
357: prmount(spec, name, flags);
358:
359: if (opflags & ISBGRND)
360: exit(1);
361: return(0);
362: }
363:
364: static
365: prmount(spec, name, flags)
366: char *spec, *name;
367: register short flags;
368: {
369: register int first;
370:
371: if (opflags & ISBGRND)
372: return;
373: (void)printf("%s on %s", spec, name);
374: if (!(flags & MNT_VISFLAGMASK)) {
375: (void)printf("\n");
376: return;
377: }
378: first = 0;
379: #define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg)
380: if (flags & MNT_RDONLY)
381: PR("read-only");
382: if (flags & MNT_NOEXEC)
383: PR("noexec");
384: if (flags & MNT_NOSUID)
385: PR("nosuid");
386: if (flags & MNT_NODEV)
387: PR("nodev");
388: if (flags & MNT_SYNCHRONOUS)
389: PR("synchronous");
390: if (flags & MNT_QUOTA)
391: PR("with quotas");
392: if (flags & MNT_LOCAL)
393: PR("local");
394: if (flags & MNT_EXPORTED)
395: if (flags & MNT_EXRDONLY)
396: PR("NFS exported read-only");
397: else
398: PR("NFS exported");
399: (void)printf(")\n");
400: }
401:
402: getmnttype(fstype)
403: char *fstype;
404: {
405:
406: mntname = fstype;
407: if (!strcmp(fstype, "ufs"))
408: return (MOUNT_UFS);
409: if (!strcmp(fstype, "nfs"))
410: return (MOUNT_NFS);
411: if (!strcmp(fstype, "mfs"))
412: return (MOUNT_MFS);
413: return (0);
414: }
415:
416: usage()
417: {
418:
419: fprintf(stderr, "usage:\n mount %s %s\n mount %s\n mount %s\n",
420: "[ -frwu ] [ -t nfs | ufs | external_type ]",
421: "[ -o options ] special node",
422: "[ -afrwu ] [ -t nfs | ufs | external_type ]",
423: "[ -frwu ] special | node");
424: exit(1);
425: }
426:
427: getstdopts(options, flagp)
428: char *options;
429: int *flagp;
430: {
431: register char *opt;
432: int negative;
433: char optbuf[BUFSIZ];
434:
435: (void)strcpy(optbuf, options);
436: for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) {
437: if (opt[0] == 'n' && opt[1] == 'o') {
438: negative++;
439: opt += 2;
440: } else {
441: negative = 0;
442: }
443: if (!negative && !strcasecmp(opt, FSTAB_RO)) {
444: *flagp |= MNT_RDONLY;
445: continue;
446: }
447: if (!negative && !strcasecmp(opt, FSTAB_RW)) {
448: *flagp &= ~MNT_RDONLY;
449: continue;
450: }
451: if (!strcasecmp(opt, "exec")) {
452: if (negative)
453: *flagp |= MNT_NOEXEC;
454: else
455: *flagp &= ~MNT_NOEXEC;
456: continue;
457: }
458: if (!strcasecmp(opt, "suid")) {
459: if (negative)
460: *flagp |= MNT_NOSUID;
461: else
462: *flagp &= ~MNT_NOSUID;
463: continue;
464: }
465: if (!strcasecmp(opt, "dev")) {
466: if (negative)
467: *flagp |= MNT_NODEV;
468: else
469: *flagp &= ~MNT_NODEV;
470: continue;
471: }
472: if (!strcasecmp(opt, "synchronous")) {
473: if (!negative)
474: *flagp |= MNT_SYNCHRONOUS;
475: else
476: *flagp &= ~MNT_SYNCHRONOUS;
477: continue;
478: }
479: }
480: }
481:
482: /* ARGSUSED */
483: getufsopts(options, flagp)
484: char *options;
485: int *flagp;
486: {
487: return;
488: }
489:
490: getexecopts(options, argv)
491: char *options;
492: char **argv;
493: {
494: register int argc = 0;
495: register char *opt;
496:
497: for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) {
498: if (opt[0] != '-')
499: continue;
500: argv[argc++] = opt;
501: if (opt[2] == '\0' || opt[2] != '=')
502: continue;
503: opt[2] = '\0';
504: argv[argc++] = &opt[3];
505: }
506: return (argc);
507: }
508:
509: struct statfs *
510: getmntpt(name)
511: char *name;
512: {
513: long mntsize;
514: register long i;
515: struct statfs *mntbuf;
516:
517: mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
518: for (i = 0; i < mntsize; i++) {
519: if (!strcmp(mntbuf[i].f_mntfromname, name) ||
520: !strcmp(mntbuf[i].f_mntonname, name))
521: return (&mntbuf[i]);
522: }
523: return ((struct statfs *)0);
524: }
525:
526: static int skipvfs;
527:
528: badvfstype(vfstype, vfslist)
529: short vfstype;
530: char **vfslist;
531: {
532:
533: if (vfslist == 0)
534: return(0);
535: while (*vfslist) {
536: if (vfstype == getmnttype(*vfslist))
537: return(skipvfs);
538: vfslist++;
539: }
540: return (!skipvfs);
541: }
542:
543: badvfsname(vfsname, vfslist)
544: char *vfsname;
545: char **vfslist;
546: {
547:
548: if (vfslist == 0)
549: return(0);
550: while (*vfslist) {
551: if (strcmp(vfsname, *vfslist) == 0)
552: return(skipvfs);
553: vfslist++;
554: }
555: return (!skipvfs);
556: }
557:
558: char **
559: makevfslist(fslist)
560: char *fslist;
561: {
562: register char **av, *nextcp;
563: register int i;
564:
565: if (fslist == NULL)
566: return (NULL);
567: if (fslist[0] == 'n' && fslist[1] == 'o') {
568: fslist += 2;
569: skipvfs = 1;
570: }
571: for (i = 0, nextcp = fslist; *nextcp; nextcp++)
572: if (*nextcp == ',')
573: i++;
574: av = (char **)malloc((size_t)(i+2) * sizeof(char *));
575: if (av == NULL)
576: return (NULL);
577: nextcp = fslist;
578: i = 0;
579: av[i++] = nextcp;
580: while (nextcp = index(nextcp, ',')) {
581: *nextcp++ = '\0';
582: av[i++] = nextcp;
583: }
584: av[i++] = 0;
585: return (av);
586: }
587:
588: #ifdef NFS
589: /*
590: * Handle the getoption arg.
591: * Essentially update "opflags", "retrycnt" and "nfsargs"
592: */
593: getnfsopts(optarg, nfsargsp, opflagsp, retrycntp)
594: char *optarg;
595: struct nfs_args *nfsargsp;
596: int *opflagsp;
597: int *retrycntp;
598: {
599: register char *cp, *nextcp;
600: int num;
601: char *nump;
602:
603: cp = optarg;
604: while (cp != NULL && *cp != '\0') {
605: if ((nextcp = index(cp, ',')) != NULL)
606: *nextcp++ = '\0';
607: if ((nump = index(cp, '=')) != NULL) {
608: *nump++ = '\0';
609: num = atoi(nump);
610: } else
611: num = -1;
612: /*
613: * Just test for a string match and do it
614: */
615: if (!strcmp(cp, "bg")) {
616: *opflagsp |= BGRND;
617: } else if (!strcmp(cp, "soft")) {
618: if (nfsargsp->flags & NFSMNT_SPONGY) {
619: fprintf(stderr,
620: "Options soft, spongy mutually exclusive\n");
621: exit(1);
622: }
623: nfsargsp->flags |= NFSMNT_SOFT;
624: } else if (!strcmp(cp, "spongy")) {
625: if (nfsargsp->flags & NFSMNT_SOFT) {
626: fprintf(stderr,
627: "Options soft, spongy mutually exclusive\n");
628: exit(1);
629: }
630: nfsargsp->flags |= NFSMNT_SPONGY;
631: } else if (!strcmp(cp, "intr")) {
632: nfsargsp->flags |= NFSMNT_INT;
633: } else if (!strcmp(cp, "tcp")) {
634: nfsargsp->sotype = SOCK_STREAM;
635: } else if (!strcmp(cp, "noconn")) {
636: nfsargsp->flags |= NFSMNT_NOCONN;
637: } else if (!strcmp(cp, "retry") && num > 0) {
638: *retrycntp = num;
639: } else if (!strcmp(cp, "rsize") && num > 0) {
640: nfsargsp->rsize = num;
641: nfsargsp->flags |= NFSMNT_RSIZE;
642: } else if (!strcmp(cp, "wsize") && num > 0) {
643: nfsargsp->wsize = num;
644: nfsargsp->flags |= NFSMNT_WSIZE;
645: } else if (!strcmp(cp, "timeo") && num > 0) {
646: nfsargsp->timeo = num;
647: nfsargsp->flags |= NFSMNT_TIMEO;
648: } else if (!strcmp(cp, "retrans") && num > 0) {
649: nfsargsp->retrans = num;
650: nfsargsp->flags |= NFSMNT_RETRANS;
651: }
652: cp = nextcp;
653: }
654: if (nfsargsp->sotype == SOCK_DGRAM) {
655: if (nfsargsp->rsize > NFS_MAXDGRAMDATA)
656: nfsargsp->rsize = NFS_MAXDGRAMDATA;
657: if (nfsargsp->wsize > NFS_MAXDGRAMDATA)
658: nfsargsp->wsize = NFS_MAXDGRAMDATA;
659: }
660: }
661:
662: char *
663: getnfsargs(spec, nfsargsp)
664: char *spec;
665: struct nfs_args *nfsargsp;
666: {
667: extern int errno;
668: register CLIENT *clp;
669: struct hostent *hp;
670: static struct sockaddr_in saddr;
671: struct timeval pertry, try;
672: enum clnt_stat clnt_stat;
673: int so = RPC_ANYSOCK;
674: char *hostp, *delimp;
675: u_short tport;
676: static struct nfhret nfhret;
677: static char nam[MNAMELEN + 1];
678:
679: strncpy(nam, spec, MNAMELEN);
680: nam[MNAMELEN] = '\0';
681: if ((delimp = index(spec, '@')) != NULL) {
682: hostp = delimp + 1;
683: } else if ((delimp = index(spec, ':')) != NULL) {
684: hostp = spec;
685: spec = delimp + 1;
686: } else {
687: fprintf(stderr,
688: "No <host>:<dirpath> or <dirpath>@<host> spec\n");
689: return (0);
690: }
691: *delimp = '\0';
692: if ((hp = gethostbyname(hostp)) == NULL) {
693: fprintf(stderr, "Can't get net id for host\n");
694: return (0);
695: }
696: bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length);
697: nfhret.stat = EACCES; /* Mark not yet successful */
698: while (retrycnt > 0) {
699: saddr.sin_family = AF_INET;
700: saddr.sin_port = htons(PMAPPORT);
701: if ((tport = pmap_getport(&saddr, RPCPROG_NFS,
702: NFS_VER2, IPPROTO_UDP)) == 0) {
703: if ((opflags & ISBGRND) == 0)
704: clnt_pcreateerror("NFS Portmap");
705: } else {
706: saddr.sin_port = 0;
707: pertry.tv_sec = 10;
708: pertry.tv_usec = 0;
709: if ((clp = clntudp_create(&saddr, RPCPROG_MNT,
710: RPCMNT_VER1, pertry, &so)) == NULL) {
711: if ((opflags & ISBGRND) == 0)
712: clnt_pcreateerror("Cannot MNT PRC");
713: } else {
714: clp->cl_auth = authunix_create_default();
715: try.tv_sec = 10;
716: try.tv_usec = 0;
717: clnt_stat = clnt_call(clp, RPCMNT_MOUNT,
718: xdr_dir, spec, xdr_fh, &nfhret, try);
719: if (clnt_stat != RPC_SUCCESS) {
720: if ((opflags & ISBGRND) == 0)
721: clnt_perror(clp, "Bad MNT RPC");
722: } else {
723: auth_destroy(clp->cl_auth);
724: clnt_destroy(clp);
725: retrycnt = 0;
726: }
727: }
728: }
729: if (--retrycnt > 0) {
730: if (opflags & BGRND) {
731: opflags &= ~BGRND;
732: if (fork())
733: return (0);
734: else
735: opflags |= ISBGRND;
736: }
737: sleep(10);
738: }
739: }
740: if (nfhret.stat) {
741: if (opflags & ISBGRND)
742: exit(1);
743: fprintf(stderr, "Can't access %s: ", spec);
744: errno = nfhret.stat;
745: perror((char *)NULL);
746: return (0);
747: }
748: saddr.sin_port = htons(tport);
749: nfsargsp->addr = (struct sockaddr *) &saddr;
750: nfsargsp->fh = &nfhret.nfh;
751: nfsargsp->hostname = nam;
752: return ((caddr_t)nfsargsp);
753: }
754:
755: /*
756: * xdr routines for mount rpc's
757: */
758: xdr_dir(xdrsp, dirp)
759: XDR *xdrsp;
760: char *dirp;
761: {
762: return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
763: }
764:
765: xdr_fh(xdrsp, np)
766: XDR *xdrsp;
767: struct nfhret *np;
768: {
769: if (!xdr_u_long(xdrsp, &(np->stat)))
770: return (0);
771: if (np->stat)
772: return (1);
773: return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH));
774: }
775: #endif /* NFS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.