121156Sdist /* 239322Smckusick * Copyright (c) 1980, 1989 The Regents of the University of California. 339322Smckusick * All rights reserved. 439322Smckusick * 539322Smckusick * Redistribution and use in source and binary forms are permitted 639322Smckusick * provided that the above copyright notice and this paragraph are 739322Smckusick * duplicated in all such forms and that any documentation, 839322Smckusick * advertising materials, and other materials related to such 939322Smckusick * distribution and use acknowledge that the software was developed 1039322Smckusick * by the University of California, Berkeley. The name of the 1139322Smckusick * University may not be used to endorse or promote products derived 1239322Smckusick * from this software without specific prior written permission. 1339322Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1439322Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1539322Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621156Sdist */ 1721156Sdist 1810811Ssam #ifndef lint 1921156Sdist char copyright[] = 2039322Smckusick "@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\ 2121156Sdist All rights reserved.\n"; 2239322Smckusick #endif /* not lint */ 231057Sbill 2421156Sdist #ifndef lint 25*39603Smckusick static char sccsid[] = "@(#)mount.c 5.20 (Berkeley) 11/24/89"; 2639322Smckusick #endif /* not lint */ 2721156Sdist 2839131Smckusick #include "pathnames.h" 2912808Ssam #include <sys/param.h> 3035339Sbostic #include <sys/file.h> 3138445Smckusick #include <sys/time.h> 3239133Smckusick #include <sys/wait.h> 3310811Ssam #include <fstab.h> 3416669Ssam #include <errno.h> 3535339Sbostic #include <stdio.h> 3638445Smckusick #include <strings.h> 3738445Smckusick #include <sys/dir.h> 3838445Smckusick #include <sys/uio.h> 3938445Smckusick #include <sys/namei.h> 4038445Smckusick #include <sys/mount.h> 4138445Smckusick #ifdef NFS 4238445Smckusick #include <sys/socket.h> 4338445Smckusick #include <sys/socketvar.h> 4438445Smckusick #include <netdb.h> 4538445Smckusick #include <rpc/rpc.h> 4638445Smckusick #include <rpc/pmap_clnt.h> 4738445Smckusick #include <rpc/pmap_prot.h> 4838445Smckusick #include <nfs/rpcv2.h> 4938445Smckusick #include <nfs/nfsv2.h> 5038445Smckusick #include <nfs/nfs.h> 5138445Smckusick #endif 521057Sbill 5335339Sbostic #define BADTYPE(type) \ 5435339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 5535339Sbostic strcmp(type, FSTAB_RQ)) 5635339Sbostic #define SETTYPE(type) \ 5735339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 581057Sbill 5939333Smckusick int fake, verbose, updateflg, mnttype; 6039322Smckusick char *mntname, **envp; 6139131Smckusick 6238445Smckusick #ifdef NFS 6338445Smckusick int xdr_dir(), xdr_fh(); 6438632Smckusick char *getnfsargs(); 6538445Smckusick struct nfs_args nfsargs = { 6638445Smckusick (struct sockaddr_in *)0, 6738445Smckusick (nfsv2fh_t *)0, 6838445Smckusick 0, 6938445Smckusick NFS_WSIZE, 7038445Smckusick NFS_RSIZE, 7138445Smckusick NFS_TIMEO, 7238445Smckusick NFS_RETRANS, 7338445Smckusick (char *)0, 7438445Smckusick }; 755073Sroot 7638445Smckusick struct nfhret { 7738445Smckusick u_long stat; 7838445Smckusick nfsv2fh_t nfh; 7938445Smckusick }; 8038445Smckusick int retrycnt = 10000; 8138445Smckusick #define BGRND 1 8238445Smckusick #define ISBGRND 2 8338445Smckusick int opflags = 0; 8438445Smckusick #endif 8538445Smckusick 8639131Smckusick main(argc, argv, arge) 875073Sroot int argc; 885073Sroot char **argv; 8939131Smckusick char **arge; 901057Sbill { 9135339Sbostic extern char *optarg; 9235339Sbostic extern int optind; 9335339Sbostic register struct fstab *fs; 9435339Sbostic register int cnt; 9539333Smckusick int all, ch, rval, flags, i; 9638632Smckusick long mntsize; 9739465Smckusick struct statfs *mntbuf, *getmntpt(); 9839131Smckusick char *type, *options = NULL; 991057Sbill 10039131Smckusick envp = arge; 10135339Sbostic all = 0; 10235339Sbostic type = NULL; 10338445Smckusick mnttype = MOUNT_UFS; 10439322Smckusick mntname = "ufs"; 10539333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 10635339Sbostic switch((char)ch) { 10735339Sbostic case 'a': 10835339Sbostic all = 1; 10935339Sbostic break; 11035339Sbostic case 'f': 11135339Sbostic fake = 1; 11235339Sbostic break; 11335339Sbostic case 'r': 11412808Ssam type = FSTAB_RO; 11535339Sbostic break; 11639333Smckusick case 'u': 11739333Smckusick updateflg = M_UPDATE; 11839333Smckusick break; 11935339Sbostic case 'v': 12035339Sbostic verbose = 1; 12135339Sbostic break; 12235339Sbostic case 'w': 12335339Sbostic type = FSTAB_RW; 12435339Sbostic break; 12539131Smckusick case 'o': 12639131Smckusick options = optarg; 12739131Smckusick break; 12838445Smckusick case 't': 12939322Smckusick mnttype = getmnttype(optarg); 13039322Smckusick break; 13135339Sbostic case '?': 13235339Sbostic default: 13335339Sbostic usage(); 13439131Smckusick /* NOTREACHED */ 1355073Sroot } 13635339Sbostic argc -= optind; 13735339Sbostic argv += optind; 13835339Sbostic 13935339Sbostic /* NOSTRICT */ 14035339Sbostic 1414460Sroot if (all) { 14235369Sbostic rval = 0; 14339333Smckusick while (fs = getfsent()) { 14435372Sbostic if (BADTYPE(fs->fs_type)) 14535372Sbostic continue; 14635372Sbostic /* `/' is special, it's always mounted */ 14735372Sbostic if (!strcmp(fs->fs_file, "/")) 14839333Smckusick flags = M_UPDATE; 14939333Smckusick else 15039333Smckusick flags = updateflg; 15139333Smckusick mnttype = getmnttype(fs->fs_vfstype); 15239333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 15339333Smckusick type, options, fs->fs_mntops); 15435372Sbostic } 15535341Sbostic exit(rval); 15635339Sbostic } 1575073Sroot 15835339Sbostic if (argc == 0) { 15935339Sbostic if (verbose || fake || type) 16035339Sbostic usage(); 16139319Smckusick if ((mntsize = getmntinfo(&mntbuf)) == 0) { 16239319Smckusick fprintf(stderr, 16339319Smckusick "mount: cannot get mount information\n"); 16438632Smckusick exit(1); 16538632Smckusick } 16639316Smckusick for (i = 0; i < mntsize; i++) 16738632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 16839316Smckusick mntbuf[i].f_flags); 1694460Sroot exit(0); 1701057Sbill } 17112808Ssam 17239465Smckusick if (argc == 1 && updateflg) { 17339465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 17439465Smckusick fprintf(stderr, 17539465Smckusick "mount: unknown special file or file system %s.\n", 17639465Smckusick *argv); 17739465Smckusick exit(1); 17839465Smckusick } 17939465Smckusick mnttype = mntbuf->f_type; 18039465Smckusick exit(mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 18139465Smckusick updateflg, type, options, NULL)); 18239465Smckusick } 18339465Smckusick 18435339Sbostic if (argc == 1) { 18535339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 18635339Sbostic fprintf(stderr, 18735339Sbostic "mount: unknown special file or file system %s.\n", 18835339Sbostic *argv); 18935339Sbostic exit(1); 19035339Sbostic } 19135339Sbostic if (BADTYPE(fs->fs_type)) { 19235339Sbostic fprintf(stderr, 19335339Sbostic "mount: %s has unknown file system type.\n", *argv); 19435339Sbostic exit(1); 19535339Sbostic } 19639333Smckusick mnttype = getmnttype(fs->fs_vfstype); 19739333Smckusick exit(mountfs(fs->fs_spec, fs->fs_file, updateflg, 19839333Smckusick type, options, fs->fs_mntops)); 19912808Ssam } 2001057Sbill 20135339Sbostic if (argc != 2) 20235339Sbostic usage(); 20312808Ssam 20439333Smckusick exit(mountfs(argv[0], argv[1], updateflg, type, options, NULL)); 20512808Ssam } 20612808Ssam 20739333Smckusick mountfs(spec, name, flags, type, options, mntopts) 20839131Smckusick char *spec, *name, *type, *options, *mntopts; 20939333Smckusick int flags; 21012808Ssam { 21135339Sbostic extern int errno; 21235339Sbostic register int cnt; 21339333Smckusick int argc, status, i; 21438070Smckusick struct ufs_args args; 21539131Smckusick char *argp, *argv[50]; 21639322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2171057Sbill 21839333Smckusick if (mntopts) 21939333Smckusick getstdopts(mntopts, &flags); 22039316Smckusick if (options) 22139316Smckusick getstdopts(options, &flags); 22239333Smckusick if (type) 22339333Smckusick getstdopts(type, &flags); 22439316Smckusick switch (mnttype) { 22539316Smckusick case MOUNT_UFS: 22639333Smckusick if (mntopts) 22739333Smckusick getufsopts(mntopts, &flags); 22839316Smckusick if (options) 22939316Smckusick getufsopts(options, &flags); 23039316Smckusick args.fspec = spec; 23139316Smckusick argp = (caddr_t)&args; 23239316Smckusick break; 23338632Smckusick 23438632Smckusick #ifdef NFS 23539316Smckusick case MOUNT_NFS: 23639333Smckusick if (mntopts) 23739333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 23839316Smckusick if (options) 23939333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 24039316Smckusick if (argp = getnfsargs(spec, name, type)) 24139316Smckusick break; 24239316Smckusick return (1); 24338632Smckusick #endif /* NFS */ 24438632Smckusick 24539316Smckusick case MOUNT_MFS: 24639322Smckusick default: 24739322Smckusick argv[0] = mntname; 24839329Smckusick argc = 1; 24939322Smckusick if (flags) { 25039322Smckusick argv[argc++] = "-F"; 25139322Smckusick sprintf(flagval, "%d", flags); 25239322Smckusick argv[argc++] = flagval; 25339322Smckusick } 25439333Smckusick if (mntopts) 25539333Smckusick argc += getexecopts(mntopts, &argv[argc]); 25639329Smckusick if (options) 25739329Smckusick argc += getexecopts(options, &argv[argc]); 25839316Smckusick argv[argc++] = spec; 25939316Smckusick argv[argc++] = name; 26039521Smckusick argv[argc++] = NULL; 261*39603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 26239316Smckusick if (verbose) { 26339322Smckusick printf("exec: %s", execname); 26439322Smckusick for (i = 1; i < argc; i++) 26539316Smckusick printf(" %s", argv[i]); 26639316Smckusick printf("\n"); 26739316Smckusick } 26839316Smckusick if (fake) 26939316Smckusick break; 27039316Smckusick if (i = vfork()) { 27139316Smckusick if (i == -1) { 27239322Smckusick perror("mount: vfork starting file system"); 27339316Smckusick return (1); 27439131Smckusick } 27539316Smckusick if (waitpid(i, &status, 0) != -1 && 27639316Smckusick WIFEXITED(status) && 27739316Smckusick WEXITSTATUS(status) != 0) 27839316Smckusick return (WEXITSTATUS(status)); 27939322Smckusick spec = mntname; 28039316Smckusick goto out; 28139316Smckusick } 28239322Smckusick execve(execname, argv, envp); 283*39603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 284*39603Smckusick execname, name); 285*39603Smckusick perror(""); 28639316Smckusick exit (1); 28739316Smckusick /* NOTREACHED */ 28838632Smckusick 28939316Smckusick } 29039316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 29139316Smckusick if (opflags & ISBGRND) 29239316Smckusick exit(1); 29339316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 29439316Smckusick switch (errno) { 29539316Smckusick case EMFILE: 29639316Smckusick fprintf(stderr, "Mount table full\n"); 29739316Smckusick break; 29839316Smckusick case EINVAL: 29939333Smckusick if (flags & M_UPDATE) 30039333Smckusick fprintf(stderr, "Specified device does %s\n", 30139333Smckusick "not match mounted device"); 30239333Smckusick else 30339333Smckusick fprintf(stderr, "Bogus super block\n"); 30439316Smckusick break; 30539333Smckusick case EOPNOTSUPP: 30639333Smckusick fprintf(stderr, "Operation not supported\n"); 30739333Smckusick break; 30839316Smckusick default: 30939316Smckusick perror((char *)NULL); 31039316Smckusick break; 3114460Sroot } 31239316Smckusick return(1); 3134460Sroot } 31435339Sbostic 31539131Smckusick out: 31612808Ssam if (verbose) 31739316Smckusick prmount(spec, name, flags); 31835339Sbostic 31938445Smckusick if (opflags & ISBGRND) 32038445Smckusick exit(); 32138445Smckusick else 32238445Smckusick return(0); 3231057Sbill } 32435339Sbostic 32535339Sbostic static 32639316Smckusick prmount(spec, name, flags) 32739316Smckusick char *spec, *name; 32839316Smckusick long flags; 32935339Sbostic { 33038632Smckusick register char *root; 33138632Smckusick 33238445Smckusick if (opflags & ISBGRND) 33338445Smckusick return; 33438632Smckusick /* 33538632Smckusick * trim trailing /'s and find last component of name 33638632Smckusick */ 33738632Smckusick for (root = index(spec, '\0'); *--root == '/';) 33838632Smckusick /* void */; 33938632Smckusick *++root = '\0'; 34038632Smckusick if (root = rindex(spec, '/')) 34138632Smckusick spec = root + 1; 34238632Smckusick printf("%s on %s", spec, name); 34339316Smckusick if (flags & M_RDONLY) 34439316Smckusick printf(" (read-only)"); 34539316Smckusick if (flags & M_NOEXEC) 34639316Smckusick printf(" (noexec)"); 34739316Smckusick if (flags & M_NOSUID) 34839316Smckusick printf(" (nosuid)"); 34939316Smckusick if (flags & M_NODEV) 35039316Smckusick printf(" (nodev)"); 35139316Smckusick if (flags & M_SYNCHRONOUS) 35239316Smckusick printf(" (synchronous)"); 35339333Smckusick if (flags & M_UPDATE) 35439333Smckusick printf(" (update only)"); 35535339Sbostic printf("\n"); 35635339Sbostic } 35735339Sbostic 35839133Smckusick getmnttype(fstype) 35939133Smckusick char *fstype; 36039133Smckusick { 36139133Smckusick 36239322Smckusick mntname = fstype; 36339133Smckusick if (!strcmp(fstype, "ufs")) 36439133Smckusick return (MOUNT_UFS); 36539133Smckusick if (!strcmp(fstype, "nfs")) 36639133Smckusick return (MOUNT_NFS); 36739133Smckusick if (!strcmp(fstype, "mfs")) 36839133Smckusick return (MOUNT_MFS); 36939133Smckusick return (0); 37039133Smckusick } 37139133Smckusick 37238632Smckusick usage() 37335339Sbostic { 37439333Smckusick fprintf(stderr, "usage: mount [-afurw]\nor mount [-furw] special | node\nor mount [-furw] special node\n"); 37535339Sbostic exit(1); 37635339Sbostic } 37735339Sbostic 37839316Smckusick getstdopts(options, flagp) 37939316Smckusick char *options; 38039316Smckusick long *flagp; 38139316Smckusick { 38239316Smckusick register char *opt; 38339316Smckusick int negative; 38439316Smckusick char *optbuf[BUFSIZ], *strtok(); 38539316Smckusick 38639316Smckusick strcpy(optbuf, options); 38739316Smckusick for (opt = strtok(optbuf, ","); opt; opt = strtok(NULL, ",")) { 38839316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 38939316Smckusick negative++; 39039316Smckusick opt += 2; 39139316Smckusick } else { 39239316Smckusick negative = 0; 39339316Smckusick } 39439333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 39539333Smckusick *flagp |= M_RDONLY; 39639333Smckusick continue; 39739333Smckusick } 39839333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 39939333Smckusick *flagp &= ~M_RDONLY; 40039333Smckusick continue; 40139333Smckusick } 40239316Smckusick if (!strcasecmp(opt, "exec")) { 40339316Smckusick if (negative) 40439316Smckusick *flagp |= M_NOEXEC; 40539333Smckusick else 40639333Smckusick *flagp &= ~M_NOEXEC; 40739316Smckusick continue; 40839316Smckusick } 40939316Smckusick if (!strcasecmp(opt, "suid")) { 41039316Smckusick if (negative) 41139316Smckusick *flagp |= M_NOSUID; 41239333Smckusick else 41339333Smckusick *flagp &= ~M_NOSUID; 41439316Smckusick continue; 41539316Smckusick } 41639316Smckusick if (!strcasecmp(opt, "dev")) { 41739316Smckusick if (negative) 41839316Smckusick *flagp |= M_NODEV; 41939333Smckusick else 42039333Smckusick *flagp &= ~M_NODEV; 42139316Smckusick continue; 42239316Smckusick } 42339316Smckusick if (!strcasecmp(opt, "synchronous")) { 42439316Smckusick if (!negative) 42539316Smckusick *flagp |= M_SYNCHRONOUS; 42639333Smckusick else 42739333Smckusick *flagp &= ~M_SYNCHRONOUS; 42839316Smckusick continue; 42939316Smckusick } 43039316Smckusick } 43139316Smckusick } 43239316Smckusick 43339131Smckusick getufsopts(options, flagp) 43439131Smckusick char *options; 43539131Smckusick long *flagp; 43639131Smckusick { 43739131Smckusick 43839131Smckusick return; 43939131Smckusick } 44039131Smckusick 44139329Smckusick getexecopts(options, argv) 44239131Smckusick char *options; 44339131Smckusick char **argv; 44439131Smckusick { 44539131Smckusick register int argc = 0; 44639131Smckusick register char *opt; 44739131Smckusick char *strtok(); 44839131Smckusick 44939131Smckusick for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { 45039131Smckusick if (opt[0] != '-') 45139131Smckusick continue; 45239131Smckusick argv[argc++] = opt; 45339131Smckusick if (opt[2] == '\0' || opt[2] != '=') 45439131Smckusick continue; 45539131Smckusick opt[2] = '\0'; 45639131Smckusick argv[argc++] = &opt[3]; 45739131Smckusick } 45839131Smckusick return (argc); 45939131Smckusick } 46039131Smckusick 46139465Smckusick struct statfs * 46239465Smckusick getmntpt(name) 46339465Smckusick char *name; 46439465Smckusick { 46539465Smckusick long mntsize; 46639465Smckusick register long i; 46739465Smckusick struct statfs *mntbuf; 46839465Smckusick 46939465Smckusick mntsize = getmntinfo(&mntbuf); 47039465Smckusick for (i = 0; i < mntsize; i++) { 47139465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 47239465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 47339465Smckusick return (&mntbuf[i]); 47439465Smckusick } 47539465Smckusick return ((struct statfs *)0); 47639465Smckusick } 47739465Smckusick 47838632Smckusick #ifdef NFS 47939131Smckusick /* 48039131Smckusick * Handle the getoption arg. 48139131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 48239131Smckusick */ 48339131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 48439131Smckusick char *optarg; 48539131Smckusick struct nfs_args *nfsargsp; 48639131Smckusick int *opflagsp; 48739131Smckusick int *retrycntp; 48839131Smckusick { 48939131Smckusick register char *cp, *nextcp; 49039131Smckusick int num; 49139131Smckusick char *nump; 49239131Smckusick 49339131Smckusick cp = optarg; 49439131Smckusick while (cp != NULL && *cp != '\0') { 49539131Smckusick if ((nextcp = index(cp, ',')) != NULL) 49639131Smckusick *nextcp++ = '\0'; 49739131Smckusick if ((nump = index(cp, '=')) != NULL) { 49839131Smckusick *nump++ = '\0'; 49939131Smckusick num = atoi(nump); 50039131Smckusick } else 50139131Smckusick num = -1; 50239131Smckusick /* 50339131Smckusick * Just test for a string match and do it 50439131Smckusick */ 50539131Smckusick if (!strcmp(cp, "bg")) { 50639131Smckusick *opflagsp |= BGRND; 50739131Smckusick } else if (!strcmp(cp, "soft")) { 50839131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 50939131Smckusick } else if (!strcmp(cp, "intr")) { 51039131Smckusick nfsargsp->flags |= NFSMNT_INT; 51139131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 51239131Smckusick *retrycntp = num; 51339131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 51439131Smckusick nfsargsp->rsize = num; 51539131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 51639131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 51739131Smckusick nfsargsp->wsize = num; 51839131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 51939131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 52039131Smckusick nfsargsp->timeo = num; 52139131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 52239131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 52339131Smckusick nfsargsp->retrans = num; 52439131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 52539131Smckusick } 52639131Smckusick cp = nextcp; 52739131Smckusick } 52839131Smckusick } 52939131Smckusick 53038632Smckusick char * 53138632Smckusick getnfsargs(spec) 53238632Smckusick char *spec; 53335339Sbostic { 53438632Smckusick register CLIENT *clp; 53538632Smckusick struct hostent *hp; 53638632Smckusick struct sockaddr_in saddr; 53738632Smckusick struct timeval pertry, try; 53838632Smckusick enum clnt_stat clnt_stat; 53938632Smckusick int so = RPC_ANYSOCK; 54038632Smckusick char *hostp, *delimp; 54138632Smckusick u_short tport; 54238632Smckusick struct nfhret nfhret; 54338632Smckusick char nam[MNAMELEN + 1]; 54438632Smckusick 54538632Smckusick strncpy(nam, spec, MNAMELEN); 54638632Smckusick nam[MNAMELEN] = '\0'; 54738632Smckusick if ((delimp = index(spec, '@')) != NULL) { 54838632Smckusick hostp = delimp + 1; 54938632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 55038632Smckusick hostp = spec; 55138632Smckusick spec = delimp + 1; 55238632Smckusick } else { 55338632Smckusick fprintf(stderr, 55438632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 55538632Smckusick return (0); 55638632Smckusick } 55738632Smckusick *delimp = '\0'; 55838632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 55938632Smckusick fprintf(stderr, "Can't get net id for host\n"); 56038632Smckusick return (0); 56138632Smckusick } 56238632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 56338632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 56438632Smckusick while (retrycnt > 0) { 56538632Smckusick saddr.sin_family = AF_INET; 56638632Smckusick saddr.sin_port = htons(PMAPPORT); 56738632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 56838632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 56938632Smckusick if ((opflags & ISBGRND) == 0) 57038632Smckusick clnt_pcreateerror("NFS Portmap"); 57138632Smckusick } else { 57238632Smckusick saddr.sin_port = 0; 57338632Smckusick pertry.tv_sec = 10; 57438632Smckusick pertry.tv_usec = 0; 57538632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 57638632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 57738632Smckusick if ((opflags & ISBGRND) == 0) 57838632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 57938632Smckusick } else { 58038632Smckusick clp->cl_auth = authunix_create_default(); 58138632Smckusick try.tv_sec = 10; 58238632Smckusick try.tv_usec = 0; 58338632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 58438632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 58538632Smckusick if (clnt_stat != RPC_SUCCESS) { 58638632Smckusick if ((opflags & ISBGRND) == 0) 58738632Smckusick clnt_perror(clp, "Bad MNT RPC"); 58838632Smckusick } else { 58938632Smckusick auth_destroy(clp->cl_auth); 59038632Smckusick clnt_destroy(clp); 59138632Smckusick retrycnt = 0; 59238632Smckusick } 59338632Smckusick } 59438632Smckusick } 59538632Smckusick if (--retrycnt > 0) { 59638632Smckusick if (opflags & BGRND) { 59738632Smckusick opflags &= ~BGRND; 59838632Smckusick if (fork()) 59938632Smckusick return (0); 60038632Smckusick else 60138632Smckusick opflags |= ISBGRND; 60238632Smckusick } 60338632Smckusick sleep(10); 60438632Smckusick } 60538632Smckusick } 60638632Smckusick if (nfhret.stat) { 60738632Smckusick if (opflags & ISBGRND) 60838632Smckusick exit(1); 60939521Smckusick fprintf(stderr, "Can't access %s: ", spec); 61039521Smckusick errno = nfhret.stat; 61139521Smckusick perror(NULL); 61238632Smckusick return (0); 61338632Smckusick } 61438632Smckusick saddr.sin_port = htons(tport); 61538632Smckusick nfsargs.addr = &saddr; 61638632Smckusick nfsargs.fh = &nfhret.nfh; 61738632Smckusick nfsargs.hostname = nam; 61838632Smckusick return ((caddr_t)&nfsargs); 61935339Sbostic } 62038445Smckusick 62138445Smckusick /* 62238445Smckusick * xdr routines for mount rpc's 62338445Smckusick */ 62438445Smckusick xdr_dir(xdrsp, dirp) 62538445Smckusick XDR *xdrsp; 62638445Smckusick char *dirp; 62738445Smckusick { 62838445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 62938445Smckusick } 63038445Smckusick 63138445Smckusick xdr_fh(xdrsp, np) 63238445Smckusick XDR *xdrsp; 63338445Smckusick struct nfhret *np; 63438445Smckusick { 63538445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 63638445Smckusick return (0); 63738445Smckusick if (np->stat) 63838445Smckusick return (1); 63938445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 64038445Smckusick } 64138632Smckusick #endif /* NFS */ 642