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*40369Smckusick static char sccsid[] = "@(#)mount.c 5.28 (Berkeley) 03/08/90"; 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/mount.h> 3838445Smckusick #ifdef NFS 3938445Smckusick #include <sys/socket.h> 4038445Smckusick #include <sys/socketvar.h> 4138445Smckusick #include <netdb.h> 4238445Smckusick #include <rpc/rpc.h> 4338445Smckusick #include <rpc/pmap_clnt.h> 4438445Smckusick #include <rpc/pmap_prot.h> 4538445Smckusick #include <nfs/rpcv2.h> 4638445Smckusick #include <nfs/nfsv2.h> 4738445Smckusick #include <nfs/nfs.h> 4838445Smckusick #endif 491057Sbill 50*40369Smckusick #define DEFAULT_ROOTUID -2 51*40369Smckusick 5235339Sbostic #define BADTYPE(type) \ 5335339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 5435339Sbostic strcmp(type, FSTAB_RQ)) 5535339Sbostic #define SETTYPE(type) \ 5635339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 571057Sbill 5839333Smckusick int fake, verbose, updateflg, mnttype; 5939322Smckusick char *mntname, **envp; 6040051Smckusick char **vfslist, **makevfslist(); 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 }; 8040051Smckusick #define DEF_RETRY 10000 8140051Smckusick int retrycnt; 8238445Smckusick #define BGRND 1 8338445Smckusick #define ISBGRND 2 8438445Smckusick int opflags = 0; 8538445Smckusick #endif 8638445Smckusick 8739131Smckusick main(argc, argv, arge) 885073Sroot int argc; 895073Sroot char **argv; 9039131Smckusick char **arge; 911057Sbill { 9235339Sbostic extern char *optarg; 9335339Sbostic extern int optind; 9435339Sbostic register struct fstab *fs; 9535339Sbostic register int cnt; 9639333Smckusick int all, ch, rval, flags, i; 9738632Smckusick long mntsize; 9839465Smckusick struct statfs *mntbuf, *getmntpt(); 9939131Smckusick char *type, *options = NULL; 1001057Sbill 10139131Smckusick envp = arge; 10235339Sbostic all = 0; 10335339Sbostic type = NULL; 10438445Smckusick mnttype = MOUNT_UFS; 10539322Smckusick mntname = "ufs"; 10639333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 10735339Sbostic switch((char)ch) { 10835339Sbostic case 'a': 10935339Sbostic all = 1; 11035339Sbostic break; 11135339Sbostic case 'f': 11235339Sbostic fake = 1; 11335339Sbostic break; 11435339Sbostic case 'r': 11512808Ssam type = FSTAB_RO; 11635339Sbostic break; 11739333Smckusick case 'u': 11839333Smckusick updateflg = M_UPDATE; 11939333Smckusick break; 12035339Sbostic case 'v': 12135339Sbostic verbose = 1; 12235339Sbostic break; 12335339Sbostic case 'w': 12435339Sbostic type = FSTAB_RW; 12535339Sbostic break; 12639131Smckusick case 'o': 12739131Smckusick options = optarg; 12839131Smckusick break; 12938445Smckusick case 't': 13040051Smckusick vfslist = makevfslist(optarg); 13139322Smckusick mnttype = getmnttype(optarg); 13239322Smckusick break; 13335339Sbostic case '?': 13435339Sbostic default: 13535339Sbostic usage(); 13639131Smckusick /* NOTREACHED */ 1375073Sroot } 13835339Sbostic argc -= optind; 13935339Sbostic argv += optind; 14035339Sbostic 14135339Sbostic /* NOSTRICT */ 14235339Sbostic 1434460Sroot if (all) { 14435369Sbostic rval = 0; 14539333Smckusick while (fs = getfsent()) { 14635372Sbostic if (BADTYPE(fs->fs_type)) 14735372Sbostic continue; 14840051Smckusick if (badvfstype(fs->fs_vfstype, vfslist)) 14940051Smckusick continue; 15035372Sbostic /* `/' is special, it's always mounted */ 15135372Sbostic if (!strcmp(fs->fs_file, "/")) 15239333Smckusick flags = M_UPDATE; 15339333Smckusick else 15439333Smckusick flags = updateflg; 15539333Smckusick mnttype = getmnttype(fs->fs_vfstype); 15639333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 15739333Smckusick type, options, fs->fs_mntops); 15835372Sbostic } 15935341Sbostic exit(rval); 16035339Sbostic } 1615073Sroot 16235339Sbostic if (argc == 0) { 16335339Sbostic if (verbose || fake || type) 16435339Sbostic usage(); 16540337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 16639319Smckusick fprintf(stderr, 16739319Smckusick "mount: cannot get mount information\n"); 16838632Smckusick exit(1); 16938632Smckusick } 17039316Smckusick for (i = 0; i < mntsize; i++) 17138632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 17239316Smckusick mntbuf[i].f_flags); 1734460Sroot exit(0); 1741057Sbill } 17512808Ssam 17639465Smckusick if (argc == 1 && updateflg) { 17739465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 17839465Smckusick fprintf(stderr, 17939465Smckusick "mount: unknown special file or file system %s.\n", 18039465Smckusick *argv); 18139465Smckusick exit(1); 18239465Smckusick } 18339465Smckusick mnttype = mntbuf->f_type; 18440124Smckusick if (!strcmp(mntbuf->f_mntfromname, "root_device")) { 18540124Smckusick fs = getfsfile("/"); 18640124Smckusick strcpy(mntbuf->f_mntfromname, fs->fs_spec); 18740124Smckusick } 18839465Smckusick exit(mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 18939465Smckusick updateflg, type, options, NULL)); 19039465Smckusick } 19139465Smckusick 19235339Sbostic if (argc == 1) { 19335339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 19435339Sbostic fprintf(stderr, 19535339Sbostic "mount: unknown special file or file system %s.\n", 19635339Sbostic *argv); 19735339Sbostic exit(1); 19835339Sbostic } 19935339Sbostic if (BADTYPE(fs->fs_type)) { 20035339Sbostic fprintf(stderr, 20135339Sbostic "mount: %s has unknown file system type.\n", *argv); 20235339Sbostic exit(1); 20335339Sbostic } 20439333Smckusick mnttype = getmnttype(fs->fs_vfstype); 20539333Smckusick exit(mountfs(fs->fs_spec, fs->fs_file, updateflg, 20639333Smckusick type, options, fs->fs_mntops)); 20712808Ssam } 2081057Sbill 20935339Sbostic if (argc != 2) 21035339Sbostic usage(); 21112808Ssam 21239333Smckusick exit(mountfs(argv[0], argv[1], updateflg, type, options, NULL)); 21312808Ssam } 21412808Ssam 21539333Smckusick mountfs(spec, name, flags, type, options, mntopts) 21639131Smckusick char *spec, *name, *type, *options, *mntopts; 21739333Smckusick int flags; 21812808Ssam { 21935339Sbostic extern int errno; 22035339Sbostic register int cnt; 22139333Smckusick int argc, status, i; 22238070Smckusick struct ufs_args args; 22339131Smckusick char *argp, *argv[50]; 22439322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2251057Sbill 22639333Smckusick if (mntopts) 22739333Smckusick getstdopts(mntopts, &flags); 22839316Smckusick if (options) 22939316Smckusick getstdopts(options, &flags); 23039333Smckusick if (type) 23139333Smckusick getstdopts(type, &flags); 23239316Smckusick switch (mnttype) { 23339316Smckusick case MOUNT_UFS: 23439333Smckusick if (mntopts) 23539333Smckusick getufsopts(mntopts, &flags); 23639316Smckusick if (options) 23739316Smckusick getufsopts(options, &flags); 23839316Smckusick args.fspec = spec; 239*40369Smckusick args.exroot = DEFAULT_ROOTUID; 240*40369Smckusick args.exflags = getexportflags(name, flags); 24139316Smckusick argp = (caddr_t)&args; 24239316Smckusick break; 24338632Smckusick 24438632Smckusick #ifdef NFS 24539316Smckusick case MOUNT_NFS: 24640051Smckusick retrycnt = DEF_RETRY; 24739333Smckusick if (mntopts) 24839333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 24939316Smckusick if (options) 25039333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 25139316Smckusick if (argp = getnfsargs(spec, name, type)) 25239316Smckusick break; 25339316Smckusick return (1); 25438632Smckusick #endif /* NFS */ 25538632Smckusick 25639316Smckusick case MOUNT_MFS: 25739322Smckusick default: 25839322Smckusick argv[0] = mntname; 25939329Smckusick argc = 1; 26039322Smckusick if (flags) { 26139322Smckusick argv[argc++] = "-F"; 26239322Smckusick sprintf(flagval, "%d", flags); 26339322Smckusick argv[argc++] = flagval; 26439322Smckusick } 26539333Smckusick if (mntopts) 26639333Smckusick argc += getexecopts(mntopts, &argv[argc]); 26739329Smckusick if (options) 26839329Smckusick argc += getexecopts(options, &argv[argc]); 26939316Smckusick argv[argc++] = spec; 27039316Smckusick argv[argc++] = name; 27139521Smckusick argv[argc++] = NULL; 27239603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 27339316Smckusick if (verbose) { 27439322Smckusick printf("exec: %s", execname); 27539322Smckusick for (i = 1; i < argc; i++) 27639316Smckusick printf(" %s", argv[i]); 27739316Smckusick printf("\n"); 27839316Smckusick } 27939316Smckusick if (fake) 28039316Smckusick break; 28139316Smckusick if (i = vfork()) { 28239316Smckusick if (i == -1) { 28339322Smckusick perror("mount: vfork starting file system"); 28439316Smckusick return (1); 28539131Smckusick } 28639316Smckusick if (waitpid(i, &status, 0) != -1 && 28739316Smckusick WIFEXITED(status) && 28839316Smckusick WEXITSTATUS(status) != 0) 28939316Smckusick return (WEXITSTATUS(status)); 29039322Smckusick spec = mntname; 29139316Smckusick goto out; 29239316Smckusick } 29339322Smckusick execve(execname, argv, envp); 29439603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 29539603Smckusick execname, name); 29639603Smckusick perror(""); 29739316Smckusick exit (1); 29839316Smckusick /* NOTREACHED */ 29938632Smckusick 30039316Smckusick } 30139316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 30239316Smckusick if (opflags & ISBGRND) 30339316Smckusick exit(1); 30439316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 30539316Smckusick switch (errno) { 30639316Smckusick case EMFILE: 30739316Smckusick fprintf(stderr, "Mount table full\n"); 30839316Smckusick break; 30939316Smckusick case EINVAL: 31039333Smckusick if (flags & M_UPDATE) 31139333Smckusick fprintf(stderr, "Specified device does %s\n", 31239333Smckusick "not match mounted device"); 31339333Smckusick else 31439333Smckusick fprintf(stderr, "Bogus super block\n"); 31539316Smckusick break; 31639333Smckusick case EOPNOTSUPP: 31739333Smckusick fprintf(stderr, "Operation not supported\n"); 31839333Smckusick break; 31939316Smckusick default: 32039316Smckusick perror((char *)NULL); 32139316Smckusick break; 3224460Sroot } 32339316Smckusick return(1); 3244460Sroot } 32535339Sbostic 32639131Smckusick out: 32712808Ssam if (verbose) 32839316Smckusick prmount(spec, name, flags); 32935339Sbostic 33038445Smckusick if (opflags & ISBGRND) 33138445Smckusick exit(); 33238445Smckusick else 33338445Smckusick return(0); 3341057Sbill } 33535339Sbostic 33635339Sbostic static 33739316Smckusick prmount(spec, name, flags) 33839316Smckusick char *spec, *name; 33939316Smckusick long flags; 34035339Sbostic { 34138632Smckusick 34238445Smckusick if (opflags & ISBGRND) 34338445Smckusick return; 34438632Smckusick printf("%s on %s", spec, name); 34539316Smckusick if (flags & M_RDONLY) 34639316Smckusick printf(" (read-only)"); 34739316Smckusick if (flags & M_NOEXEC) 34839316Smckusick printf(" (noexec)"); 34939316Smckusick if (flags & M_NOSUID) 35039316Smckusick printf(" (nosuid)"); 35139316Smckusick if (flags & M_NODEV) 35239316Smckusick printf(" (nodev)"); 35339316Smckusick if (flags & M_SYNCHRONOUS) 35439316Smckusick printf(" (synchronous)"); 35539333Smckusick if (flags & M_UPDATE) 35639333Smckusick printf(" (update only)"); 35735339Sbostic printf("\n"); 35835339Sbostic } 35935339Sbostic 36039133Smckusick getmnttype(fstype) 36139133Smckusick char *fstype; 36239133Smckusick { 36339133Smckusick 36439322Smckusick mntname = fstype; 36539133Smckusick if (!strcmp(fstype, "ufs")) 36639133Smckusick return (MOUNT_UFS); 36739133Smckusick if (!strcmp(fstype, "nfs")) 36839133Smckusick return (MOUNT_NFS); 36939133Smckusick if (!strcmp(fstype, "mfs")) 37039133Smckusick return (MOUNT_MFS); 37139133Smckusick return (0); 37239133Smckusick } 37339133Smckusick 37438632Smckusick usage() 37535339Sbostic { 37639333Smckusick fprintf(stderr, "usage: mount [-afurw]\nor mount [-furw] special | node\nor mount [-furw] special node\n"); 37735339Sbostic exit(1); 37835339Sbostic } 37935339Sbostic 38039316Smckusick getstdopts(options, flagp) 38139316Smckusick char *options; 38239316Smckusick long *flagp; 38339316Smckusick { 38439316Smckusick register char *opt; 38539316Smckusick int negative; 38639316Smckusick char *optbuf[BUFSIZ], *strtok(); 38739316Smckusick 38839316Smckusick strcpy(optbuf, options); 38939316Smckusick for (opt = strtok(optbuf, ","); opt; opt = strtok(NULL, ",")) { 39039316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 39139316Smckusick negative++; 39239316Smckusick opt += 2; 39339316Smckusick } else { 39439316Smckusick negative = 0; 39539316Smckusick } 39639333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 39739333Smckusick *flagp |= M_RDONLY; 39839333Smckusick continue; 39939333Smckusick } 40039333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 40139333Smckusick *flagp &= ~M_RDONLY; 40239333Smckusick continue; 40339333Smckusick } 40439316Smckusick if (!strcasecmp(opt, "exec")) { 40539316Smckusick if (negative) 40639316Smckusick *flagp |= M_NOEXEC; 40739333Smckusick else 40839333Smckusick *flagp &= ~M_NOEXEC; 40939316Smckusick continue; 41039316Smckusick } 41139316Smckusick if (!strcasecmp(opt, "suid")) { 41239316Smckusick if (negative) 41339316Smckusick *flagp |= M_NOSUID; 41439333Smckusick else 41539333Smckusick *flagp &= ~M_NOSUID; 41639316Smckusick continue; 41739316Smckusick } 41839316Smckusick if (!strcasecmp(opt, "dev")) { 41939316Smckusick if (negative) 42039316Smckusick *flagp |= M_NODEV; 42139333Smckusick else 42239333Smckusick *flagp &= ~M_NODEV; 42339316Smckusick continue; 42439316Smckusick } 42539316Smckusick if (!strcasecmp(opt, "synchronous")) { 42639316Smckusick if (!negative) 42739316Smckusick *flagp |= M_SYNCHRONOUS; 42839333Smckusick else 42939333Smckusick *flagp &= ~M_SYNCHRONOUS; 43039316Smckusick continue; 43139316Smckusick } 43239316Smckusick } 43339316Smckusick } 43439316Smckusick 43539131Smckusick getufsopts(options, flagp) 43639131Smckusick char *options; 43739131Smckusick long *flagp; 43839131Smckusick { 43939131Smckusick 44039131Smckusick return; 44139131Smckusick } 44239131Smckusick 44339329Smckusick getexecopts(options, argv) 44439131Smckusick char *options; 44539131Smckusick char **argv; 44639131Smckusick { 44739131Smckusick register int argc = 0; 44839131Smckusick register char *opt; 44939131Smckusick char *strtok(); 45039131Smckusick 45139131Smckusick for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { 45239131Smckusick if (opt[0] != '-') 45339131Smckusick continue; 45439131Smckusick argv[argc++] = opt; 45539131Smckusick if (opt[2] == '\0' || opt[2] != '=') 45639131Smckusick continue; 45739131Smckusick opt[2] = '\0'; 45839131Smckusick argv[argc++] = &opt[3]; 45939131Smckusick } 46039131Smckusick return (argc); 46139131Smckusick } 46239131Smckusick 46339465Smckusick struct statfs * 46439465Smckusick getmntpt(name) 46539465Smckusick char *name; 46639465Smckusick { 46739465Smckusick long mntsize; 46839465Smckusick register long i; 46939465Smckusick struct statfs *mntbuf; 47039465Smckusick 47140337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 47239465Smckusick for (i = 0; i < mntsize; i++) { 47339465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 47439465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 47539465Smckusick return (&mntbuf[i]); 47639465Smckusick } 47739465Smckusick return ((struct statfs *)0); 47839465Smckusick } 47939465Smckusick 48040051Smckusick static int skipvfs; 48140051Smckusick 48240051Smckusick badvfstype(vfstype, vfslist) 48340051Smckusick char *vfstype; 48440051Smckusick char **vfslist; 48540051Smckusick { 48640051Smckusick 48740051Smckusick if (vfslist == 0) 48840051Smckusick return(0); 48940051Smckusick while (*vfslist) { 49040051Smckusick if (strcmp(vfstype, *vfslist) == 0) 49140051Smckusick return(skipvfs); 49240051Smckusick vfslist++; 49340051Smckusick } 49440051Smckusick return (!skipvfs); 49540051Smckusick } 49640051Smckusick 49740051Smckusick char ** 49840051Smckusick makevfslist(fslist) 49940051Smckusick char *fslist; 50040051Smckusick { 50140051Smckusick register char **av, *nextcp; 50240051Smckusick register int i; 50340051Smckusick char *malloc(); 50440051Smckusick 50540051Smckusick if (fslist == NULL) 50640051Smckusick return (NULL); 50740051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 50840051Smckusick fslist += 2; 50940051Smckusick skipvfs = 1; 51040051Smckusick } 51140051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 51240051Smckusick if (*nextcp == ',') 51340051Smckusick i++; 51440051Smckusick av = (char **)malloc((i+2) * sizeof(char *)); 51540051Smckusick if (av == NULL) 51640051Smckusick return (NULL); 51740051Smckusick nextcp = fslist; 51840051Smckusick i = 0; 51940051Smckusick av[i++] = nextcp; 52040051Smckusick while (nextcp = index(nextcp, ',')) { 52140051Smckusick *nextcp++ = '\0'; 52240051Smckusick av[i++] = nextcp; 52340051Smckusick } 52440051Smckusick av[i++] = 0; 52540051Smckusick return (av); 52640051Smckusick } 52740051Smckusick 528*40369Smckusick /* 529*40369Smckusick * Check to see if a UFS filesystem is being exported. 530*40369Smckusick */ 531*40369Smckusick getexportflags(name, mntflags) 532*40369Smckusick char *name; 533*40369Smckusick int mntflags; 534*40369Smckusick { 535*40369Smckusick FILE *fd; 536*40369Smckusick int flags = 0; 537*40369Smckusick char *cp, line[BUFSIZ]; 538*40369Smckusick 539*40369Smckusick if (mntflags & M_RDONLY) 540*40369Smckusick flags |= M_EXRDONLY; 541*40369Smckusick if ((fd = fopen(_PATH_EXPORTS, "r")) == NULL) 542*40369Smckusick return (flags); 543*40369Smckusick while (fgets(line, BUFSIZ, fd)) { 544*40369Smckusick cp = strtok(line, " \t\n"); 545*40369Smckusick if (strcmp(cp, name)) 546*40369Smckusick continue; 547*40369Smckusick flags |= M_EXPORTED; 548*40369Smckusick break; 549*40369Smckusick } 550*40369Smckusick fclose(fd); 551*40369Smckusick return (flags); 552*40369Smckusick } 553*40369Smckusick 55438632Smckusick #ifdef NFS 55539131Smckusick /* 55639131Smckusick * Handle the getoption arg. 55739131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 55839131Smckusick */ 55939131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 56039131Smckusick char *optarg; 56139131Smckusick struct nfs_args *nfsargsp; 56239131Smckusick int *opflagsp; 56339131Smckusick int *retrycntp; 56439131Smckusick { 56539131Smckusick register char *cp, *nextcp; 56639131Smckusick int num; 56739131Smckusick char *nump; 56839131Smckusick 56939131Smckusick cp = optarg; 57039131Smckusick while (cp != NULL && *cp != '\0') { 57139131Smckusick if ((nextcp = index(cp, ',')) != NULL) 57239131Smckusick *nextcp++ = '\0'; 57339131Smckusick if ((nump = index(cp, '=')) != NULL) { 57439131Smckusick *nump++ = '\0'; 57539131Smckusick num = atoi(nump); 57639131Smckusick } else 57739131Smckusick num = -1; 57839131Smckusick /* 57939131Smckusick * Just test for a string match and do it 58039131Smckusick */ 58139131Smckusick if (!strcmp(cp, "bg")) { 58239131Smckusick *opflagsp |= BGRND; 58339131Smckusick } else if (!strcmp(cp, "soft")) { 58439131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 58539131Smckusick } else if (!strcmp(cp, "intr")) { 58639131Smckusick nfsargsp->flags |= NFSMNT_INT; 58739131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 58839131Smckusick *retrycntp = num; 58939131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 59039131Smckusick nfsargsp->rsize = num; 59139131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 59239131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 59339131Smckusick nfsargsp->wsize = num; 59439131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 59539131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 59639131Smckusick nfsargsp->timeo = num; 59739131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 59839131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 59939131Smckusick nfsargsp->retrans = num; 60039131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 60139131Smckusick } 60239131Smckusick cp = nextcp; 60339131Smckusick } 60439131Smckusick } 60539131Smckusick 60638632Smckusick char * 60738632Smckusick getnfsargs(spec) 60838632Smckusick char *spec; 60935339Sbostic { 61040273Sbostic extern int errno; 61138632Smckusick register CLIENT *clp; 61238632Smckusick struct hostent *hp; 61339604Smckusick static struct sockaddr_in saddr; 61438632Smckusick struct timeval pertry, try; 61538632Smckusick enum clnt_stat clnt_stat; 61638632Smckusick int so = RPC_ANYSOCK; 61738632Smckusick char *hostp, *delimp; 61838632Smckusick u_short tport; 61939604Smckusick static struct nfhret nfhret; 62039604Smckusick static char nam[MNAMELEN + 1]; 62138632Smckusick 62238632Smckusick strncpy(nam, spec, MNAMELEN); 62338632Smckusick nam[MNAMELEN] = '\0'; 62438632Smckusick if ((delimp = index(spec, '@')) != NULL) { 62538632Smckusick hostp = delimp + 1; 62638632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 62738632Smckusick hostp = spec; 62838632Smckusick spec = delimp + 1; 62938632Smckusick } else { 63038632Smckusick fprintf(stderr, 63138632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 63238632Smckusick return (0); 63338632Smckusick } 63438632Smckusick *delimp = '\0'; 63538632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 63638632Smckusick fprintf(stderr, "Can't get net id for host\n"); 63738632Smckusick return (0); 63838632Smckusick } 63938632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 64038632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 64138632Smckusick while (retrycnt > 0) { 64238632Smckusick saddr.sin_family = AF_INET; 64338632Smckusick saddr.sin_port = htons(PMAPPORT); 64438632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 64538632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 64638632Smckusick if ((opflags & ISBGRND) == 0) 64738632Smckusick clnt_pcreateerror("NFS Portmap"); 64838632Smckusick } else { 64938632Smckusick saddr.sin_port = 0; 65038632Smckusick pertry.tv_sec = 10; 65138632Smckusick pertry.tv_usec = 0; 65238632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 65338632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 65438632Smckusick if ((opflags & ISBGRND) == 0) 65538632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 65638632Smckusick } else { 65738632Smckusick clp->cl_auth = authunix_create_default(); 65838632Smckusick try.tv_sec = 10; 65938632Smckusick try.tv_usec = 0; 66038632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 66138632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 66238632Smckusick if (clnt_stat != RPC_SUCCESS) { 66338632Smckusick if ((opflags & ISBGRND) == 0) 66438632Smckusick clnt_perror(clp, "Bad MNT RPC"); 66538632Smckusick } else { 66638632Smckusick auth_destroy(clp->cl_auth); 66738632Smckusick clnt_destroy(clp); 66838632Smckusick retrycnt = 0; 66938632Smckusick } 67038632Smckusick } 67138632Smckusick } 67238632Smckusick if (--retrycnt > 0) { 67338632Smckusick if (opflags & BGRND) { 67438632Smckusick opflags &= ~BGRND; 67538632Smckusick if (fork()) 67638632Smckusick return (0); 67738632Smckusick else 67838632Smckusick opflags |= ISBGRND; 67938632Smckusick } 68038632Smckusick sleep(10); 68138632Smckusick } 68238632Smckusick } 68338632Smckusick if (nfhret.stat) { 68438632Smckusick if (opflags & ISBGRND) 68538632Smckusick exit(1); 68639521Smckusick fprintf(stderr, "Can't access %s: ", spec); 68739521Smckusick errno = nfhret.stat; 68839521Smckusick perror(NULL); 68938632Smckusick return (0); 69038632Smckusick } 69138632Smckusick saddr.sin_port = htons(tport); 69238632Smckusick nfsargs.addr = &saddr; 69338632Smckusick nfsargs.fh = &nfhret.nfh; 69438632Smckusick nfsargs.hostname = nam; 69538632Smckusick return ((caddr_t)&nfsargs); 69635339Sbostic } 69738445Smckusick 69838445Smckusick /* 69938445Smckusick * xdr routines for mount rpc's 70038445Smckusick */ 70138445Smckusick xdr_dir(xdrsp, dirp) 70238445Smckusick XDR *xdrsp; 70338445Smckusick char *dirp; 70438445Smckusick { 70538445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 70638445Smckusick } 70738445Smckusick 70838445Smckusick xdr_fh(xdrsp, np) 70938445Smckusick XDR *xdrsp; 71038445Smckusick struct nfhret *np; 71138445Smckusick { 71238445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 71338445Smckusick return (0); 71438445Smckusick if (np->stat) 71538445Smckusick return (1); 71638445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 71738445Smckusick } 71838632Smckusick #endif /* NFS */ 719