|
|
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.