121156Sdist /* 239322Smckusick * Copyright (c) 1980, 1989 The Regents of the University of California. 339322Smckusick * All rights reserved. 439322Smckusick * 542702Sbostic * %sccs.include.redist.c% 621156Sdist */ 721156Sdist 810811Ssam #ifndef lint 921156Sdist char copyright[] = 1039322Smckusick "@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\ 1121156Sdist All rights reserved.\n"; 1239322Smckusick #endif /* not lint */ 131057Sbill 1421156Sdist #ifndef lint 15*45524Sbostic static char sccsid[] = "@(#)mount.c 5.41 (Berkeley) 11/07/90"; 1639322Smckusick #endif /* not lint */ 1721156Sdist 1812808Ssam #include <sys/param.h> 1935339Sbostic #include <sys/file.h> 2038445Smckusick #include <sys/time.h> 2139133Smckusick #include <sys/wait.h> 22*45524Sbostic #include <sys/errno.h> 23*45524Sbostic #include <sys/signal.h> 2438445Smckusick #include <sys/mount.h> 2538445Smckusick #ifdef NFS 2638445Smckusick #include <sys/socket.h> 2738445Smckusick #include <sys/socketvar.h> 2838445Smckusick #include <netdb.h> 2938445Smckusick #include <rpc/rpc.h> 3038445Smckusick #include <rpc/pmap_clnt.h> 3138445Smckusick #include <rpc/pmap_prot.h> 3238445Smckusick #include <nfs/rpcv2.h> 3338445Smckusick #include <nfs/nfsv2.h> 3438445Smckusick #include <nfs/nfs.h> 3538445Smckusick #endif 36*45524Sbostic #include <fstab.h> 37*45524Sbostic #include <string.h> 38*45524Sbostic #include <stdio.h> 39*45524Sbostic #include <stdlib.h> 40*45524Sbostic #include "pathnames.h" 411057Sbill 4240369Smckusick #define DEFAULT_ROOTUID -2 4340369Smckusick 4435339Sbostic #define BADTYPE(type) \ 4535339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 4635339Sbostic strcmp(type, FSTAB_RQ)) 4735339Sbostic #define SETTYPE(type) \ 4835339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 491057Sbill 5039333Smckusick int fake, verbose, updateflg, mnttype; 5139322Smckusick char *mntname, **envp; 5240051Smckusick char **vfslist, **makevfslist(); 5339131Smckusick 5438445Smckusick #ifdef NFS 5538445Smckusick int xdr_dir(), xdr_fh(); 5638632Smckusick char *getnfsargs(); 5741911Smckusick struct nfs_args nfsdefargs = { 5841911Smckusick (struct sockaddr *)0, 5941911Smckusick SOCK_DGRAM, 6041911Smckusick 0, 6138445Smckusick (nfsv2fh_t *)0, 6238445Smckusick 0, 6338445Smckusick NFS_WSIZE, 6438445Smckusick NFS_RSIZE, 6538445Smckusick NFS_TIMEO, 6638445Smckusick NFS_RETRANS, 6738445Smckusick (char *)0, 6838445Smckusick }; 695073Sroot 7038445Smckusick struct nfhret { 7138445Smckusick u_long stat; 7238445Smckusick nfsv2fh_t nfh; 7338445Smckusick }; 7440051Smckusick #define DEF_RETRY 10000 7540051Smckusick int retrycnt; 7638445Smckusick #define BGRND 1 7738445Smckusick #define ISBGRND 2 7838445Smckusick int opflags = 0; 7938445Smckusick #endif 8038445Smckusick 8139131Smckusick main(argc, argv, arge) 825073Sroot int argc; 835073Sroot char **argv; 8439131Smckusick char **arge; 851057Sbill { 8635339Sbostic extern char *optarg; 8735339Sbostic extern int optind; 8835339Sbostic register struct fstab *fs; 8940496Smckusick int all, ch, rval, flags, ret, pid, i; 9038632Smckusick long mntsize; 9139465Smckusick struct statfs *mntbuf, *getmntpt(); 9239131Smckusick char *type, *options = NULL; 9340496Smckusick FILE *pidfile; 941057Sbill 9539131Smckusick envp = arge; 9635339Sbostic all = 0; 9735339Sbostic type = NULL; 9838445Smckusick mnttype = MOUNT_UFS; 9939322Smckusick mntname = "ufs"; 10039333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 10135339Sbostic switch((char)ch) { 10235339Sbostic case 'a': 10335339Sbostic all = 1; 10435339Sbostic break; 10535339Sbostic case 'f': 10635339Sbostic fake = 1; 10735339Sbostic break; 10835339Sbostic case 'r': 10912808Ssam type = FSTAB_RO; 11035339Sbostic break; 11139333Smckusick case 'u': 11241403Smckusick updateflg = MNT_UPDATE; 11339333Smckusick break; 11435339Sbostic case 'v': 11535339Sbostic verbose = 1; 11635339Sbostic break; 11735339Sbostic case 'w': 11835339Sbostic type = FSTAB_RW; 11935339Sbostic break; 12039131Smckusick case 'o': 12139131Smckusick options = optarg; 12239131Smckusick break; 12338445Smckusick case 't': 12440051Smckusick vfslist = makevfslist(optarg); 12539322Smckusick mnttype = getmnttype(optarg); 12639322Smckusick break; 12735339Sbostic case '?': 12835339Sbostic default: 12935339Sbostic usage(); 13039131Smckusick /* NOTREACHED */ 1315073Sroot } 13235339Sbostic argc -= optind; 13335339Sbostic argv += optind; 13435339Sbostic 13535339Sbostic /* NOSTRICT */ 13635339Sbostic 1374460Sroot if (all) { 13835369Sbostic rval = 0; 13939333Smckusick while (fs = getfsent()) { 14035372Sbostic if (BADTYPE(fs->fs_type)) 14135372Sbostic continue; 14240844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 14340051Smckusick continue; 14435372Sbostic /* `/' is special, it's always mounted */ 14535372Sbostic if (!strcmp(fs->fs_file, "/")) 14641403Smckusick flags = MNT_UPDATE; 14739333Smckusick else 14839333Smckusick flags = updateflg; 14939333Smckusick mnttype = getmnttype(fs->fs_vfstype); 15039333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 15139333Smckusick type, options, fs->fs_mntops); 15235372Sbostic } 15335341Sbostic exit(rval); 15435339Sbostic } 1555073Sroot 15635339Sbostic if (argc == 0) { 15735339Sbostic if (verbose || fake || type) 15835339Sbostic usage(); 15940337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 16039319Smckusick fprintf(stderr, 16139319Smckusick "mount: cannot get mount information\n"); 16238632Smckusick exit(1); 16338632Smckusick } 16440844Smckusick for (i = 0; i < mntsize; i++) { 16540844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 16640844Smckusick continue; 16738632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 16839316Smckusick mntbuf[i].f_flags); 16940844Smckusick } 1704460Sroot exit(0); 1711057Sbill } 17212808Ssam 17339465Smckusick if (argc == 1 && updateflg) { 17439465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 17539465Smckusick fprintf(stderr, 17639465Smckusick "mount: unknown special file or file system %s.\n", 17739465Smckusick *argv); 17839465Smckusick exit(1); 17939465Smckusick } 18039465Smckusick mnttype = mntbuf->f_type; 18140124Smckusick if (!strcmp(mntbuf->f_mntfromname, "root_device")) { 18240124Smckusick fs = getfsfile("/"); 18340124Smckusick strcpy(mntbuf->f_mntfromname, fs->fs_spec); 18440124Smckusick } 18540496Smckusick ret = mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 18642253Sbostic updateflg, type, options, (char *)NULL); 18740496Smckusick } else if (argc == 1) { 18835339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 18935339Sbostic fprintf(stderr, 19035339Sbostic "mount: unknown special file or file system %s.\n", 19135339Sbostic *argv); 19235339Sbostic exit(1); 19335339Sbostic } 19435339Sbostic if (BADTYPE(fs->fs_type)) { 19535339Sbostic fprintf(stderr, 19635339Sbostic "mount: %s has unknown file system type.\n", *argv); 19735339Sbostic exit(1); 19835339Sbostic } 19939333Smckusick mnttype = getmnttype(fs->fs_vfstype); 20040496Smckusick ret = mountfs(fs->fs_spec, fs->fs_file, updateflg, 20140496Smckusick type, options, fs->fs_mntops); 20240496Smckusick } else if (argc != 2) { 20340496Smckusick usage(); 20440496Smckusick ret = 1; 20540496Smckusick } else { 20642857Smckusick /* 20742857Smckusick * If -t flag has not been specified, and spec 20842857Smckusick * contains either a ':' or a '@' then assume that 20942857Smckusick * an NFS filesystem is being specified ala Sun. 21042857Smckusick */ 21142857Smckusick if (vfslist == (char **)0 && 21242857Smckusick (index(argv[0], ':') || index(argv[0], '@'))) 21342857Smckusick mnttype = MOUNT_NFS; 21442253Sbostic ret = mountfs(argv[0], argv[1], updateflg, type, options, 21542253Sbostic (char *)NULL); 21612808Ssam } 21740496Smckusick if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 21840496Smckusick pid = 0; 21940496Smckusick fscanf(pidfile, "%d", &pid); 22040496Smckusick fclose(pidfile); 22140496Smckusick if (pid > 0) 22240496Smckusick kill(pid, SIGHUP); 22340496Smckusick } 22440496Smckusick exit (ret); 22512808Ssam } 22612808Ssam 22739333Smckusick mountfs(spec, name, flags, type, options, mntopts) 22839131Smckusick char *spec, *name, *type, *options, *mntopts; 22939333Smckusick int flags; 23012808Ssam { 23142253Sbostic union wait status; 23242253Sbostic pid_t pid; 23342253Sbostic int argc, i; 23438070Smckusick struct ufs_args args; 23541911Smckusick struct nfs_args nfsargs; 23639131Smckusick char *argp, *argv[50]; 23739322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2381057Sbill 23941911Smckusick nfsargs = nfsdefargs; 24039333Smckusick if (mntopts) 24139333Smckusick getstdopts(mntopts, &flags); 24239316Smckusick if (options) 24339316Smckusick getstdopts(options, &flags); 24439333Smckusick if (type) 24539333Smckusick getstdopts(type, &flags); 24639316Smckusick switch (mnttype) { 24739316Smckusick case MOUNT_UFS: 24839333Smckusick if (mntopts) 24939333Smckusick getufsopts(mntopts, &flags); 25039316Smckusick if (options) 25139316Smckusick getufsopts(options, &flags); 25239316Smckusick args.fspec = spec; 25340369Smckusick args.exroot = DEFAULT_ROOTUID; 25441403Smckusick if (flags & MNT_RDONLY) 25541403Smckusick args.exflags = MNT_EXRDONLY; 25640496Smckusick else 25740496Smckusick args.exflags = 0; 25839316Smckusick argp = (caddr_t)&args; 25939316Smckusick break; 26038632Smckusick 26138632Smckusick #ifdef NFS 26239316Smckusick case MOUNT_NFS: 26340051Smckusick retrycnt = DEF_RETRY; 26439333Smckusick if (mntopts) 26539333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 26639316Smckusick if (options) 26739333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 26841911Smckusick if (argp = getnfsargs(spec, &nfsargs)) 26939316Smckusick break; 27039316Smckusick return (1); 27138632Smckusick #endif /* NFS */ 27238632Smckusick 27339316Smckusick case MOUNT_MFS: 27439322Smckusick default: 27539322Smckusick argv[0] = mntname; 27639329Smckusick argc = 1; 27739322Smckusick if (flags) { 27839322Smckusick argv[argc++] = "-F"; 27939322Smckusick sprintf(flagval, "%d", flags); 28039322Smckusick argv[argc++] = flagval; 28139322Smckusick } 28239333Smckusick if (mntopts) 28339333Smckusick argc += getexecopts(mntopts, &argv[argc]); 28439329Smckusick if (options) 28539329Smckusick argc += getexecopts(options, &argv[argc]); 28639316Smckusick argv[argc++] = spec; 28739316Smckusick argv[argc++] = name; 28839521Smckusick argv[argc++] = NULL; 28939603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 29039316Smckusick if (verbose) { 29142253Sbostic (void)printf("exec: %s", execname); 29242253Sbostic for (i = 1; i < argc - 1; i++) 29342253Sbostic (void)printf(" %s", argv[i]); 29442253Sbostic (void)printf("\n"); 29539316Smckusick } 29639316Smckusick if (fake) 29739316Smckusick break; 29842253Sbostic if (pid = vfork()) { 29942253Sbostic if (pid == -1) { 30039322Smckusick perror("mount: vfork starting file system"); 30139316Smckusick return (1); 30239131Smckusick } 30342253Sbostic if (waitpid(pid, &status, 0) != -1 && 30439316Smckusick WIFEXITED(status) && 30539316Smckusick WEXITSTATUS(status) != 0) 30639316Smckusick return (WEXITSTATUS(status)); 30739322Smckusick spec = mntname; 30839316Smckusick goto out; 30939316Smckusick } 31039322Smckusick execve(execname, argv, envp); 31139603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 31239603Smckusick execname, name); 31342253Sbostic perror((char *)NULL); 31439316Smckusick exit (1); 31539316Smckusick /* NOTREACHED */ 31638632Smckusick 31739316Smckusick } 31839316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 31939316Smckusick if (opflags & ISBGRND) 32039316Smckusick exit(1); 32139316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 32239316Smckusick switch (errno) { 32339316Smckusick case EMFILE: 32439316Smckusick fprintf(stderr, "Mount table full\n"); 32539316Smckusick break; 32639316Smckusick case EINVAL: 32741403Smckusick if (flags & MNT_UPDATE) 32839333Smckusick fprintf(stderr, "Specified device does %s\n", 32939333Smckusick "not match mounted device"); 33039333Smckusick else 33139333Smckusick fprintf(stderr, "Bogus super block\n"); 33239316Smckusick break; 33339333Smckusick case EOPNOTSUPP: 33439333Smckusick fprintf(stderr, "Operation not supported\n"); 33539333Smckusick break; 33639316Smckusick default: 33739316Smckusick perror((char *)NULL); 33839316Smckusick break; 3394460Sroot } 34039316Smckusick return(1); 3414460Sroot } 34235339Sbostic 34339131Smckusick out: 34412808Ssam if (verbose) 34539316Smckusick prmount(spec, name, flags); 34635339Sbostic 34738445Smckusick if (opflags & ISBGRND) 34842253Sbostic exit(1); 34942253Sbostic return(0); 3501057Sbill } 35135339Sbostic 35235339Sbostic static 35339316Smckusick prmount(spec, name, flags) 35439316Smckusick char *spec, *name; 35542253Sbostic register short flags; 35635339Sbostic { 35742253Sbostic register int first; 35838632Smckusick 35938445Smckusick if (opflags & ISBGRND) 36038445Smckusick return; 36142253Sbostic (void)printf("%s on %s", spec, name); 36242253Sbostic if (!(flags & MNT_VISFLAGMASK)) { 36342253Sbostic (void)printf("\n"); 36442253Sbostic return; 36542253Sbostic } 36642253Sbostic first = 0; 36742253Sbostic #define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg) 36841403Smckusick if (flags & MNT_RDONLY) 36942253Sbostic PR("read-only"); 37041403Smckusick if (flags & MNT_NOEXEC) 37142253Sbostic PR("noexec"); 37241403Smckusick if (flags & MNT_NOSUID) 37342253Sbostic PR("nosuid"); 37441403Smckusick if (flags & MNT_NODEV) 37542253Sbostic PR("nodev"); 37641403Smckusick if (flags & MNT_SYNCHRONOUS) 37742253Sbostic PR("synchronous"); 37841403Smckusick if (flags & MNT_QUOTA) 37942253Sbostic PR("with quotas"); 38041403Smckusick if (flags & MNT_LOCAL) 38142253Sbostic PR("local"); 38241403Smckusick if (flags & MNT_EXPORTED) 38341403Smckusick if (flags & MNT_EXRDONLY) 38442253Sbostic PR("NFS exported read-only"); 38541285Smckusick else 38642253Sbostic PR("NFS exported"); 38742253Sbostic (void)printf(")\n"); 38835339Sbostic } 38935339Sbostic 39039133Smckusick getmnttype(fstype) 39139133Smckusick char *fstype; 39239133Smckusick { 39339133Smckusick 39439322Smckusick mntname = fstype; 39539133Smckusick if (!strcmp(fstype, "ufs")) 39639133Smckusick return (MOUNT_UFS); 39739133Smckusick if (!strcmp(fstype, "nfs")) 39839133Smckusick return (MOUNT_NFS); 39939133Smckusick if (!strcmp(fstype, "mfs")) 40039133Smckusick return (MOUNT_MFS); 40139133Smckusick return (0); 40239133Smckusick } 40339133Smckusick 40438632Smckusick usage() 40535339Sbostic { 40640871Smckusick 40740871Smckusick fprintf(stderr, "usage:\n mount %s %s\n mount %s\n mount %s\n", 40840871Smckusick "[ -frwu ] [ -t nfs | ufs | external_type ]", 40940871Smckusick "[ -o options ] special node", 41040871Smckusick "[ -afrwu ] [ -t nfs | ufs | external_type ]", 41140871Smckusick "[ -frwu ] special | node"); 41235339Sbostic exit(1); 41335339Sbostic } 41435339Sbostic 41539316Smckusick getstdopts(options, flagp) 41639316Smckusick char *options; 41742253Sbostic int *flagp; 41839316Smckusick { 41939316Smckusick register char *opt; 42039316Smckusick int negative; 42142253Sbostic char optbuf[BUFSIZ]; 42239316Smckusick 42342253Sbostic (void)strcpy(optbuf, options); 42442253Sbostic for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) { 42539316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 42639316Smckusick negative++; 42739316Smckusick opt += 2; 42839316Smckusick } else { 42939316Smckusick negative = 0; 43039316Smckusick } 43139333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 43241403Smckusick *flagp |= MNT_RDONLY; 43339333Smckusick continue; 43439333Smckusick } 43539333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 43641403Smckusick *flagp &= ~MNT_RDONLY; 43739333Smckusick continue; 43839333Smckusick } 43939316Smckusick if (!strcasecmp(opt, "exec")) { 44039316Smckusick if (negative) 44141403Smckusick *flagp |= MNT_NOEXEC; 44239333Smckusick else 44341403Smckusick *flagp &= ~MNT_NOEXEC; 44439316Smckusick continue; 44539316Smckusick } 44639316Smckusick if (!strcasecmp(opt, "suid")) { 44739316Smckusick if (negative) 44841403Smckusick *flagp |= MNT_NOSUID; 44939333Smckusick else 45041403Smckusick *flagp &= ~MNT_NOSUID; 45139316Smckusick continue; 45239316Smckusick } 45339316Smckusick if (!strcasecmp(opt, "dev")) { 45439316Smckusick if (negative) 45541403Smckusick *flagp |= MNT_NODEV; 45639333Smckusick else 45741403Smckusick *flagp &= ~MNT_NODEV; 45839316Smckusick continue; 45939316Smckusick } 46039316Smckusick if (!strcasecmp(opt, "synchronous")) { 46139316Smckusick if (!negative) 46241403Smckusick *flagp |= MNT_SYNCHRONOUS; 46339333Smckusick else 46441403Smckusick *flagp &= ~MNT_SYNCHRONOUS; 46539316Smckusick continue; 46639316Smckusick } 46739316Smckusick } 46839316Smckusick } 46939316Smckusick 47042253Sbostic /* ARGSUSED */ 47139131Smckusick getufsopts(options, flagp) 47239131Smckusick char *options; 47342253Sbostic int *flagp; 47439131Smckusick { 47539131Smckusick return; 47639131Smckusick } 47739131Smckusick 47839329Smckusick getexecopts(options, argv) 47939131Smckusick char *options; 48039131Smckusick char **argv; 48139131Smckusick { 48239131Smckusick register int argc = 0; 48339131Smckusick register char *opt; 48439131Smckusick 48542253Sbostic for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) { 48639131Smckusick if (opt[0] != '-') 48739131Smckusick continue; 48839131Smckusick argv[argc++] = opt; 48939131Smckusick if (opt[2] == '\0' || opt[2] != '=') 49039131Smckusick continue; 49139131Smckusick opt[2] = '\0'; 49239131Smckusick argv[argc++] = &opt[3]; 49339131Smckusick } 49439131Smckusick return (argc); 49539131Smckusick } 49639131Smckusick 49739465Smckusick struct statfs * 49839465Smckusick getmntpt(name) 49939465Smckusick char *name; 50039465Smckusick { 50139465Smckusick long mntsize; 50239465Smckusick register long i; 50339465Smckusick struct statfs *mntbuf; 50439465Smckusick 50540337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 50639465Smckusick for (i = 0; i < mntsize; i++) { 50739465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 50839465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 50939465Smckusick return (&mntbuf[i]); 51039465Smckusick } 51139465Smckusick return ((struct statfs *)0); 51239465Smckusick } 51339465Smckusick 51440051Smckusick static int skipvfs; 51540051Smckusick 51640051Smckusick badvfstype(vfstype, vfslist) 51742253Sbostic short vfstype; 51840051Smckusick char **vfslist; 51940051Smckusick { 52040051Smckusick 52140051Smckusick if (vfslist == 0) 52240051Smckusick return(0); 52340051Smckusick while (*vfslist) { 52440844Smckusick if (vfstype == getmnttype(*vfslist)) 52540051Smckusick return(skipvfs); 52640051Smckusick vfslist++; 52740051Smckusick } 52840051Smckusick return (!skipvfs); 52940051Smckusick } 53040051Smckusick 53140844Smckusick badvfsname(vfsname, vfslist) 53240844Smckusick char *vfsname; 53340844Smckusick char **vfslist; 53440844Smckusick { 53540844Smckusick 53640844Smckusick if (vfslist == 0) 53740844Smckusick return(0); 53840844Smckusick while (*vfslist) { 53940844Smckusick if (strcmp(vfsname, *vfslist) == 0) 54040844Smckusick return(skipvfs); 54140844Smckusick vfslist++; 54240844Smckusick } 54340844Smckusick return (!skipvfs); 54440844Smckusick } 54540844Smckusick 54640051Smckusick char ** 54740051Smckusick makevfslist(fslist) 54840051Smckusick char *fslist; 54940051Smckusick { 55040051Smckusick register char **av, *nextcp; 55140051Smckusick register int i; 55240051Smckusick 55340051Smckusick if (fslist == NULL) 55440051Smckusick return (NULL); 55540051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 55640051Smckusick fslist += 2; 55740051Smckusick skipvfs = 1; 55840051Smckusick } 55940051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 56040051Smckusick if (*nextcp == ',') 56140051Smckusick i++; 56242253Sbostic av = (char **)malloc((size_t)(i+2) * sizeof(char *)); 56340051Smckusick if (av == NULL) 56440051Smckusick return (NULL); 56540051Smckusick nextcp = fslist; 56640051Smckusick i = 0; 56740051Smckusick av[i++] = nextcp; 56840051Smckusick while (nextcp = index(nextcp, ',')) { 56940051Smckusick *nextcp++ = '\0'; 57040051Smckusick av[i++] = nextcp; 57140051Smckusick } 57240051Smckusick av[i++] = 0; 57340051Smckusick return (av); 57440051Smckusick } 57540051Smckusick 57638632Smckusick #ifdef NFS 57739131Smckusick /* 57839131Smckusick * Handle the getoption arg. 57939131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 58039131Smckusick */ 58139131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 58239131Smckusick char *optarg; 58339131Smckusick struct nfs_args *nfsargsp; 58439131Smckusick int *opflagsp; 58539131Smckusick int *retrycntp; 58639131Smckusick { 58739131Smckusick register char *cp, *nextcp; 58839131Smckusick int num; 58939131Smckusick char *nump; 59039131Smckusick 59139131Smckusick cp = optarg; 59239131Smckusick while (cp != NULL && *cp != '\0') { 59339131Smckusick if ((nextcp = index(cp, ',')) != NULL) 59439131Smckusick *nextcp++ = '\0'; 59539131Smckusick if ((nump = index(cp, '=')) != NULL) { 59639131Smckusick *nump++ = '\0'; 59739131Smckusick num = atoi(nump); 59839131Smckusick } else 59939131Smckusick num = -1; 60039131Smckusick /* 60139131Smckusick * Just test for a string match and do it 60239131Smckusick */ 60339131Smckusick if (!strcmp(cp, "bg")) { 60439131Smckusick *opflagsp |= BGRND; 60539131Smckusick } else if (!strcmp(cp, "soft")) { 60643416Smckusick if (nfsargsp->flags & NFSMNT_SPONGY) { 60743416Smckusick fprintf(stderr, 60843416Smckusick "Options soft, spongy mutually exclusive\n"); 60943416Smckusick exit(1); 61043416Smckusick } 61139131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 61243416Smckusick } else if (!strcmp(cp, "spongy")) { 61343416Smckusick if (nfsargsp->flags & NFSMNT_SOFT) { 61443416Smckusick fprintf(stderr, 61543416Smckusick "Options soft, spongy mutually exclusive\n"); 61643416Smckusick exit(1); 61743416Smckusick } 61843416Smckusick nfsargsp->flags |= NFSMNT_SPONGY; 61945284Smckusick } else if (!strcmp(cp, "compress")) { 62045284Smckusick nfsargsp->flags |= NFSMNT_COMPRESS; 62139131Smckusick } else if (!strcmp(cp, "intr")) { 62239131Smckusick nfsargsp->flags |= NFSMNT_INT; 62341911Smckusick } else if (!strcmp(cp, "tcp")) { 62441911Smckusick nfsargsp->sotype = SOCK_STREAM; 62541911Smckusick } else if (!strcmp(cp, "noconn")) { 62641911Smckusick nfsargsp->flags |= NFSMNT_NOCONN; 62739131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 62839131Smckusick *retrycntp = num; 62939131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 63039131Smckusick nfsargsp->rsize = num; 63139131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 63239131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 63339131Smckusick nfsargsp->wsize = num; 63439131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 63539131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 63639131Smckusick nfsargsp->timeo = num; 63739131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 63839131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 63939131Smckusick nfsargsp->retrans = num; 64039131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 64139131Smckusick } 64239131Smckusick cp = nextcp; 64339131Smckusick } 64443416Smckusick if (nfsargsp->sotype == SOCK_DGRAM) { 64543416Smckusick if (nfsargsp->rsize > NFS_MAXDGRAMDATA) 64643416Smckusick nfsargsp->rsize = NFS_MAXDGRAMDATA; 64743416Smckusick if (nfsargsp->wsize > NFS_MAXDGRAMDATA) 64843416Smckusick nfsargsp->wsize = NFS_MAXDGRAMDATA; 64943416Smckusick } 65039131Smckusick } 65139131Smckusick 65238632Smckusick char * 65341911Smckusick getnfsargs(spec, nfsargsp) 65438632Smckusick char *spec; 65541911Smckusick struct nfs_args *nfsargsp; 65635339Sbostic { 65738632Smckusick register CLIENT *clp; 65838632Smckusick struct hostent *hp; 65939604Smckusick static struct sockaddr_in saddr; 66038632Smckusick struct timeval pertry, try; 66138632Smckusick enum clnt_stat clnt_stat; 66238632Smckusick int so = RPC_ANYSOCK; 66338632Smckusick char *hostp, *delimp; 66438632Smckusick u_short tport; 66539604Smckusick static struct nfhret nfhret; 66639604Smckusick static char nam[MNAMELEN + 1]; 66738632Smckusick 66838632Smckusick strncpy(nam, spec, MNAMELEN); 66938632Smckusick nam[MNAMELEN] = '\0'; 67038632Smckusick if ((delimp = index(spec, '@')) != NULL) { 67138632Smckusick hostp = delimp + 1; 67238632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 67338632Smckusick hostp = spec; 67438632Smckusick spec = delimp + 1; 67538632Smckusick } else { 67638632Smckusick fprintf(stderr, 67738632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 67838632Smckusick return (0); 67938632Smckusick } 68038632Smckusick *delimp = '\0'; 68138632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 68238632Smckusick fprintf(stderr, "Can't get net id for host\n"); 68338632Smckusick return (0); 68438632Smckusick } 68538632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 68638632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 68738632Smckusick while (retrycnt > 0) { 68838632Smckusick saddr.sin_family = AF_INET; 68938632Smckusick saddr.sin_port = htons(PMAPPORT); 69038632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 69138632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 69238632Smckusick if ((opflags & ISBGRND) == 0) 69338632Smckusick clnt_pcreateerror("NFS Portmap"); 69438632Smckusick } else { 69538632Smckusick saddr.sin_port = 0; 69638632Smckusick pertry.tv_sec = 10; 69738632Smckusick pertry.tv_usec = 0; 69838632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 69938632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 70038632Smckusick if ((opflags & ISBGRND) == 0) 70138632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 70238632Smckusick } else { 70338632Smckusick clp->cl_auth = authunix_create_default(); 70438632Smckusick try.tv_sec = 10; 70538632Smckusick try.tv_usec = 0; 70638632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 70738632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 70838632Smckusick if (clnt_stat != RPC_SUCCESS) { 70938632Smckusick if ((opflags & ISBGRND) == 0) 71038632Smckusick clnt_perror(clp, "Bad MNT RPC"); 71138632Smckusick } else { 71238632Smckusick auth_destroy(clp->cl_auth); 71338632Smckusick clnt_destroy(clp); 71438632Smckusick retrycnt = 0; 71538632Smckusick } 71638632Smckusick } 71738632Smckusick } 71838632Smckusick if (--retrycnt > 0) { 71938632Smckusick if (opflags & BGRND) { 72038632Smckusick opflags &= ~BGRND; 72138632Smckusick if (fork()) 72238632Smckusick return (0); 72338632Smckusick else 72438632Smckusick opflags |= ISBGRND; 72538632Smckusick } 72638632Smckusick sleep(10); 72738632Smckusick } 72838632Smckusick } 72938632Smckusick if (nfhret.stat) { 73038632Smckusick if (opflags & ISBGRND) 73138632Smckusick exit(1); 73239521Smckusick fprintf(stderr, "Can't access %s: ", spec); 73339521Smckusick errno = nfhret.stat; 73442253Sbostic perror((char *)NULL); 73538632Smckusick return (0); 73638632Smckusick } 73738632Smckusick saddr.sin_port = htons(tport); 73841911Smckusick nfsargsp->addr = (struct sockaddr *) &saddr; 73941911Smckusick nfsargsp->fh = &nfhret.nfh; 74041911Smckusick nfsargsp->hostname = nam; 74141911Smckusick return ((caddr_t)nfsargsp); 74235339Sbostic } 74338445Smckusick 74438445Smckusick /* 74538445Smckusick * xdr routines for mount rpc's 74638445Smckusick */ 74738445Smckusick xdr_dir(xdrsp, dirp) 74838445Smckusick XDR *xdrsp; 74938445Smckusick char *dirp; 75038445Smckusick { 75138445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 75238445Smckusick } 75338445Smckusick 75438445Smckusick xdr_fh(xdrsp, np) 75538445Smckusick XDR *xdrsp; 75638445Smckusick struct nfhret *np; 75738445Smckusick { 75838445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 75938445Smckusick return (0); 76038445Smckusick if (np->stat) 76138445Smckusick return (1); 76238445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 76338445Smckusick } 76438632Smckusick #endif /* NFS */ 765