121156Sdist /* 239322Smckusick * Copyright (c) 1980, 1989 The Regents of the University of California. 339322Smckusick * All rights reserved. 439322Smckusick * 5*42702Sbostic * %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*42702Sbostic static char sccsid[] = "@(#)mount.c 5.37 (Berkeley) 06/01/90"; 1639322Smckusick #endif /* not lint */ 1721156Sdist 1839131Smckusick #include "pathnames.h" 1912808Ssam #include <sys/param.h> 2035339Sbostic #include <sys/file.h> 2138445Smckusick #include <sys/time.h> 2239133Smckusick #include <sys/wait.h> 2310811Ssam #include <fstab.h> 2416669Ssam #include <errno.h> 2535339Sbostic #include <stdio.h> 2640496Smckusick #include <signal.h> 2742040Sbostic #include <string.h> 2838445Smckusick #include <sys/mount.h> 2938445Smckusick #ifdef NFS 3038445Smckusick #include <sys/socket.h> 3138445Smckusick #include <sys/socketvar.h> 3238445Smckusick #include <netdb.h> 3338445Smckusick #include <rpc/rpc.h> 3438445Smckusick #include <rpc/pmap_clnt.h> 3538445Smckusick #include <rpc/pmap_prot.h> 3638445Smckusick #include <nfs/rpcv2.h> 3738445Smckusick #include <nfs/nfsv2.h> 3838445Smckusick #include <nfs/nfs.h> 3938445Smckusick #endif 401057Sbill 4140369Smckusick #define DEFAULT_ROOTUID -2 4240369Smckusick 4335339Sbostic #define BADTYPE(type) \ 4435339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 4535339Sbostic strcmp(type, FSTAB_RQ)) 4635339Sbostic #define SETTYPE(type) \ 4735339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 481057Sbill 4939333Smckusick int fake, verbose, updateflg, mnttype; 5039322Smckusick char *mntname, **envp; 5140051Smckusick char **vfslist, **makevfslist(); 5239131Smckusick 5338445Smckusick #ifdef NFS 5438445Smckusick int xdr_dir(), xdr_fh(); 5538632Smckusick char *getnfsargs(); 5641911Smckusick struct nfs_args nfsdefargs = { 5741911Smckusick (struct sockaddr *)0, 5841911Smckusick SOCK_DGRAM, 5941911Smckusick 0, 6038445Smckusick (nfsv2fh_t *)0, 6138445Smckusick 0, 6238445Smckusick NFS_WSIZE, 6338445Smckusick NFS_RSIZE, 6438445Smckusick NFS_TIMEO, 6538445Smckusick NFS_RETRANS, 6638445Smckusick (char *)0, 6738445Smckusick }; 685073Sroot 6938445Smckusick struct nfhret { 7038445Smckusick u_long stat; 7138445Smckusick nfsv2fh_t nfh; 7238445Smckusick }; 7340051Smckusick #define DEF_RETRY 10000 7440051Smckusick int retrycnt; 7538445Smckusick #define BGRND 1 7638445Smckusick #define ISBGRND 2 7738445Smckusick int opflags = 0; 7838445Smckusick #endif 7938445Smckusick 8039131Smckusick main(argc, argv, arge) 815073Sroot int argc; 825073Sroot char **argv; 8339131Smckusick char **arge; 841057Sbill { 8535339Sbostic extern char *optarg; 8635339Sbostic extern int optind; 8735339Sbostic register struct fstab *fs; 8840496Smckusick int all, ch, rval, flags, ret, pid, i; 8938632Smckusick long mntsize; 9039465Smckusick struct statfs *mntbuf, *getmntpt(); 9139131Smckusick char *type, *options = NULL; 9240496Smckusick FILE *pidfile; 931057Sbill 9439131Smckusick envp = arge; 9535339Sbostic all = 0; 9635339Sbostic type = NULL; 9738445Smckusick mnttype = MOUNT_UFS; 9839322Smckusick mntname = "ufs"; 9939333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 10035339Sbostic switch((char)ch) { 10135339Sbostic case 'a': 10235339Sbostic all = 1; 10335339Sbostic break; 10435339Sbostic case 'f': 10535339Sbostic fake = 1; 10635339Sbostic break; 10735339Sbostic case 'r': 10812808Ssam type = FSTAB_RO; 10935339Sbostic break; 11039333Smckusick case 'u': 11141403Smckusick updateflg = MNT_UPDATE; 11239333Smckusick break; 11335339Sbostic case 'v': 11435339Sbostic verbose = 1; 11535339Sbostic break; 11635339Sbostic case 'w': 11735339Sbostic type = FSTAB_RW; 11835339Sbostic break; 11939131Smckusick case 'o': 12039131Smckusick options = optarg; 12139131Smckusick break; 12238445Smckusick case 't': 12340051Smckusick vfslist = makevfslist(optarg); 12439322Smckusick mnttype = getmnttype(optarg); 12539322Smckusick break; 12635339Sbostic case '?': 12735339Sbostic default: 12835339Sbostic usage(); 12939131Smckusick /* NOTREACHED */ 1305073Sroot } 13135339Sbostic argc -= optind; 13235339Sbostic argv += optind; 13335339Sbostic 13435339Sbostic /* NOSTRICT */ 13535339Sbostic 1364460Sroot if (all) { 13735369Sbostic rval = 0; 13839333Smckusick while (fs = getfsent()) { 13935372Sbostic if (BADTYPE(fs->fs_type)) 14035372Sbostic continue; 14140844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 14240051Smckusick continue; 14335372Sbostic /* `/' is special, it's always mounted */ 14435372Sbostic if (!strcmp(fs->fs_file, "/")) 14541403Smckusick flags = MNT_UPDATE; 14639333Smckusick else 14739333Smckusick flags = updateflg; 14839333Smckusick mnttype = getmnttype(fs->fs_vfstype); 14939333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 15039333Smckusick type, options, fs->fs_mntops); 15135372Sbostic } 15235341Sbostic exit(rval); 15335339Sbostic } 1545073Sroot 15535339Sbostic if (argc == 0) { 15635339Sbostic if (verbose || fake || type) 15735339Sbostic usage(); 15840337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 15939319Smckusick fprintf(stderr, 16039319Smckusick "mount: cannot get mount information\n"); 16138632Smckusick exit(1); 16238632Smckusick } 16340844Smckusick for (i = 0; i < mntsize; i++) { 16440844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 16540844Smckusick continue; 16638632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 16739316Smckusick mntbuf[i].f_flags); 16840844Smckusick } 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; 18040124Smckusick if (!strcmp(mntbuf->f_mntfromname, "root_device")) { 18140124Smckusick fs = getfsfile("/"); 18240124Smckusick strcpy(mntbuf->f_mntfromname, fs->fs_spec); 18340124Smckusick } 18440496Smckusick ret = mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 18542253Sbostic updateflg, type, options, (char *)NULL); 18640496Smckusick } else if (argc == 1) { 18735339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 18835339Sbostic fprintf(stderr, 18935339Sbostic "mount: unknown special file or file system %s.\n", 19035339Sbostic *argv); 19135339Sbostic exit(1); 19235339Sbostic } 19335339Sbostic if (BADTYPE(fs->fs_type)) { 19435339Sbostic fprintf(stderr, 19535339Sbostic "mount: %s has unknown file system type.\n", *argv); 19635339Sbostic exit(1); 19735339Sbostic } 19839333Smckusick mnttype = getmnttype(fs->fs_vfstype); 19940496Smckusick ret = mountfs(fs->fs_spec, fs->fs_file, updateflg, 20040496Smckusick type, options, fs->fs_mntops); 20140496Smckusick } else if (argc != 2) { 20240496Smckusick usage(); 20340496Smckusick ret = 1; 20440496Smckusick } else { 20542253Sbostic ret = mountfs(argv[0], argv[1], updateflg, type, options, 20642253Sbostic (char *)NULL); 20712808Ssam } 20840496Smckusick if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 20940496Smckusick pid = 0; 21040496Smckusick fscanf(pidfile, "%d", &pid); 21140496Smckusick fclose(pidfile); 21240496Smckusick if (pid > 0) 21340496Smckusick kill(pid, SIGHUP); 21440496Smckusick } 21540496Smckusick exit (ret); 21612808Ssam } 21712808Ssam 21839333Smckusick mountfs(spec, name, flags, type, options, mntopts) 21939131Smckusick char *spec, *name, *type, *options, *mntopts; 22039333Smckusick int flags; 22112808Ssam { 22235339Sbostic extern int errno; 22342253Sbostic union wait status; 22442253Sbostic pid_t pid; 22542253Sbostic int argc, i; 22638070Smckusick struct ufs_args args; 22741911Smckusick struct nfs_args nfsargs; 22839131Smckusick char *argp, *argv[50]; 22939322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2301057Sbill 23141911Smckusick nfsargs = nfsdefargs; 23239333Smckusick if (mntopts) 23339333Smckusick getstdopts(mntopts, &flags); 23439316Smckusick if (options) 23539316Smckusick getstdopts(options, &flags); 23639333Smckusick if (type) 23739333Smckusick getstdopts(type, &flags); 23839316Smckusick switch (mnttype) { 23939316Smckusick case MOUNT_UFS: 24039333Smckusick if (mntopts) 24139333Smckusick getufsopts(mntopts, &flags); 24239316Smckusick if (options) 24339316Smckusick getufsopts(options, &flags); 24439316Smckusick args.fspec = spec; 24540369Smckusick args.exroot = DEFAULT_ROOTUID; 24641403Smckusick if (flags & MNT_RDONLY) 24741403Smckusick args.exflags = MNT_EXRDONLY; 24840496Smckusick else 24940496Smckusick args.exflags = 0; 25039316Smckusick argp = (caddr_t)&args; 25139316Smckusick break; 25238632Smckusick 25338632Smckusick #ifdef NFS 25439316Smckusick case MOUNT_NFS: 25540051Smckusick retrycnt = DEF_RETRY; 25639333Smckusick if (mntopts) 25739333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 25839316Smckusick if (options) 25939333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 26041911Smckusick if (argp = getnfsargs(spec, &nfsargs)) 26139316Smckusick break; 26239316Smckusick return (1); 26338632Smckusick #endif /* NFS */ 26438632Smckusick 26539316Smckusick case MOUNT_MFS: 26639322Smckusick default: 26739322Smckusick argv[0] = mntname; 26839329Smckusick argc = 1; 26939322Smckusick if (flags) { 27039322Smckusick argv[argc++] = "-F"; 27139322Smckusick sprintf(flagval, "%d", flags); 27239322Smckusick argv[argc++] = flagval; 27339322Smckusick } 27439333Smckusick if (mntopts) 27539333Smckusick argc += getexecopts(mntopts, &argv[argc]); 27639329Smckusick if (options) 27739329Smckusick argc += getexecopts(options, &argv[argc]); 27839316Smckusick argv[argc++] = spec; 27939316Smckusick argv[argc++] = name; 28039521Smckusick argv[argc++] = NULL; 28139603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 28239316Smckusick if (verbose) { 28342253Sbostic (void)printf("exec: %s", execname); 28442253Sbostic for (i = 1; i < argc - 1; i++) 28542253Sbostic (void)printf(" %s", argv[i]); 28642253Sbostic (void)printf("\n"); 28739316Smckusick } 28839316Smckusick if (fake) 28939316Smckusick break; 29042253Sbostic if (pid = vfork()) { 29142253Sbostic if (pid == -1) { 29239322Smckusick perror("mount: vfork starting file system"); 29339316Smckusick return (1); 29439131Smckusick } 29542253Sbostic if (waitpid(pid, &status, 0) != -1 && 29639316Smckusick WIFEXITED(status) && 29739316Smckusick WEXITSTATUS(status) != 0) 29839316Smckusick return (WEXITSTATUS(status)); 29939322Smckusick spec = mntname; 30039316Smckusick goto out; 30139316Smckusick } 30239322Smckusick execve(execname, argv, envp); 30339603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 30439603Smckusick execname, name); 30542253Sbostic perror((char *)NULL); 30639316Smckusick exit (1); 30739316Smckusick /* NOTREACHED */ 30838632Smckusick 30939316Smckusick } 31039316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 31139316Smckusick if (opflags & ISBGRND) 31239316Smckusick exit(1); 31339316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 31439316Smckusick switch (errno) { 31539316Smckusick case EMFILE: 31639316Smckusick fprintf(stderr, "Mount table full\n"); 31739316Smckusick break; 31839316Smckusick case EINVAL: 31941403Smckusick if (flags & MNT_UPDATE) 32039333Smckusick fprintf(stderr, "Specified device does %s\n", 32139333Smckusick "not match mounted device"); 32239333Smckusick else 32339333Smckusick fprintf(stderr, "Bogus super block\n"); 32439316Smckusick break; 32539333Smckusick case EOPNOTSUPP: 32639333Smckusick fprintf(stderr, "Operation not supported\n"); 32739333Smckusick break; 32839316Smckusick default: 32939316Smckusick perror((char *)NULL); 33039316Smckusick break; 3314460Sroot } 33239316Smckusick return(1); 3334460Sroot } 33435339Sbostic 33539131Smckusick out: 33612808Ssam if (verbose) 33739316Smckusick prmount(spec, name, flags); 33835339Sbostic 33938445Smckusick if (opflags & ISBGRND) 34042253Sbostic exit(1); 34142253Sbostic return(0); 3421057Sbill } 34335339Sbostic 34435339Sbostic static 34539316Smckusick prmount(spec, name, flags) 34639316Smckusick char *spec, *name; 34742253Sbostic register short flags; 34835339Sbostic { 34942253Sbostic register int first; 35038632Smckusick 35138445Smckusick if (opflags & ISBGRND) 35238445Smckusick return; 35342253Sbostic (void)printf("%s on %s", spec, name); 35442253Sbostic if (!(flags & MNT_VISFLAGMASK)) { 35542253Sbostic (void)printf("\n"); 35642253Sbostic return; 35742253Sbostic } 35842253Sbostic first = 0; 35942253Sbostic #define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg) 36041403Smckusick if (flags & MNT_RDONLY) 36142253Sbostic PR("read-only"); 36241403Smckusick if (flags & MNT_NOEXEC) 36342253Sbostic PR("noexec"); 36441403Smckusick if (flags & MNT_NOSUID) 36542253Sbostic PR("nosuid"); 36641403Smckusick if (flags & MNT_NODEV) 36742253Sbostic PR("nodev"); 36841403Smckusick if (flags & MNT_SYNCHRONOUS) 36942253Sbostic PR("synchronous"); 37041403Smckusick if (flags & MNT_QUOTA) 37142253Sbostic PR("with quotas"); 37241403Smckusick if (flags & MNT_LOCAL) 37342253Sbostic PR("local"); 37441403Smckusick if (flags & MNT_EXPORTED) 37541403Smckusick if (flags & MNT_EXRDONLY) 37642253Sbostic PR("NFS exported read-only"); 37741285Smckusick else 37842253Sbostic PR("NFS exported"); 37942253Sbostic (void)printf(")\n"); 38035339Sbostic } 38135339Sbostic 38239133Smckusick getmnttype(fstype) 38339133Smckusick char *fstype; 38439133Smckusick { 38539133Smckusick 38639322Smckusick mntname = fstype; 38739133Smckusick if (!strcmp(fstype, "ufs")) 38839133Smckusick return (MOUNT_UFS); 38939133Smckusick if (!strcmp(fstype, "nfs")) 39039133Smckusick return (MOUNT_NFS); 39139133Smckusick if (!strcmp(fstype, "mfs")) 39239133Smckusick return (MOUNT_MFS); 39339133Smckusick return (0); 39439133Smckusick } 39539133Smckusick 39638632Smckusick usage() 39735339Sbostic { 39840871Smckusick 39940871Smckusick fprintf(stderr, "usage:\n mount %s %s\n mount %s\n mount %s\n", 40040871Smckusick "[ -frwu ] [ -t nfs | ufs | external_type ]", 40140871Smckusick "[ -o options ] special node", 40240871Smckusick "[ -afrwu ] [ -t nfs | ufs | external_type ]", 40340871Smckusick "[ -frwu ] special | node"); 40435339Sbostic exit(1); 40535339Sbostic } 40635339Sbostic 40739316Smckusick getstdopts(options, flagp) 40839316Smckusick char *options; 40942253Sbostic int *flagp; 41039316Smckusick { 41139316Smckusick register char *opt; 41239316Smckusick int negative; 41342253Sbostic char optbuf[BUFSIZ]; 41439316Smckusick 41542253Sbostic (void)strcpy(optbuf, options); 41642253Sbostic for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) { 41739316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 41839316Smckusick negative++; 41939316Smckusick opt += 2; 42039316Smckusick } else { 42139316Smckusick negative = 0; 42239316Smckusick } 42339333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 42441403Smckusick *flagp |= MNT_RDONLY; 42539333Smckusick continue; 42639333Smckusick } 42739333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 42841403Smckusick *flagp &= ~MNT_RDONLY; 42939333Smckusick continue; 43039333Smckusick } 43139316Smckusick if (!strcasecmp(opt, "exec")) { 43239316Smckusick if (negative) 43341403Smckusick *flagp |= MNT_NOEXEC; 43439333Smckusick else 43541403Smckusick *flagp &= ~MNT_NOEXEC; 43639316Smckusick continue; 43739316Smckusick } 43839316Smckusick if (!strcasecmp(opt, "suid")) { 43939316Smckusick if (negative) 44041403Smckusick *flagp |= MNT_NOSUID; 44139333Smckusick else 44241403Smckusick *flagp &= ~MNT_NOSUID; 44339316Smckusick continue; 44439316Smckusick } 44539316Smckusick if (!strcasecmp(opt, "dev")) { 44639316Smckusick if (negative) 44741403Smckusick *flagp |= MNT_NODEV; 44839333Smckusick else 44941403Smckusick *flagp &= ~MNT_NODEV; 45039316Smckusick continue; 45139316Smckusick } 45239316Smckusick if (!strcasecmp(opt, "synchronous")) { 45339316Smckusick if (!negative) 45441403Smckusick *flagp |= MNT_SYNCHRONOUS; 45539333Smckusick else 45641403Smckusick *flagp &= ~MNT_SYNCHRONOUS; 45739316Smckusick continue; 45839316Smckusick } 45939316Smckusick } 46039316Smckusick } 46139316Smckusick 46242253Sbostic /* ARGSUSED */ 46339131Smckusick getufsopts(options, flagp) 46439131Smckusick char *options; 46542253Sbostic int *flagp; 46639131Smckusick { 46739131Smckusick return; 46839131Smckusick } 46939131Smckusick 47039329Smckusick getexecopts(options, argv) 47139131Smckusick char *options; 47239131Smckusick char **argv; 47339131Smckusick { 47439131Smckusick register int argc = 0; 47539131Smckusick register char *opt; 47639131Smckusick 47742253Sbostic for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) { 47839131Smckusick if (opt[0] != '-') 47939131Smckusick continue; 48039131Smckusick argv[argc++] = opt; 48139131Smckusick if (opt[2] == '\0' || opt[2] != '=') 48239131Smckusick continue; 48339131Smckusick opt[2] = '\0'; 48439131Smckusick argv[argc++] = &opt[3]; 48539131Smckusick } 48639131Smckusick return (argc); 48739131Smckusick } 48839131Smckusick 48939465Smckusick struct statfs * 49039465Smckusick getmntpt(name) 49139465Smckusick char *name; 49239465Smckusick { 49339465Smckusick long mntsize; 49439465Smckusick register long i; 49539465Smckusick struct statfs *mntbuf; 49639465Smckusick 49740337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 49839465Smckusick for (i = 0; i < mntsize; i++) { 49939465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 50039465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 50139465Smckusick return (&mntbuf[i]); 50239465Smckusick } 50339465Smckusick return ((struct statfs *)0); 50439465Smckusick } 50539465Smckusick 50640051Smckusick static int skipvfs; 50740051Smckusick 50840051Smckusick badvfstype(vfstype, vfslist) 50942253Sbostic short vfstype; 51040051Smckusick char **vfslist; 51140051Smckusick { 51240051Smckusick 51340051Smckusick if (vfslist == 0) 51440051Smckusick return(0); 51540051Smckusick while (*vfslist) { 51640844Smckusick if (vfstype == getmnttype(*vfslist)) 51740051Smckusick return(skipvfs); 51840051Smckusick vfslist++; 51940051Smckusick } 52040051Smckusick return (!skipvfs); 52140051Smckusick } 52240051Smckusick 52340844Smckusick badvfsname(vfsname, vfslist) 52440844Smckusick char *vfsname; 52540844Smckusick char **vfslist; 52640844Smckusick { 52740844Smckusick 52840844Smckusick if (vfslist == 0) 52940844Smckusick return(0); 53040844Smckusick while (*vfslist) { 53140844Smckusick if (strcmp(vfsname, *vfslist) == 0) 53240844Smckusick return(skipvfs); 53340844Smckusick vfslist++; 53440844Smckusick } 53540844Smckusick return (!skipvfs); 53640844Smckusick } 53740844Smckusick 53840051Smckusick char ** 53940051Smckusick makevfslist(fslist) 54040051Smckusick char *fslist; 54140051Smckusick { 54240051Smckusick register char **av, *nextcp; 54340051Smckusick register int i; 54440051Smckusick 54540051Smckusick if (fslist == NULL) 54640051Smckusick return (NULL); 54740051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 54840051Smckusick fslist += 2; 54940051Smckusick skipvfs = 1; 55040051Smckusick } 55140051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 55240051Smckusick if (*nextcp == ',') 55340051Smckusick i++; 55442253Sbostic av = (char **)malloc((size_t)(i+2) * sizeof(char *)); 55540051Smckusick if (av == NULL) 55640051Smckusick return (NULL); 55740051Smckusick nextcp = fslist; 55840051Smckusick i = 0; 55940051Smckusick av[i++] = nextcp; 56040051Smckusick while (nextcp = index(nextcp, ',')) { 56140051Smckusick *nextcp++ = '\0'; 56240051Smckusick av[i++] = nextcp; 56340051Smckusick } 56440051Smckusick av[i++] = 0; 56540051Smckusick return (av); 56640051Smckusick } 56740051Smckusick 56838632Smckusick #ifdef NFS 56939131Smckusick /* 57039131Smckusick * Handle the getoption arg. 57139131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 57239131Smckusick */ 57339131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 57439131Smckusick char *optarg; 57539131Smckusick struct nfs_args *nfsargsp; 57639131Smckusick int *opflagsp; 57739131Smckusick int *retrycntp; 57839131Smckusick { 57939131Smckusick register char *cp, *nextcp; 58039131Smckusick int num; 58139131Smckusick char *nump; 58239131Smckusick 58339131Smckusick cp = optarg; 58439131Smckusick while (cp != NULL && *cp != '\0') { 58539131Smckusick if ((nextcp = index(cp, ',')) != NULL) 58639131Smckusick *nextcp++ = '\0'; 58739131Smckusick if ((nump = index(cp, '=')) != NULL) { 58839131Smckusick *nump++ = '\0'; 58939131Smckusick num = atoi(nump); 59039131Smckusick } else 59139131Smckusick num = -1; 59239131Smckusick /* 59339131Smckusick * Just test for a string match and do it 59439131Smckusick */ 59539131Smckusick if (!strcmp(cp, "bg")) { 59639131Smckusick *opflagsp |= BGRND; 59739131Smckusick } else if (!strcmp(cp, "soft")) { 59839131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 59939131Smckusick } else if (!strcmp(cp, "intr")) { 60039131Smckusick nfsargsp->flags |= NFSMNT_INT; 60141911Smckusick } else if (!strcmp(cp, "tcp")) { 60241911Smckusick nfsargsp->sotype = SOCK_STREAM; 60341911Smckusick } else if (!strcmp(cp, "noconn")) { 60441911Smckusick nfsargsp->flags |= NFSMNT_NOCONN; 60539131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 60639131Smckusick *retrycntp = num; 60739131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 60839131Smckusick nfsargsp->rsize = num; 60939131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 61039131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 61139131Smckusick nfsargsp->wsize = num; 61239131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 61339131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 61439131Smckusick nfsargsp->timeo = num; 61539131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 61639131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 61739131Smckusick nfsargsp->retrans = num; 61839131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 61939131Smckusick } 62039131Smckusick cp = nextcp; 62139131Smckusick } 62239131Smckusick } 62339131Smckusick 62438632Smckusick char * 62541911Smckusick getnfsargs(spec, nfsargsp) 62638632Smckusick char *spec; 62741911Smckusick struct nfs_args *nfsargsp; 62835339Sbostic { 62940273Sbostic extern int errno; 63038632Smckusick register CLIENT *clp; 63138632Smckusick struct hostent *hp; 63239604Smckusick static struct sockaddr_in saddr; 63338632Smckusick struct timeval pertry, try; 63438632Smckusick enum clnt_stat clnt_stat; 63538632Smckusick int so = RPC_ANYSOCK; 63638632Smckusick char *hostp, *delimp; 63738632Smckusick u_short tport; 63839604Smckusick static struct nfhret nfhret; 63939604Smckusick static char nam[MNAMELEN + 1]; 64038632Smckusick 64138632Smckusick strncpy(nam, spec, MNAMELEN); 64238632Smckusick nam[MNAMELEN] = '\0'; 64338632Smckusick if ((delimp = index(spec, '@')) != NULL) { 64438632Smckusick hostp = delimp + 1; 64538632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 64638632Smckusick hostp = spec; 64738632Smckusick spec = delimp + 1; 64838632Smckusick } else { 64938632Smckusick fprintf(stderr, 65038632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 65138632Smckusick return (0); 65238632Smckusick } 65338632Smckusick *delimp = '\0'; 65438632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 65538632Smckusick fprintf(stderr, "Can't get net id for host\n"); 65638632Smckusick return (0); 65738632Smckusick } 65838632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 65938632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 66038632Smckusick while (retrycnt > 0) { 66138632Smckusick saddr.sin_family = AF_INET; 66238632Smckusick saddr.sin_port = htons(PMAPPORT); 66338632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 66438632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 66538632Smckusick if ((opflags & ISBGRND) == 0) 66638632Smckusick clnt_pcreateerror("NFS Portmap"); 66738632Smckusick } else { 66838632Smckusick saddr.sin_port = 0; 66938632Smckusick pertry.tv_sec = 10; 67038632Smckusick pertry.tv_usec = 0; 67138632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 67238632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 67338632Smckusick if ((opflags & ISBGRND) == 0) 67438632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 67538632Smckusick } else { 67638632Smckusick clp->cl_auth = authunix_create_default(); 67738632Smckusick try.tv_sec = 10; 67838632Smckusick try.tv_usec = 0; 67938632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 68038632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 68138632Smckusick if (clnt_stat != RPC_SUCCESS) { 68238632Smckusick if ((opflags & ISBGRND) == 0) 68338632Smckusick clnt_perror(clp, "Bad MNT RPC"); 68438632Smckusick } else { 68538632Smckusick auth_destroy(clp->cl_auth); 68638632Smckusick clnt_destroy(clp); 68738632Smckusick retrycnt = 0; 68838632Smckusick } 68938632Smckusick } 69038632Smckusick } 69138632Smckusick if (--retrycnt > 0) { 69238632Smckusick if (opflags & BGRND) { 69338632Smckusick opflags &= ~BGRND; 69438632Smckusick if (fork()) 69538632Smckusick return (0); 69638632Smckusick else 69738632Smckusick opflags |= ISBGRND; 69838632Smckusick } 69938632Smckusick sleep(10); 70038632Smckusick } 70138632Smckusick } 70238632Smckusick if (nfhret.stat) { 70338632Smckusick if (opflags & ISBGRND) 70438632Smckusick exit(1); 70539521Smckusick fprintf(stderr, "Can't access %s: ", spec); 70639521Smckusick errno = nfhret.stat; 70742253Sbostic perror((char *)NULL); 70838632Smckusick return (0); 70938632Smckusick } 71038632Smckusick saddr.sin_port = htons(tport); 71141911Smckusick nfsargsp->addr = (struct sockaddr *) &saddr; 71241911Smckusick nfsargsp->fh = &nfhret.nfh; 71341911Smckusick nfsargsp->hostname = nam; 71441911Smckusick return ((caddr_t)nfsargsp); 71535339Sbostic } 71638445Smckusick 71738445Smckusick /* 71838445Smckusick * xdr routines for mount rpc's 71938445Smckusick */ 72038445Smckusick xdr_dir(xdrsp, dirp) 72138445Smckusick XDR *xdrsp; 72238445Smckusick char *dirp; 72338445Smckusick { 72438445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 72538445Smckusick } 72638445Smckusick 72738445Smckusick xdr_fh(xdrsp, np) 72838445Smckusick XDR *xdrsp; 72938445Smckusick struct nfhret *np; 73038445Smckusick { 73138445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 73238445Smckusick return (0); 73338445Smckusick if (np->stat) 73438445Smckusick return (1); 73538445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 73638445Smckusick } 73738632Smckusick #endif /* NFS */ 738